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); } } } } }
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; }
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; }