void c_ggrid::sommerfeld( nec_float epr, nec_float sig, nec_float freq_mhz ) { static nec_complex const1_neg = - nec_complex(0.0,4.771341189); int nth, irs, nr; nec_float tim, wavelength, tst, dr, dth, r, rk, thet, tfac1, tfac2; nec_complex erv, ezv, erh, eph, cl1, cl2, con; if(sig >= 0.0) { wavelength=CVEL/freq_mhz; m_epscf=nec_complex(epr,-sig*wavelength*59.96); } else m_epscf=nec_complex(epr,sig); secnds(&tst); m_evlcom.m_ck2=two_pi(); m_evlcom.m_ck2sq=m_evlcom.m_ck2*m_evlcom.m_ck2; /* sommerfeld integral evaluation uses exp(-jwt), nec uses exp(+jwt), */ /* hence need conjg(epscf). conjugate of fields occurs in subroutine */ /* evlua. */ m_evlcom.m_ck1sq=m_evlcom.m_ck2sq*conj(m_epscf); m_evlcom.m_ck1=sqrt(m_evlcom.m_ck1sq); m_evlcom.m_ck1r=real(m_evlcom.m_ck1); m_evlcom.m_tkmag=100.0*abs(m_evlcom.m_ck1); // m_evlcom.m_tsmag=100.0*abs(m_evlcom.m_ck1*conj(m_evlcom.m_ck1)); // TCAM added abs() m_evlcom.m_tsmag=100.0*norm(m_evlcom.m_ck1); // TCAM changed from previous line m_evlcom.m_cksm=m_evlcom.m_ck2sq/(m_evlcom.m_ck1sq+m_evlcom.m_ck2sq); m_evlcom.m_ct1=.5*(m_evlcom.m_ck1sq-m_evlcom.m_ck2sq); erv=m_evlcom.m_ck1sq*m_evlcom.m_ck1sq; ezv=m_evlcom.m_ck2sq*m_evlcom.m_ck2sq; m_evlcom.m_ct2=.125*(erv-ezv); erv *= m_evlcom.m_ck1sq; ezv *= m_evlcom.m_ck2sq; m_evlcom.m_ct3=.0625*(erv-ezv); /* loop over 3 grid regions */ for (int k = 0; k < 3; k++ ) { nr = m_nxa[k]; nth = m_nya[k]; dr = m_dxa[k]; dth = m_dya[k]; r = m_xsa[k]-dr; irs=1; if(k == 0) { r=m_xsa[k]; irs=2; } /* loop over r. (r=sqrt(m_evlcom.m_rho**2 + (z+h)**2)) */ for (int ir = irs-1; ir < nr; ir++ ) { r += dr; thet = m_ysa[k]-dth; /* loop over theta. (theta=atan((z+h)/m_evlcom.m_rho)) */ for (int ith = 0; ith < nth; ith++ ) { thet += dth; m_evlcom.m_rho=r*cos(thet); m_evlcom.m_zph=r*sin(thet); if(m_evlcom.m_rho < 1.e-7) m_evlcom.m_rho=1.e-8; if(m_evlcom.m_zph < 1.e-7) m_evlcom.m_zph=0.; m_evlcom.evlua( &erv, &ezv, &erh, &eph ); rk=m_evlcom.m_ck2*r; con=const1_neg*r/nec_complex(cos(rk),-sin(rk)); switch( k ) { case 0: m_ar1[ir+ith*11+ 0]=erv*con; m_ar1[ir+ith*11+110]=ezv*con; m_ar1[ir+ith*11+220]=erh*con; m_ar1[ir+ith*11+330]=eph*con; break; case 1: m_ar2[ir+ith*17+ 0]=erv*con; m_ar2[ir+ith*17+ 85]=ezv*con; m_ar2[ir+ith*17+170]=erh*con; m_ar2[ir+ith*17+255]=eph*con; break; case 2: m_ar3[ir+ith*9+ 0]=erv*con; m_ar3[ir+ith*9+ 72]=ezv*con; m_ar3[ir+ith*9+144]=erh*con; m_ar3[ir+ith*9+216]=eph*con; } /* switch( k ) */ } /* for ( ith = 0; ith < nth; ith++ ) */ } /* for ( ir = irs-1; ir < nr; ir++; ) */ } /* for ( k = 0; k < 3; k++; ) */ /* fill grid 1 for r equal to zero. */ cl2 = -CONST4*(m_epscf-1.)/(m_epscf+1.); cl1 = cl2/(m_epscf+1.); ezv = m_epscf*cl1; thet=-dth; nth = m_nya[0]; for (int ith = 0; ith < nth; ith++ ) { thet += dth; if( (ith+1) != nth ) { tfac2=cos(thet); tfac1=(1.-sin(thet))/tfac2; tfac2=tfac1/tfac2; erv=m_epscf*cl1*tfac1; erh=cl1*(tfac2-1.)+cl2; eph=cl1*tfac2-cl2; } else { erv=0.; erh=cl2-.5*cl1; eph=-erh; } m_ar1[0+ith*11+ 0]=erv; m_ar1[0+ith*11+110]=ezv; m_ar1[0+ith*11+220]=erh; m_ar1[0+ith*11+330]=eph; } secnds(&tim); tim -= tst; return; }
/* * Main program : Molecular Dynamics simulation. */ int main(){ int move; double x[npart*3], vh[npart*3], f[npart*3]; double ekin; double vel; double sc; double start, time; /* * Parameter definitions */ double den = 0.83134; double side = pow((double)npart/den,0.3333333); double tref = 0.722; double rcoff = (double)mm/4.0; double h = 0.064; int irep = 10; int istop = 20; int iprint = 5; int movemx = 20; double a = side/(double)mm; double hsq = h*h; double hsq2 = hsq*0.5; double tscale = 16.0/((double)npart-1.0); double vaver = 1.13*sqrt(tref/24.0); /* * Initial output */ printf(" Molecular Dynamics Simulation example program\n"); printf(" ---------------------------------------------\n"); printf(" number of particles is ............ %6d\n",npart); printf(" side length of the box is ......... %13.6f\n",side); printf(" cut off is ........................ %13.6f\n",rcoff); printf(" reduced temperature is ............ %13.6f\n",tref); printf(" basic timestep is ................. %13.6f\n",h); printf(" temperature scale interval ........ %6d\n",irep); printf(" stop scaling at move .............. %6d\n",istop); printf(" print interval .................... %6d\n",iprint); printf(" total no. of steps ................ %6d\n",movemx); /* * Generate fcc lattice for atoms inside box */ fcc(x, npart, mm, a); /* * Initialise velocities and forces (which are zero in fcc positions) */ mxwell(vh, 3*npart, h, tref); dfill(3*npart, 0.0, f, 1); /* * Start of md */ printf("\n i ke pe e temp " " pres vel rp\n ----- ---------- ----------" " ---------- -------- -------- -------- ----\n"); start = secnds(); for (move=1; move<=movemx; move++) { /* * Move the particles and partially update velocities */ domove(3*npart, x, vh, f, side); /* * Compute forces in the new positions and accumulate the virial * and potential energy. */ forces(npart, x, f, side, rcoff); //kernelWrapper(npart,x,f,side,rcoff); /* * Scale forces, complete update of velocities and compute k.e. */ ekin=mkekin(npart, f, vh, hsq2, hsq); /* * Average the velocity and temperature scale if desired */ vel=velavg(npart, vh, vaver, h); if (move<istop && fmod(move, irep)==0) { sc=sqrt(tref/(tscale*ekin)); dscal(3*npart, sc, vh, 1); ekin=tref/tscale; } /* * Sum to get full potential energy and virial */ if (fmod(move, iprint)==0) prnout(move, ekin, epot, tscale, vir, vel, count, npart, den); } time = secnds() - start; printf("Time = %f\n",(float) time); }