EXPORT COMPONENT nearest_interior_comp( boolean multiple_comps, COMPONENT dflt_comp, double *coords, INTERFACE *intfc) { COMPONENT comp; double t[MAXD], coords_on[MAXD]; HYPER_SURF *hs; HYPER_SURF_ELEMENT *hse; if ((multiple_comps == NO) || (intfc->hss == NULL)) return dflt_comp; comp = component(coords,intfc); if (!is_exterior_comp(comp,intfc)) return comp; if (nearest_interface_point(coords,comp,intfc,INCLUDE_BOUNDARIES,NULL, coords_on,t,&hse,&hs) != YES) { screen("ERROR in nearest_interior_comp(), " "nearest_interface_point() failed\n"); clean_up(ERROR); } return (is_exterior_comp(negative_component(hs),intfc)) ? positive_component(hs) : negative_component(hs); } /*end nearest_interior_comp*/
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*/
EXPORT int add_to_o_surfaces( O_SURFACE **sarr, int *n, SURFACE *sp[4]) { int i, j, pc, nc; SURFACE *s_tmp; /*arrange the surfaces and assume the sp[2] is physical */ qsort((POINTER)sp, 3, sizeof(SURFACE*), compare_surf); j = -1; for(i=0; i<3; i++) { if(!is_wall_surface(sp[i])) j = i; } /*sp[2] is the physical surface */ if(j == 1 || j == 0) { s_tmp = sp[2]; sp[2] = sp[j]; sp[j] = s_tmp; } for(j=0; j<*n; j++) if(sp[0] == sarr[j][0].surface && sp[1] == sarr[j][1].surface && sp[2] == sarr[j][2].surface ) return j; for(j=0; j<3; j++) sarr[*n][j].surface = sp[j]; /*the physical surface has the same orient as the curve. */ sarr[*n][2].orient = POSITIVE_ORIENTATION; pc = positive_component(sp[2]); nc = negative_component(sp[2]); for(j=0; j<2; j++) { if(positive_component(sp[j]) == pc) sarr[*n][j].orient = NEGATIVE_ORIENTATION; else if(positive_component(sp[j]) == nc) sarr[*n][j].orient = POSITIVE_ORIENTATION; else if(negative_component(sp[j]) == pc) sarr[*n][j].orient = POSITIVE_ORIENTATION; else if(negative_component(sp[j]) == nc) sarr[*n][j].orient = NEGATIVE_ORIENTATION; else { printf("ERROR add_to_o_surface sp[%d] impossible components\n", j); clean_up(ERROR); } } (*n)++; return -1; }
EXPORT int comps_consistent_at_node( NODE *node) { INTERFACE *intfc = node->interface; COMPONENT compi, compj; CURVE **c; int i, j; int ans; static O_NODE On; static int alloc_num_c = 0; /* Don't check for consistency on subdomain boundaries */ if (is_pp_node(node)) return YES; ans = YES; On.node = node; On.num_c = 0; On.prev = On.next = NULL; for (c = node->in_curves; c && *c; ++c) ++On.num_c; for (c = node->out_curves; c && *c; ++c) ++On.num_c; if (On.num_c == 0) return YES; if ((alloc_num_c == 0) || (alloc_num_c < On.num_c)) { if (alloc_num_c > 0) free_these(5,On.nc,On.nopp,On.pt,On.ang,On.orient); uni_array(&On.nc,On.num_c,sizeof(CURVE *)); uni_array(&On.nopp,On.num_c,sizeof(NODE *)); uni_array(&On.pt,On.num_c,sizeof(POINT *)); uni_array(&On.ang,On.num_c,FLOAT); uni_array(&On.orient,On.num_c,INT); alloc_num_c = On.num_c; } set_curves_at_onode(&On); for (i = 0; i < On.num_c; ++i) { j = (i + 1) % On.num_c; if (On.orient[i] == POSITIVE_ORIENTATION) compi = negative_component(On.nc[i]); else compi = positive_component(On.nc[i]); if (On.orient[j] == POSITIVE_ORIENTATION) compj = positive_component(On.nc[j]); else compj = negative_component(On.nc[j]); if (!equivalent_comps(compi,compj,intfc)) { ans = NO; break; } } return ans; } /*end comps_consistent_at_node*/
LOCAL int compare_surf(const void *a, const void *b) { SURFACE **c1=(SURFACE**)a, **c2=(SURFACE**)b; if(positive_component(*c1) < positive_component(*c2)) return -1; else if(positive_component(*c1) > positive_component(*c2)) return 1; else if(negative_component(*c1) < negative_component(*c2)) return -1; else if(negative_component(*c1) > negative_component(*c2)) return 1; return 0; }
LOCAL void EnforceFlowSpecifedStates1d( Front *fr) { INTERFACE *intfc; HYPER_SURF *hs; POINT **p; Locstate sl, sr; if ((fr==NULL) || (Fsr_list(fr)==NULL) || (fr->rect_grid->dim!=1)) return; intfc = fr->interf; for (p = intfc->points; p && *p; ++p) { hs = Hyper_surf(*p); if (BothSidesActive(hs,fr) == NO) { slsr(*p,NULL,Hyper_surf(*p),&sl,&sr); (void) RegionIsFlowSpecified(sl,NULL,Coords(*p), negative_component(hs),NO_COMP,fr); (void) RegionIsFlowSpecified(sr,NULL,Coords(*p), positive_component(hs),NO_COMP,fr); } } } /*end EnforceFlowSpecifedStates1d*/
LOCAL void set_oned_state_from_interface( float *coords, Locstate s, COMP_TYPE *ct, ONED_OVERLAY *olay) { HYPER_SURF *hs; HYPER_SURF_ELEMENT *hse; POINT *p; float coords_on[MAXD]; if (nearest_interface_point(coords,ct->comp,olay->intfc1d, INCLUDE_BOUNDARIES,NULL, coords_on,NULL,&hse,&hs) != YES) { screen("ERROR in set_oned_state_from_interface(), " "nearest_interface_point() failed\n"); clean_up(ERROR); } coords[0] = coords_on[0]; p = Point_of_hs(hs); if (ct->comp == positive_component(hs)) ft_assign(s,right_state(p),ct->params->sizest); else if (ct->comp == negative_component(hs)) ft_assign(s,left_state(p),ct->params->sizest); else { screen("ERROR in set_oned_state_from_interface(), " "ct->comp not on interface\n"); clean_up(ERROR); } Init_params(s,ct->params); } /*end set_oned_state_from_interface*/
EXPORT void set_wall_flag_for_surface(INTERFACE *intfc) { SURFACE **s; int comp1, comp2; get_default_fluid_comp(&comp1,&comp2,intfc); for(s=intfc->surfaces; s && *s; s++) if(positive_component(*s) == comp1 && negative_component(*s) == comp2 || positive_component(*s) == comp2 && negative_component(*s) == comp1) { set_is_not_wall_surface(*s); } else { set_is_wall_surface(*s); } }
LOCAL void EnforceFlowSpecifedStates2d( Front *fr) { INTERFACE *intfc; CURVE **c; POINT *p; HYPER_SURF *hs; BOND *b; Locstate sl, sr; if ((fr==NULL) || (Fsr_list(fr)==NULL) || (fr->rect_grid->dim!=2)) return; intfc = fr->interf; for (c = intfc->curves; c && *c; ++c) { hs = Hyper_surf(*c); if (is_subdomain_boundary(hs) || is_passive_boundary(hs)) continue; if (BothSidesActive(hs,fr) == NO) { b = (*c)->first; p = b->start; slsr(p,Hyper_surf_element(b),hs,&sl,&sr); (void) RegionIsFlowSpecified(sl,NULL,Coords(p), negative_component(hs),NO_COMP,fr); (void) RegionIsFlowSpecified(sr,NULL,Coords(p), positive_component(hs),NO_COMP,fr); for (; b != NULL; b = b->next) { p = b->end; slsr(p,Hyper_surf_element(b),hs,&sl,&sr); (void) RegionIsFlowSpecified(sl,NULL,Coords(p), negative_component(hs),NO_COMP,fr); (void) RegionIsFlowSpecified(sr,NULL,Coords(p), positive_component(hs),NO_COMP,fr); } } } } /*end EnforceFlowSpecifedStates2d*/
EXPORT void reset_intfc_components( INTERFACE *intfc) { POINT **p; int i, np; p = intfc->points; if (p == NULL) return; np = intfc->num_points; for (i = 1; i < np; ++i) { if (positive_component(p[i-1]) != negative_component(p[i])) { COMPONENT new_comp, ncomp, pcomp; ncomp = positive_component(p[i-1]); pcomp = negative_component(p[i]); negative_component(p[i]) = ncomp; set_equivalent_comps(ncomp,pcomp,intfc); } } } /*end reset_intfc_components */
EXPORT bool consistent_components1d( INTERFACE *intfc) { POINT **p; int i, np; p = intfc->points; if (p == NULL) return YES; np = intfc->num_points; for (i = 1; i < np; ++i) { if (positive_component(p[i-1]) != negative_component(p[i])) return NO; } return YES; } /*end consistent_components1d */
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 boolean BothSidesActive( HYPER_SURF *hs, Front *front) { FlowSpecifiedRegion *fsr; INTERFACE *intfc = front->interf; COMPONENT pcomp = positive_component(hs); COMPONENT ncomp = negative_component(hs); if (hs == NULL) return NO; for (fsr = Fsr_list(front); fsr != NULL; fsr = fsr->next) { if (equivalent_comps(fsr->comp,pcomp,intfc)) return NO; if (equivalent_comps(fsr->comp,ncomp,intfc)) return NO; } return YES; } /*end BothSidesActive*/
EXPORT bool FrontStateAtGridCrossing( Front *front, int *icoords, GRID_DIRECTION dir, COMPONENT comp, float (*state_func)(Locstate), float *ans, float *crx_coords) { Locstate state; HYPER_SURF *hs; INTERFACE *grid_intfc = front->grid_intfc; static CRXING *crxs[MAX_NUM_CRX]; int i,nc,dim = grid_intfc->dim; nc = GridSegCrossing(crxs,icoords,dir,grid_intfc); if (nc == 0) return NO; hs = crxs[0]->hs; if (comp == negative_component(hs)) { state = left_state(crxs[0]->pt); for (i = 0; i < dim; ++i) crx_coords[i] = Coords(crxs[0]->pt)[i]; } else if (comp == positive_component(hs)) { state = right_state(crxs[0]->pt); for (i = 0; i < dim; ++i) crx_coords[i] = Coords(crxs[0]->pt)[i]; } else { screen("ERROR: In FrontStateAtGridCrossing()," "component does not match\n"); return NO; } *ans = (*state_func)(state); return YES; } /* end FrontStateAtGridCrossing */
LOCAL bool comp_is_on_point( POINT *pt, const COMPONENT *comps, int n_eq) { int i; COMPONENT pcomp, ncomp; if (comps == NULL) return YES; pcomp = positive_component(pt); ncomp = negative_component(pt); for (i = 0; i < n_eq; ++i) { if (pcomp == comps[i]) return YES; else if (ncomp == comps[i]) return YES; } return NO; } /*end comp_is_on_curve*/
EXPORT bool make_point_comp_lists( INTERFACE *intfc) { int ix, ix0, ix1; int zp; POINT **p; struct Table *T; COMPONENT icomp; RECT_GRID *grid; if (DEBUG) (void) printf("Entered make_point_comp_lists()\n"); if ((T = table_of_interface(intfc)) == NULL) { (void) printf("WARNING in make_point_comp_lists(), " "table_of_interface = NULL\n"); return FUNCTION_FAILED; } if (no_topology_lists(intfc) == YES) { screen("ERROR in make_point_comp_lists(), " "illegal attempt to construct interface topology\n" "no_topology_lists(intfc) == YES\n"); clean_up(ERROR); } grid = &T->rect_grid; /* Free old storage if necessary */ if (T->num_of_points != NULL) free(T->num_of_points); if (T->pts_in_zone != NULL) free(T->pts_in_zone); if (T->compon1d != NULL) free(T->compon1d); /* Create a Grid if Needed: */ if (!T->fixed_grid) set_topological_grid(intfc,(RECT_GRID *)NULL); /* Allocate new storage if necessary */ uni_array(&T->num_of_points,grid->gmax[0],INT); if (T->num_of_points == NULL) { (void) printf("WARNING in make_point_complist(), " "can't allocate T->num_of_points\n"); return FUNCTION_FAILED; } if (DEBUG) (void) printf("T->num_of_points allocated\n"); /* NOTE: vector returns integer values initalized to zero */ uni_array(&T->compon1d,grid->gmax[0],sizeof(COMPONENT)); if (T->compon1d == NULL) { (void) printf("WARNING in make_point_complist(), " "can't allocate T->compon1d\n"); return FUNCTION_FAILED; } if (DEBUG) (void) printf("T->compon1d allocated\n"); for (ix = 0; ix < grid->gmax[0]; ++ix) T->compon1d[ix] = NO_COMP; uni_array(&T->pts_in_zone,grid->gmax[0],sizeof(POINT **)); /* NOTE: vector returns pointer values initalized to NULL */ if (T->pts_in_zone == NULL) { (void) printf("WARNING in make_point_complist(), " "can't allocate T->pts_in_zone\n"); return FUNCTION_FAILED; } start_clock("make_point_comp_lists"); if ((intfc->modified) && (intfc->num_points > 0)) sort_point_list(intfc->points,intfc->num_points); /* Default setting */ ix0 = 0; if (intfc->num_points != 0) { p = intfc->points; icomp = negative_component(*p); ix1 = -1; for (p = intfc->points; p && *p; ++p) { if (rect_in_which(Coords(*p),&zp,&T->rect_grid) == FUNCTION_FAILED) continue; ++T->num_of_points[zp]; if ((p == intfc->points) || (zp != ix1)) { T->pts_in_zone[zp] = p; } T->compon1d[zp] = ONFRONT; ix1 = zp; for (ix = ix0; ix < ix1; ++ix) T->compon1d[ix] = icomp; icomp = positive_component(*p); ix0 = zp + 1; } for (ix = ix0; ix < grid->gmax[0]; ++ix) T->compon1d[ix] = icomp; } stop_clock("make_point_comp_lists"); intfc->modified = NO; intfc->table->new_grid = NO; if (DEBUG) (void) printf("Leaving make_point_comp_lists()\n\n"); return FUNCTION_SUCCEEDED; } /*end make_point_comp_lists*/
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); } }
LOCAL void add_intfc_blk_pcs3d( int num_tris, TRI **tris, SURFACE **surfs, BLK_EL0 *blk_el0, P_LINK *hash_table, int h_size) { POINT_COMP_ST *pcs = blk_el0_pcs_els(blk_el0); TRI *t, *tri; SURFACE *s; BOND *b; BOND_TRI **btris; POINT *p; int i,j,k, npcs; TG_PT *tp; Locstate sl,sr; /* reset points in block tris */ for (i = 0; i < num_tris; ++i) { t = tris[i]; for (k = 0; k < 3; ++k) sorted(Point_of_tri(t)[k]) = NO; } //see count_num_pcs3d for alloc //#bjet2 add points in the boundary of the surfaces for (i = 0; i < num_tris; ++i) { t = tris[i]; for (k = 0; k < 3; ++k) { if(!is_side_bdry(t, k)) continue; b = Bond_on_side(t, k); for(j = 0; j < 2; j++) { p = Point_of_tri(t)[(k+j)%3]; //two points on side k if(sorted(p)) continue; sorted(p) = YES; tp = (TG_PT*)find_from_hash_table((POINTER)p, hash_table, h_size); for(btris = Btris(b); btris && *btris; btris++) { tri = (*btris)->tri; s = (*btris)->surface; slsr(p,Hyper_surf_element(tri),Hyper_surf(s),&sl,&sr); npcs = num_pcs_els_in_blk(blk_el0); pcs[npcs].p = tp; pcs[npcs].comp[0] = negative_component(s); pcs[npcs].comp[1] = positive_component(s); pcs[npcs].s[0] = sl; pcs[npcs].s[1] = sr; ++num_pcs_els_in_blk(blk_el0); if(debugging("pcs_cell")) { printf("npcsc %d comp %d %d\n", npcs, pcs[npcs].comp[0], pcs[npcs].comp[1]); print_general_vector("p ", Coords(tp), 3, "\n"); } } //for btris } // for j, two points for a side } // for k, sides for t } // add points in the interior of the surface for (i = 0; i < num_tris; ++i) { t = tris[i]; s = surfs[i]; for (k = 0; k < 3; ++k) { p = Point_of_tri(t)[k]; if (sorted(p) == YES) continue; sorted(p) = YES; tp = (TG_PT*)find_from_hash_table((POINTER)p,hash_table, h_size); slsr(p,Hyper_surf_element(t),Hyper_surf(s),&sl,&sr); npcs = num_pcs_els_in_blk(blk_el0); pcs[npcs].p = tp; pcs[npcs].comp[0] = negative_component(s); pcs[npcs].comp[1] = positive_component(s); pcs[npcs].s[0] = sl; pcs[npcs].s[1] = sr; ++num_pcs_els_in_blk(blk_el0); if(debugging("pcs_cell")) { printf("npcs %d comp %d %d\n", npcs, pcs[npcs].comp[0], pcs[npcs].comp[1]); print_general_vector("p ", Coords(tp), 3, "\n"); } } } } /* end add_intfc_blk_pcs3d */
EXPORT int check_comps_at_nodes( INTERFACE *intfc, O_NODE **onode_list) { NODE **n; O_NODE O_node; O_NODE *onode, *on; COMPONENT compi, compj; int i, j; int num_inconsistent = 0; debug_print("ccn","Entered check_comps_at_nodes()\n"); O_node.prev = O_node.next = NULL; on = &O_node; if (intfc->dim != 2) return 0; for (n = intfc->nodes; n && *n; ++n) { onode = make_onode(*n); for (i = 0; i < onode->num_c; ++i) { j = (i + 1) % onode->num_c; if (onode->orient[i] == POSITIVE_ORIENTATION) compi = negative_component(onode->nc[i]); else compi = positive_component(onode->nc[i]); if (onode->orient[j] == POSITIVE_ORIENTATION) compj = positive_component(onode->nc[j]); else compj = negative_component(onode->nc[j]); if (compi != compj) { if (debugging("inconsis")) { char xname[100]; double radius = 3.0*topological_grid(intfc).h[0]; int ii,jj; print_node(*n); sprintf(xname,"inconsis_comp-%d-%d",pp_mynode(), num_inconsistent); xgraph_2d_intfc_within_range(xname,intfc, Coords((*n)->posn),radius,NO); for (ii = 0; ii < onode->num_c; ++ii) { jj = (ii + 1) % onode->num_c; if (onode->orient[ii] == POSITIVE_ORIENTATION) compi = negative_component(onode->nc[ii]); else compi = positive_component(onode->nc[ii]); if (onode->orient[jj] == POSITIVE_ORIENTATION) compj = positive_component(onode->nc[jj]); else compj = negative_component(onode->nc[jj]); printf("compi = %d\n",compi); printf("compj = %d\n",compj); print_curve(onode->nc[jj]); } } ++num_inconsistent; on->next = onode; onode->prev = on; on = onode; break; } } } if (onode_list!= NULL) { *onode_list = O_node.next; if (*onode_list) (*onode_list)->prev = NULL; } if ((num_inconsistent > 0) && debugging("ccn")) { (void) printf("Inconsistent components found at nodes\n"); for (onode = *onode_list; onode != NULL; onode = onode->next) print_onode(onode); print_interface(intfc); } debug_print("ccn","Left check_comps_at_nodes(), num_inconsistent = %d\n", num_inconsistent); return num_inconsistent; } /*end check_comps_at_node*/
EXPORT COMPONENT new_component( COMPONENT comp) { COMPONENT mincomp, maxcomp; HYPER_SURF **hs; INTERFACE *intfc; struct Table *firstIT, *T; static COMPONENT last_reused_comp = NO_COMP; if (comp != NO_COMP) { firstIT = interface_table_list(); switch (comp) { case UNUSED_COMP: maxcomp = INT_MIN; mincomp = INT_MAX; for (T = firstIT; T != NULL; T = T->next) { intfc = T->interface; maxcomp = max(maxcomp,max_component(intfc)); mincomp = min(mincomp,min_component(intfc)); } ++maxcomp; for (comp = mincomp; comp <= maxcomp; ++comp) { if (comp == last_reused_comp) continue; for (T = firstIT; T != NULL; T = T->next) { intfc = T->interface; if (is_exterior_comp(comp,intfc) || is_excluded_comp(comp,intfc)) break; if (intfc->hss != NULL) { for (hs = intfc->hss; *hs; ++hs) { if ((positive_component(*hs) == comp) || (negative_component(*hs) == comp)) break; } if (*hs) break; } } if (T == NULL) break; } last_reused_comp = comp; break; case NEW_COMP: comp = INT_MIN; for (T = firstIT; T != NULL; T = T->next) { intfc = T->interface; comp = max(comp,max_component(intfc)); } ++comp; last_reused_comp = NO_COMP; break; default: last_reused_comp = NO_COMP; break; } for (T = firstIT; T != NULL; T = T->next) { intfc = T->interface; max_component(intfc) = max(comp,max_component(intfc)); min_component(intfc) = min(comp,min_component(intfc)); } } return comp; } /*end new_component*/
EXPORT int collect_pcs_in_mesh3d(TRI_GRID *ntg) { struct Table *T; P_LINK *hash_table; Locstate *states; COMPONENT *comp; TG_PT *node_pts; BLK_EL0 *blk_el0; TRI **tris; SURFACE **surfs; POINT_COMP_ST *pcs; int ix, iy, iz, l, nt, ***num_tris;; int *offset = ntg->offset; int num_pcs = 0; int h_size; int xmax, ymax, zmax; xmax = ntg->rect_grid.gmax[0]; ymax = ntg->rect_grid.gmax[1]; zmax = ntg->rect_grid.gmax[2]; ntg->_locate_on_trigrid = tg_build; set_tri3d_tolerances(ntg); T = table_of_interface(ntg->grid_intfc); //orig_construct_tri_grid //reconstruct_intfc_and_tri_grid // init_triangulation_storage // components, states // set_crx_structure_storage3dv0 // ntg->n_bilin_els = xmax*ymax*zmax; //expanded_topological_grid // ntg->n_node_points = (xmax+1)*(ymax+1)*(zmax+1); // // alloc_node_points(ntg,ntg->n_node_points); // node_points // alloc_blk_els0(ntg,ntg->n_bilin_els); // blk_els0 // set_interpolation_storage3dv0 // count_num_pcs3d // n_pcs, pcs, front_points /* Allocate space for hashing table */ h_size = (ntg->grid_intfc->num_points)*4+1; uni_array(&hash_table,h_size,sizeof(P_LINK)); copy_tg_pts_from_intfc(ntg,hash_table,h_size); //front_points copy_tg_pts_from_regular_grid(ntg); //node_points /* Triangulate each mesh block */ comp = T->components; states = ntg->states; node_pts = ntg->node_points; blk_el0 = ntg->blk_els0; num_tris = T->num_of_tris; for (iz = 0; iz < zmax; ++iz) { for (iy = 0; iy < ymax; ++iy) { for (ix = 0; ix < xmax; ++ix) { //debug with tg_build line_pj remove_from_debug("pcs_cell"); //if((ix == 3 && iy == 5 && iz == 0 && pp_mynode() == 0) || // (ix == 33 && iy == 5 && iz == 0 && pp_mynode() == 2) ) // add_to_debug("pcs_cell"); nt = num_tris[iz][iy][ix]; pcs = blk_el0_pcs_els(blk_el0) = &(ntg->pcs[num_pcs]); if (nt != 0) { tris = T->tris[iz][iy][ix]; surfs = T->surfaces[iz][iy][ix]; if(debugging("pcs_cell")) { int nd; printf("#pcs_cell %d\n", nt); for(nd = 0; nd < nt; nd++) { print_tri(tris[nd], surfs[nd]->interface); printf("%d (%d %d)\n", surfs[nd], negative_component(surfs[nd]), positive_component(surfs[nd])); } } for (l = 0; l < 8; ++l) { pcs[l].p = node_pts + offset[l]; pcs[l].comp[0] = comp[offset[l]]; pcs[l].s[0] = states[offset[l]]; pcs[l].comp[1] = NO_COMP; pcs[l].s[1] = NULL; } num_pcs_els_in_blk(blk_el0) = 8; add_intfc_blk_pcs3d(nt,tris,surfs,blk_el0, hash_table,h_size); num_pcs += num_pcs_els_in_blk(blk_el0); } else { set_bilinear_blk_el0(blk_el0); pcs[0].p = node_pts; pcs[0].comp[0] = comp[0]; pcs[0].s[0] = states[0]; pcs[0].comp[1] = NO_COMP; pcs[0].s[1] = NULL; ++num_pcs; } ++node_pts; ++states; ++comp; ++blk_el0; } ++node_pts; ++states; ++comp; } if (iz < zmax-1) { //node_pts, states, comp are defined on the nodes of the topological grid. node_pts += xmax+1; states += xmax+1; comp += xmax+1; } } //printf("#collect_pcs_in_mesh3d af: num_pcs = %d ntg->n_pcs=%d\n", // num_pcs, ntg->n_pcs); if(num_pcs != ntg->n_pcs) { printf("ERROR: num_pcs != ntg->n_pcs\n"); clean_up(ERROR); } free(hash_table); return GOOD_STEP; } /*end collect_pcs_in_mesh3d*/
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 */
LOCAL void add_intfc_blk_pcs2d( int num_bonds, BOND **bond, CURVE **curve, BLK_EL0 *blk_el0, P_LINK *hash_table, int h_size) { BOND *b; CURVE *c; POINT *p; int i; TG_PT *tp; POINT_COMP_ST *pcs = blk_el0_pcs_els(blk_el0); Locstate sl,sr; /* reset points in block bonds */ for (i = 0; i < num_bonds; ++i) { b = bond[i]; sorted(b->start) = NO; sorted(b->end) = NO; } /* add interface points inside cell */ for (i = 0; i < num_bonds; ++i) { b = bond[i]; c = curve[i]; p = b->start; if (sorted(p) == NO) { sorted(p) = YES; tp = (TG_PT*)find_from_hash_table((POINTER)p,hash_table, h_size); slsr(p,Hyper_surf_element(b),Hyper_surf(c),&sl,&sr); pcs[num_pcs_els_in_blk(blk_el0)].p = tp; pcs[num_pcs_els_in_blk(blk_el0)].comp[0] = negative_component(c); pcs[num_pcs_els_in_blk(blk_el0)].comp[1] = positive_component(c); pcs[num_pcs_els_in_blk(blk_el0)].s[0] = sl; pcs[num_pcs_els_in_blk(blk_el0)].s[1] = sr; ++num_pcs_els_in_blk(blk_el0); } p = b->end; if (sorted(p)==NO) { sorted(p) = YES; tp = (TG_PT*)find_from_hash_table((POINTER)p,hash_table, h_size); slsr(p,Hyper_surf_element(b),Hyper_surf(c),&sl,&sr); pcs[num_pcs_els_in_blk(blk_el0)].p = tp; pcs[num_pcs_els_in_blk(blk_el0)].comp[0] = negative_component(c); pcs[num_pcs_els_in_blk(blk_el0)].comp[1] = positive_component(c); pcs[num_pcs_els_in_blk(blk_el0)].s[0] = sl; pcs[num_pcs_els_in_blk(blk_el0)].s[1] = sr; ++num_pcs_els_in_blk(blk_el0); } } if (debugging("add_intfc_blk_pcs2d")) { int i; (void) printf("\nblk_el0 %llu\n", ptr2ull(blk_el0)); (void) printf("\t num_pcs_els_in_blk = %d\n", num_pcs_els_in_blk(blk_el0)); for (i=0; i< num_pcs_els_in_blk(blk_el0);++i) { (void) printf("%d: (%g,%g),", i, Coords(pcs[i].p)[0],Coords(pcs[i].p)[1]); (void) printf("comp = (%d,%d)\n", pcs[i].comp[0],pcs[i].comp[1]); } } } /* end add_intfc_blk_pcs2d */