/* 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_tags( struct mds_apf* m, struct mds_apf* m2, struct mds_tag* old_of, struct mds_tag* new_of) { struct mds_tag* t; struct mds_tag* nt; int d; mds_id e; mds_id ne; void* p; void* q; for (t = m->tags.first; t; t = t->next) { if (t == new_of) continue; nt = mds_create_tag(&(m2->tags), t->name,t->bytes,t->user_type); mds_swap_tag_structs(&m->tags, &t, &m2->tags, &nt); for (d = 0; d <= m2->mds.d; ++d) { for (ne = mds_begin(&(m2->mds),d); ne != MDS_NONE; ne = mds_next(&(m2->mds),ne)) { e = lookup(old_of,ne); if ( ! mds_has_tag(t,e)) continue; p = mds_get_tag(t,e); mds_give_tag(nt,&(m2->mds),ne); q = mds_get_tag(nt,ne); memcpy(q,p,t->bytes); } } } }
static mds_id* sort_verts(struct mds_apf* m, struct mds_tag* tag) { mds_id v; mds_id* sorted_verts; sorted_verts = malloc(sizeof(mds_id) * m->mds.n[MDS_VERTEX]); for (v = mds_begin(&m->mds, 0); v != MDS_NONE; v = mds_next(&m->mds, v)) { mds_id* ip; ip = mds_get_tag(tag, v); sorted_verts[*ip] = v; } return sorted_verts; }
struct mds_tag* mds_number_verts_bfs(struct mds_apf* m) { struct mds_tag* tag; mds_id label; mds_id v; tag = mds_create_tag(&m->tags, "mds_number", sizeof(mds_id), 1); label = 0; v = find_seed(m); number_connected_verts(&m->mds, v, tag, &label); for (v = mds_begin(&m->mds, 0); v != MDS_NONE; v = mds_next(&m->mds, v)) number_connected_verts(&m->mds, v, tag, &label); assert(label == m->mds.n[MDS_VERTEX]); return tag; }
static void rebuild_parts( struct mds_apf* m, struct mds_apf* m2, struct mds_tag* old_of) { int d; mds_id ne; mds_id e; for (d = 0; d <= m->mds.d; ++d) for (ne = mds_begin(&m2->mds, d); ne != MDS_NONE; ne = mds_next(&m2->mds, ne)) { e = lookup(old_of, ne); mds_set_part(m2, ne, mds_get_part(m, e)); } }
static mds_id find_seed(struct mds_apf* m) { int best_dim = 4; mds_id best_v = MDS_NONE; int dim; mds_id v; for (v = mds_begin(&m->mds, 0); v != MDS_NONE; v = mds_next(&m->mds, v)) { dim = mds_model_dim(m, mds_apf_model(m, v)); if (dim < best_dim) { best_dim = dim; best_v = v; } } return best_v; }
static void rebuild_coords( struct mds_apf* m, struct mds_apf* m2, struct mds_tag* old_of) { mds_id ne; mds_id e; for (ne = mds_begin(&m2->mds, 0); ne != MDS_NONE; ne = mds_next(&m2->mds, ne)) { e = lookup(old_of, ne); memcpy(mds_apf_point(m2, ne), mds_apf_point(m, e), 3 * sizeof(double)); memcpy(mds_apf_param(m2, ne), mds_apf_param(m, e), 2 * sizeof(double)); } }
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); } } }
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; }