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()*/
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 } } }
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()*/