Пример #1
0
void laser_rescale_2()
/* Instead of just rescaling, add the momentum increment in random direction.
   Only thereafter rescale so the right amount of energy gets absorbed.
   Involves several square roots, probably slower
*/ 
{

  real exp_gauss_time_etc, gauss_time_squared, gauss_time_squared1;
  int k;

  gauss_time_squared = timestep * steps - laser_t_0;
  gauss_time_squared *= gauss_time_squared;
  exp_gauss_time_etc = exp(-gauss_time_squared/laser_sigma_t_squared/2.0)
                       * laser_p_peak * timestep * laser_atom_vol;
  if (laser_t_1>0) {
    gauss_time_squared1 = timestep * steps - laser_t_1;
    gauss_time_squared1 *= gauss_time_squared1;
    exp_gauss_time_etc += exp(-gauss_time_squared1/laser_sigma_t1_squared/2.0)
                       * laser_p_peak1 * timestep * laser_atom_vol;
  }

  for (k=0; k<NCELLS; k++) {
    cell *p;
    p = CELLPTR(k);
    int i;
    for (i=0; i < p->n; i++) {
      real p_0_square; /* square of initial atom momentum */
      real p_0;
      real de; /* Kinetic energy to be added to the atom */
      real dp;
      real depth; /* Distance from origin along laser_dir */
      real tmpx, tmpy, tmpsqr;
#ifndef TWOD
      real tmpz;
#endif
      real scale_p; /* Scale factor for atom momentum */

      p_0_square = SPRODN(IMPULS,p,i,IMPULS,p,i);
      p_0=sqrt(p_0_square);

      depth = laser_calc_depth(p,i);

#ifdef LASERYZ  /* spacial dependence of laser beam */    
    
    
      double x = ORT(p,i,X);
      double y = ORT(p,i,Y);
      double z = ORT(p,i,Z);
      de = exp( -laser_mu*depth ) * exp_gauss_time_etc * laser_intensity_profile(x,y,z);   

#else
      de = exp(-laser_mu*depth) * exp_gauss_time_etc;
    
#endif
      dp = sqrt( p_0_square + 2*de*MASSE(p,i) ) - p_0;
    

      /* Momentum increment is to point in a random direction... */
#ifndef TWOD
      rand_uvec_3d(&tmpx, &tmpy, &tmpz);
#else
      rand_uvec_2d(&tmpx, &tmpy);
#endif
      IMPULS(p,i,X) += tmpx * dp;
      IMPULS(p,i,Y) += tmpy * dp;
#ifndef TWOD
      IMPULS(p,i,Z) += tmpz * dp;
#endif

      /* rescale present momentum to an absolute value of dp + p_0 */
      scale_p = (p_0 + dp) / SQRT( SPRODN(IMPULS,p,i,IMPULS,p,i) );
      IMPULS(p,i,X) *= scale_p;
      IMPULS(p,i,Y) *= scale_p;
#ifndef TWOD
      IMPULS(p,i,Z) *= scale_p;
#endif
    
    }
  }
} /* void laser_rescale_2()*/
Пример #2
0
void maxwell(real temp)
{ 
   int         k;
   vektor      tot_impuls;
   int         nactive_x, nactive_y, nactive_z;
   static long dummy = 0;
   int slice;
#ifdef DAMP
   real tmp1,tmp2,tmp3,f,maxax,maxax2;
#endif
#ifdef LASER
   real depth;
#endif

#ifdef UNIAX
   real xisq;
   real xi0;
   real xi1;
   real xi2;
   real dot;
   real norm;
   real osq;
#endif
   real   TEMP;
   real   scale, xx, tmp;
   int    num, nhalf, typ;

   TEMP = temp;
   tot_impuls.x = 0.0;   nactive_x = 0;
   tot_impuls.y = 0.0;   nactive_y = 0;
#ifndef TWOD
   tot_impuls.z = 0.0;   nactive_z = 0;
#endif

   /* set temperature */
   for (k=0; k<NCELLS; ++k) {

      int i;
      cell *p;
      vektor *rest;

      p = CELLPTR(k);

      for (i=0; i<p->n; ++i) {
#ifdef LASER
	 depth =   laser_dir.x * ORT(p,i,X)
		 + laser_dir.y * ORT(p,i,Y)
#ifndef TWOD
		 + laser_dir.z * ORT(p,i,Z)
#endif
	 ;
	 depth -= laser_offset;
         if (depth < 0) {
	   depth=0; /* we don't want to exceed laser_delta_temp */
         }
	 
	 TEMP =  laser_delta_temp * exp(-laser_mu * depth);
         TEMP += temperature; /* add base temperature of sample */

#endif /* LASER */

#ifdef DAMP
            /* Calculate stadium function f */
         maxax = MAX(MAX(stadium.x,stadium.y),stadium.z);
         maxax2 = MAX(MAX(stadium2.x,stadium2.y),stadium2.z);

         tmp1 = (stadium2.x == 0) ? 0 : SQR((ORT(p,i,X)-center.x)/(2.0*stadium2.x));
         tmp2 = (stadium2.y == 0) ? 0 : SQR((ORT(p,i,Y)-center.y)/(2.0*stadium2.y));
         tmp3 = (stadium2.z == 0) ? 0 : SQR((ORT(p,i,Z)-center.z)/(2.0*stadium2.z));

         f    = (tmp1+tmp2+tmp3-SQR(maxax/(2.0*maxax2)))/\
             (.25- SQR(maxax/(2.0*maxax2)));

         if (f<= 0.0)
             f = 0.0;
         else if (f>1.0)
             f = 1.0;

      /* we smooth the stadium function: to get a real bath tub !
        fully damped atoms have temp=0, temperature gradient determined
          by bath tub */
         if (f !=0)
             TEMP = damptemp * (1.0 - 0.5 * (1 + sin(-M_PI/2.0 + M_PI*f)));
         else TEMP= temp;

#endif

#ifdef FTG
	  /* calc slice and set TEMP  */
	 tmp = ORT(p,i,X) / box_x.x;
	 slice = (int) nslices * tmp;
	 if (slice<0)        slice = 0;
	 if (slice>=nslices) slice = nslices -1;;
	 
	 TEMP=  Tleft + (Tright-Tleft)*(slice-nslices_Left+1) /
	   (real) (nslices-nslices_Left-nslices_Right+1);
    
	 if (slice>=nslices-nslices_Right) TEMP = Tright;
	 if (slice<nslices_Left)           TEMP=  Tleft;
#endif
         
	 tmp  = sqrt(TEMP * MASSE(p,i));
         rest = restrictions + VSORTE(p,i);
#ifndef RIGID
         IMPULS(p,i,X) = imd_gaussian(tmp) * rest->x;
         IMPULS(p,i,Y) = imd_gaussian(tmp) * rest->y;
#ifndef TWOD
         IMPULS(p,i,Z) = imd_gaussian(tmp) * rest->z;
#endif
#else
	 /* superatoms get velocity zero */
	 if (superatom[VSORTE(p,i)]>-1) {
	   IMPULS(p,i,X) = 0.0;
	   IMPULS(p,i,Y) = 0.0;
#ifndef TWOD
	   IMPULS(p,i,Z) = 0.0;
#endif
	 }
#endif
         nactive_x += (int) rest->x;
         nactive_y += (int) rest->y;
#ifndef TWOD
         nactive_z += (int) rest->z;
#endif
         tot_impuls.x += IMPULS(p,i,X);
         tot_impuls.y += IMPULS(p,i,Y);
#ifndef TWOD
         tot_impuls.z += IMPULS(p,i,Z);
#endif

#ifdef UNIAX

         /* angular velocities for uniaxial molecules */

         /* choose a random vector in space */

         do {
           xi1 = 2.0 * drand48() - 1.0 ;
           xi2 = 2.0 * drand48() - 1.0 ;
           xisq = xi1 * xi1 + xi2 * xi2 ;
         } while ( xisq >= 1.0 );

         xi0 = sqrt( 1.0 - xisq ) ;

         DREH_IMPULS(p,i,X) = 2.0 * xi1 * xi0 ;
         DREH_IMPULS(p,i,Y) = 2.0 * xi2 * xi0 ;
         DREH_IMPULS(p,i,Z) = 1.0 - 2.0 * xisq ;

        /* constrain the vector to be perpendicular to the molecule */

        dot = SPRODN(DREH_IMPULS,p,i,ACHSE,p,i);

        DREH_IMPULS(p,i,X) -= dot * ACHSE(p,i,X) ; 
        DREH_IMPULS(p,i,Y) -= dot * ACHSE(p,i,Y) ; 
        DREH_IMPULS(p,i,Z) -= dot * ACHSE(p,i,Z) ; 

        /* renormalize vector */	   

        osq = SPRODN(DREH_IMPULS,p,i,DREH_IMPULS,p,i);
        norm = SQRT( osq );

        DREH_IMPULS(p,i,X) /= norm ;
        DREH_IMPULS(p,i,Y) /= norm ;
        DREH_IMPULS(p,i,Z) /= norm ;

        /* choose the magnitude of the angular momentum */

        osq = - 2.0 * uniax_inert * TEMP * log( drand48() ) ;
        norm = sqrt( osq );

        DREH_IMPULS(p,i,X) *= norm ;
        DREH_IMPULS(p,i,Y) *= norm ;
        DREH_IMPULS(p,i,Z) *= norm ;

#endif /* UNIAX */

#ifdef SHOCK
	/* plate against bulk */
	 if (shock_mode == 1) {
	   if ( ORT(p,i,X) < shock_strip ) 
	       IMPULS(p,i,X) += shock_speed * MASSE(p,i);
	 }
	 /* two halves against one another */
	 if (shock_mode == 2) {
	   if ( ORT(p,i,X) < box_x.x*0.5 ) 
	     IMPULS(p,i,X) += shock_speed * MASSE(p,i);
	   else
	     IMPULS(p,i,X) -= shock_speed * MASSE(p,i);
	 }
	 /* bulk against wall */
	 if (shock_mode == 3) IMPULS(p,i,X) += shock_speed * MASSE(p,i);
#endif
      }
   }

#ifdef CLONE

   /* compute the total momentum afresh */
   tot_impuls.x = 0.0;
   tot_impuls.y = 0.0;
#ifndef TWOD
   tot_impuls.z = 0.0;
#endif

   /* set velocities of clones equal */
   for (k=0; k<NCELLS; k++) {

      int i, j;
      cell *p;
      p = CELLPTR(k);

      for (i=0; i<p->n; i+=nclones) {

        tot_impuls.x += nclones * IMPULS(p,i,X);
        tot_impuls.y += nclones * IMPULS(p,i,Y);
#ifndef TWOD
        tot_impuls.z += nclones * IMPULS(p,i,Z);
#endif
	for (j=1; j<nclones; j++) {
          IMPULS(p,i+j,X) = IMPULS(p,i,X);
          IMPULS(p,i+j,Y) = IMPULS(p,i,Y);
#ifndef TWOD
          IMPULS(p,i+j,Z) = IMPULS(p,i,Z);
#endif
        }
      }
   }

#endif /* CLONE */

   tot_impuls.x = nactive_x == 0 ? 0.0 : tot_impuls.x / nactive_x;
   tot_impuls.y = nactive_y == 0 ? 0.0 : tot_impuls.y / nactive_y;
#ifndef TWOD
   tot_impuls.z = nactive_z == 0 ? 0.0 : tot_impuls.z / nactive_z;
#endif

   /* correct center of mass momentum */
   for (k=0; k<NCELLS; ++k) {
      int i;
      cell *p;
      vektor *rest;
      p = CELLPTR(k);
      for (i=0; i<p->n; ++i) {
         rest = restrictions + VSORTE(p,i);
         IMPULS(p,i,X) -= tot_impuls.x * rest->x;
         IMPULS(p,i,Y) -= tot_impuls.y * rest->y;
#ifndef TWOD
         IMPULS(p,i,Z) -= tot_impuls.z * rest->z;
#endif
      }
   }

} 
Пример #3
0
void laser_rescale_1()
{ /* Rescale all atom velocities so that exactly the same amount of
     kinetic energy is added to the atoms at a given depth.
     The direction of the momentum vectors remains unchanged, except for
     zero-velocity atoms, which will be given a random direction.*/

  real exp_gauss_time_etc, gauss_time_squared, gauss_time_squared1;
  int k;
  real cosph, sinph, theta, costh, sinth;

  gauss_time_squared = timestep * steps - laser_t_0;
  gauss_time_squared *= gauss_time_squared;
  exp_gauss_time_etc = exp(-gauss_time_squared/laser_sigma_t_squared/2.0)
                       * laser_p_peak * timestep * laser_atom_vol;
  if (laser_t_1>0) {
    gauss_time_squared1 = timestep * steps - laser_t_1;
    gauss_time_squared1 *= gauss_time_squared1;
    exp_gauss_time_etc += exp(-gauss_time_squared1/laser_sigma_t1_squared/2.0)
                       * laser_p_peak1 * timestep * laser_atom_vol;
  }


  for (k=0; k<NCELLS; k++) {
    cell *p;
    p = CELLPTR(k);
    int i;
    for (i=0; i < p->n; i++) {
      real p_0_square; /* square of initial atom momentum */
      real de; /* Kinetic energy to be added to the atom */
      real depth; /* Distance from origin along laser_dir */
      real tmpx, tmpy, tmpsqr;
#ifndef TWOD
      real tmpz;
#endif
      real scale_p; /* Scale factor for atom momentum */

      p_0_square = SPRODN(IMPULS,p,i,IMPULS,p,i);
      depth = laser_calc_depth(p,i);

#ifdef PDECAY
	if( ORT(p,i,X) > ramp_start )
	  {
	    switch ( pdecay_mode){
	    case 0:
	      {
		/* y= m * x + b */
		double m = 1 / ( (ramp_end - ramp_start ) ) ;
		double b = - ramp_start / ( ramp_end - ramp_start );
		
		double xia = ORT(p,i,X) *m + b ;
	
		IMPULS(p,i,X) *= 1.0 - ( ORT(p,i,X) *m + b)  ;
		
		if(steps==-1)
		  printf(" %f %f \n",  ORT(p,i,X),1.0 - ( ORT(p,i,X) * m + b) );
		break;
	      }
	    case 1:	      
	      {
		double a = 1.0 / ( ramp_start - ramp_end);
		a *= a;
	
		IMPULS(p,i,X) *= a * ( ORT(p,i,X) - ramp_end ) * ( ORT(p,i,X) - ramp_end );

		if(steps==-1)
		  printf("%f %f \n",  ORT(p,i,X), a * ( ORT(p,i,X) - ramp_end ) * ( ORT(p,i,X) - ramp_end ));
		break;
	      }
	      break;
	    case 2:
	      {
		double m = 1 / ( (ramp_end - ramp_start ) ) ;
		double b = - ramp_start / ( ramp_end - ramp_start );
		
		KRAFT(p,i,X) -=  ( IMPULS(p,i,X)/MASSE(p,i)) * ( ORT(p,i,X) *m + b  ) * xipdecay;
		
		
		if(steps==-1)
		  printf(" %f %f \n",  ORT(p,i,X),ORT(p,i,X) *m + b);
		break;
	      }
	      break;
	    case 3:
	      {
		double a = 1.0 / ( ramp_end - ramp_start);
		a *= a;
			
		 KRAFT(p,i,X) -=  ( IMPULS(p,i,X)/MASSE(p,i)) * xipdecay * a * ( ORT(p,i,X) - ramp_start ) * ( ORT(p,i,X) - ramp_start );

		if(steps==-1)
		  printf("%f %f \n",  ORT(p,i,X), a * ( ORT(p,i,X) - ramp_start ) * ( ORT(p,i,X) - ramp_start ) );
		break;
	      }
	      break;
	    default:
	      error("Illegal value for parameter pdecay_mode.\n");
	      break;
	    }
	  }
#endif 


#ifdef LASERYZ  /* spacial dependence of laser beam */    
    
     
      double x = ORT(p,i,X);
      double y = ORT(p,i,Y);
      double z = ORT(p,i,Z);
   
      
     
      de = exp( -laser_mu*depth ) * exp_gauss_time_etc * laser_intensity_profile(x,y,z);     
  
    

#else
      de = exp(-laser_mu*depth) * exp_gauss_time_etc;
       
#endif         

       if ( p_0_square == 0.0 ) { /* we need a direction for the momentum. */
#ifndef TWOD
        /* find random 3d unit vector */
        rand_uvec_3d(&tmpx, &tmpy, &tmpz);
#else
        /* find random 2d unit vector */
        rand_uvec_2d(&tmpx, &tmpy);      
#endif
        scale_p = sqrt( de * 2.0 * MASSE(p,i) );
        IMPULS(p,i,X) = tmpx * scale_p;
        IMPULS(p,i,Y) = tmpy * scale_p;
#ifndef TWOD
        IMPULS(p,i,Z) = tmpz * scale_p;
#endif
      } else { /* rescale present momentum */

        scale_p = sqrt( de * 2.0 * MASSE(p,i) / p_0_square + 1.0 );
        IMPULS(p,i,X) *= scale_p;
        IMPULS(p,i,Y) *= scale_p;
#ifndef TWOD
        IMPULS(p,i,Z) *= scale_p;
#endif

      }
    }
  }
} /* void laser_rescale_1()*/