void IWeights::Prune(const Mesh &mesh, const MEField<> &mask) { WeightMap::iterator wi = begin_row(), we = end_row(), wn; for (; wi != we;) { wn = wi; ++wn; UInt gid = wi->first.id; Mesh::MeshObjIDMap::const_iterator mi = mesh.map_find(MeshObj::NODE, gid); ThrowRequire(mi != mesh.map_end(MeshObj::NODE)); double *mval = mask.data(*mi); if (*mval < 0.5 || !GetMeshObjContext(*mi).is_set(Attr::OWNED_ID)) weights.erase(wi); wi = wn; } }
void static sync(CommRel &comm) { Trace __trace("sync(CommRel &comm)"); UInt csize = Par::Size(); SparseMsg msg; // Sizing loop std::vector<UInt> send_sizes_all(csize, 0); std::vector<UInt> to_proc; std::vector<UInt> to_sizes; CommRel::MapType::iterator di = comm.domain_begin(), de = comm.domain_end(); for (; di != de; ++di) { UInt proc = di->processor; std::vector<UInt>::iterator lb = std::lower_bound(to_proc.begin(), to_proc.end(), proc); if (lb == to_proc.end() || *lb != proc) to_proc.insert(lb, proc); // Attr send_sizes_all[proc] += SparsePack<Attr>::size(); } //sizes UInt nsend = to_proc.size(); msg.setPattern(nsend, nsend == 0 ? NULL : &to_proc[0]); to_sizes.resize(nsend, 0); for (UInt i = 0; i < nsend; i++) to_sizes[i] = send_sizes_all[to_proc[i]]; msg.setSizes(nsend == 0 ? NULL : &to_sizes[0]); // Pack loop di = comm.domain_begin(); for (; di != de; ++di) { UInt proc = di->processor; MeshObj &obj = *di->obj; SparseMsg::buffer &b = *msg.getSendBuffer(proc); // Attr SparsePack<Attr>(b, GetAttr(obj)); } if (!msg.filled()) Throw() << "Message not full in sync attr!"; msg.communicate(); // Create an object to context map so that objects are // only updated in the mesh onces. typedef std::map<MeshObj*, Context> Obj_To_Ctxt_Type; Obj_To_Ctxt_Type obj_to_ctxt; // Unpack di = comm.domain_begin(); for (; di != de; ++di) { MeshObj &obj = *di->obj; UInt proc = di->processor; SparseMsg::buffer &b = *msg.getRecvBuffer(proc); Attr a; SparseUnpack<Attr>(b, a); // Now the kernel. Or all attributes except the shared ones // (ownership, etc...) const Attr &oa = GetAttr(obj); // For sanity: ThrowRequire(a.GetType() == oa.GetType()); ThrowRequire(a.GetBlock() == oa.GetBlock()); // Now merge the contexts Context c = a.GetContext(); const Context &oc = oa.GetContext(); Context nc(oc); // More sanity checks //ThrowRequire(c.is_set(Attr::ACTIVE_ID) == oc.is_set(Attr::ACTIVE_ID)); if (!(c.is_set(Attr::ACTIVE_ID) == oc.is_set(Attr::ACTIVE_ID))) { Par::Out() << "Error, ACTIVE_ID incongruence, obj:" << obj; Par::Out() << "Incoming ctxt:" << c << std::endl; Throw(); } ThrowRequire(c.is_set(Attr::SHARED_ID) && oc.is_set(Attr::SHARED_ID)); ThrowRequire(c.is_set(Attr::GENESIS_ID) == oc.is_set(Attr::GENESIS_ID)); // Both can't claim to own object //ThrowRequire(!(c.is_set(Attr::OWNED_ID) && oc.is_set(Attr::OWNED_ID))); if ((c.is_set(Attr::OWNED_ID) && oc.is_set(Attr::OWNED_ID))) { Par::Out() << "Error, OWNED_ID incongruence, obj:" << obj; Par::Out() << "Incoming attr:" << a << std::endl; Par::Out() << "From processor:" << proc << std::endl; Throw(); } // Clear the bits not to merge c.clear(Attr::SHARED_ID); c.clear(Attr::OWNED_ID); c.clear(Attr::ACTIVE_ID); c.clear(Attr::GENESIS_ID); // Or the rest nc |= c; // Add or OR in the new context, depending on whether object is in map. std::pair<Obj_To_Ctxt_Type::iterator, bool> otci = obj_to_ctxt.insert(std::make_pair(&obj, nc)); if (otci.second == false) { // already there otci.first->second |= nc; } } // One last loop through the object map, updating the mesh Obj_To_Ctxt_Type::iterator oi = obj_to_ctxt.begin(), oe = obj_to_ctxt.end(); for (; oi != oe; ++oi) { MeshObj &obj = *oi->first; Context &nc = oi->second; if (nc != GetMeshObjContext(obj)) { Attr oa(GetAttr(obj), nc); comm.DomainMesh()->update_obj(&obj, oa); } } }