/* 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; } } } }
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); } }
mds_id mds_apf_create_entity( struct mds_apf* m, int type, struct gmi_ent* model, mds_id* from) { int t; mds_id old_cap[MDS_TYPES]; mds_id e; mds_id i; old_cap[type] = m->mds.cap[type]; e = mds_create_entity(&(m->mds),type,from); i = mds_index(e); if (m->mds.cap[type] != old_cap[type]) { for (t = 0; t < MDS_TYPES; ++t) if (t != type) old_cap[t] = m->mds.cap[t]; mds_grow_tags(&(m->tags),&(m->mds),old_cap); if (type == MDS_VERTEX) { m->point = realloc(m->point,m->mds.cap[type] * sizeof(*(m->point))); m->param = realloc(m->param,m->mds.cap[type] * sizeof(*(m->param))); } m->model[type] = realloc(m->model[type], m->mds.cap[type] * sizeof(*(m->model[type]))); m->parts[type] = realloc(m->parts[type], m->mds.cap[type] * sizeof(*(m->parts[type]))); mds_grow_net(&m->remotes, &m->mds, old_cap); mds_grow_net(&m->ghosts, &m->mds, old_cap); //seol mds_grow_net(&m->matches, &m->mds, old_cap); } m->model[type][i] = model; m->parts[type][i] = NULL; if (type == MDS_VERTEX) { m->point[i][0] = m->point[i][1] = m->point[i][2] = 0; m->param[i][0] = m->param[i][1] = 0; } return e; }
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 note_local_link(mds_id i, struct mds_copy c, void* u) { if (c.p == PCU_Comm_Self()) { if (i < mds_index(c.e)) note_peer(u, PCU_Comm_Self()); else /* hack id to store self-receivers */ note_peer(u, PCU_Comm_Peers()); } }
static void recv_links(struct mds_links* ln) { int from; mds_id* tmp; int pi; unsigned i; from = PCU_Comm_Sender(); pi = find_peer(ln, from); tmp = PCU_Comm_Extract(ln->n[pi] * sizeof(mds_id)); for (i = 0; i < ln->n[pi]; ++i) ln->l[pi][i] = mds_index(tmp[i]); }
static void take_local_link(mds_id i, struct mds_copy c, void* u) { struct mds_links* ln = u; int self = find_peer(ln, PCU_Comm_Self()); int other = find_peer(ln, PCU_Comm_Peers()); mds_id j = mds_index(c.e); if ((PCU_Comm_Self() == c.p) && (i < j)) { ln->l[self][ln->n[self]] = i; ln->l[other][ln->n[other]] = j; /* use ns as (redundant) position keepers */ ++ln->n[self]; ++ln->n[other]; } }
static struct mds_tag* invert( struct mds* m, struct mds_apf* m2, struct mds_tag* new_of) { struct mds_tag* old_of; int d; mds_id e; mds_id ne; mds_id* ip; old_of = mds_create_tag(&(m2->tags), "mds_inverse",sizeof(mds_id),1); for (d = 0; d <= m->d; ++d) { for (e = mds_begin(m,d); e != MDS_NONE; e = mds_next(m,e)) { ne = lookup(new_of,e); mds_give_tag(old_of,&(m2->mds),ne); ip = mds_get_tag(old_of,ne); *ip = mds_index(e); } } return old_of; }
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)]; }
double* mds_apf_param(struct mds_apf* m, mds_id e) { return m->param[mds_index(e)]; }
double* mds_apf_point(struct mds_apf* m, mds_id e) { return m->point[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)]; }