LIB_LOCAL COMPONENT component1d( float *coords, INTERFACE *intfc) { float x = coords[0]; POINT **p; int ix; int k; struct Table *T = intfc->table; /* Check for no points in the interface (interior only) */ if (intfc->points == NULL) return MIN_INTERIOR_COMP; if (intfc->modified || T->new_grid) { if (make_point_comp_lists(intfc) == FUNCTION_FAILED) { (void) printf("WARNING in component1d(), " "make_point_comp_lists failed\n"); return NO_COMP; } } if (rect_in_which(coords,&ix,&T->rect_grid) == FUNCTION_FAILED) return exterior_component(intfc); /* Point Outside */ if (T->compon1d[ix] != ONFRONT) /* Off Front */ return T->compon1d[ix]; else /* On Front: */ { for (k=0, p=T->pts_in_zone[ix]; k < T->num_of_points[ix]; ++k, ++p) { if (x <= Coords(*p)[0]) return negative_component(*p); } p--; return positive_component(*p); } } /*end component1d*/
LOCAL void set_tr_tf_pf_list( Front *front, C_CURVE *cc, TRI ***tr_list, int *num_trs, TRI ***tf_list, int *num_tfs, POINT ***pf_list, int *num_pfs) { int i,j,k,num_cbs,num_tf,num_tr,nt; C_BOND *cb,**cbs; SURFACE *sr,*sf; /* rigid and fabric surfaces */ TRI **tr,**tf; /* rigid and fabric tri lists */ POINT *p,**pf; /* fabric point lists */ int npf,ntr,ntf; int max_npf,max_ntr,max_ntf; COMPONENT comp,ext_comp,int_comp; /* ext_comp is the component exterior to comp domain */ /* int_comp is the component interior to comp domain */ SIDE status; TRI *t,*nbt,*tr_on,**ptris; double nearest_pt[MAXD],nor[MAXD]; int id; char dirname[100]; POINTER_Q *seed_queue,*pq; set_pointer_queue_opts(PQ_BLOCK_SIZE,200,PQ_ALLOC_TYPE,"vmalloc", PQ_ALLOC_SIZE_FOR_POINTERS,sizeof(TRI*),0); /* resetting */ num_cbs = 0; sr = sf = NULL; tr = tf = NULL; pf = NULL; npf = ntf = ntr = 0; max_npf = max_ntf = max_ntr = 0; for (cb = cc->first; cb != NULL; cb = cb->next) num_cbs++; for (i = 0; i < 2; ++i) { if (wave_type(cc->s[i]) == NEUMANN_BOUNDARY || wave_type(cc->s[i]) == MOVABLE_BODY_BOUNDARY) sr = cc->s[i]; if (wave_type(cc->s[i]) == ELASTIC_BOUNDARY) sf = cc->s[i]; } ext_comp = exterior_component(front->interf); int_comp = (positive_component(sr) == ext_comp) ? negative_component(sr) : positive_component(sr); /* Tri lists of collision rings */ for (i = 0, cb = cc->first; cb != NULL; i++, cb = cb->next) { for (k = 0; k < 2; ++k) { t = cb->s[k].t; if (t->surf == sr) check_add_tri(&tr,t,&ntr,&max_ntr); if (t->surf == sf) check_add_tri(&tf,t,&ntf,&max_ntf); } } /* Find seed tri inside the rigid surface ring */ t = find_inner_seed_tri(cc,sr,tr,ntr); if (debugging("collision")) { int ns = (t == NULL) ? 0 : 1; sprintf(dirname,"cross-tris/rigid-seed-%d",front->step); gview_plot_crossing_tris(dirname,tr,ntr,&t,ns); } /* Fill tr list with tris inside the ring */ if (t != NULL) { seed_queue = add_to_pointer_queue(NULL,NULL); seed_queue->pointer = (POINTER)t; check_add_tri(&tr,t,&ntr,&max_ntr); while (seed_queue) { pq = head_of_pointer_queue(seed_queue); t = (TRI*)(pq->pointer); for (i = 0; i < 3; ++i) { if (is_side_bdry(t,i)) continue; nbt = Tri_on_side(t,i); if (pointer_in_list((POINTER)nbt,ntr,(POINTER*)tr)) continue; seed_queue = add_to_pointer_queue(NULL,seed_queue); seed_queue->pointer = (POINTER)nbt; check_add_tri(&tr,nbt,&ntr,&max_ntr); } seed_queue = delete_from_pointer_queue(pq); } } /* Find seed tri inside the fabric surface ring */ t = find_inner_seed_tri(cc,sf,tf,ntf); if (debugging("collision")) { int ns = (t == NULL) ? 0 : 1; sprintf(dirname,"cross-tris/fabric-seed-%d",front->step); gview_plot_crossing_tris(dirname,tf,ntf,&t,ns); } /* Fill tf list with tris inside the ring */ if (t != NULL) { seed_queue = add_to_pointer_queue(NULL,NULL); seed_queue->pointer = (POINTER)t; check_add_tri(&tf,t,&ntf,&max_ntf); while (seed_queue) { pq = head_of_pointer_queue(seed_queue); t = (TRI*)(pq->pointer); for (i = 0; i < 3; ++i) { if (is_side_bdry(t,i)) continue; nbt = Tri_on_side(t,i); if (pointer_in_list((POINTER)nbt,ntf,(POINTER*)tf)) continue; seed_queue = add_to_pointer_queue(NULL,seed_queue); seed_queue->pointer = (POINTER)nbt; check_add_tri(&tf,nbt,&ntf,&max_ntf); } seed_queue = delete_from_pointer_queue(pq); } } if (debugging("collision")) { sprintf(dirname,"cross-tris/convex-%d",front->step); gview_plot_crossing_tris(dirname,tr,ntr,tf,ntf); } for (i = 0; i < ntf; ++i) { for (j = 0; j < 3; ++j) { p = Point_of_tri(tf[i])[j]; if (pointer_in_list((POINTER)p,npf,(POINTER*)pf)) continue; comp = component_wrt_tri_cluster(Coords(p),sr,tr,ntr); if (comp == ext_comp) { check_add_pt(&pf,p,&npf,&max_npf); nt = set_tri_list_around_point(p,tf[i],&ptris, front->interf); for (k = 0; k < nt; ++k) check_add_tri(&tf,ptris[k],&ntf,&max_ntf); } status = nearest_point_to_tri_cluster(Coords(p),int_comp, sr,tr,ntr,&tr_on,&id,nearest_pt,nor); add_neighbors_of_landing_tri(&tr,&ntr,sr,&max_ntr,tr_on); } } if (debugging("collision")) { (void) printf("ntr = %d ntf = %d npf = %d\n",ntr,ntf,npf); } *tr_list = tr; *num_trs = ntr; *tf_list = tf; *num_tfs = ntf; *pf_list = pf; *num_pfs = npf; } /* end set_tr_tf_pf_list */
LOCAL void insert_cuts_and_bdry2d( INTERFACE *intfc, /* an orginal intfc */ double **pc) /* given corners of the subdomain */ { COMPONENT comp; CROSS *cross; CURVE **cc, *c[4]; CURVE **curves1, **curves2; POINT *p; INTERFACE *sav_intfc; NODE *n, **nn, *bn[4]; int i; sav_intfc = current_interface(); set_current_interface(intfc); comp = (intfc->modified) ? long_component(pc[0],intfc) : component(pc[0],intfc); redo_curve_list: for (cc = intfc->curves; cc && *cc; cc++) { if (is_bdry(*cc)) { (void) delete_curve(*cc); goto redo_curve_list; } } for (nn = intfc->nodes; nn && *nn; nn++) { if (is_bdry(*nn)) { int num_in, num_out; if (num_curves_at_node(*nn,&num_in,&num_out) == 0) (void) delete_node(*nn); else set_not_bdry(*nn); } } bn[0] = make_node(Point(pc[0])); bn[1] = make_node(Point(pc[2])); bn[2] = make_node(Point(pc[3])); bn[3] = make_node(Point(pc[1])); for (i = 0; i < 4; i++) { c[i] = make_curve(NO_COMP,NO_COMP,bn[i],bn[(i+1)%4]); set_is_bdry(c[0]); } if (intersections(intfc,&cross,YES) == FUNCTION_FAILED) { screen("ERROR in insert_cuts_and_bdry2d(), " "intersections() failed\n"); clean_up(ERROR); } if (cross == NULL) { for (i = 0; i < 4; i++) { positive_component(c[i]) = comp; negative_component(c[i]) = exterior_component(intfc); } return; } for (; cross != NULL; cross = cross->next) { p = cross->p; if (insert_point_in_bond(p,cross->b1,cross->c1)!=FUNCTION_SUCCEEDED) { screen("ERROR in insert_cuts_and_bdry2d(), " "insert_point_in_bond() failed\n"); clean_up(ERROR); } rcl_after_insert_point(cross,p,cross->b1); curves1 = split_curve(p,cross->b1,cross->c1, positive_component(cross->c1), negative_component(cross->c1), positive_component(cross->c1), negative_component(cross->c1)); rcl_after_split(cross,p,cross->b1,cross->c1,curves1); if (insert_point_in_bond(p,cross->b2,cross->c2)!=FUNCTION_SUCCEEDED) { screen("ERROR in insert_cuts_and_bdry2d(), " "insert_point_in_bond() failed\n"); clean_up(ERROR); } rcl_after_insert_point(cross,p,cross->b2); curves2 = split_curve(p,cross->b2,cross->c2, positive_component(cross->c2), negative_component(cross->c2), positive_component(cross->c2), negative_component(cross->c2)); rcl_after_split(cross,p,cross->b2,cross->c2,curves1); n = curves2[0]->end; change_node_of_curve(curves2[0], NEGATIVE_ORIENTATION,curves1[0]->end); change_node_of_curve(curves2[1], POSITIVE_ORIENTATION,curves1[0]->end); (void) delete_node(n); } set_current_interface(sav_intfc); return; } /*end insert_cuts_and_bdry2d*/
LOCAL void fabric_rigid_collision( Front *front, C_CURVE *cc) { int i,j,k,num_trs,num_tfs,num_pfs; TRI **tr_list,**tf_list,*tri_on; POINT *p,**pf_list; double scaled_gap_tol = 0.05; double **newpts; SIDE status; SURFACE *sr = NULL; SURFACE *sf = NULL; double nearest_pt[MAXD],nor[MAXD]; double hdir,*h = front->rect_grid->h; COMPONENT int_comp,ext_comp; POINT **pr_list; int num_prs,max_num_prs; int id; char dirname[200]; if (debugging("collision")) (void) printf("Entering fabric_rigid_collision()\n"); for (i = 0; i < 2; ++i) { if (wave_type(cc->s[i]) == NEUMANN_BOUNDARY || wave_type(cc->s[i]) == MOVABLE_BODY_BOUNDARY) sr = cc->s[i]; if (wave_type(cc->s[i]) == ELASTIC_BOUNDARY) sf = cc->s[i]; } if (sr == NULL) { (void) printf("In fabric_rigid_collision(): "); (void) printf("cannot find rigid body surface!\n"); clean_up(ERROR); } ext_comp = exterior_component(front->interf); int_comp = (positive_component(sr) == ext_comp) ? negative_component(sr) : positive_component(sr); set_tr_tf_pf_list(front,cc,&tr_list,&num_trs,&tf_list,&num_tfs, &pf_list,&num_pfs); FT_MatrixMemoryAlloc((POINTER*)&newpts,num_pfs,MAXD,sizeof(double)); for (i = 0; i < num_pfs; ++i) { status = nearest_point_to_tri_cluster(Coords(pf_list[i]),int_comp, sr,tr_list,num_trs,&tri_on,&id,nearest_pt,nor); hdir = grid_size_in_direction(nor,h,3); for (k = 0; k < 3; ++k) newpts[i][k] = nearest_pt[k] + scaled_gap_tol*hdir*nor[k]; } for (i = 0; i < num_pfs; ++i) { for (k = 0; k < 3; ++k) Coords(pf_list[i])[k] = newpts[i][k]; } if (debugging("collision")) { sprintf(dirname,"cross-tris/after-lifting-%d",front->step); gview_plot_crossing_tris(dirname,tr_list,num_trs,tf_list,num_tfs); } for (i = 0; i < num_pfs; ++i) { COMPONENT comp; p = pf_list[i]; comp = component_wrt_tri_cluster(Coords(p),sr,tr_list, num_trs); } num_prs = max_num_prs = 0; pr_list = NULL; for (i = 0; i < num_trs; ++i) { double v[MAXD]; for (k = 0; k < 3; ++k) { p = Point_of_tri(tr_list[i])[k]; status = nearest_point_to_tri_cluster(Coords(p),int_comp, sf,tf_list,num_tfs,&tri_on,&id,nearest_pt,nor); for (j = 0; j < 3; ++j) { v[j] = Coords(p)[j] - nearest_pt[j]; } if (Dot3d(v,nor) > 0.0) check_add_pt(&pr_list,p,&num_prs,&max_num_prs); } } add_to_debug("tri_cluster"); for (i = 0; i < num_prs; ++i) { p = pr_list[i]; status = nearest_point_to_tri_cluster(Coords(p),int_comp, sf,tf_list,num_tfs,&tri_on,&id,nearest_pt,nor); if (status == ONEDGE) printf("ie = %d\n",id); else printf("\n"); } remove_from_debug("tri_cluster"); if (debugging("collision")) { sprintf(dirname,"cross-tris/before-leaving-%d",front->step); gview_plot_crossing_tris(dirname,tr_list,num_trs,tf_list,num_tfs); } free_these(4,tr_list,tf_list,pf_list,newpts); } /* end fabric_rigid_collision */