Example #1
0
        public void UpdateStaticStructureData(CSRDictionary csrd)
        {
            csrd.ClearDynamic();
            // update node interaction information for creating CSR later
            // this is done (1) before simulation starts, (2) if number of CZs changes

            UpdateCZs();

            foreach (CZ cz in nonFailedCZs)
            {
                if (!cz.failed)
                {
                    foreach (Node nd1 in cz.vrts)
                    {
                        foreach (Node nd2 in cz.vrts)
                        {
                            if (!nd1.anchored && !nd2.anchored && nd2.altId >= nd1.altId)
                            {
                                csrd.AddStatic(nd1.altId, nd2.altId);
                            }
                        }
                    }
                }
            }

            foreach (Element elem in elasticElements)
            {
                foreach (Node nd1 in elem.vrts)
                {
                    foreach (Node nd2 in elem.vrts)
                    {
                        if (!nd1.anchored && !nd2.anchored && nd2.altId >= nd1.altId)
                        {
                            csrd.AddStatic(nd1.altId, nd2.altId);
                        }
                    }
                }
            }
        }
Example #2
0
        public void collisionResponse()
        {
            if (nImpacts == 0)
            {
                return;
            }
            sw.Restart();
            CSRDictionary csrd = linearSystem.csrd;

            // allocate memory
            int cr_stride = grid(nImpacts) * block_size;
            int size_icr  = cr_stride * 28;

            if (c_icr == null || c_icr.Length < size_icr)
            {
                if (g_icr != null)
                {
                    g_icr.Dispose();
                }
                c_icr = new int[size_icr * 2];
                g_icr = new CudaDeviceVariable <int>(size_icr * 2);
            }

            const int pcsr_offset = 4;

            // populate and transfer to GPU
            Parallel.For(0, nImpacts, i_im => {
                for (int i = 0; i < 4; i++)
                {
                    Node ni = mc.allNodes[c_itet[i_im + i * tet_stride]];
                    c_icr[i_im + cr_stride * i] = ni.globalNodeId;
                    c_icr[i_im + cr_stride * (pcsr_offset + 16 + i)] = ni.anchored ? -1 : ni.altId;
//                    c_icz[i_im + cz_stride * (pcsr_offset + 20 + i)] = ni.allNeighbors.Count;

                    for (int j = 0; j < 4; j++)
                    {
                        int pcsr_ij;
                        Node nj = mc.allNodes[c_itet[i_im + j * tet_stride]];
                        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_icr[i_im + cr_stride * (pcsr_offset + (i * 4 + j))] = pcsr_ij;
                    }
                }
            });
            g_icr.CopyToDevice(c_icr, 0, 0, sizeof(int) * cr_stride * 28);

            // set grid size, execute kernel
            kCollisionResponseForce.GridDimensions = new dim3(grid(nImpacts), 1, 1);

            kCollisionResponseForce.Run(g_icr.DevicePointer, g_dn.DevicePointer, cf.TimeStep,
                                        g_dvals.DevicePointer, g_drhs.DevicePointer, nImpacts, cr_stride, nd_stride, prms.penaltyK,
                                        prms.DistanceEpsilon);

            sw.Stop();
            cf.CollForce += sw.ElapsedMilliseconds;
        }
Example #3
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;
        }