void ChMatterSPH::FillBox(const ChVector<> size, const double spacing, const double initial_density, const ChCoordsys<> boxcoords, const bool do_centeredcube, const double kernel_sfactor, const double randomness) { int samples_x = (int)(size.x() / spacing); int samples_y = (int)(size.y() / spacing); int samples_z = (int)(size.z() / spacing); int totsamples = 0; double mrandomness = randomness; if (do_centeredcube) mrandomness = randomness * 0.5; for (int ix = 0; ix < samples_x; ix++) for (int iy = 0; iy < samples_y; iy++) for (int iz = 0; iz < samples_z; iz++) { ChVector<> pos(ix * spacing - 0.5 * size.x(), iy * spacing - 0.5 * size.y(), iz * spacing - 0.5 * size.z()); pos += ChVector<>(mrandomness * ChRandom() * spacing, mrandomness * ChRandom() * spacing, mrandomness * ChRandom() * spacing); AddNode(boxcoords.TransformLocalToParent(pos)); totsamples++; if (do_centeredcube) { ChVector<> pos2 = pos + 0.5 * ChVector<>(spacing, spacing, spacing); pos2 += ChVector<>(mrandomness * ChRandom() * spacing, mrandomness * ChRandom() * spacing, mrandomness * ChRandom() * spacing); AddNode(boxcoords.TransformLocalToParent(pos2)); totsamples++; } } double mtotvol = size.x() * size.y() * size.z(); double mtotmass = mtotvol * initial_density; double nodemass = mtotmass / (double)totsamples; double kernelrad = kernel_sfactor * spacing; for (unsigned int ip = 0; ip < GetNnodes(); ip++) { // downcasting std::shared_ptr<ChNodeSPH> mnode(nodes[ip]); assert(mnode); mnode->SetKernelRadius(kernelrad); mnode->SetCollisionRadius(spacing * 0.05); mnode->SetMass(nodemass); } GetMaterial().Set_density(initial_density); }
bool push(const T &node) { if (!node.valid()) return false; bool proceeded = false; Lock(); { typename NodeListT::iterator it; it = std::find(InternalList.begin(), InternalList.end(), node); if (it != InternalList.end()) { //既存なら最後尾へ T mnode(*it); InternalList.erase(it); mnode.marge(node); mnode.lastlink = time(NULL); InternalList.push_back(mnode); proceeded = true; } else if (InternalList.size() < Capacity) { //リストに余裕があるなら最後尾に追加 T newnode(node); newnode.lastlink = time(NULL); InternalList.push_back(newnode); proceeded = true; } #if !USEPING else { pop_front(); T newnode(node); newnode.lastlink = time(NULL); InternalList.push_back(newnode); proceeded = true; } #endif } Unlock(); #if USEPING if (proceeded) return true; //リストの一番上のノード=最古ノードの生存確認 T head; get_front(head); bool alive = ping(head); if (alive) { //最古ノードが生きている:最古ノードを最後尾へ //※対象ノードは追加しない pop_front(); head.lastlink = time(NULL); Lock(); InternalList.push_back(head); Unlock(); } else { //最古ノードが死んでいる:対象ノードを最後尾に追加 pop_front(); T newnode(node); newnode.lastlink = time(NULL); Lock(); InternalList.push_back(newnode); Unlock(); } #endif return true; };
void ChMatterSPH::VariablesFbLoadForces(double factor) { // COMPUTE THE SPH FORCES HERE // First, find if any ChProximityContainerSPH object is present in the system std::shared_ptr<ChProximityContainerSPH> edges; for (auto otherphysics : GetSystem()->Get_otherphysicslist()) { if ((edges = std::dynamic_pointer_cast<ChProximityContainerSPH>(otherphysics))) break; } assert(edges); // If using a ChMatterSPH, you must add also a ChProximityContainerSPH. if (!edges) return; // 1- Per-node initialization for (unsigned int j = 0; j < nodes.size(); j++) { nodes[j]->UserForce = VNULL; nodes[j]->density = 0; } // 2- Per-edge initialization and accumulation of particles's density edges->AccumulateStep1(); // 3- Per-node volume and pressure computation for (unsigned int j = 0; j < nodes.size(); j++) { std::shared_ptr<ChNodeSPH> mnode(nodes[j]); assert(mnode); // node volume is v=mass/density if (mnode->density) mnode->volume = mnode->GetMass() / mnode->density; else mnode->volume = 0; // node pressure = k(dens - dens_0); mnode->pressure = material.Get_pressure_stiffness() * (mnode->density - material.Get_density()); } // 4- Per-edge forces computation and accumulation edges->AccumulateStep2(); // 5- Per-node load forces for (unsigned int j = 0; j < nodes.size(); j++) { // particle gyroscopic force: // none. // add gravity ChVector<> Gforce = GetSystem()->Get_G_acc() * nodes[j]->GetMass(); ChVector<> TotForce = nodes[j]->UserForce + Gforce; // downcast std::shared_ptr<ChNodeSPH> mnode(nodes[j]); assert(mnode); mnode->variables.Get_fb().PasteSumVector(TotForce * factor, 0, 0); } }