void mds_add_copy(struct mds_net* net, struct mds* m, mds_id e, struct mds_copy c) { struct mds_copies* cs; int t; int p; mds_id i; t = mds_type(e); i = mds_index(e); cs = mds_get_copies(net, e); if (cs) { p = find_place(cs, c.p); cs = realloc(cs, sizeof(struct mds_copies) + (cs->n) * sizeof(struct mds_copy)); /* insert sorted by moving greater items up by one */ memmove(&cs->c[p + 1], &cs->c[p], (cs->n - p) * sizeof(struct mds_copy)); cs->c[p] = c; ++cs->n; net->data[t][i] = cs; } else { cs = mds_make_copies(1); cs->c[0] = c; mds_set_copies(net, m, e, cs); } }
/* uses the null model to classify a mesh that did not have a model in such a way that verification will accept it */ void mds_derive_model(struct mds_apf* m) { int d; mds_id e; int i; mds_id de; struct mds_set s; struct mds_copies* c; struct gmi_ent* interior = mds_find_model(m, m->mds.d, 0); struct gmi_ent* boundary = mds_find_model(m, m->mds.d - 1, 0); /* first classify everything to the interior */ for (d = 0; d <= m->mds.d; ++d) for (e = mds_begin(&m->mds, d); e != MDS_NONE; e = mds_next(&m->mds, e)) m->model[mds_type(e)][mds_index(e)] = interior; /* then if a face has neither two adjacent elements nor a remote copy, classify its closure onto the model boundary */ for (e = mds_begin(&m->mds, m->mds.d - 1); e != MDS_NONE; e = mds_next(&m->mds, e)) { mds_get_adjacent(&m->mds, e, m->mds.d, &s); c = mds_get_copies(&m->remotes, e); if (c || s.n == 2) continue; for (d = 0; d < m->mds.d; ++d) { mds_get_adjacent(&m->mds, e, d, &s); for (i = 0; i < s.n; ++i) { de = s.e[i]; m->model[mds_type(de)][mds_index(de)] = boundary; } } } }
static int has_copy(struct mds_net* net, mds_id e, struct mds_copy c) { int i; struct mds_copies* cs; cs = mds_get_copies(net, e); PCU_ALWAYS_ASSERT(cs); for (i = 0; i < cs->n; ++i) if ((cs->c[i].p == c.p)&&(cs->c[i].e == c.e)) return 1; return 0; }
static void for_type_net(struct mds_net* net, struct mds* m, int t, void (*f)(mds_id i, struct mds_copy c, void* u), void* u) { mds_id i; int j; struct mds_copies* cs; for (i = 0; i < m->end[t]; ++i) { cs = mds_get_copies(net, mds_identify(t, i)); if (!cs) continue; for (j = 0; j < cs->n; ++j) f(i, cs->c[j], u); } }
static int align_copies(struct mds_net* net, struct mds* m) { int d; mds_id e; struct mds_copies* c; int did_change = 0; PCU_Comm_Begin(); for (d = 1; d < m->d; ++d) for (e = mds_begin(m, d); e != MDS_NONE; e = mds_next(m, e)) { c = mds_get_copies(net, e); if (!c) continue; if (owns_copies(e, c)) downs_to_copies(m, e, c); } PCU_Comm_Send(); while (PCU_Comm_Receive()) if (recv_down_copies(net, m)) did_change = 1; return PCU_Or(did_change); }
/* see apf/apfConvert.cc apf::Converter::createRemotes */ static void rebuild_net(struct mds_net* net, struct mds* m, struct mds_net* net2, struct mds* m2, struct mds_tag* new_of) { int d; mds_id e; mds_id ne; mds_id ce; mds_id nce; struct mds_copies* cs; struct mds_copy c; int i; PCU_Comm_Begin(); for (d = 0; d <= m->d; ++d) for (e = mds_begin(m, d); e != MDS_NONE; e = mds_next(m, e)) { cs = mds_get_copies(net, e); if (!cs) continue; ne = lookup(new_of, e); for (i = 0; i < cs->n; ++i) { ce = cs->c[i].e; PCU_COMM_PACK(cs->c[i].p, ce); PCU_COMM_PACK(cs->c[i].p, ne); } } PCU_Comm_Send(); while (PCU_Comm_Listen()) { c.p = PCU_Comm_Sender(); while (!PCU_Comm_Unpacked()) { PCU_COMM_UNPACK(ce); PCU_COMM_UNPACK(ne); c.e = ne; nce = lookup(new_of, ce); mds_add_copy(net2, m2, nce, c); } } }