Пример #1
0
        public FixEmit(SPARTA sparta, int narg, string[] arg) : base(sparta, narg, arg)
        {
            this.sparta = sparta;
            vector_flag = 1;
            size_vector = 2;
            global_freq = 1;
            gridmigrate = 1;

            // RNG

            int me = sparta.comm.me;

            random = new RanPark(sparta.update.ranmaster.uniform());
            double seed = sparta.update.ranmaster.uniform();

            random.reset(seed, me, 100);

            // local storage of emit data structures

            c2list  = null;
            nglocal = nglocalmax = 0;
            clist   = clistnum = clistfirst = null;
            nlist   = nlistmax = 0;

            // counters common to all emit styles for output from fix

            nsingle = ntotal = 0;
        }
Пример #2
0
        public Collide(SPARTA sparta, int narg, string[] arg)
        {
            this.sparta = sparta;
            int n = arg[0].Length + 1;

            style = string.Copy(arg[0]);

            n     = arg[1].Length + 1;
            mixID = string.Copy(arg[1]);

            random = new RanPark(sparta.update.ranmaster.uniform());
            double seed = sparta.update.ranmaster.uniform();

            random.reset(seed, sparta.comm.me, 100);

            ngroups = 0;

            npmax = 0;
            plist = null;

            nglocal = nglocalmax = 0;

            ngroup   = null;
            maxgroup = null;
            glist    = null;
            gpair    = null;

            maxdelete = 0;
            dellist   = null;

            vre_first      = 1;
            vre_start      = 1;
            vre_every      = 0;
            remainflag     = 1;
            vremax         = null;
            vremax_initial = null;
            remain         = null;
            rotstyle       = (int)Enum1.SMOOTH;
            vibstyle       = (int)Enum1.NONE;
            nearcp         = 0;
            nearlimit      = 10;

            recomb_ijflag = null;

            ambiflag    = 0;
            maxelectron = 0;
            elist       = null;
        }
Пример #3
0
        public int copy, copymode;        // 1 if copy of class (prevents deallocation of
                                          //  base class when child copy is destroyed)

        // methods

        public void init()
        {
            for (int i = 0; i < nmixture; i++)
            {
                mixture[i].init();
            }

            // RNG for particle weighting

            if (wrandom == null)
            {
                wrandom = new RanPark(sparta.update.ranmaster.uniform());
                double seed = sparta.update.ranmaster.uniform();
                wrandom.reset(seed, me, 100);
            }

            // if first run after reading a restart file,
            // delete any custom particle attributes that have not been re-defined
            // use nactive since remove_custom() may alter ncustom

            if (custom_restart_flag != null)
            {
                int nactive = ncustom;
                for (int i = 0; i < nactive; i++)
                {
                    if (custom_restart_flag[i] == 0)
                    {
                        remove_custom(i);
                    }
                }
                //delete[] custom_restart_flag;
                custom_restart_flag = null;
            }

            // reallocate cellcount and first lists as needed
            // NOTE: when grid becomes dynamic, will need to do this in sort()

            //if (maxgrid < sparta.grid.nlocal) {
            //  maxgrid = sparta.grid.nlocal;
            //    memory.destroy(cellcount);
            //memory.destroy(first);
            //memory.create(first,maxgrid,"particle:first");
            //memory.create(cellcount,maxgrid,"particle:cellcount");
            // }
        }
Пример #4
0
        public void command(int narg, string[] args, int outflag = 1)
        {
            string[] arg = new string[narg];
            Array.Copy(args, 1, arg, 0, narg);
            if (sparta.grid.exist == 0)
            {
                sparta.error.all("Cannot balance grid before grid is defined");
            }

            if (narg < 1)
            {
                sparta.error.all("Illegal balance_grid command");
            }

            int order = 0, bstyle = 0;
            int px = 0, py = 0, pz = 0;
            int rcbwt = 0, rcbflip = 0;

            if (string.Equals(arg[0], "none"))
            {
                if (narg != 1)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.NONE;
            }
            else if (string.Equals(arg[0], "stride"))
            {
                if (narg != 2)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.STRIDE;
                if (string.Equals(arg[1], "xyz"))
                {
                    order = (int)Enum2.XYZ;
                }
                else if (string.Equals(arg[1], "xzy"))
                {
                    order = (int)Enum2.XZY;
                }
                else if (string.Equals(arg[1], "yxz"))
                {
                    order = (int)Enum2.YXZ;
                }
                else if (string.Equals(arg[1], "yzx"))
                {
                    order = (int)Enum2.YZX;
                }
                else if (string.Equals(arg[1], "zxy"))
                {
                    order = (int)Enum2.ZXY;
                }
                else if (string.Equals(arg[1], "zyx"))
                {
                    order = (int)Enum2.ZYX;
                }
                else
                {
                    sparta.error.all("Illegal balance_grid command");
                }
            }
            else if (string.Equals(arg[0], "clump"))
            {
                if (narg != 2)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.CLUMP;
                if (string.Equals(arg[1], "xyz"))
                {
                    order = (int)Enum2.XYZ;
                }
                else if (string.Equals(arg[1], "xzy"))
                {
                    order = (int)Enum2.XZY;
                }
                else if (string.Equals(arg[1], "yxz"))
                {
                    order = (int)Enum2.YXZ;
                }
                else if (string.Equals(arg[1], "yzx"))
                {
                    order = (int)Enum2.YZX;
                }
                else if (string.Equals(arg[1], "zxy"))
                {
                    order = (int)Enum2.ZXY;
                }
                else if (string.Equals(arg[1], "zyx"))
                {
                    order = (int)Enum2.ZYX;
                }
                else
                {
                    sparta.error.all("Illegal balance_grid command");
                }
            }
            else if (string.Equals(arg[0], "block"))
            {
                if (narg != 4)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.BLOCK;
                if (string.Equals(arg[1], "*"))
                {
                    px = 0;
                }
                else
                {
                    px = int.Parse(arg[1]);
                }
                if (string.Equals(arg[2], "*"))
                {
                    py = 0;
                }
                else
                {
                    py = int.Parse(arg[2]);
                }
                if (string.Equals(arg[3], "*"))
                {
                    pz = 0;
                }
                else
                {
                    pz = int.Parse(arg[3]);
                }
            }
            else if (string.Equals(arg[0], "random"))
            {
                if (narg != 1)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.RANDOM;
            }
            else if (string.Equals(arg[0], "proc"))
            {
                if (narg != 1)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.PROC;
            }
            else if (string.Equals(arg[0], "rcb"))
            {
                if (narg != 2 && narg != 3)
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                bstyle = (int)Enum1.BISECTION;
                if (string.Equals(arg[1], "cell"))
                {
                    rcbwt = (int)Enum3.CELL;
                }
                else if (string.Equals(arg[1], "part"))
                {
                    rcbwt = (int)Enum3.PARTICLE;
                }
                else
                {
                    sparta.error.all("Illegal balance_grid command");
                }
                // undocumented optional 3rd arg
                // rcbflip = 3rd arg = 1 forces rcb.compute() to flip sign
                //           of all grid cell "dots" to force totally different
                //           assignment of grid cells to procs and induce
                //           complete rebalance data migration
                rcbflip = 0;
                if (narg == 3)
                {
                    rcbflip = int.Parse(arg[2]);
                }
            }
            else
            {
                sparta.error.all("Illegal balance_grid command");
            }


            // error check on methods only allowed for a uniform grid

            if (bstyle == (int)Enum1.STRIDE || bstyle == (int)Enum1.CLUMP || bstyle == (int)Enum1.BLOCK)
            {
                if (sparta.grid.uniform == 0)
                {
                    sparta.error.all("Invalid balance_grid style for non-uniform grid");
                }
            }

            // re-assign each of my local child cells to a proc
            // only assign unsplit and split cells
            // do not assign sub-cells since they migrate with their split cell
            // set nmigrate = # of cells that will migrate to a new proc
            // reset proc field in cells for migrating cells
            // style NONE performs no re-assignment

            sparta.mpi.MPI_Barrier(sparta.world);
            double time1 = sparta.mpi.MPI_Wtime();

            Grid.ChildCell[] cells = sparta.grid.cells;
            Grid.ChildInfo[] cinfo = sparta.grid.cinfo;
            int nglocal            = sparta.grid.nlocal;

            int nprocs = sparta.comm.nprocs;
            int newproc;
            int nmigrate = 0;

            if (bstyle == (int)Enum1.STRIDE)
            {
                cellint idm1, ix, iy, iz, nth = 0;

                cellint nx = sparta.grid.unx;
                cellint ny = sparta.grid.uny;
                cellint nz = sparta.grid.unz;

                for (int icell = 0; icell < nglocal; icell++)
                {
                    if (cells[icell].nsplit <= 0)
                    {
                        continue;
                    }
                    idm1 = cells[icell].id - 1;
                    ix   = idm1 % nx;
                    iy   = (idm1 / nx) % ny;
                    iz   = idm1 / (nx * ny);

                    if (order == (int)Enum2.XYZ)
                    {
                        nth = iz * nx * ny + iy * nx + ix;
                    }
                    else if (order == (int)Enum2.XZY)
                    {
                        nth = iy * nx * nz + iz * nx + ix;
                    }
                    else if (order == (int)Enum2.YXZ)
                    {
                        nth = iz * ny * nx + ix * ny + iy;
                    }
                    else if (order == (int)Enum2.YZX)
                    {
                        nth = ix * ny * nz + iz * ny + iy;
                    }
                    else if (order == (int)Enum2.ZXY)
                    {
                        nth = iy * nz * nx + ix * nz + iz;
                    }
                    else if (order == (int)Enum2.ZYX)
                    {
                        nth = ix * nz * ny + iy * nz + iz;
                    }

                    newproc = nth % nprocs;

                    if (newproc != cells[icell].proc)
                    {
                        nmigrate++;
                    }
                    cells[icell].proc = newproc;
                }
            }
            else if (bstyle == (int)Enum1.BLOCK)
            {
                cellint idm1, ix, iy, iz;
                int     ipx, ipy, ipz;

                int nx = sparta.grid.unx;
                int ny = sparta.grid.uny;
                int nz = sparta.grid.unz;

                procs2grid(nx, ny, nz, ref px, ref py, ref pz);
                if (px * py * pz != nprocs)
                {
                    sparta.error.all("Bad grid of processors for balance_grid block");
                }

                for (int icell = 0; icell < nglocal; icell++)
                {
                    if (cells[icell].nsplit <= 0)
                    {
                        continue;
                    }
                    idm1 = cells[icell].id - 1;
                    ix   = idm1 % nx;
                    iy   = (idm1 / nx) % ny;
                    iz   = idm1 / (nx * ny);
                    ipx  = ix * px / nx;
                    ipy  = iy * py / ny;
                    ipz  = iz * pz / nz;

                    newproc = ipz * px * py + ipy * px + ipx;

                    if (newproc != cells[icell].proc)
                    {
                        nmigrate++;
                    }
                    cells[icell].proc = newproc;
                }
            }
            else if (bstyle == (int)Enum1.RANDOM)
            {
                RanPark random = new RanPark(sparta.update.ranmaster.uniform());
                double  seed   = sparta.update.ranmaster.uniform();
                random.reset(seed, sparta.comm.me, 100);

                for (int icell = 0; icell < nglocal; icell++)
                {
                    if (cells[icell].nsplit <= 0)
                    {
                        continue;
                    }
                    newproc = Convert.ToInt32(nprocs * random.uniform());
                    if (newproc != cells[icell].proc)
                    {
                        nmigrate++;
                    }
                    cells[icell].proc = newproc;
                }

                //delete random;
            }
            else if (bstyle == (int)Enum1.BISECTION)
            {
                RCB rcb = new RCB(sparta);

                double[,] x = new double[nglocal, 3];

                double[] lo, hi;

                int nbalance = 0;

                for (int icell = 0; icell < nglocal; icell++)
                {
                    if (cells[icell].nsplit <= 0)
                    {
                        continue;
                    }
                    lo             = cells[icell].lo;
                    hi             = cells[icell].hi;
                    x[nbalance, 0] = 0.5 * (lo[0] + hi[0]);
                    x[nbalance, 1] = 0.5 * (lo[1] + hi[1]);
                    x[nbalance, 2] = 0.5 * (lo[2] + hi[2]);
                    nbalance++;
                }

                double[] wt;

                if (rcbwt == (int)Enum3.PARTICLE)
                {
                    sparta.particle.sort();
                    int zero = 0;
                    int n;
                    wt       = new double[nglocal];
                    nbalance = 0;
                    for (int icell = 0; icell < nglocal; icell++)
                    {
                        if (cells[icell].nsplit <= 0)
                        {
                            continue;
                        }
                        n = cinfo[icell].count;
                        if (n != 0)
                        {
                            wt[nbalance++] = n;
                        }
                        else
                        {
                            wt[nbalance++] = ZEROPARTICLE;
                            zero++;
                        }
                    }
                }
                else
                {
                    wt = new double[nglocal];
                }

                rcb.compute(nbalance, x, wt, rcbflip);
                rcb.invert();

                nbalance = 0;
                int[] sendproc = rcb.sendproc;
                for (int icell = 0; icell < nglocal; icell++)
                {
                    if (cells[icell].nsplit <= 0)
                    {
                        continue;
                    }
                    cells[icell].proc = sendproc[nbalance++];
                }
                nmigrate = nbalance - rcb.nkeep;
            }

            // set clumped of not, depending on style
            // NONE style does not change clumping

            if (nprocs == 1 || bstyle == (int)Enum1.CLUMP || bstyle == (int)Enum1.BLOCK || bstyle == (int)Enum1.BISECTION)
            {
                sparta.grid.clumped = 1;
            }
            else if (bstyle != (int)Enum1.NONE)
            {
                sparta.grid.clumped = 0;
            }

            sparta.mpi.MPI_Barrier(sparta.world);
            double time2 = sparta.mpi.MPI_Wtime();

            // sort particles
            // NOTE: not needed again if rcbwt = PARTICLE for bstyle = BISECTION ??

            sparta.particle.sort();
            sparta.mpi.MPI_Barrier(sparta.world);
            double time3 = sparta.mpi.MPI_Wtime();


            // invoke init() so all grid cell info, including collide & fixes,
            //   is ready to migrate
            // for init, do not require surfs be assigned collision models
            //   this allows balance call early in script, e.g. from ReadRestart
            // migrate grid cells and their particles to new owners
            // invoke grid methods to complete grid setup

            int ghost_previous = sparta.grid.exist_ghost;

            sparta.domain.boundary_collision_check = 0;
            sparta.surf.surf_collision_check       = 0;
            sparta.init();
            sparta.domain.boundary_collision_check = 1;
            sparta.surf.surf_collision_check       = 1;

            sparta.grid.unset_neighbors();
            sparta.grid.remove_ghosts();
            sparta.comm.migrate_cells(nmigrate);

            sparta.mpi.MPI_Barrier(sparta.world);
            double time4 = sparta.mpi.MPI_Wtime();

            sparta.grid.setup_owned();
            sparta.grid.acquire_ghosts();
            if (ghost_previous != 0)
            {
                sparta.grid.reset_neighbors();
            }
            else
            {
                sparta.grid.find_neighbors();
            }
            sparta.comm.reset_neighbors();


            // reallocate per grid arrays in per grid dumps

            for (int i = 0; i < sparta.output.ndump; i++)
            {
                sparta.output.dump[i].reset_grid();
            }

            sparta.mpi.MPI_Barrier(sparta.world);
            double time5 = sparta.mpi.MPI_Wtime();

            // stats on balance operation
            // only print if outflag = 1
            // some callers suppress output, e.g. ReadRestart

            bigint count        = nmigrate;
            bigint nmigrate_all = 0;

            sparta.mpi.MPI_Allreduce(ref count, ref nmigrate_all, 1, MPI.MPI_LONG_LONG, MPI.MPI_SUM, sparta.world);
            double time_total = time5 - time1;

            if (sparta.comm.me == 0 && outflag != 0)
            {
                string str1 = string.Format("Balance grid migrated {0} cells\n", nmigrate_all);
                string str2 = string.Format("  CPU time = {0:G} secs\n", time_total);
                string str3 = string.Format("  reassign/sort/migrate/ghost percent = {0:G6} {1:G6} {2:G6} {3:G6}\n",
                                            100.0 * (time2 - time1) / time_total, 100.0 * (time3 - time2) / time_total,
                                            100.0 * (time4 - time3) / time_total, 100.0 * (time5 - time4) / time_total);

                Console.WriteLine(str1 + str2 + str3);
                if (sparta.screen != null)
                {
                    new StreamWriter(sparta.screen).WriteLine(str1 + str2 + str3);
                    //fprintf(screen, "Balance grid migrated " BIGINT_FORMAT " cells\n",
                    //        nmigrate_all);
                    //fprintf(screen, "  CPU time = %g secs\n", time_total);
                    //fprintf(screen, "  reassign/sort/migrate/ghost percent = %g %g %g %g\n",
                    //        100.0 * (time2 - time1) / time_total, 100.0 * (time3 - time2) / time_total,
                    //        100.0 * (time4 - time3) / time_total, 100.0 * (time5 - time4) / time_total);
                }
                if (sparta.logfile != null)
                {
                    new StreamWriter(sparta.logfile).WriteLine(str1 + str2 + str3);
                }
            }
        }
Пример #5
0
        public SurfCollideDiffuse(SPARTA sparta, int narg, string[] arg) : base(sparta, narg, arg)
        {
            this.sparta = sparta;
            if (narg < 4)
            {
                sparta.error.all("Illegal surf_collide diffuse command");
            }

            tstr = null;

            if (arg[2].Contains("v_"))
            {
                //int n = arg[2,2].Length + 1;
                //tstr = new char[n];
                //strcpy(tstr, &arg[2][2]);
                tstr = string.Copy(arg[2]);
            }
            else
            {
                twall = double.Parse(arg[2]);
                if (twall <= 0.0)
                {
                    sparta.error.all("Surf_collide diffuse temp <= 0.0");
                }
            }

            acc = double.Parse(arg[3]);
            if (acc < 0.0 || acc > 1.0)
            {
                sparta.error.all("Illegal surf_collide diffuse command");
            }

            // optional args
            tflag = rflag = 0;

            int iarg = 4;

            while (iarg < narg)
            {
                switch (arg[iarg])
                {
                case "translate":
                    if (iarg + 4 > narg)
                    {
                        sparta.error.all("Illegal surf_collide diffuse command");
                    }
                    tflag = 1;
                    vx    = double.Parse(arg[iarg + 1]);
                    vy    = double.Parse(arg[iarg + 2]);
                    vz    = double.Parse(arg[iarg + 3]);
                    iarg += 4;
                    break;

                case "rotate":
                    if (iarg + 7 > narg)
                    {
                        sparta.error.all("Illegal surf_collide diffuse command");
                    }
                    rflag = 1;
                    px    = double.Parse(arg[iarg + 1]);
                    py    = double.Parse(arg[iarg + 2]);
                    pz    = double.Parse(arg[iarg + 3]);
                    wx    = double.Parse(arg[iarg + 4]);
                    wy    = double.Parse(arg[iarg + 5]);
                    wz    = double.Parse(arg[iarg + 6]);
                    if (sparta.domain.dimension == 2 && pz != 0.0)
                    {
                        sparta.error.all("Surf_collide diffuse rotation invalid for 2d");
                    }
                    if (sparta.domain.dimension == 2 && (wx != 0.0 || wy != 0.0))
                    {
                        sparta.error.all("Surf_collide diffuse rotation invalid for 2d");
                    }
                    iarg += 7;
                    break;

                default:
                    sparta.error.all("Illegal surf_collide diffuse command");
                    break;
                }
            }
            if (tflag != 0 && rflag != 0)
            {
                sparta.error.all("Illegal surf_collide diffuse command");
            }
            if (tflag != 0 || rflag != 0)
            {
                trflag = 1;
            }
            else
            {
                trflag = 0;
            }

            // initialize RNG

            random = new RanPark(sparta.update.ranmaster.uniform());
            double seed = sparta.update.ranmaster.uniform();

            random.reset(seed, sparta.comm.me, 100);
        }