示例#1
0
        public void TransferUpdatedStateToHost()
        {
            if (cz_stride != 0)
            {
                // transfer to host dcz and icz
                g_dcz.CopyToHost(c_dcz, 0, 0, sizeof(double) * cz_stride * FP_DATA_SIZE_CZ); // pmax, tmax
                g_icz.CopyToHost(c_icz, 0, 0, sizeof(int) * cz_stride * 4);                  // cz_failed

                // infer failed state, pmax[] and tmax[]
                Parallel.For(0, mc.nonFailedCZs.Length, i =>
                {
                    CZ cz = mc.nonFailedCZs[i];
                    if (!cz.failed)
                    {
                        bool tentative_fail = c_icz[i + cz_stride * (TENTATIVE_FAILED_OFFSET_CZ)] == 0 ? false : true;
                        if (tentative_fail)
                        {
                            cz.failed = true;
                        }
                        for (int j = 0; j < 3; j++)
                        {
                            cz.pmax[j] = c_dcz[i + cz_stride * (TENTATIVE_PMAX_OFFSET_CZ + j)];
                            cz.tmax[j] = c_dcz[i + cz_stride * (TENTATIVE_TMAX_OFFSET_CZ + j)];
                        }
                        cz.avgDn = c_dcz[i + cz_stride * DELTA_N_OFFSET_CZ];
                        cz.avgDt = c_dcz[i + cz_stride * DELTA_T_OFFSET_CZ];
                        cz.avgTn = c_dcz[i + cz_stride * T_N_OFFSET_CZ];
                        cz.avgTt = c_dcz[i + cz_stride * T_T_OFFSET_CZ];

                        if (cz.maxAvgDn < cz.avgDn)
                        {
                            cz.maxAvgDn = cz.avgDn;
                        }
                        if (cz.maxAvgDt < cz.avgDt)
                        {
                            cz.maxAvgDt = cz.avgDt;
                        }
                    }
                });
            }

            // copy back elastic forces (should be zero on rigid objects)
            g_dn.CopyToHost(c_dn, sizeof(double) * nd_stride * F_OFFSET, sizeof(double) * nd_stride * F_OFFSET, sizeof(double) * nd_stride * 3);
            Parallel.For(0, mc.allNodes.Length, i =>
            {
                Node nd = mc.allNodes[i];
                nd.fx   = c_dn[i + nd_stride * (F_OFFSET + 0)];
                nd.fy   = c_dn[i + nd_stride * (F_OFFSET + 1)];
                nd.fz   = c_dn[i + nd_stride * (F_OFFSET + 2)];
            });
        }
示例#2
0
        public static void ConvertBack(this Mesh mg)
        {
            // Nodes, Faces, Elements and CZs are converted from Extended to normal
            for (int i = 0; i < mg.nodes.Count; i++)
            {
                mg.nodes[i] = new Node(mg.nodes[i]);
            }

            for (int i = 0; i < mg.elems.Count; i++)
            {
                Element old_elem = mg.elems[i];
                old_elem.id = i;
                Element new_elem = new Element();
                for (int j = 0; j < 4; j++)
                {
                    new_elem.vrts[j] = mg.nodes[old_elem.vrts[j].id];
                }
                new_elem.granule = old_elem.granule;
                mg.elems[i]      = new_elem;
            }

            for (int i = 0; i < mg.faces.Count; i++)
            {
                Face old_fc = mg.faces[i];
                old_fc.id = i;
                Face new_fc = new Face();
                if (old_fc.elem != null)
                {
                    new_fc.elem = mg.elems[old_fc.elem.id];
                }
                new_fc.id      = i;
                new_fc.tag     = old_fc.tag;
                new_fc.granule = old_fc.granule;
                new_fc.exposed = old_fc.exposed;
                for (int j = 0; j < 3; j++)
                {
                    new_fc.vrts[j] = mg.nodes[old_fc.vrts[j].id];
                }
                mg.faces[i] = new_fc;
            }

            for (int i = 0; i < mg.czs.Count; i++)
            {
                CZ old_cz = mg.czs[i];
                CZ new_cz = new CZ();
                for (int j = 0; j < 6; j++)
                {
                    new_cz.vrts[j] = mg.nodes[old_cz.vrts[j].id];
                }
                for (int j = 0; j < 2; j++)
                {
                    new_cz.faces[j] = mg.faces[old_cz.faces[j].id];
                }
                mg.czs[i] = new_cz;
            }

            // grain edges
            for (int i = 0; i < mg.edges.Count; i++)
            {
                GranuleEdge ge = mg.edges[i];
                ge.vrts[0] = mg.nodes[ge.vrts[0].id];
                ge.vrts[1] = mg.nodes[ge.vrts[1].id];
            }
        }
示例#3
0
文件: Mesh.cs 项目: my81656581/icFlow
        // loads from proprietary binary format
        public void LoadFrame(Stream str, bool update = false)
        {
            BinaryReader br = new BinaryReader(str);

            // read properties
            isDeformable = br.ReadBoolean();
            isIndenter   = br.ReadBoolean();
            isFloor      = br.ReadBoolean();
            bool _hide = br.ReadBoolean(); // discard

            name = br.ReadString();

            int nNodes = br.ReadInt32();
            int nElems = br.ReadInt32();
            int nCZs   = br.ReadInt32();
            int nFaces = br.ReadInt32();
            int nEdges = br.ReadInt32();

            // make sure that List<> objects are filled with proper # of elements
            if (!update)
            {
                nodes.Clear();
                nodes.Capacity = nNodes;
                for (int i = 0; i < nNodes; i++)
                {
                    nodes.Add(new Node());
                }

                elems.Clear();
                elems.Capacity = nElems;
                for (int i = 0; i < nElems; i++)
                {
                    elems.Add(new Element());
                }

                czs.Clear();
                czs.Capacity = nCZs;
                for (int i = 0; i < nCZs; i++)
                {
                    czs.Add(new CZ());
                }

                faces.Clear();
                faces.Capacity = nFaces;
                for (int i = 0; i < nFaces; i++)
                {
                    faces.Add(new Face());
                }

                edges.Clear();
                edges.Capacity = nEdges;
                for (int i = 0; i < nEdges; i++)
                {
                    edges.Add(new GranuleEdge());
                }
            }
            else
            {
//                Debug.Assert(nNodes == nodes.Count && nElems == elems.Count && nCZs == czs.Count &&
//                   nFaces == faces.Count && nEdges == edges.Count, "mesh update: incorrect count");
                Debug.Assert(nNodes == nodes.Count, "mesh update: incorrect node count");
                Debug.Assert(nElems == elems.Count, "mesh update: incorrect element count");
                Debug.Assert(nFaces == faces.Count, "mesh update: incorrect face count");
                Debug.Assert(nEdges == edges.Count, "mesh update: incorrect edge count");
                Debug.Assert(nCZs == czs.Count, "mesh update: incorrect czs count");
            }

            LoadSaveMemAlloc();
            by_snapshot = br.ReadBytes(byteSize);

            // convert byte array to bool, int and double arrays
            Buffer.BlockCopy(by_snapshot, 0, isn, 0, iSize * sizeof(int));
            int offset = iSize * sizeof(int);

            Buffer.BlockCopy(by_snapshot, offset, bsn, 0, bSize * sizeof(bool));
            offset += bSize * sizeof(bool);
            Buffer.BlockCopy(by_snapshot, offset, dsn, 0, dSize * sizeof(double));

            // restore nodes
            int i_off = 0, d_off = 0, b_off = 0;

            Parallel.For(0, nNodes, i => {
                Node nd = nodes[i];
                nd.id   = i;
                nd.x0   = dsn[i * ndd_str + 0];
                nd.y0   = dsn[i * ndd_str + 1];
                nd.z0   = dsn[i * ndd_str + 2];
                nd.ux   = dsn[i * ndd_str + 3];
                nd.uy   = dsn[i * ndd_str + 4];
                nd.uz   = dsn[i * ndd_str + 5];
                nd.vx   = dsn[i * ndd_str + 6];
                nd.vy   = dsn[i * ndd_str + 7];
                nd.vz   = dsn[i * ndd_str + 8];
                nd.ax   = dsn[i * ndd_str + 9];
                nd.ay   = dsn[i * ndd_str + 10];
                nd.az   = dsn[i * ndd_str + 11];
                nd.fx   = nd.fy = nd.fz = 0;
                nd.cx   = nd.x0 + nd.ux;
                nd.cy   = nd.y0 + nd.uy;
                nd.cz   = nd.z0 + nd.uz;
                nd.tx   = nd.ty = nd.tz = nd.unx = nd.uny = nd.unz = 0;
            });
            d_off += ndd_str * nodes.Count;

            // elements
            Parallel.For(0, nElems, i => {
                Element elem = elems[i];
                for (int j = 0; j < 4; j++)
                {
                    elem.vrts[j] = nodes[isn[i * eli_str + j]];
                }
                elem.granule = isn[i * eli_str + 4];
            });
            i_off += eli_str * elems.Count;

            // cohesive zones
            Parallel.For(0, nCZs, i => {
                CZ cz = czs[i];
                for (int j = 0; j < 6; j++)
                {
                    cz.vrts[j] = nodes[isn[i_off + i * czi_str + j]];
                }
                cz.faces[0]    = faces[isn[i_off + i * czi_str + 6]];
                cz.faces[1]    = faces[isn[i_off + i * czi_str + 7]];
                cz.immutableID = isn[i_off + i * czi_str + 8];

                cz.pmax[0]  = dsn[d_off + i * czd_str + 0];
                cz.pmax[1]  = dsn[d_off + i * czd_str + 1];
                cz.pmax[2]  = dsn[d_off + i * czd_str + 2];
                cz.tmax[0]  = dsn[d_off + i * czd_str + 3];
                cz.tmax[1]  = dsn[d_off + i * czd_str + 4];
                cz.tmax[2]  = dsn[d_off + i * czd_str + 5];
                cz.avgDn    = dsn[d_off + i * czd_str + 6];
                cz.avgDt    = dsn[d_off + i * czd_str + 7];
                cz.avgTn    = dsn[d_off + i * czd_str + 8];
                cz.avgTt    = dsn[d_off + i * czd_str + 9];
                cz.maxAvgDn = dsn[d_off + i * czd_str + 10];
                cz.maxAvgDt = dsn[d_off + i * czd_str + 11];

                cz.failed = bsn[b_off + i + 0];
            });
            b_off += czb_str * czs.Count;
            i_off += czi_str * czs.Count;
            d_off += czd_str * czs.Count;

            // faces
            Parallel.For(0, nFaces, i => {
                Face f = faces[i];
                f.id   = i;
                for (int j = 0; j < 3; j++)
                {
                    f.vrts[j] = nodes[isn[i_off + i * fi_str + j]];
                }
                f.granule   = isn[i_off + i * fi_str + 3];
                f.exposed   = bsn[b_off + i * fb_str + 0];
                f.created   = bsn[b_off + i * fb_str + 1];
                int elem_id = isn[i_off + i * fi_str + 4];
                f.elem      = elem_id < 0 ? null : elems[elem_id];
            });
            b_off += fb_str * faces.Count;
            i_off += fi_str * faces.Count;

            // edges
            Parallel.For(0, nEdges, i => {
                GranuleEdge ge = edges[i];
                ge.vrts[0]     = nodes[isn[i_off + i * gei_str + 0]];
                ge.vrts[1]     = nodes[isn[i_off + i * gei_str + 1]];
                ge.exposed     = bsn[b_off + i];
            });

            if (!update)
            {
                BoundingBox();
                ComputeVolume();
            }
            IFormatter bf = new BinaryFormatter();

            surfaceFragments = (List <SurfaceFragment>)bf.Deserialize(str);
            object tcollObject = bf.Deserialize(str);

            translationCollection = (TranslationCollection)tcollObject;
            foreach (SurfaceFragment sf in surfaceFragments)
            {
                sf.allFaces = faces; sf.ComputeArea();
            }
        }
示例#4
0
        public void TransferPCSR()
        {
            CSRDictionary csrd = linearSystem.csrd;

            // tranfer elastic elems and CZs along with offsets in sparse matrix (where to write the result)
            sw.Restart();
            // elastic elements
            Parallel.For(0, mc.elasticElements.Length, i_elem =>
            {
                Element elem = mc.elasticElements[i_elem];

                for (int i = 0; i < 4; i++)
                {
                    Node ni = elem.vrts[i];
                    for (int j = 0; j < 4; j++)
                    {
                        int pcsr_ij;
                        Node nj = elem.vrts[j];
                        if (!ni.anchored && !nj.anchored && nj.altId >= ni.altId)
                        {
                            pcsr_ij = csrd[ni.altId, nj.altId];
                        }
                        else
                        {
                            pcsr_ij = -1;  // ni is anchored => ignore
                        }
                        c_ie_pcsr[i_elem + el_elastic_stride * (PCSR_OFFSET_ELEM + (i * 4 + j))] = pcsr_ij;
                    }
                    c_ie_pcsr[i_elem + el_elastic_stride * (PCSR_OFFSET_ELEM + 16 + i)] = ni.anchored ? -1 : ni.altId;
                    c_ie_pcsr[i_elem + el_elastic_stride * (N0_OFFSET_ELEM + i)]        = ni.globalNodeId;
//                    c_ie_pcsr[i_elem + el_elastic_stride * (ROWSIZE_OFFSET_ELEM + i)] = ni.allNeighbors.Count;
                }
            });
            g_ie_pcsr.CopyToDevice(c_ie_pcsr, 0, 0, el_elastic_stride * INT_DATA_SIZE_ELEM * sizeof(int));

            // initialize indices in cohesive zones
            cz_stride = grid(mc.nonFailedCZs.Length) * block_size;

            if (cz_stride != 0)
            {
                Array.Clear(c_dcz, 0, c_dcz.Length);
                Parallel.For(0, mc.nonFailedCZs.Length, i_cz =>
                {
                    CZ cz = mc.nonFailedCZs[i_cz];
                    Trace.Assert(!cz.failed, "failed CZ in GPU array");

                    c_icz[i_cz + cz_stride * (CURRENT_FAILED_OFFSET_CZ)]    = 0;
                    c_icz[i_cz + cz_stride * (TENTATIVE_FAILED_OFFSET_CZ)]  = 0;
                    c_icz[i_cz + cz_stride * (TENTATIVE_DAMAGED_OFFSET_CZ)] = 0;

                    for (int i = 0; i < 6; i++)
                    {
                        Node ni = cz.vrts[i];
                        for (int j = 0; j < 6; j++)
                        {
                            Node nj = cz.vrts[j];
                            int pcsr_ij;
                            if (!ni.anchored && !nj.anchored && nj.altId >= ni.altId)
                            {
                                pcsr_ij = csrd[ni.altId, nj.altId];
                            }
                            else
                            {
                                pcsr_ij = -1;  // ni is anchored => ignore
                            }
                            c_icz[i_cz + cz_stride * (PCSR_OFFSET_CZ + (i * 6 + j))] = pcsr_ij;
                        }
                        c_icz[i_cz + cz_stride * (PCSR_OFFSET_CZ + 36 + i)] = ni.anchored ? -1 : ni.altId;
                        c_icz[i_cz + cz_stride * (VRTS_OFFSET_CZ + i)]      = ni.globalNodeId;
//                        c_icz[i_cz + cz_stride * (ROWSIZE_OFFSET_CZ + i)] = ni.allNeighbors.Count;
                    }

                    for (int j = 0; j < 3; j++)
                    {
                        c_dcz[i_cz + cz_stride * (CURRENT_PMAX_OFFSET_CZ + j)] = cz.pmax[j];
                        c_dcz[i_cz + cz_stride * (CURRENT_TMAX_OFFSET_CZ + j)] = cz.tmax[j];
                    }
                });
                g_icz.CopyToDevice(c_icz, 0, 0, cz_stride * sizeof(int) * INT_DATA_SIZE_CZ);
                g_dcz.CopyToDevice(c_dcz, 0, 0, cz_stride * sizeof(double) * FP_DATA_SIZE_CZ);
            }
            sw.Stop();
            cf.KForcePrepare += sw.ElapsedMilliseconds;
        }
示例#5
0
文件: Mesh.cs 项目: my81656581/icFlow
        public void SaveFrame(BinaryWriter bw)
        {
            LoadSaveMemAlloc();

            // write nodes
            int i_off = 0, d_off = 0, b_off = 0;

            Parallel.For(0, nodes.Count, i => {
                Node nd = nodes[i];
                Debug.Assert(nd.id == i, "Node ids are not sequential");
                dsn[i * ndd_str + 0]  = nd.x0;
                dsn[i * ndd_str + 1]  = nd.y0;
                dsn[i * ndd_str + 2]  = nd.z0;
                dsn[i * ndd_str + 3]  = nd.ux;
                dsn[i * ndd_str + 4]  = nd.uy;
                dsn[i * ndd_str + 5]  = nd.uz;
                dsn[i * ndd_str + 6]  = nd.vx;
                dsn[i * ndd_str + 7]  = nd.vy;
                dsn[i * ndd_str + 8]  = nd.vz;
                dsn[i * ndd_str + 9]  = nd.ax;
                dsn[i * ndd_str + 10] = nd.ay;
                dsn[i * ndd_str + 11] = nd.az;
            });
            d_off += ndd_str * nodes.Count;

            // elements
            Parallel.For(0, elems.Count, i => {
                Element elem         = elems[i];
                elem.id              = i;
                isn[i * eli_str + 0] = elem.vrts[0].id;
                isn[i * eli_str + 1] = elem.vrts[1].id;
                isn[i * eli_str + 2] = elem.vrts[2].id;
                isn[i * eli_str + 3] = elem.vrts[3].id;
                isn[i * eli_str + 4] = elem.granule;
            });
            i_off += eli_str * elems.Count;

            // cohesive zones
            Parallel.For(0, czs.Count, i => {
                CZ cz = czs[i];
                isn[i_off + i * czi_str + 0] = cz.vrts[0].id;
                isn[i_off + i * czi_str + 1] = cz.vrts[1].id;
                isn[i_off + i * czi_str + 2] = cz.vrts[2].id;
                isn[i_off + i * czi_str + 3] = cz.vrts[3].id;
                isn[i_off + i * czi_str + 4] = cz.vrts[4].id;
                isn[i_off + i * czi_str + 5] = cz.vrts[5].id;
                isn[i_off + i * czi_str + 6] = cz.faces[0].id;
                isn[i_off + i * czi_str + 7] = cz.faces[1].id;
                isn[i_off + i * czi_str + 8] = cz.immutableID;

                dsn[d_off + i * czd_str + 0]  = cz.pmax[0];
                dsn[d_off + i * czd_str + 1]  = cz.pmax[1];
                dsn[d_off + i * czd_str + 2]  = cz.pmax[2];
                dsn[d_off + i * czd_str + 3]  = cz.tmax[0];
                dsn[d_off + i * czd_str + 4]  = cz.tmax[1];
                dsn[d_off + i * czd_str + 5]  = cz.tmax[2];
                dsn[d_off + i * czd_str + 6]  = cz.avgDn;
                dsn[d_off + i * czd_str + 7]  = cz.avgDt;
                dsn[d_off + i * czd_str + 8]  = cz.avgTn;
                dsn[d_off + i * czd_str + 9]  = cz.avgTt;
                dsn[d_off + i * czd_str + 10] = cz.maxAvgDn;
                dsn[d_off + i * czd_str + 11] = cz.maxAvgDt;

                bsn[b_off + i + 0] = cz.failed;
            });

            b_off += czb_str * czs.Count;
            i_off += czi_str * czs.Count;
            d_off += czd_str * czs.Count;

            // faces
            Parallel.For(0, faces.Count, i => {
                Face f = faces[i];
                isn[i_off + i * fi_str + 0] = f.vrts[0].id;
                isn[i_off + i * fi_str + 1] = f.vrts[1].id;
                isn[i_off + i * fi_str + 2] = f.vrts[2].id;
                isn[i_off + i * fi_str + 3] = f.granule;
                isn[i_off + i * fi_str + 4] = f.elem == null ? -1 : f.elem.id;
                bsn[b_off + i * fb_str + 0] = f.exposed;
                bsn[b_off + i * fb_str + 1] = f.created;
            });

            b_off += fb_str * faces.Count;
            i_off += fi_str * faces.Count;

            // edges
            Parallel.For(0, edges.Count, i => {
                GranuleEdge ge = edges[i];
                isn[i_off + i * gei_str + 0] = ge.vrts[0].id;
                isn[i_off + i * gei_str + 1] = ge.vrts[1].id;
                bsn[b_off + i] = ge.exposed;
            });

            // convert to byte array and write
            if (by_snapshot == null || by_snapshot.Length < byteSize)
            {
                by_snapshot = new byte[byteSize];
            }
            Buffer.BlockCopy(isn, 0, by_snapshot, 0, iSize * sizeof(int));
            int offset = iSize * sizeof(int);

            Buffer.BlockCopy(bsn, 0, by_snapshot, offset, bSize * sizeof(bool));
            offset += bSize * sizeof(bool);
            Buffer.BlockCopy(dsn, 0, by_snapshot, offset, dSize * sizeof(double));

            // save mesh properties
            bw.Write(isDeformable);
            bw.Write(isIndenter);
            bw.Write(isFloor);
            bw.Write(hide);
            bw.Write(name);

            bw.Write(nodes.Count);
            bw.Write(elems.Count);
            bw.Write(czs.Count);
            bw.Write(faces.Count);
            bw.Write(edges.Count);
            bw.Write(by_snapshot, 0, byteSize);
            bw.Flush();

            IFormatter bf = new BinaryFormatter();

            bf.Serialize(bw.BaseStream, surfaceFragments);
            bf.Serialize(bw.BaseStream, translationCollection);
            bw.Flush();
        }