public void compute_line_normal(int nstart, int n) { int p1, p2; double[] z = new double[3], delta = new double[3], norm = new double[3]; z[0] = 0.0; z[1] = 0.0; z[2] = 1.0; int m = nstart; for (int i = 0; i < n; i++) { p1 = lines[m].p1; p2 = lines[m].p2; MathExtra.sub3(pts[p2].x, pts[p1].x, delta); MathExtra.cross3(z, delta, norm); MathExtra.norm3(norm); norm[2] = 0.0; Line line = lines[m]; line.norm = new double[3]; line.norm[0] = norm[0]; line.norm[1] = norm[1]; line.norm[2] = norm[2]; lines[m] = line; m++; } }
//public double axi_line_size(int); public double tri_size(int m, out double len) { double[] delta12 = new double[3], delta13 = new double[3], delta23 = new double[3], cross = new double[3]; MathExtra.sub3(pts[tris[m].p2].x, pts[tris[m].p1].x, delta12); MathExtra.sub3(pts[tris[m].p3].x, pts[tris[m].p1].x, delta13); MathExtra.sub3(pts[tris[m].p3].x, pts[tris[m].p2].x, delta23); len = Math.Min(MathExtra.len3(delta12), MathExtra.len3(delta13)); len = Math.Min(len, MathExtra.len3(delta23)); MathExtra.cross3(delta12, delta13, cross); double area = 0.5 * MathExtra.len3(cross); return(area); }
public void compute_tri_normal(int nstart, int n) { int p1, p2, p3; double[] delta12 = new double[3], delta13 = new double[3]; int m = nstart; for (int i = 0; i < n; i++) { p1 = tris[m].p1; p2 = tris[m].p2; p3 = tris[m].p3; MathExtra.sub3(pts[p2].x, pts[p1].x, delta12); MathExtra.sub3(pts[p3].x, pts[p1].x, delta13); MathExtra.cross3(delta12, delta13, tris[m].norm); MathExtra.norm3(tris[m].norm); m++; } }
public void end(int flag, double time_multiple_runs) { int i; int[] histo = new int[10]; int loopflag, statsflag, timeflag, histoflag; double time, tmp = 0, ave = 0, max = 0, min = 0; double time_loop = 0, time_other = 0; int me = 0, nprocs = 0; sparta.mpi.MPI_Comm_rank(sparta.world, ref me); sparta.mpi.MPI_Comm_size(sparta.world, ref nprocs); // choose flavors of statistical output // flag = 0 = just loop summary // flag = 1 = dynamics or minimization loopflag = 1; statsflag = timeflag = histoflag = 0; if (flag == 1) { statsflag = timeflag = histoflag = 1; } // loop stats // time_multiple_runs used for moves/CPU/proc statistic below if (loopflag != 0) { time_other = sparta.timer.array[(int)EnumTime.Time_LOOP] - (sparta.timer.array[(int)EnumTime.Time_MOVE] + sparta.timer.array[(int)EnumTime.Time_COLLIDE] + sparta.timer.array[(int)EnumTime.Time_SORT] + sparta.timer.array[(int)EnumTime.Time_COMM] + sparta.timer.array[(int)EnumTime.Time_MODIFY] + sparta.timer.array[(int)EnumTime.Time_OUTPUT]); time_loop = sparta.timer.array[(int)EnumTime.Time_LOOP]; sparta.mpi.MPI_Allreduce(ref time_loop, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time_loop = tmp / nprocs; if (time_multiple_runs == 0.0) { time_multiple_runs = time_loop; } else { tmp = time_multiple_runs; sparta.mpi.MPI_Allreduce(ref tmp, ref time_multiple_runs, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time_multiple_runs /= nprocs; } } // recalculate nglobal Int64 n = sparta.particle.nlocal; sparta.mpi.MPI_Allreduce(ref n, ref sparta.particle.nglobal, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); // overall loop time if (me == 0) { string str = string.Format("Loop time of {0} on {1} procs for {2} steps with {3} particles\n", time_loop, nprocs, sparta.update.nsteps, sparta.particle.nglobal); Console.WriteLine(str); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine(str); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine(str); } } // cummulative stats over entire run if (statsflag != 0) { Int64 nmove_total = 0, ntouch_total = 0, ncomm_total = 0; Int64 nboundary_total = 0, nexit_total = 0; Int64 nscheck_total = 0, nscollide_total = 0, nsreact_total = 0; Int64 nattempt_total = 0; Int64 ncollide_total = 0; Int64 nreact_total = 0; int stuck_total = 0; sparta.mpi.MPI_Allreduce(ref sparta.update.nmove_running, ref nmove_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.update.ntouch_running, ref ntouch_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.update.ncomm_running, ref ncomm_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.update.nboundary_running, ref nboundary_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.update.nexit_running, ref nexit_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.update.nscheck_running, ref nscheck_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.update.nscollide_running, ref nscollide_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.surf.nreact_running, ref nsreact_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); if (sparta.collide != null) { sparta.mpi.MPI_Allreduce(ref sparta.collide.nattempt_running, ref nattempt_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.collide.ncollide_running, ref ncollide_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); sparta.mpi.MPI_Allreduce(ref sparta.collide.nreact_running, ref nreact_total, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world); } sparta.mpi.MPI_Allreduce(ref sparta.update.nstuck, ref stuck_total, 1, MPI.MPI_INT, MPI.MPI_SUM, sparta.world); double pms, pmsp, ctps, cis, pfc, pfcwb, pfeb, schps, sclps, srps, caps, cps, rps; pms = pmsp = ctps = cis = pfc = pfcwb = pfeb = schps = sclps = srps = caps = cps = rps = 0.0; Int64 elapsed = sparta.update.ntimestep - sparta.update.first_running_step; if (elapsed != 0) { pms = 1.0 * nmove_total / elapsed; } if (nmove_total != 0) { pmsp = 1.0 * nmove_total / time_multiple_runs / nprocs; ctps = 1.0 * ntouch_total / nmove_total; cis = 1.0 * sparta.update.niterate_running / elapsed; pfc = 1.0 * ncomm_total / nmove_total; pfcwb = 1.0 * nboundary_total / nmove_total; pfeb = 1.0 * nexit_total / nmove_total; schps = 1.0 * nscheck_total / nmove_total; sclps = 1.0 * nscollide_total / nmove_total; srps = 1.0 * nsreact_total / nmove_total; caps = 1.0 * nattempt_total / nmove_total; cps = 1.0 * ncollide_total / nmove_total; rps = 1.0 * nreact_total / nmove_total; } string str; if (me == 0) { str = "\n"; str += string.Format("Particle moves = {0} {1}\n", nmove_total, MathExtra.num2str(nmove_total)); str += string.Format("Cells touched = {0} {1}\n", ntouch_total, MathExtra.num2str(ntouch_total)); str += string.Format("Particle comms = {0} {1}\n", ncomm_total, MathExtra.num2str(ncomm_total)); str += string.Format("Boundary collides = {0} {1}\n", nboundary_total, MathExtra.num2str(nboundary_total)); str += string.Format("Boundary exits = {0} {1}\n", nboundary_total, MathExtra.num2str(nexit_total)); str += string.Format("SurfColl checks = {0} {1}\n", nscheck_total, MathExtra.num2str(nscheck_total)); str += string.Format("SurfColl occurs = {0} {1}\n", nscollide_total, MathExtra.num2str(nscollide_total)); str += string.Format("Surf reactions = {0} {1}\n", nsreact_total, MathExtra.num2str(nsreact_total)); str += string.Format("Collide attempts = {0} {1}\n", nattempt_total, MathExtra.num2str(nattempt_total)); str += string.Format("Collide occurs = {0} {1}\n", ncollide_total, MathExtra.num2str(ncollide_total)); str += string.Format("Gas reactions = {0} {1}\n", nreact_total, MathExtra.num2str(nreact_total)); str += string.Format("Particles stuck = {0}\n", stuck_total); str += string.Format("\n"); str += string.Format("Particle-moves/CPUsec/proc: {0}\n", pmsp); str += string.Format("Particle-moves/step: {0}\n", pms); str += string.Format("Cell-touches/particle/step: {0}\n", ctps); str += string.Format("Particle comm iterations/step: {0}\n", cis); str += string.Format("Particle fraction communicated: {0}\n", pfc); str += string.Format("Particle fraction colliding with boundary: {0}\n", pfcwb); str += string.Format("Particle fraction exiting boundary: {0}\n", pfeb); str += string.Format("Surface-checks/particle/step: {0}\n", schps); str += string.Format("Surface-collisions/particle/step: {0}\n", sclps); str += string.Format("Surface-reactions/particle/step: {0}\n", srps); str += string.Format("Collision-attempts/particle/step: {0}\n", caps); str += string.Format("Collisions/particle/step: {0}\n", cps); str += string.Format("Gas-reactions/particle/step: {0}\n", rps); Console.WriteLine(str); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine(str); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine(str); } } } // timing breakdowns if (timeflag != 0) { if (me == 0) { if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("\n"); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("\n"); } } time = sparta.timer.array[(int)EnumTime.Time_MOVE]; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Move time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Move time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Move time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } time = sparta.timer.array[(int)EnumTime.Time_COLLIDE]; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Coll time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Coll time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Coll time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } time = sparta.timer.array[(int)EnumTime.Time_SORT]; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Sort time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Sort time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Sort time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } time = sparta.timer.array[(int)EnumTime.Time_COMM]; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Comm time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Comm time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Comm time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } time = sparta.timer.array[(int)EnumTime.Time_MODIFY]; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Modfy time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Modfy time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Modfy time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } time = sparta.timer.array[(int)EnumTime.Time_OUTPUT]; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Outpt time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Outpt time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Outpt time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } time = time_other; sparta.mpi.MPI_Allreduce(ref time, ref tmp, 1, MPI.MPI_DOUBLE, MPI.MPI_SUM, sparta.world); time = tmp / nprocs; if (me == 0) { Console.WriteLine("Other time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("Other time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("Other time (%%) = {0} ({1})\n", time, time / time_loop * 100.0); } } } // histograms if (histoflag != 0) { if (me == 0) { Console.WriteLine("\n"); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine("\n"); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine("\n"); } } tmp = sparta.particle.nlocal; stats(1, ref tmp, ref ave, ref max, ref min, 10, ref histo); if (me == 0) { string str = string.Format("Particles: {0} ave {1} max {2} min\n", ave, max, min); str += "Histogram:"; for (int a = 0; a < 10; a++) { str += string.Format(" {0}", histo[a]); } str += "\n"; Console.WriteLine(str); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine(str); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine(str); } } tmp = sparta.grid.nlocal; stats(1, ref tmp, ref ave, ref max, ref min, 10, ref histo); if (me == 0) { string str = string.Format("Cells: {0} ave {1} max {2} min\n", ave, max, min); str += "Histogram:"; for (int a = 0; a < 10; a++) { str += string.Format(" {0}", histo[a]); } str += "\n"; Console.WriteLine(str); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine(str); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine(str); } } tmp = sparta.grid.nghost; stats(1, ref tmp, ref ave, ref max, ref min, 10, ref histo); if (me == 0) { string str = string.Format("GhostCell: {0} ave {1} max {2} min\n", ave, max, min); str += "Histogram:"; for (int a = 0; a < 10; a++) { str += string.Format(" {0}", histo[a]); } str += "\n"; Console.WriteLine(str); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine(str); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine(str); } } tmp = sparta.grid.nempty; stats(1, ref tmp, ref ave, ref max, ref min, 10, ref histo); if (me == 0) { string str = string.Format("EmptyCell: {0} ave {1} max {2} min\n", ave, max, min); str += "Histogram:"; for (int a = 0; a < 10; a++) { str += string.Format(" {0}", histo[a]); } str += "\n"; Console.WriteLine(str); if (sparta.screen != null) { new StreamWriter(sparta.screen).WriteLine(str); } if (sparta.logfile != null) { new StreamWriter(sparta.logfile).WriteLine(str); } } } if (sparta.logfile != null) { sparta.logfile.Flush(); } }
//public void quad_corner_point(int, double*, double*, double*); //public void hex_corner_point(int, double*, double*, double*); public double line_size(int m) { double[] delta = new double[3]; MathExtra.sub3(pts[lines[m].p2].x, pts[lines[m].p1].x, delta); return(MathExtra.len3(delta)); }
protected RanPark random; // RNG for particle reflection void diffuse(Particle.OnePart p, double[] norm) { // specular reflection // reflect incident v around norm if (random.uniform() > acc) { MathExtra.reflect3(p.v, norm); // diffuse reflection // vrm = most probable speed of species, eqns (4.1) and (4.7) // vperp = velocity component perpendicular to surface along norm, eqn (12.3) // vtan12 = 2 velocity components tangential to surface // tangent1 = component of particle v tangential to surface, // check if tangent1 = 0 (normal collision), set randomly // tangent2 = norm x tangent1 = orthogonal tangential direction // tangent12 are both unit vectors } else { double[] tangent1 = new double[3], tangent2 = new double[3]; List <Particle.Species> species = sparta.particle.species; int ispecies = p.ispecies; double vrm = Math.Sqrt(2.0 * sparta.update.boltz * twall / species[ispecies].mass); double vperp = vrm * Math.Sqrt(-Math.Log(random.uniform())); double theta = MyConst.MY_2PI * random.uniform(); double vtangent = vrm * Math.Sqrt(-Math.Log(random.uniform())); double vtan1 = vtangent * Math.Sin(theta); double vtan2 = vtangent * Math.Cos(theta); double[] v = p.v; double dot = MathExtra.dot3(v, norm); double beta_un, normalized_distbn_fn; tangent1[0] = v[0] - dot * norm[0]; tangent1[1] = v[1] - dot * norm[1]; tangent1[2] = v[2] - dot * norm[2]; if (MathExtra.lensq3(tangent1) == 0.0) { tangent2[0] = random.uniform(); tangent2[1] = random.uniform(); tangent2[2] = random.uniform(); MathExtra.cross3(norm, tangent2, tangent1); } MathExtra.norm3(tangent1); MathExtra.cross3(norm, tangent1, tangent2); // add in translation or rotation vector if specified // only keep portion of vector tangential to surface element if (trflag != 0) { double vxdelta, vydelta, vzdelta; if (tflag != 0) { vxdelta = vx; vydelta = vy; vzdelta = vz; double adot = vxdelta * norm[0] + vydelta * norm[1] + vzdelta * norm[2]; if (Math.Abs(adot) > 0.001) { adot /= vrm; do { do { beta_un = (6.0 * random.uniform() - 3.0); } while (beta_un + adot < 0.0); normalized_distbn_fn = 2.0 * (beta_un + adot) / (adot + Math.Sqrt(adot * adot + 2.0)) * Math.Exp(0.5 + (0.5 * adot) * (adot - Math.Sqrt(adot * adot + 2.0)) - beta_un * beta_un); } while (normalized_distbn_fn < random.uniform()); vperp = beta_un * vrm; } } else { double[] x = p.x; vxdelta = wy * (x[2] - pz) - wz * (x[1] - py); vydelta = wz * (x[0] - px) - wx * (x[2] - pz); vzdelta = wx * (x[1] - py) - wy * (x[0] - px); double adot = vxdelta * norm[0] + vydelta * norm[1] + vzdelta * norm[2]; vxdelta -= adot * norm[0]; vydelta -= adot * norm[1]; vzdelta -= adot * norm[2]; } v[0] = vperp * norm[0] + vtan1 * tangent1[0] + vtan2 * tangent2[0] + vxdelta; v[1] = vperp * norm[1] + vtan1 * tangent1[1] + vtan2 * tangent2[1] + vydelta; v[2] = vperp * norm[2] + vtan1 * tangent1[2] + vtan2 * tangent2[2] + vzdelta; // no translation or rotation } else { v[0] = vperp * norm[0] + vtan1 * tangent1[0] + vtan2 * tangent2[0]; v[1] = vperp * norm[1] + vtan1 * tangent1[1] + vtan2 * tangent2[1]; v[2] = vperp * norm[2] + vtan1 * tangent1[2] + vtan2 * tangent2[2]; } p.erot = sparta.particle.erot(ispecies, twall, random); p.evib = sparta.particle.evib(ispecies, twall, random); } }