LOCAL int delete_phys_curves_at_old_node( NODE *oldn, int status) { boolean untrack = NO; CURVE **c; int wtype = FIRST_VECTOR_PHYSICS_WAVE_TYPE; for (c = oldn->in_curves; c && *c; ++c) { if (wave_type(*c) < wtype) continue; untracked_hyper_surf(*c) = YES; untrack = YES; status = REPEAT_TIME_STEP; } for (c = oldn->out_curves; c && *c; ++c) { if (wave_type(*c) < wtype) continue; untracked_hyper_surf(*c) = YES; untrack = YES; status = REPEAT_TIME_STEP; } if (untrack == YES) { (void) printf("WARNING in delete_phys_curves_at_old_node(), " "turning off tracking of vector curves at node\n"); print_node(oldn); } return status; } /*end delete_phys_curves_at_old_node*/
LOCAL int collision_type( INTERFACE *intfc, SURFACE **s) { int w_type1,w_type2; w_type1 = wave_type(s[0]); w_type2 = wave_type(s[1]); if (w_type1 == ELASTIC_BOUNDARY) { if (w_type2 == ELASTIC_BOUNDARY) return FABRIC_FABRIC_COLLISION; else if (w_type2 == NEUMANN_BOUNDARY || w_type2 == MOVABLE_BODY_BOUNDARY) return FABRIC_RIGID_COLLISION; else return UNKNOWN_COLLISION; } else if (w_type1 == NEUMANN_BOUNDARY || w_type1 == MOVABLE_BODY_BOUNDARY) { if (w_type2 == ELASTIC_BOUNDARY) return FABRIC_RIGID_COLLISION; else if (w_type2 == NEUMANN_BOUNDARY || w_type2 == MOVABLE_BODY_BOUNDARY) return RIGID_RIGID_COLLISION; else return UNKNOWN_COLLISION; } else return UNKNOWN_COLLISION; } /* end collision_type */
EXPORT SIDE physical_side_of_bdry_curve( CURVE *c) { if (wave_type(c) >= FIRST_PHYSICS_WAVE_TYPE) { screen("ERROR in physical_side_of_bdry_curve(), non bdry curve\n"); print_curve(c); clean_up(ERROR); } if (is_bdry(c)) { return is_exterior_comp(negative_component(c),c->interface) ? POSITIVE_SIDE : NEGATIVE_SIDE; } else if (is_excluded_comp(negative_component(c),c->interface)) return POSITIVE_SIDE; else if (is_excluded_comp(positive_component(c),c->interface)) return NEGATIVE_SIDE; else { screen("ERROR in physical_side_of_bdry_curve(), " "interior boundary not bounded by an excluded component\n"); print_curve(c); clean_up(ERROR); } return UNKNOWN_SIDE; /* for lint */ } /*end physical_side_of_bdry_curve*/
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 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 */
LOCAL void change_states_param( Front *front, Wave *wave, int comp, Gas_param *new_param) { HYPER_SURF *hs; HYPER_SURF_ELEMENT *hse; POINT *pt; SURFACE **s; Locstate stl, str, ref_st; int i, d, gridmax, vgmax[MAXD], tmp, ic[MAXD]; FD_DATA *fd_data; INTERFACE *intfc = front->interf; int dim = intfc->dim; printf("#change dirichlet boundary condition params.\n"); for(s=intfc->surfaces; s && *s; s++) { hs = Hyper_surf(*s); if(wave_type(hs) != DIRICHLET_BOUNDARY) continue; if(boundary_state_data(hs) == NULL) continue; fd_data = (FD_DATA *)boundary_state_data(hs); ref_st = fd_data->state; if(gas_params_for_comp(comp, intfc) != Params(ref_st)) continue; printf("change param for FD_DATA.\n"); verbose_print_state("bf ref", ref_st); change_param(ref_st, comp, new_param); verbose_print_state("af ref", ref_st); } printf("#change intfc params.\n"); next_point(intfc, NULL,NULL,NULL); while (next_point(intfc,&pt,&hse,&hs)) { slsr(pt,hse,hs,&stl,&str); change_param(str,positive_component(hs),new_param); change_param(stl,negative_component(hs),new_param); if(the_point(pt)) { printf("%d %d\n", negative_component(hs), positive_component(hs)); verbose_print_state("stl", stl); verbose_print_state("str", str); } } //check_print_intfc("After change intfc params", "ch_param", 'g', // intfc, 1, -1, NO); printf("#change interior params.\n"); gridmax = 1; for (d = 0; d < dim; d++) { vgmax[d] = wave->rect_grid->gmax[d] + wave->rect_grid->lbuf[d] + wave->rect_grid->ubuf[d]; gridmax *= vgmax[d]; } for (i = 0; i < gridmax; i++) { tmp = i; for (d = 0; d < dim; d++) { ic[d] = tmp % vgmax[d] - wave->rect_grid->lbuf[d]; tmp /= vgmax[d]; } change_param(Rect_state(ic,wave), Rect_comp(ic,wave), new_param); } }
/* ARGSUSED */ EXPORT void f_tan_curve_propagate( Front *fr, Front *newfr, INTERFACE *tempintfc, CURVE *tempc, CURVE *newc, double dt) { BOND *tempb, *newb; Locstate ansl, ansr; boolean curveIsClosed; double *h = fr->rect_grid->h; double tngt[MAXD], ds, sbl; int i, dim = fr->rect_grid->dim; static int nrad = 0; static Tan_stencil *sten = NULL; debug_print("f_tan_prop","Entered f_tan_curve_propagate()\n"); if (debugging("f_tan_prop")) { (void) printf("tempc %llu newc %llu\n",(long long unsigned int)curve_number(tempc), (long long unsigned int)curve_number(newc)); (void) printf("tempc\n"); print_curve(tempc); (void) printf("\nnewc\n"); print_curve(newc); } if (sten == NULL) { nrad = fr->npts_tan_sten/2; sten = alloc_tan_stencil(fr,nrad); } switch (wave_type(tempc)) { case PASSIVE_BOUNDARY: case SUBDOMAIN_BOUNDARY: return; default: break; } curveIsClosed = (is_closed_node(newc->end)) ? YES : NO; tempb = tempc->first; newb = newc->first; /* Check if zero length curve */ if (tempc->first == tempc->last) { sbl = scaled_bond_length(tempc->first,h,dim); if (sbl < MIN_SC_SEP(tempintfc)) { debug_print("f_tan_prop","Left f_tan_curve_propagate()\n"); return; } } for (; newb; tempb = tempb->next, newb = newb->next) { if (t_pt_propagated(newb->end)) continue; /* stop at tempc->last if no continuation */ if ((tempb == tempc->last) && !curveIsClosed && !is_fixed_node(newc->end)) { break; } /* calculate tangential displacement */ /* * TODO: the upgrade of this function * to 3 dimensions is non-trivial. * There will need to be either two * operator splitting sweeps, or one * unsplit solver. There is arbitrary * choice of tangent directions and this * will have to be resolved. */ tangent(newb->end,newb,newc,tngt,newfr); ds = grid_size_in_direction(tngt,h,dim); /* find the stencil states */ states_at_distance_along_curve(tempb->end,tempb,tempc, NEGATIVE_ORIENTATION,ds,nrad, sten->leftst-1,sten->rightst-1, sten->hs-1,sten->hse-1,sten->t-1, sten->p-1,newfr); if (tempb->next != NULL) { ansl = left_state(newb->end); ansr = right_state(newb->end); } else { ansl = left_end_state(newc); ansr = right_end_state(newc); } states_at_distance_along_curve(tempb->end,tempb,tempc, POSITIVE_ORIENTATION,ds,nrad, sten->leftst+1,sten->rightst+1, sten->hs+1,sten->hse+1,sten->t+1, sten->p+1,newfr); sten->p[0] = tempb->end; sten->hse[0] = Hyper_surf_element(tempb); sten->hs[0] = Hyper_surf(tempc); sten->t[0] = 1.0; sten->curvature = mean_curvature_at_point(sten->p[0],sten->hse[0], sten->hs[0],fr); if (debugging("f_tan_prop")) { int j; static const char *xyz[3] = { "x", "y", "z" }; (void) printf("state locations\n"); (void) printf("%-8s"," "); for (i = 0; i < dim; ++i) (void) printf("%-14s",xyz[i]); (void) printf("\n"); for (j = -nrad; j <= nrad; ++j) { for (i = 0; i < dim; ++i) (void) printf("%-14g",Coords(sten->p[j])[i]); (void) printf("\n"); } (void) printf("\n"); (void) printf("State values\n"); for (j = -nrad; j <= nrad; ++j) { (void) printf("left state[%d] at ",j); print_general_vector("",Coords(sten->p[j]),dim,"\n"); (*fr->print_state)( left_state_at_point_on_curve(sten->p[j], Bond_of_hse(sten->hse[j]), Curve_of_hs(sten->hs[j]))); (void) printf("right state[%d] at ",j); print_general_vector("",Coords(sten->p[j]),dim,"\n"); (*fr->print_state)( right_state_at_point_on_curve(sten->p[j], Bond_of_hse(sten->hse[j]), Curve_of_hs(sten->hs[j]))); (void) printf("\n"); } } /* update using n-point stencil tangential op */ sten->newhs = Hyper_surf(newc); sten->dir = tngt; npt_tang_solver(ds,dt,sten,ansl,ansr,fr); if (fr->parab == YES) npt_parab_tan_solver2d(ds,dt,sten,ansl,ansr,fr); t_pt_propagated(newb->end) = YES; if (debugging("f_tan_prop")) { (void) printf("answers: left right\n"); (*newfr->print_state)(ansl); (*newfr->print_state)(ansr); (void) printf("\n"); } } if (curveIsClosed) { /* assign start states to end states */ ft_assign(left_start_state(newc),left_end_state(newc),fr->sizest); ft_assign(right_start_state(newc),right_end_state(newc),fr->sizest); } debug_print("f_tan_prop","Left f_tan_curve_propagate()\n"); } /*end f_tan_curve_propagate*/
EXPORT void f_curve_propagate2d( Front *fr, POINTER wave, CURVE *oldc, CURVE *newc, double dt) { BOND *oldb = oldc->first; BOND *newb = newc->first; double V[MAXD]; int dim = fr->interf->dim; double L[MAXD],U[MAXD]; /* propagation boundary */ debug_print("f_curve_propagate","Entered f_curve_propagate2d\n"); if ((fr->_point_propagate == NULL) || (oldc == NULL) || (newc == NULL) || (correspond_curve(oldc) != newc) || (correspond_curve(newc) != oldc)) return; set_propagation_bounds(fr,L,U); while (oldb) { if ((oldb != oldc->last) && (!n_pt_propagated(newb->end))) { n_pt_propagated(newb->end) = YES; if (out_of_bound(oldb->end,L,U,dim) && wave_type(oldc) != MOVABLE_BODY_BOUNDARY && wave_type(oldc) != ICE_PARTICLE_BOUNDARY) { Locstate newsl,newsr; Locstate oldsl,oldsr; slsr(newb->end,Hyper_surf_element(newb),Hyper_surf(newc), &newsl,&newsr); slsr(oldb->end,Hyper_surf_element(oldb),Hyper_surf(oldc), &oldsl,&oldsr); ft_assign(newsl,oldsl,fr->sizest); ft_assign(newsr,oldsr,fr->sizest); continue; } point_propagate(fr,wave,oldb->end,newb->end,oldb->next, oldc,dt,V); } if (fr->bond_propagate != NULL) (*fr->bond_propagate)(fr,wave,oldb,newb,oldc,dt); else set_bond_length(newb,dim); /* Update new bond length */ if (oldb == oldc->last) break; oldb = oldb->next; newb = newb->next; } if (wave_type(oldc) == MOVABLE_BODY_BOUNDARY || wave_type(oldc) == ICE_PARTICLE_BOUNDARY) { /* Propagate center of mass */ /* int i,dim; dim = fr->rect_grid->dim; for (i = 0; i < dim; ++i) { center_of_mass_velo(newc)[i] = center_of_mass_velo(oldc)[i]; center_of_mass(newc)[i] = center_of_mass(oldc)[i] + dt*center_of_mass_velo(oldc)[i]; } angular_velo(newc) = angular_velo(oldc); spherical_radius(newc) = spherical_radius(oldc);*/ } debug_print("f_curve_propagate","Leaving f_curve_propagate2d\n"); } /*end f_curve_propagate2d*/