EXPORT INTERFACE *pp_copy_interface( INTERFACE *intfc) { INTERFACE *new_intfc; boolean stat; boolean delete_status; DEBUG_ENTER(pp_copy_interface) new_intfc = copy_interface(intfc); stat = (new_intfc != NULL) ? YES : NO; if (stat == NO) { (void) printf("WARNING in pp_copy_interface(), " "unable to copy interface"); if (pp_numnodes() > 1) (void) printf(" on processor %d\n",pp_mynode()); else (void) printf("\n"); } delete_status = YES; if (pp_min_status(stat) == NO) { if (stat == YES) { (void) printf("WARNING in pp_copy_interface(), " "unable to copy interface " "on a remote processor\n"); delete_status = (delete_interface(new_intfc)) ? YES : NO; if (delete_status == NO) { screen("ERROR in pp_copy_interface() " "unable to delete interface "); if (pp_numnodes() > 1) screen(" on processor %d\n",pp_mynode()); else screen("\n"); } new_intfc = NULL; } } if (pp_min_status(delete_status) == NO) { if (delete_status == YES) { screen("ERROR in pp_copy_interface(), unable to delete " "interface on a remote processor\n"); } clean_up(ERROR); } DEBUG_LEAVE(pp_copy_interface) return new_intfc; } /*end pp_copy_interface*/
EXPORT void stripcomm( char *scfname, /*Strip commented file name*/ const char *fname) /*Raw input file name*/ { FILE *file = fopen(fname,"r"); FILE *scfile; char *c, line[2048]; static const char *separator = ": "; boolean status; size_t sep_len = strlen(separator); long io_pid; if (file == NULL) { screen("ERROR in stripcomm(), can't open %s\n",fname); clean_up(ERROR); } if (fgetstring(file,separator) == FUNCTION_FAILED) { /*File is already stripcommented*/ (void) strcpy(scfname,fname); (void) fclose(file); return; } io_pid = (is_io_node(pp_mynode())) ? (long) getpid() : 0; pp_global_lmax(&io_pid,1L); (void) sprintf(scfname,"%s-%ld.sc",fname,io_pid); if (is_io_node(pp_mynode())) { rewind(file); if ((scfile = fopen(scfname,"w")) == NULL) status = NO; else { status = YES; while (fgets(line,2046,file) != NULL) if ((c = strstr(line,separator)) != NULL) (void) fprintf(scfile,"%s",c+sep_len); (void) fclose(scfile); } } else status = YES; (void) fclose(file); if (pp_min_status(status) == NO) { screen("ERROR in stripcomm(), can't open %s\n",scfname); clean_up(ERROR); } return; } /*end stripcomm*/
EXPORT bool scatter_front( Front *front) { COMPONENT max_comp; INTERFACE *intfc = front->interf; RECT_GRID *gr = front->rect_grid; bool status; bool sav_copy = copy_intfc_states(); bool sav_intrp = interpolate_intfc_states(intfc); int i, dim = gr->dim; DEBUG_ENTER(scatter_front) max_comp = max_component(intfc); pp_global_imax(&max_comp,1L); add_time_start(3); if ((dim == 3) && debugging("consistency")) { (void) printf("Check consistency of interface " "before scatter_front()\n"); if (!consistent_interface(intfc)) { screen("ERROR in scatter_front(), input interface is " "inconsistent\n"); clean_up(ERROR); } (void) printf("Interface into scatter_front is consistent\n"); } if (dim == 2) { for (i = 0; i < dim; ++i) if ((gr->lbuf[i] > 0) || (gr->ubuf[i] > 0)) break; if (i == dim) { DEBUG_LEAVE(scatter_front) status = FUNCTION_SUCCEEDED; /* No subdomains to process */ return pp_min_status(status); } } set_copy_intfc_states(YES); interpolate_intfc_states(intfc) = NO; status = form_subintfc_via_communication(front); //if(dim == 3) // delete_outside_surface(front->interf); max_comp = max_component(intfc); pp_global_imax(&max_comp,1L); max_component(intfc) = max_comp; interpolate_intfc_states(intfc) = sav_intrp; set_copy_intfc_states(sav_copy); if ((status) && (dim == 3) && debugging("consistency")) { (void) printf("Check consistency of interface "); (void) printf("after scatter_front()\n"); if (!consistent_interface(intfc)) { screen("ERROR in scatter_front(), output interface is " "inconsistent\n"); clean_up(ERROR); } } DEBUG_LEAVE(scatter_front) status = pp_min_status(status); add_time_end(3); return status; } /*end scatter_front*/
void DUAL_ELLIPTIC_SOLVER::solve1d(double *soln) { int index,index_nb[2],size; double k_nb[2]; double rhs,coeff[2]; int I,I_nb[2]; int i,j,ii,jj,l,icoords[MAXD]; COMPONENT comp; double aII; int num_nb; GRID_DIRECTION dir[2] = {WEST,EAST}; boolean use_neumann_solver = YES; PetscInt num_iter = 0; double rel_residual = 0.0; HYPER_SURF *hs; double crx_coords[MAXD]; int status; POINTER intfc_state; int icrds_max[MAXD],icrds_min[MAXD]; if (debugging("trace")) (void) printf("Entering DUAL_ELLIPTIC_SOLVER::solve1d()\n"); PETSc solver; solver.Create(ilower, iupper-1, 3, 3); solver.Reset_A(); solver.Reset_b(); solver.Reset_x(); size = iupper - ilower; max_soln = -HUGE; min_soln = HUGE; for (i = cimin; i <= cimax; i++) { index = d_index1d(i,ctop_gmax); comp = ctop_comp[index]; I = i_to_I[i]; if (I == -1) continue; I_nb[0] = i_to_I[i-1]; I_nb[1] = i_to_I[i+1]; icoords[0] = i; get_dual_D(icoords,k_nb); num_nb = 0; for (l = 0; l < 2; ++l) { status = (*findStateAtCrossing)(front,icoords,dir[l],comp, &intfc_state,&hs,crx_coords); if (status != CONST_V_PDE_BOUNDARY) num_nb++; coeff[l] = k_nb[l]/(top_h[l/2]*top_h[l/2]); } rhs = source[index]; aII = 0.0; for (l = 0; l < 2; ++l) { if (num_nb == 0) break; status = (*findStateAtCrossing)(front,icoords,dir[l],comp, &intfc_state,&hs,crx_coords); if (status == NO_PDE_BOUNDARY) { solver.Set_A(I,I_nb[l],coeff[l]); aII += -coeff[l]; } else if (status == CONST_P_PDE_BOUNDARY) { rhs += -coeff[l]*getStateVar(intfc_state); aII += -coeff[l]; use_neumann_solver = NO; } } /* * This change reflects the need to treat point with only one * interior neighbor (a convex point). Not sure why PETSc cannot * handle such case. If we have better understanding, this should * be changed back. */ if(num_nb > 0) { solver.Set_A(I,I,aII); } else { (void) printf("WARNING: isolated value!\n"); solver.Set_A(I,I,1.0); rhs = soln[index]; } solver.Set_b(I,rhs); } use_neumann_solver = pp_min_status(use_neumann_solver); solver.SetMaxIter(40000); solver.SetTol(1e-10); start_clock("Petsc Solver"); if (use_neumann_solver) { (void) printf("\nUsing Neumann Solver!\n"); if (size < 6) { (void) printf("Isolated small region for solve2d()\n"); stop_clock("Petsc Solver"); } solver.Solve_withPureNeumann(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); if(rel_residual > 1) { (void) printf("\n The solution diverges! The residual " "is %g. Solve again using GMRES!\n",rel_residual); solver.Reset_x(); solver.Solve_withPureNeumann_GMRES(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); } } else { (void) printf("\nUsing non-Neumann Solver!\n"); solver.Solve(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); if(rel_residual > 1) { (void) printf("\n The solution diverges! The residual " "is %g. Solve again using GMRES!\n",rel_residual); solver.Reset_x(); solver.Solve_GMRES(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); } } stop_clock("Petsc Solver"); double *x; FT_VectorMemoryAlloc((POINTER*)&x,size,sizeof(double)); solver.Get_x(x); if (debugging("PETSc")) (void) printf("In poisson_solver(): " "num_iter = %d, rel_residual = %g \n", num_iter, rel_residual); for (i = cimin; i <= cimax; i++) { index = d_index1d(i,ctop_gmax); I = i_to_I[i]; if (I == -1) continue; else soln[index] = x[I-ilower]; if (max_soln < soln[index]) { icrds_max[0] = i; max_soln = soln[index]; } if (min_soln > soln[index]) { icrds_min[0] = i; min_soln = soln[index]; } } FT_ParallelExchCompGridArrayBuffer(soln,front,NULL); pp_global_max(&max_soln,1); pp_global_min(&min_soln,1); if (debugging("step_size")) { (void) printf("Max solution = %20.14f occuring at: %d\n", max_soln,icrds_max[0]); checkSolver(icrds_max,YES); (void) printf("Min solution = %20.14f occuring at: %d\n", min_soln,icrds_min[0]); checkSolver(icrds_min,YES); } if (debugging("elliptic_error")) { double error,max_error = 0.0; for (i = cimin; i <= cimax; i++) { icoords[0] = i; if (i_to_I[i] == -1) continue; error = checkSolver(icoords,NO); if (error > max_error) { max_error = error; icrds_max[0] = i; } } (void) printf("In dual elliptic solver:\n"); (void) printf("Max relative elliptic error: %20.14f\n",max_error); (void) printf("Occuring at (%d)\n",icrds_max[0]); error = checkSolver(icrds_max,YES); } FT_FreeThese(1,x); if (debugging("trace")) (void) printf("Leaving DUAL_ELLIPTIC_SOLVER::solve1d()\n"); } /* end solve1d */
EXPORT int redistribute1d( Front *fr) { CROSS *cross; INTERFACE *intfc = fr->interf; boolean istatus; int flag = NORMAL_ATTEMPT_TO_UNTANGLE; int status; debug_print("redist1d","Entered redistribute1d()\n"); istatus = intersections(intfc,&cross,YES); if (istatus == FUNCTION_FAILED) { (void) printf("WARNING in redistribute1d(), " "intersections() failed\n"); } if (pp_min_status(istatus) == FUNCTION_FAILED) { if (istatus == FUNCTION_SUCCEEDED) { (void) printf("WARNING in redistribute1d(), " "intersections() failed on remote node\n"); } if (debugging("redist1d")) { (void) printf("WARNING in redistribute1d(), " "intersections() failed\n"); } debug_print("redist1d","Left redistribute1d()\n"); return BAD_REDISTRIBUTION; } if (interface_is_tangled(cross) == NO) { debug_print("redist1d","Left redistribute1d()\n"); return GOOD_REDISTRIBUTION; } (void) print_number_of_tangles("",intfc,cross); if (fr->fr_bdry_untangle) { if (debugging("redist1d")) (void) printf("Attempting to untangle boundary interactions\n"); status = (cross == NULL) ? CURVES_UNTANGLED : (*fr->fr_bdry_untangle)(fr,&cross, NULL,NULL,flag); status = synchronize_untangle_status(status); if (status != CURVES_UNTANGLED) { (void) printf("WARNING in redistribute1d(), " "unable to untangle boundary tangles\n"); debug_print("redist1d","Left redistribute1d()\n"); return BAD_REDISTRIBUTION; } } if (interface_is_tangled(cross) == NO) { debug_print("redist1d","Left redistribute1d()\n"); return GOOD_REDISTRIBUTION; } if (fr->untangle_front) { if (debugging("redist1d")) (void) printf("Attempting to untangle interior interactions\n"); status = (cross==NULL) ? CURVES_UNTANGLED : (*fr->untangle_front)(fr,&cross,flag); status = synchronize_untangle_status(status); switch (status) { case CURVES_UNTANGLED: break; case MODIFY_TIME_STEP_TO_UNTANGLE: (void) printf("WARNING in redistributed1d, " "fr->untangle_front returns \n" "\t\tMODIFY_TIME_STEP_TO_UNTANGLE\n"); debug_print("redist1d","Left redistribute1d()\n"); return MODIFY_TIME_STEP_REDISTRIBUTE; default: (void) printf("WARNING in redistribute1d(), " "unable to untangle interior tangles\n"); debug_print("redist1d","Left redistribute1d()\n"); return BAD_REDISTRIBUTION; } } if (interface_is_tangled(cross) == YES) { (void) printf("WARNING in redistribute1d(), " "unable to untangle interface\n"); print_intersections(cross,intfc); debug_print("redist1d","Left redistribute1d()\n"); return BAD_REDISTRIBUTION; } if (consistent_components1d(intfc) == NO) { screen("ERROR in redistribute1d(), " "inconsistent components\n"); print_interface(intfc); clean_up(ERROR); debug_print("redist1d","Left redistribute1d()\n"); return BAD_REDISTRIBUTION; } if (debugging("redist1d")) { (void) printf("Untangled interface\n"); print_interface(fr->interf); } debug_print("redist1d","Left redistribute1d()\n"); return GOOD_REDISTRIBUTION; } /*end redistribute1d*/
LOCAL int advance_front2d( double dt, double *dt_frac, Front *front, Front **newfront, POINTER wave) { CURVE *oldc,*tempc,*newc; CURVE **c; INTERFACE *tempintfc; NODE *oldn,*tempn,*newn; NODE_FLAG flag; RPROBLEM *rp; RPROBLEM *rp1; boolean scatter_normally_propagated_front = YES; boolean scatter_tangentially_propagated_front = YES; boolean stat; boolean do_redist; int status; long intfc_modified; long redo_advance_front; static const char *fname = "advance_front2d()"; int debug_flag = NO; debug_print("front","Entered %s(step %d time %g dt %g)\n",fname, front->step,front->time,dt); debug_front("old_front","into advance front",front); *newfront = copy_front(front); Interface_redistributed(*newfront) = NO; do_redist = (front->num_mts == 0) ? YES : NO; begin_advance_front2d: redo_advance_front = 0; tempintfc = NULL; rp = NULL; set_to_next_node_only(flag); set_node_doubly_linked_list(front->interf); /* Initialize Newfront */ start_clock("init_new_front"); capture_waves(front); print_storage("before init_new_front","ADV_storage"); /* TODO: Remove this option!!!!! */ if (front->init_topology_of_new_interface) status = (*front->init_topology_of_new_interface)(front,*newfront); else { set_size_of_intfc_state(size_of_state(front->interf)); set_copy_intfc_states(NO); set_add_to_correspond_list(YES); (*newfront)->interf = pp_copy_interface(front->interf); reset_hs_flags_on_intfc((*newfront)->interf); status = ((*newfront)->interf != NULL) ? GOOD_STEP : ERROR_IN_STEP; set_copy_intfc_states(YES); } if (front->pp_grid) status = syncronize_time_step_status(status,front->pp_grid); if (status != GOOD_STEP) { (void) printf("WARNING in advance_front2d(), " "unable to copy interface\n"); status = ERROR_IN_STEP; stop_clock("init_new_front"); return return_advance_front(front,newfront,status,fname); } print_storage("after init_new_front","ADV_storage"); stop_clock("init_new_front"); /* Set Default Propagation Limits */ set_propagation_limits(front,*newfront); /* Propagate the Curves */ if (front->intfc_propagate != NULL) { start_clock("intfc_propagate"); intfc_propagate(front,wave,front->interf,(*newfront)->interf,dt); debug_front("cp_front","after intfc prop",*newfront); stop_clock("curve_propagate"); } else if (front->curve_propagate != NULL) { start_clock("curve_propagate"); if (debugging("front")) (void) printf("Loop over Curves\n"); for (c = front->interf->curves; c && *c; ++c) { oldc = *c; if (((newc = correspond_curve(oldc)) != NULL) && (correspond_curve(newc) != NULL)) { if (debugging("propagate")) (void) printf("\t\tpropagating curve %llu\n", (long long unsigned int)curve_number(oldc)); curve_propagate(front,wave,oldc,newc,dt); /*f_curve_propagate2d */ } } debug_front("cp_front","after curve prop",*newfront); stop_clock("curve_propagate"); } /* Propagate the Nodes */ if (debugging("front")) { print_correspond_hyper_surf_list(front->interf); print_correspond_hyper_surf_list((*newfront)->interf); } if (front->node_propagate != NULL) { start_clock("node_propagate"); set_corresponds_for_node_prop(front->interf,(*newfront)->interf); oldn = first_node(front->interf); while (oldn != NULL) { newn = correspond_node(oldn); if (debugging("crx_status")) print_linked_node_list((*newfront)->interf); status = (newn != NULL) ? (*front->node_propagate)(front,wave,oldn,newn,&rp, dt,dt_frac,flag,NULL) : GOOD_NODE; if (debugging("crx_status")) if (is_bad_status(status) && (point_in_buffer(Coords(oldn->posn),front->rect_grid) == YES)) { print_node_status("WARNING in advance_front2d(), " "node_propagation returns ",status,"\n"); (void) printf("Problem occurs in buffer zone - ignoring\n"); if (set_node_states_and_continue(oldn,newn,front)) status = GOOD_NODE; } switch (status) { case GOOD_NODE: oldn = adv_node_loop_after_good_prop(oldn,newn,&rp); break; case PSEUDOCROSS_NODE_NODE: debug_print("PSEUDOCROSS","PSEUDOCROSS case\n"); oldn = reorder_node_loop(oldn,newn); break; case CROSS_NODE_NODE: case BIFURCATION_NODE: debug_print("CROSS","CROSS case\n"); oldn = next_node(oldn); break; case CROSS_PAST_CURVE_NODE: print_node_status("WARNING in advance_front2d(), " "node_propagate failed with status ", status,"\n"); print_node(oldn); if (debugging("CROSS_PAST")) { (void) printf("Cross past curve case\n" "dt_frac = %g\n",*dt_frac); (void) printf("Reducing time step\n"); } status = node_modify_time_step(oldn,front,dt_frac, MODIFY_TIME_STEP); free_rp_list(&rp); goto sync_prop_stat1; case MODIFY_TIME_STEP_NODE: (void) printf("WARNING in advance_front2d(), " "node_propagate returns " "MODIFY_TIME_STEP_NODE\n"); free_rp_list(&rp); status = node_modify_time_step(oldn,front,NULL, MODIFY_TIME_STEP); goto sync_prop_stat1; case REPEAT_TIME_STEP_NODE: (void) printf("WARNING in advance_front2d(), " "node_propagate returns " "REPEAT_TIME_STEP_NODE\n"); free_rp_list(&rp); status = node_modify_time_step(oldn,front,NULL, REPEAT_TIME_STEP); goto sync_prop_stat1; case NO_CROSS_NODE: print_node_status("WARNING in advance_front2d(), " "node_propagate failed with status ", status,"\n"); print_node(oldn); if (debugging("NO_CROSS")) { (void) printf("No cross case\n"); (void) printf("dt_frac = %g\n",*dt_frac); (void) printf("Reducing time step\n"); } free_rp_list(&rp); status = node_modify_time_step(oldn,front,dt_frac, MODIFY_TIME_STEP); goto sync_prop_stat1; case ERROR_NODE: default: print_node_status("WARNING in advance_front2d(), " "node_propagate failed with status ", status,"\n"); print_node(oldn); if (debugging("ERROR_NODE")) { (void) printf("Old interface:\n"); print_interface(front->interf); print_correspond_hyper_surf_list(front->interf); (void) printf("New interface:\n"); print_interface((*newfront)->interf); print_correspond_hyper_surf_list((*newfront)->interf); } status = node_modify_time_step(oldn,front,dt_frac, ERROR_IN_STEP); free_rp_list(&rp); goto sync_prop_stat1; } } /* end of while (oldn != NULL) */ set_correspond_hyper_surf_bdrys_to_NULL(front->interf); set_correspond_hyper_surf_bdrys_to_NULL((*newfront)->interf); if (rp && (front->twodrproblem != NULL)) { for (rp1 = rp; rp1; rp1 = rp1->prev) { debug_front("2drp_front", "new between node loop and rp loop",*newfront); status = (*front->twodrproblem)(front,*newfront,wave,&rp1); /* At this point, rp is nothing more than a valid element * of the list which provides a starting point * for deleting the list. If we delete an element of * the list in front->twodrproblem (presumably due to * merging two RPROBLEM's), then rp may point to freed * storage and will need to be updated. rp1 should still * be a valid element of the list. */ rp = rp1; if (status != GOOD_STEP) { print_time_step_status("WARNING in advance_front2d(), " "rp failed with status = ", status,"\n"); switch (status) { case GOOD_STEP: break; case REPEAT_TIME_STEP: break; case MODIFY_TIME_STEP: status = rp_modify_time_step(rp1,front,status); if (status == MODIFY_TIME_STEP) { *dt_frac = rp1->dt_frac; if (debugging("2drp")) { print_rproblem(rp1); (void) printf("dt_frac %g\n",*dt_frac); (void) printf("Reducing time step\n"); } *dt_frac = limit_dt_frac(*dt_frac,front); } break; case ERROR_IN_STEP: default: print_rproblem(rp1); /* Try reducing the time step */ status = rp_modify_time_step(rp1,front,status); if (status == MODIFY_TIME_STEP) *dt_frac *= TIME_STEP_REDUCTION_FACTOR(front->interf); break; } } if (status != GOOD_STEP) break; } free_rp_list(&rp); debug_front("2drp_front","after 2drp loop",*newfront); } else if (rp) { for (rp1 = rp; rp1; rp1 = rp1->prev) print_rproblem(rp1); free_rp_list(&rp); (void) printf("WARNING in advance_front2d(), " "CROSS code needed\n"); status = ERROR_IN_STEP; } sync_prop_stat1: stop_clock("node_propagate"); if (front->pp_grid) status = syncronize_time_step_status(status,front->pp_grid); if (status != GOOD_STEP) return return_advance_front(front,newfront,status,fname); } if (*front->max_scaled_propagation > 0.5) { (void) printf("WARNING in advance_front2d(), " "front->max_scaled_propagation = %f\n", *(front->max_scaled_propagation)); *dt_frac = 0.4/(*front->max_scaled_propagation); status = MODIFY_TIME_STEP; goto sync_prop_stat2; } stat = consistent_propagated_loop_orientations(dt,dt_frac,front,wave); if (stat == NO) { (void) printf("WARNING in advance_front2d(), " "Inconsistent orientation of propagated loop " "detected after point and node propagations"); if (pp_numnodes() > 1) (void) printf(" on processor %d\n",pp_mynode()); else (void) printf("\n"); } if (pp_min_status(stat) == NO) { if (stat == YES) { (void) printf("WARNING in advance_front2d(), " "Inconsistent orientation of propagated loop " "detected on a remote processor " "after point and node propagations "); } status = MODIFY_TIME_STEP; goto sync_prop_stat2; } /* Make Temp Interface for Tangential Propagation */ set_node_doubly_linked_list((*newfront)->interf); if (front->snd_node_propagate) { start_clock("snd_copy_interface"); print_storage("before snd_copy_interface","ADV_storage"); tempintfc = (*newfront)->interf; set_size_of_intfc_state(size_of_state(tempintfc)); set_add_to_correspond_list(YES); if (((*newfront)->interf = pp_copy_interface(tempintfc)) == NULL) { (void) printf("WARNING in advance_front2d(), " "unable to copy interface\n"); status = ERROR_IN_STEP; goto sync_prop_stat2; } copy_hypersurface_flags((*newfront)->interf); print_storage("after snd_copy_interface","ADV_storage"); stop_clock("snd_copy_interface"); } interpolate_intfc_states((*newfront)->interf) = YES; /* Second Propagation for the States Around the Nodes */ if (front->snd_node_propagate) { start_clock("snd_node_propagate"); if (debugging("front")) (void) printf("Second Loop over Nodes\n"); tempn = first_node(tempintfc); newn = first_node((*newfront)->interf); while (newn != NULL) { (*front->snd_node_propagate)(front,*newfront,wave, tempintfc,tempn,newn,dt); tempn = next_node(tempn); newn = next_node(newn); } debug_front("snd_front","after snd_node prop",*newfront); stop_clock("snd_node_propagate"); } if (tempintfc) (void) delete_interface(tempintfc); print_storage("after delete tempintfc","ADV_storage"); /* Redistribute the New Front */ switch (redistribute(*newfront,do_redist,NO)) { case GOOD_REDISTRIBUTION: status = GOOD_STEP; break; case UNABLE_TO_UNTANGLE: (void) printf("WARNING in advance_front2d(), " "redistribution of front failed\n" "Restarting advance_front2d()\n"); *dt_frac = Min_time_step_modification_factor(front); status = MODIFY_TIME_STEP; break; case MODIFY_TIME_STEP_REDISTRIBUTE: (void) printf("WARNING in advance_front2d(), " "redistribute returns\n" "\t\tMODIFY_TIME_STEP_REDISTRIBUTE, dt_frac = %g\n", *dt_frac); *dt_frac = Min_time_step_modification_factor(front); status = MODIFY_TIME_STEP; break; case BAD_REDISTRIBUTION: default: (void) printf("WARNING in advance_front2d(), " "redistribution of front failed\n"); debug_front("ERROR_front","after error",*newfront); *dt_frac = Min_time_step_modification_factor(front); status = MODIFY_TIME_STEP; break; } if (front->pp_grid) status = syncronize_time_step_status(status,front->pp_grid); if (status != GOOD_STEP) return return_advance_front(front,newfront,status,fname); Redistribution_count(front) = Redistribution_count(*newfront); (*newfront)->step = front->step + 1; (*newfront)->time = front->time + dt; debug_front("redist_front","after redistribution",*newfront); /* Communicate topologically propagated front */ if (scatter_normally_propagated_front == YES) { start_clock("scatter_front"); if (!scatter_front(*newfront)) { (void) printf("WARNING in advance_front2d(), " "scatter_front() failed for " "normally propagated front\n"); scatter_normally_propagated_front = NO; scatter_tangentially_propagated_front = NO; (void) delete_interface((*newfront)->interf); (*newfront)->interf = NULL; goto begin_advance_front2d; } stop_clock("scatter_front"); } debug_front("node_front","after node loop",*newfront); if (debugging("front")) { print_correspond_hyper_surf_list(front->interf); print_correspond_hyper_surf_list((*newfront)->interf); } if (front->mass_consv_diagn_driver) (*front->mass_consv_diagn_driver)(front,wave,dt); if (debugging("bond_lengths")) check_bond_lengths((*newfront)->interf); /* Check for the geometric orientation of loops */ /* ONLY check loops that will not be deleted !!!! */ delete_small_loops(*newfront); /* Delete non-boundary curves that lie */ /* fully on or exterior to the boundary */ delete_exterior_curves(*newfront,front->interf); intfc_delete_fold_back_bonds(*newfront); debug_front("dec_front","after delete_exterior_curves:",*newfront); interpolate_intfc_states((*newfront)->interf) = YES; /* Make Temp Interface for Tangential Propagation */ if (front->tan_curve_propagate) { start_clock("snd_copy_interface"); print_storage("before snd_copy_interface","ADV_storage"); tempintfc = (*newfront)->interf; set_size_of_intfc_state(size_of_state(tempintfc)); set_add_to_correspond_list(YES); if (((*newfront)->interf = pp_copy_interface(tempintfc)) == NULL) { (void) printf("WARNING in advance_front2d(), " "unable to copy interface\n"); status = ERROR_IN_STEP; goto sync_prop_stat2; } copy_hypersurface_flags((*newfront)->interf); interpolate_intfc_states((*newfront)->interf) = YES; print_storage("after snd_copy_interface","ADV_storage"); stop_clock("snd_copy_interface"); } /* Tangential Sweep for States on the Curves */ if (front->tan_curve_propagate) { start_clock("tan_curve_propagate"); if (debugging("front")) (void) printf("Second Loop over Curves\n"); for (c = tempintfc->curves; c && *c; ++c) { tempc = *c; newc = correspond_curve(tempc); (*front->tan_curve_propagate)(front,*newfront, tempintfc,tempc,newc,dt); } debug_front("tcp_front","after tan_curve_propagate:",*newfront); stop_clock("tan_curve_propagate"); } if (tempintfc) (void) delete_interface(tempintfc); print_storage("after delete tempintfc","ADV_storage"); /* Provide robustness for untangle algorithms */ /* delete remnants of scalar physical */ /* curves sticking to NEUMANN boundaries */ /* Add to delete_exterior_curves()? */ if (pp_min_status(delete_phys_remn_on_bdry(*newfront)) == NO) { (void) printf("WARNING in advance_front2d(), " "delete_phys_remn_on_bdry() detected error\n"); debug_front("ERROR_front","after error",*newfront); *dt_frac = Min_time_step_modification_factor(front); status = MODIFY_TIME_STEP; goto sync_prop_stat2; } debug_front("dspr_front", "after 1st delete_phys_remn_on_bdry():",*newfront); sync_prop_stat2: if (front->pp_grid) status = syncronize_time_step_status(status,front->pp_grid); if (status != GOOD_STEP) return return_advance_front(front,newfront,status,fname); /* Communicate tangentially propagated front */ if (scatter_tangentially_propagated_front == YES) { start_clock("scatter_front"); if (!scatter_front(*newfront)) { (void) printf("WARNING in advance_front2d(), " "scatter_front() failed for " "tangentially propagated front\n"); scatter_normally_propagated_front = NO; scatter_tangentially_propagated_front = NO; (void) delete_interface((*newfront)->interf); (*newfront)->interf = NULL; goto begin_advance_front2d; } stop_clock("scatter_front"); } if (status != GOOD_STEP) return return_advance_front(front,newfront,status,fname); /* Post-process newfront->interf */ /* Provide robustness after redistribution */ /* for node propagate on next time step */ /* Delete non-boundary curves that lie */ /* fully on or exterior to the boundary */ delete_exterior_curves(*newfront,front->interf); debug_front("dec_front","after delete_exterior_curves:",*newfront); /* delete remnants of scalar physical */ /* curves sticking to NEUMANN boundaries */ /* Add to delete_exterior_curves()? */ if (pp_min_status(delete_phys_remn_on_bdry(*newfront)) == NO) { (void) printf("WARNING in advance_front2d(), " "delete_phys_remn_on_bdry() detected error\n"); debug_front("ERROR_front","after error",*newfront); *dt_frac = Min_time_step_modification_factor(front); status = MODIFY_TIME_STEP; return return_advance_front(front,newfront,status,fname); } debug_front("dspr_front", "after 2nd delete_phys_remn_on_bdry():",*newfront); /* These guys keep sneaking through !! */ /* This should be the most effective place for this call */ /* Brent - I believe it is better to have the function at * the end of advance_front2d() applied to the newfront * instead of at the beginning applied to front. * In general our policy should be never to modify the * old interface data. */ delete_small_loops(*newfront); debug_front("dsloop_front","after delete_small_loops():",*newfront); test_for_mono_comp_curves((*newfront)->interf); /* Check if post processing has changed topology */ intfc_modified = (*newfront)->interf->modified; pp_global_lmax(&intfc_modified,1L); if (intfc_modified) { if (!scatter_front(*newfront)) { (void) printf("WARNING in advance_front2d(), " "final scatter_front() failed\n"); *dt_frac = Max_time_step_modification_factor(front); return return_advance_front(front,newfront, MODIFY_TIME_STEP,fname); } stat = make_bond_comp_lists((*newfront)->interf); if (pp_min_status(stat) == FUNCTION_FAILED) { screen("ERROR in advance_front2d(), " "make_bond_comp_lists() failed\n"); clean_up(ERROR); } } return return_advance_front(front,newfront,GOOD_STEP,fname); } /*end advance_front2d*/