void adjust() { int k; for (k=0; k<ncells; ++k) { cell *p; int i,typ; real x,y,z; p = cell_array + CELLS(k); for (i=0; i<p->n; ++i) { x = ORT(p,i,X)-0.1; y = ORT(p,i,Y)-0.1; z = ORT(p,i,Z)-0.1; typ = VSORTE(p,i); /* fix the type of the first atom */ if (FABS(x+2.*gmin.x) < 0.0001 && FABS(y+2.*gmin.y) < 0.0001 && FABS(z+2.*gmin.z) < 0.0001) { typ=0; SORTE (p,i) = typ; VSORTE(p,i) = typ; } num_sort[typ]++; } } }
void init_extpot(void) { long tmpvec1[3], tmpvec2[3]; int i,k,sort; nactive_vect[0]=0; nactive_vect[1]=0; nactive_vect[2]=0; if (0==myid) { printf( "EXTPOT: choosen potential ep_key = %d\n", ep_key); printf( "EXTPOT: number of indenters = %d\n", ep_n); printf( "EXTPOT: number of walls = %d\n", ep_n-ep_nind); printf( "EXTPOT: external potential constant = %f\n",ep_a ); printf( "EXTPOT: cutoff radius = %f\n", ep_rcut ); for (i=0; i<ep_n; i++) { printf("EXTPOT: ep_pos #%d %.10g %.10g %.10g \n", i, ep_pos[i].x, ep_pos[i].y, ep_pos[i].z); printf("EXTPOT: ep_vel #%d %.10g %.10g %.10g \n", i, ep_vel[i].x, ep_vel[i].y, ep_vel[i].z); printf("EXTPOT: ep_dir #%d %.10g %.10g %.10g \n", i, ep_dir[i].x, ep_dir[i].y, ep_dir[i].z); } } /* needed if the indenter impulse should be balanced */ /* might not work with 2D, epitax, clone, superatom */ if(ep_key==1 || ep_key==2 ){ for (k=0; k<NCELLS; ++k) { cell *p = CELLPTR(k); for (i=0; i<p->n; ++i) { sort = VSORTE(p,i); nactive_vect[0] += (restrictions + sort)->x; nactive_vect[1] += (restrictions + sort)->y; nactive_vect[2] += (restrictions + sort)->z; } } #ifdef MPI tmpvec1[0] = nactive_vect[0] ; tmpvec1[1] = nactive_vect[1] ; tmpvec1[2] = nactive_vect[2] ; MPI_Allreduce( tmpvec1, tmpvec2, 3, MPI_LONG, MPI_SUM, MPI_COMM_WORLD); nactive_vect[0] = tmpvec2[0]; nactive_vect[1] = tmpvec2[1]; nactive_vect[2] = tmpvec2[2]; #endif if (0==myid) { if (nactive_vect[0] == 0 || nactive_vect[1] == 0 || nactive_vect[2] == 0) error ("ep_key=1 requires atoms free to move in all directions\n"); printf("EXTPOT: active degrees of freedom: x %ld y %ld z %ld\n",nactive_vect[0],nactive_vect[1],nactive_vect[2]); } #ifdef RELAX printf( "EXTPOT: max number of relaxation steps = %d\n", ep_max_int); printf( "EXTPOT: ekin_threshold = %f\n", glok_ekin_threshold); printf( "EXTPOT: fnorm_threshold = %f\n", fnorm_threshold); #endif } }
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 fix_cells(void) { int i,j,k,l,clone,to_cpu, ii; minicell *p, *q; ivektor coord, lcoord; msgbuf *buf; #ifdef MPI empty_mpi_buffers(); #endif /* apply periodic boundary conditions */ do_boundaries(); /* for each cell in bulk */ for (i=cellmin.x; i < cellmax.x; ++i) for (j=cellmin.y; j < cellmax.y; ++j) for (k=cellmin.z; k < cellmax.z; ++k) { p = PTR_3D_V(cell_array, i, j, k, cell_dim); #ifdef LOADBALANCE /* Only check content in real cells */ if (p->lb_cell_type != LB_REAL_CELL) continue; #endif /* loop over atoms in cell */ l=0; while( l<p->n ) { coord = cell_coord( ORT(p,l,X), ORT(p,l,Y), ORT(p,l,Z) ); lcoord = local_cell_coord( coord ); #ifdef LOADBALANCE /* Wrap around pbcs if necessary to get the correct index using the loadbalance scheme*/ if (cpu_dim.x >= 2 && pbc_dirs.x == 1) { if (lcoord.x >= global_cell_dim.x) lcoord.x -= global_cell_dim.x; if (lcoord.x < 0) lcoord.x += global_cell_dim.x; } if (cpu_dim.y >= 2 && pbc_dirs.y == 1) { if (lcoord.y >= global_cell_dim.y) lcoord.y -= global_cell_dim.y; if (lcoord.y < 0) lcoord.y += global_cell_dim.y; } if (cpu_dim.z >= 2 && pbc_dirs.z == 1) { if (lcoord.z >= global_cell_dim.z) lcoord.z -= global_cell_dim.z; if (lcoord.z < 0) lcoord.z += global_cell_dim.z; } #endif /* see if atom is in wrong cell */ if ((lcoord.x == i) && (lcoord.y == j) && (lcoord.z == k)) { l++; } else { #ifdef LOADBALANCE if (lcoord.x< 0 || lcoord.x >= cell_dim.x || lcoord.y < 0 || lcoord.y >= cell_dim.y || lcoord.z < 0 || lcoord.z >= cell_dim.z || (PTR_VV(cell_array,lcoord,cell_dim))->lb_cell_type == LB_EMPTY_CELL) { error("LB: Illegal cell accessed, Atom jumped multiple CPUs"); } to_cpu = (PTR_VV(cell_array,lcoord,cell_dim))->lb_cpu_affinity; #else to_cpu = cpu_coord(coord); #endif buf = NULL; /* atom is on my cpu */ if (to_cpu==myid) { q = PTR_VV(cell_array,lcoord,cell_dim); MOVE_ATOM(q, p, l); #ifdef CLONE if (l < p->n-nclones) for (clone=1; clone<nclones; clone++) MOVE_ATOM(q, p, l+clone); else /* we are dealing with the last in the stack */ for (clone=1; clone<nclones; clone++) MOVE_ATOM(q, p, l); #endif } #ifdef MPI #ifdef LOADBALANCE else { buf = &lb_send_buf[(PTR_VV(cell_array,lcoord,cell_dim))->lb_neighbor_index]; } #else /* west */ else if ((cpu_dim.x>1) && ((to_cpu==nbwest) || (to_cpu==nbnw) || (to_cpu==nbws) || (to_cpu==nbuw ) || (to_cpu==nbunw) || (to_cpu==nbuws)|| (to_cpu==nbdw ) || (to_cpu==nbdwn) || (to_cpu==nbdsw))) { buf = &send_buf_west; } /* east */ else if ((cpu_dim.x>1) && ((to_cpu==nbeast) || (to_cpu==nbse) || (to_cpu==nben) || (to_cpu==nbue ) || (to_cpu==nbuse) || (to_cpu==nbuen)|| (to_cpu==nbde ) || (to_cpu==nbdes) || (to_cpu==nbdne))) { buf = &send_buf_east; } /* south */ else if ((cpu_dim.y>1) && ((to_cpu==nbsouth) || (to_cpu==nbus) || (to_cpu==nbds))) { buf = &send_buf_south; } /* north */ else if ((cpu_dim.y>1) && ((to_cpu==nbnorth) || (to_cpu==nbun) || (to_cpu==nbdn))) { buf = &send_buf_north; } /* down */ else if ((cpu_dim.z>1) && (to_cpu==nbdown)) { buf = &send_buf_down; } /* up */ else if ((cpu_dim.z>1) && (to_cpu==nbup)) { buf = &send_buf_up; } else { #ifdef SHOCK /* remove atom from simulation */ buf = &dump_buf; dump_buf.n = 0; natoms -= nclones; nactive -= nclones * DIM; num_sort [ SORTE(p,l)] -= nclones; num_vsort[VSORTE(p,l)] -= nclones; warning("Atom jumped multiple CPUs"); #else error("Atom jumped multiple CPUs"); #endif } #endif /* not LOADBALANCE*/ if (buf != NULL) { copy_one_atom( buf, to_cpu, p, l, 1); #ifdef CLONE if (l < p->n-nclones) for (clone=1; clone<nclones; clone++) copy_one_atom( buf, to_cpu, p, l+clone, 1); else /* we are dealing with the last in the stack */ for (clone=1; clone<nclones; clone++) copy_one_atom( buf, to_cpu, p, l, 1); #endif } #endif /* MPI */ } } }
void sortin (int ifeld[]) { int typ,sign,icell,i,hv,it,to_cpu; ivektor cellc; real x,y,z,dx,dy,dz,dist; cell *p, *q; x=tx[0]*ifeld[0]+tx[1]*ifeld[1]+tx[2]*ifeld[2]+ tx[3]*ifeld[3]+tx[4]*ifeld[4]+tx[5]*ifeld[5]+0.1-2.*gmin.x; y=ty[0]*ifeld[0]+ty[1]*ifeld[1]+ty[2]*ifeld[2]+ ty[3]*ifeld[3]+ty[4]*ifeld[4]+ty[5]*ifeld[5]+0.1-2.*gmin.y; z=tz[0]*ifeld[0]+tz[1]*ifeld[1]+tz[2]*ifeld[2]+ tz[3]*ifeld[3]+tz[4]*ifeld[4]+tz[5]*ifeld[5]+0.1-2.*gmin.z; if (x < perp[0] && y < perp[1] && z < perp[2] && x > perm[0] && y > perm[1] && z > perm[2]) { cellc = cell_coord(x, y, z); #ifdef BUFCELLS cellc = local_cell_coord(cellc); #endif p = PTR_3D_VV(cell_array,cellc,cell_dim); hv=1; for (i = 0 ; i < p->n; i++) { dx = x - ORT(p,i,X); dy = y - ORT(p,i,Y); dz = z - ORT(p,i,Z); dist = dx*dx+dy*dy+dz*dz; if (dist < 0.01) { hv=0; break; } } if (hv == 1) { natoms++; nactive +=3; input->n = 1; ORT(input,0,X) = x; ORT(input,0,Y) = y; ORT(input,0,Z) = z; NUMMER(input,0) = natoms; typ=ifeld[6]-1; if (FABS(x+2.*gmin.x) < 0.0001 && FABS(y+2.*gmin.y) < 0.0001 && FABS(z+2.*gmin.z) < 0.0001) typ=0; if (typ == 1) typ=0; if (typ == 2) typ=1; SORTE (input,0) = typ; VSORTE(input,0) = typ; MASSE(input,0) = masses[typ]; INSERT_ATOM(p, input, 0); } } }