/* 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 void rebuild_ents( struct mds_apf* m, struct mds_apf* m2, struct mds_tag* old_of, struct mds_tag* new_of) { int t; mds_id i; mds_id e; mds_id ne; void* model; int j; struct mds_set old_down; struct mds_set new_down; for (t = 1; t < MDS_TYPES; ++t) { for (i = 0; i < m->mds.n[t]; ++i) { ne = mds_identify(t,i); e = lookup(old_of,ne); model = mds_apf_model(m,e); mds_get_adjacent(&(m->mds),e,mds_dim[mds_type(e)]-1,&old_down); for (j = 0; j < old_down.n; ++j) new_down.e[j] = lookup(new_of,old_down.e[j]); ne = mds_apf_create_entity(m2,t,model,new_down.e); assert(ne == mds_identify(t,i)); } assert(m->mds.n[t] == m2->mds.n[t]); } }
struct mds_copies* mds_get_copies(struct mds_net* net, mds_id e) { int t = mds_type(e); if (!net->data[t]) return NULL; return net->data[t][mds_index(e)]; }
void mds_set_copies(struct mds_net* net, struct mds* m, mds_id e, struct mds_copies* c) { struct mds_copies** p; int t; mds_id i; t = mds_type(e); i = mds_index(e); if (!net->data[t]) { if (c) net->data[t] = calloc(m->cap[t], sizeof(*(net->data[t]))); else return; } p = &net->data[t][i]; assert(p); if (!*p && c) ++net->n[t]; else if (*p && !c) --net->n[t]; free(*p); *p = c; if (!net->n[t]) { free(net->data[t]); net->data[t] = NULL; } }
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); } }
void mds_update_model_for_entity(struct mds_apf* m, mds_id e, int dim, int modelTag) { struct gmi_ent* modelEntity = mds_find_model(m, dim, modelTag); m->model[mds_type(e)][mds_index(e)] = modelEntity; // TODO: Also classify the closure? }
static void change_down(struct mds* m, mds_id e, struct mds_set* s) { mds_id e2; /* note: this sortof hack relies on the LIFO property of create/destroy */ mds_destroy_entity(m, e); e2 = mds_create_entity(m, mds_type(e), s->e); PCU_ALWAYS_ASSERT(e2 == e); }
static void downs_to_copies( struct mds* m, mds_id e, struct mds_copies* c) { int i; struct mds_set s; mds_get_adjacent(m, e, mds_dim[mds_type(e)] - 1, &s); for (i = 0; i < c->n; ++i) downs_to_copy(&s, c->c[i]); }
static void number_ents_of_type(struct mds* m, mds_id* sorted_verts, struct mds_tag* tag, int type) { int dim; struct mds_set adj; mds_id label; int i, j; label = 0; dim = mds_dim[type]; for (i = 0; i < m->n[MDS_VERTEX]; ++i) { mds_get_adjacent(m, sorted_verts[i], dim, &adj); for (j = 0; j < adj.n; ++j) if (mds_type(adj.e[j]) == type) visit(m, tag, &label, adj.e[j]); } }
static int recv_down_copies(struct mds_net* net, struct mds* m) { mds_id e; struct mds_set s; struct mds_set rs; struct mds_set s2; int i; int from = PCU_Comm_Sender(); PCU_COMM_UNPACK(e); mds_get_adjacent(m, e, mds_dim[mds_type(e)] - 1, &s); rs.n = s.n; for (i = 0; i < s.n; ++i) PCU_COMM_UNPACK(rs.e[i]); if (compare_copy_sets(net, &s, from, &rs)) return 0; for (i = -s.n; i < s.n; ++i) { rotate_set(&s, i, &s2); if (compare_copy_sets(net, &s2, from, &rs)) { change_down(m, e, &s2); return 1; } } abort(); }
static mds_id lookup(struct mds_tag* tag, mds_id old) { mds_id* ip; ip = mds_get_tag(tag,old); return mds_identify(mds_type(old),*ip); }
void mds_apf_set_model(struct mds_apf* m, mds_id e, struct gmi_ent* model) { m->model[mds_type(e)][mds_index(e)] = model; }
struct gmi_ent* mds_apf_model(struct mds_apf* m, mds_id e) { return m->model[mds_type(e)][mds_index(e)]; }
void mds_set_part(struct mds_apf* m, mds_id e, void* p) { m->parts[mds_type(e)][mds_index(e)] = p; }
void* mds_get_part(struct mds_apf* m, mds_id e) { return m->parts[mds_type(e)][mds_index(e)]; }