Exemple #1
0
LOCAL	double area_of_rect_grid(
	const RECT_GRID *rect_grid)
{
	double       area;
	const double *L = rect_grid->L, *U = rect_grid->U;
	int         i, dim = rect_grid->dim;

	area = -HUGE_VAL;
	switch (rect_grid->Remap.remap) 
	{
	case IDENTITY_REMAP:
	    area = U[0] - L[0];
	    for (i = 1; i < dim; ++i)
	    	area *= U[i] - L[i];
	    break;
	case CYLINDRICAL_REMAP:
	    if (L[0] < 0.0)
	        area = PI*(U[0]*U[0] + L[0]*L[0]);
	    else
	        area = PI*(U[0]+L[0])*(U[0]-L[0]);
	    for (i = 1; i < dim; ++i)
	    	area *= U[i] - L[i];
	    break;
	case SPHERICAL_REMAP:
	    area = 4.0/3.0*PI*(U[0]*U[0]*U[0] - L[0]*L[0]*L[0]);
	    break;
	default:
	    screen("ERROR in area_of_rect_grid(), "
	           "illegal or unavailable geometry\n");
	    clean_up(ERROR);
	}
	if (area <= 0.0)
	{
	    screen("ERROR in area_of_rect_grid(), "
	           "Nonpositive computational area\n");
	    (void) printf("dim = %d, remap = %d, area = %g\n",
	                  dim,rect_grid->Remap.remap,area);
	    if (1 <= dim && dim <= 3)
	    {
	        print_general_vector("L = ",L,dim,", ");
	        print_general_vector("U = ",U,dim,"\n");
	    }
	    else
	        (void) printf("Invalid dimension %d\n",dim);
	    clean_up(ERROR);
	}
	return area;
}		/*end area_of_rect_grid*/
Exemple #2
0
EXPORT	void nearest_intfc_state_and_pt(
	double		*coords,
	COMPONENT	comp,
	Front		*front,
	Front		*newfront,
	Locstate	state,
	double		*coords_on,
	HYPER_SURF	**hs_on)
{
	boolean		status;
	INTERFACE	*intfc;

			/* try old intfc first */
	intfc = front->interf;
	status = nearest_intfc_state(coords,comp,intfc,state,coords_on,hs_on);
	if ((status != YES) && (newfront != NULL))
	{
	    (void) printf("WARNING in nearest_intfc_state_and_pt(), "
	    	      "nearest_intfc_state failed on front->interf\n");
	    intfc = newfront->interf;
	    status = nearest_intfc_state(coords,comp,intfc,
				         state,coords_on,hs_on);
	}
	if (status != YES)
	{
	    int dim = front->rect_grid->dim;
	    screen("ERROR in nearest_intfc_state_and_pt(), "
	           "nearest_intfc_state() failed on both interfaces\n");
	    (void) printf("nearest_intfc_state_and_pt() fails to find\n");
	    print_general_vector("intfc point for ",coords,dim,"");
	    (void) printf(" comp %d\n",comp);
	    clean_up(ERROR);
	}
}		/*end nearest_intfc_state_and_pt*/
Exemple #3
0
/*ARGSUSED*/
LOCAL	void	get_state_rt_kh(
	float		*coords,
	Locstate	state,
	COMP_TYPE	*ct,
	HYPER_SURF	*hs,
	INTERFACE	*intfc,
	INIT_DATA	*init,
	int	        stype)
{
	int		    dim = ct->params->dim;
	STRATIFICATION_TYPE s_type = Rt_kh(ct)->stratification_type;
	float		    *ref_c = Rt_kh(ct)->ref_coords;
	Locstate	    ref_st = Rt_kh(ct)->ref_state;
	float		    z, z_r, g_z;
	const float	    *grav;

	debug_print("init_states","Entered get_state_rt_kh()\n");
	z = coords[dim-1]; 
	z_r = ref_c[dim-1];
	grav = gravity(coords,initial_time(init));
	g_z = grav[dim-1];
	get_state_in_stratified_region(s_type,state,z-z_r,g_z,ref_st);
	if (Dens(state) < 0)
	{
	    screen("ERROR in get_state_rt_kh().\n");
	    fprint_general_vector(stderr,"At point ",coords,dim,"");
	    print_general_vector("At point ",coords,dim,"");
	    screen(", the density of the state is less than 0.\n");
	    clean_up(ERROR);
	}
	if (Press(state) < 0.0)
	{
	    (void) printf("WARNING in get_state_rt_kh().\n");
	    print_general_vector("At point ",coords,dim,"");
	    (void) printf(", the pressure of the state is less than 0.\n");
	}
	set_state(state,stype,state);
}		/*end get_state_rt_kh*/
Exemple #4
0
EXPORT	void	get_state_rt_kh_perturbed(
	float		*coords,
	Locstate	s,
	COMP_TYPE	*ct,
	HYPER_SURF	*hs,
	INTERFACE	*intfc,
	INIT_DATA	*init,
	int             stype)
{
	int		prob_type = ct->type;

	debug_print("init_states","Entered get_state_rt_kh_perturbed()\n");
	if ((prob_type != RT_PERTURBED) && (prob_type != KH_PERTURBED))
	{
	    screen("ERROR in get_state_rt_kh_perturbed(), "
	           "inconsistent comp_type->type\n");
	    clean_up(ERROR);
	}

	if (prob_type == RT_PERTURBED)
	{
	    POINTER		extra = ct->extra;
	    ct->extra = (POINTER) Rt_perturbed(ct)->rt_kh;
	    get_state_rt_kh(coords,s,ct,hs,intfc,init,TGAS_STATE);
	    ct->extra = extra;
	    rt_add_to_state(coords,s,ct,init);
	}
	else if (prob_type == KH_PERTURBED)
	    kh_add_to_state(coords, s, ct);

	if (Dens(s) < 0)
	{
	    int	dim = ct->params->dim;

	    screen("\nERROR in get_state_rt_kh_perturbed(), ");
	    print_general_vector("At point ",coords,dim,"");
	    screen(", the density of the state is less than 0.\n");
	    clean_up(ERROR);
	}
	set_state(s,stype,s);
}		/*end get_state_rt_kh_perturbed*/
Exemple #5
0
EXPORT	int	return_advance_front(
	Front		*front,
	Front		**newfront,
	int		status,
	const char	*fname)
{
	if (front->pp_grid && front->pp_grid->nn > 1)
 	    status = syncronize_time_step_status(status,front->pp_grid);

	if (debugging("final_front"))
	{
	    print_Front_structure(front);
	    print_Front_structure(*newfront);
	}
	if (status != GOOD_STEP)
	{
	    free_front(*newfront);
	    *newfront = NULL;
	}
	else if (front->_EnforceFlowSpecifedStates != NULL)
	{
	    (*front->_EnforceFlowSpecifedStates)(*newfront);
	}
	if (debugging("trace"))
        {
            int dim = front->rect_grid->dim;
            (void) printf("Maximum propagated scaled distance = %f\n",
                        *(front->max_scaled_propagation));
            print_general_vector("Max propagated point: ",
                        front->max_prop_point,dim,"\n");
        }
	debug_front("final_front","after EnforceFlowSpecifedStates():",
	           *newfront);
	debug_print("front","Left %s\n",fname);
	return status;
}		/*end return_advance_front*/
Exemple #6
0
/*ARGSUSED*/
EXPORT	void	get_state_1d_overlay(
	float		*coords,
	Locstate	s,
	COMP_TYPE	*ct,
	HYPER_SURF	*hs,
	INTERFACE	*intfc,
	INIT_DATA	*init,
	int		stype)
{
	ONED_OVERLAY	*olay = (ONED_OVERLAY*)ct->extra;
	INPUT_SOLN	**is = olay->is;
	RECT_GRID	*gr = &is[0]->grid;
	INTERFACE	*intfc1d = olay->intfc1d;
	float		x, coords1d[3], m, sp;
	float		dcoords[3];
	float		c0[3], c1[3];
	float		alpha;
	int		i0[3], i1[3], i, dim = ct->params->dim;
	int		nvars = olay->prt->n_restart_vars;
	static Locstate	s0 = 0, s1 = 0;

	debug_print("init_states","Entered get_state_1d_overlay()\n");
	if (s0 == NULL)
	{
	    (*ct->params->_alloc_state)(&s0,ct->params->sizest);
	    (*ct->params->_alloc_state)(&s1,ct->params->sizest);
	}

	for (i = 0; i < dim; ++i)
	    dcoords[i] = coords[i] - olay->origin[i];
	switch (olay->overlay_type)
	{
	case RADIAL_OVERLAY:
	    x = mag_vector(dcoords,dim);
	    break;
	case CYLINDRICAL_OVERLAY:
	    sp = scalar_product(dcoords,olay->direction,dim);
	    for (i = 0; i < dim; ++i)
	    	dcoords[i] -= sp*olay->direction[i];
	    x = mag_vector(dcoords,dim);
	    break;
	case RECTANGULAR_OVERLAY:
	    x = scalar_product(dcoords,olay->direction,dim);
	    break;
	case OVERLAY_TYPE_UNSET:
	default:
	    x = -HUGE_VAL;
	    screen("ERROR in get_state_1d_overlay(), unset overlay type\n");
	    clean_up(ERROR);
	    break;
	}
	if (x > gr->U[0])
	    x = gr->U[0];
	if (x < gr->L[0])
	    x = gr->L[0];
	coords1d[0] = x;
	if (rect_in_which(coords1d,i0,gr) == FUNCTION_FAILED)
	{
	    screen("ERROR in get_state_1d_overlay(), rect_in_which() failed\n");
	    print_general_vector("dcoords = ",dcoords,dim,"\n");
	    (void) printf("overlay type = %d, x = %g\n",olay->overlay_type,x);
	    (void) printf("rectangular grid gr\n");
	    print_rectangular_grid(gr);
	    (void) printf("One dimensional interface\n");
	    print_interface(intfc1d);
	    clean_up(ERROR);
	}
	c0[0] = cell_center(i0[0],0,gr);
	if (x < c0[0])
	{
	    i1[0] = i0[0];
	    i0[0]--;
	    if (i0[0] < 0)
		i0[0] = 0;
	    c1[0] = c0[0];
	    c0[0] = cell_center(i0[0],0,gr);
	}
	else
	{
	    i1[0] = i0[0] + 1;
	    if (i1[0] >= gr->gmax[0])
	    	i1[0] = i0[0];
	    c1[0] = cell_center(i1[0],0,gr);
	}
	if (component(c0,intfc1d) != ct->comp)
	{
	    set_oned_state_from_interface(c0,s0,ct,olay);
	}
	else
	{
	    g_restart_initializer(i0,nvars,ct->comp,is,s0,init);
	    Init_params(s0,ct->params);
	}
	if (component(c1,intfc1d) != ct->comp)
	{
	    set_oned_state_from_interface(c1,s1,ct,olay);
	}
	else
	{
	    g_restart_initializer(i1,nvars,ct->comp,is,s1,init);
	    Init_params(s1,ct->params);
	}
	alpha = (c1[0] > c0[0]) ? (x - c0[0])/(c1[0] - c0[0]) : 0.5;
	ct->params->dim = 1;
	interpolate_states(olay->front,1.0-alpha,alpha,c0,s0,c1,s1,s);
	ct->params->dim = dim;

	m = Mom(s)[0];
	switch (olay->overlay_type)
	{
	case RADIAL_OVERLAY:
	case CYLINDRICAL_OVERLAY:
	    if (x > 0.0)
	    {
	        for (i = 0; i < dim; ++i)
	    	    Mom(s)[i] = m*dcoords[i]/x;
	    }
	    else
	    {
	        for (i = 0; i < dim; ++i)
	    	    Mom(s)[i] = 0.0;
	    }
	    break;
	case RECTANGULAR_OVERLAY:
	    for (i = 0; i < dim; ++i)
	    	Mom(s)[i] = m*olay->direction[i];
	    break;
	case OVERLAY_TYPE_UNSET:
	default:
	    screen("ERROR in get_state_1d_overlay(), unset overlay type\n");
	    clean_up(ERROR);
	    break;
	}
	set_state(s,stype,s);
}		/*end get_state_1d_overlay*/
Exemple #7
0
EXPORT void set_topological_grid(
	INTERFACE *intfc,
	RECT_GRID *input_grid)
{
	enum { DEFAULT_GMAX = 20 };
	HYPER_SURF	*hs;
	HYPER_SURF_ELEMENT *hse;
	POINT		*p;
	RECT_GRID	*top_grid = &topological_grid(intfc);
	double		*L, *U;
	int		dim = intfc->dim;
	int		i;
	static int	dgmax[3] = {DEFAULT_GMAX, DEFAULT_GMAX, DEFAULT_GMAX};

	if (DEBUG)
	    (void) printf("\n\nEntered set_topological_grid()\n");
	intfc->table->new_grid = YES;
	if (input_grid != NULL)
	{
	    copy_rect_grid(top_grid,input_grid);
	    intfc->table->fixed_grid = YES;
	    if (DEBUG)
		(void) printf("Left set_topological_grid()\n\n");
	    return;
	}
	else
	    intfc->table->fixed_grid = NO;

			/* Find Rectangle Containing INTERFACE: */
	L = top_grid->L;
	U = top_grid->U;
	for (i = 0; i < dim; ++i)
	{
	    L[i] = HUGE_VAL;
	    U[i] = -HUGE_VAL;
	}

	(void) next_point(intfc,NULL,NULL,NULL);
	while (next_point(intfc,&p,&hse,&hs))
	{
	    for (i = 0; i < dim; ++i)
	    {
	    	L[i] = min(L[i],Coords(p)[i]);
	    	U[i] = max(U[i],Coords(p)[i]);
	    }
	}


	if (DEBUG) 
	{
	    (void) printf("Rectsolid: ");
	    print_general_vector("L = ",L,dim,"");
	    print_general_vector("U = ",L,dim,"\n");
	}

	set_rect_grid(L,U,L,U,NOBUF,NOBUF,dgmax,dim,remap_info(),top_grid);

	if (DEBUG)
	    (void) printf("Left set_topological_grid()\n\n");
	return;
}		/*end set_toplogical_grid*/
Exemple #8
0
/* 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*/
Exemple #9
0
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 */
Exemple #10
0
LOCAL	bool	check_curve3d(
	CURVE     *c,
	INTERFACE *intfc)
{
	BOND     *b;
	BOND_TRI **bts, **bts0;
	NODE     *ns, *ne;
	SURFACE  *s, **ss;
	TRI      *tri, **tris;
	bool     status = YES;
	char     warn[1024];
	int      nsides, nbts, i;
	int      ntris;

	(void) sprintf(warn,"WARNING in check_curve3d(), curve %llu inconsistent ",
		       curve_number(c));
	if (c->interface != intfc)
	{
	    (void) printf("%s c->interface (%llu) != intfc (%llu)\n",
			  warn,interface_number(c->interface),
			  interface_number(intfc));
	    status = NO;
	}
	ns = c->start;
	if (!pointer_is_in_array(c,ns->out_curves))
	{
	    (void) printf("%s curve in not in start node (%llu) "
			  "out_curves\n",warn,node_number(ns));
	    status = NO;
	}
	ne = c->end;
	if (!pointer_is_in_array(c,ne->in_curves))
	{
	    (void) printf("%s curve in not in end node (%llu) "
			  "in_curves\n",warn,node_number(ne));
	    status = NO;
	}
	if (ns->posn != c->first->start)
	{
	    (void) printf("%s ns->posn != c->first->start\n"
			  "c->first->start = %llu, "
			  "ns = %llu, ns->posn = %llu\n",
			  warn,point_number(c->first->start),
			  node_number(ns),point_number(ns->posn));
	    status = NO;
	}
	if (ne->posn != c->last->end)
	{
	    (void) printf("%s ne->posn != c->last->end\n"
			  "c->last->end = %llu, "
			  "ne = %llu, ne->posn = %llu\n",
			  warn,point_number(c->last->end),
			  node_number(ne),point_number(ne->posn));

	    print_general_vector("c->last->end", Coords(c->last->end), 3, "\n");
	    print_general_vector("ne->posn", Coords(ne->posn), 3, "\n");
	    print_curve(c);
	    status = NO;
	}
	if (!Boundary_point(ns->posn))
	{
	    (void) printf("%s ns->posn (ns = %llu, ns->posn = %llu) is not a "
			  "boundary point\n",
			  warn,node_number(ns),point_number(ns->posn));
	    status = NO;
	}
	if (!Boundary_point(ne->posn))
	{
	    (void) printf("%s ne->posn (ne = %llu, ne->posn = %llu) is not a "
			  "boundary point\n",
			  warn,node_number(ne),point_number(ne->posn));
	    status = NO;
	}
	if (!Boundary_point(c->first->start))
	{
	    (void) printf("%s c->first->start = %llu is not a "
			  "boundary point\n",
			  warn,point_number(c->first->start));
	    status = NO;
	}
	if (!Boundary_point(c->last->end))
	{
	    (void) printf("%s c->last->end = %llu is not a "
			  "boundary point\n",
			  warn,point_number(c->last->end));
	    status = NO;
	}
	for (ss = c->pos_surfaces; ss && *ss; ++ss)
	{
	    if (!pointer_is_in_array(c,(*ss)->pos_curves))
	    {
	        (void) printf("%s curve in not s->pos_curves "
			      " s = %llu but s is in c->neg_surfaces\n",
			      warn,surface_number(*ss));
		status = NO;
	    }
	}
	for (ss = c->neg_surfaces; ss && *ss; ++ss)
	{
	    if (!pointer_is_in_array(c,(*ss)->neg_curves))
	    {
	        (void) printf("%s curve in not s->neg_curves "
			      " s = %llu but s is in c->neg_surfaces\n",
			      warn,surface_number(*ss));
		status = NO;
	    }
	}
	b = c->first;
	bts0 = Btris(b);
	for (nbts = 0, bts = Btris(b); bts && *bts; ++nbts, ++bts);
	if (nbts == 0)
	{
	    if (c->pos_surfaces || c->neg_surfaces)
	    {
		(void) printf("%s curve has no bond tris but is "
			      "connected to some surface\n",warn);
		status = NO;
	    }
	}
	if (c->first->prev != NULL)
	{
	    (void) printf("%s c->first->prev != NULL\n",warn);
	    print_bond(c->first);
	    print_bond(c->first->prev);
	    status = NO;
	}
	if (c->last->next != NULL)
	{
	    (void) printf("%s c->last->next != NULL\n",warn);
	    print_bond(c->last);
	    print_bond(c->last->next);
	    status = NO;
	}
	for (b = c->first; b != NULL; b = b->next)
	{
	    if (b->next && b->next->start != b->end)
	    {
	        (void) printf("%s bond pair (%llu -> %llu) point pointers "
			      "inconsistent\n",
			      warn,bond_number(b,intfc),
			      bond_number(b->next,intfc));
		print_bond(b);
		print_bond(b->next);
	        status = NO;
	    }
	    if (!Boundary_point(b->start))
	    {
	        (void) printf("%s b->start = %llu is not a "
			      "boundary point\n",
			      warn,point_number(b->start));
		print_bond(b);
	        status = NO;
	    }
	    if (!Boundary_point(b->end))
	    {
	        (void) printf("%s b->end = %llu is not a "
			      "boundary point\n",
			      warn,point_number(b->end));
		print_bond(b);
	        status = NO;
	    }
	    for (i = 0, bts = Btris(b); bts && *bts; ++i, ++bts)
	    {
		if ((i < nbts) &&
		    !(((*bts)->surface == bts0[i]->surface) &&
		          ((*bts)->orient == bts0[i]->orient)))
		{
	            (void) printf("%s inconsistent surface numbers on "
				  "bond tri\n",warn);
		    (void) printf("surface = %llu surface[%d] = %llu\n",
				  surface_number((*bts)->surface),i,
				  surface_number(bts0[i]->surface));
		    (void) printf("orient = %s orient[%d] = %s\n",
				  orientation_name((*bts)->orient),i,
				  orientation_name(bts0[i]->orient));
		    print_bond(b);
	            status = NO;
		}
	    }
	    if (i != nbts)
	    {
	        (void) printf("%s inconsistent %d != %d number of bond tris "
			      "on bond\n",warn,i,nbts);
		print_bond(b);
	        status = NO;
	    }
	    for (bts = Btris(b); bts && *bts; ++bts)
	    {
		if ((*bts)->curve != c)
		{
		    (void) printf("%s bond tri curve field (%llu) != c\n",
				  warn,curve_number((*bts)->curve));
		    print_bond(b);
		    status = NO;
		}
		if ((*bts)->bond != b)
		{
		    (void) printf("%s bond tri bond field (%llu) != b (%llu)\n",
				  warn,bond_number((*bts)->bond,intfc),
				  bond_number(b,intfc));
		    print_bond(b);
		    status = NO;
		}
		tri = (*bts)->tri;
		s = Surface_of_tri(tri);
		if ((*bts)->surface != s)
		{
		    (void) printf("%s bond tri surface field (%llu)"
				  "!= Surface_of_tri(tri) (%llu)\n",
				  warn,surface_number((*bts)->surface),
				  surface_number(s));
		    print_bond(b);
		    status = NO;
		}
		for (nsides = 0, i = 0; i < 3; ++i)
		{
		    if (is_side_bdry(tri,i) && (b==Bond_on_side(tri,i)))
			++nsides;
		}
		if (nsides == 0)
		{
		    (void) printf("%s bond not found on tri side\n",warn);
		    print_bond(b);
		    print_tri(tri,intfc);
		    status = NO;
		}
		else if (nsides > 1)
		{
		    (void) printf("%s bond found on multiple tri sides\n",warn);
		    print_bond(b);
		    print_tri(tri,intfc);
		    status = NO;
		}
		else
		{
		    if (orientation_of_bond_at_tri(b,tri) != (*bts)->orient)
		    {
		        (void) printf("%s inconsistent orientation at "
				      "bond tri\n",warn);
		        print_tri(tri,intfc);
		        print_bond(b);
		        status = NO;
		    }
		    switch ((*bts)->orient)
		    {
		    case POSITIVE_ORIENTATION:
	                if (!pointer_is_in_array(c,s->pos_curves))
	                {
	                    (void) printf("%s curve in not s->pos_curves "
					  " s = %llu\n",
			                  warn,surface_number(s));
		            print_bond(b);
		            print_tri(tri,intfc);
	                    status = NO;
	                }
	                if (!pointer_is_in_array(s,c->pos_surfaces))
	                {
	                    (void) printf("%s surface in not c->pos_surfaces "
					  " s = %llu\n",
			                  warn,surface_number(s));
		            print_bond(b);
		            print_tri(tri,intfc);
	                    status = NO;
	                }
			break;
		    case NEGATIVE_ORIENTATION:
	                if (!pointer_is_in_array(c,s->neg_curves))
	                {
	                    (void) printf("%s curve in not s->neg_curves "
					  " s = %llu\n",
			                  warn,surface_number(s));
		            print_bond(b);
		            print_tri(tri,intfc);
	                    status = NO;
	                }
	                if (!pointer_is_in_array(s,c->neg_surfaces))
	                {
	                    (void) printf("%s surface in not c->neg_surfaces "
					  " s = %llu\n",
			                  warn,surface_number(s));
		            print_bond(b);
		            print_tri(tri,intfc);
	                    status = NO;
	                }
			break;
		    case ORIENTATION_NOT_SET:
			(void) printf("%s inconsistent point and tri "
				      "points\n",warn);
		        print_bond(b);
		        print_tri(tri,intfc);
	                status = NO;
			break;
		    }
		}
		if (b->prev)
		{
		    TRI *t0, *t1;
	            ntris = set_tri_list_around_point(b->start,tri,&tris,intfc);
		    t0 = tris[0]; t1 = tris[ntris-1];
		    if (!(((side_of_tri_with_bond(b,t0) < 3) &&
			      (side_of_tri_with_bond(b->prev,t1) < 3))
		        ||
			     ((side_of_tri_with_bond(b,t1) < 3) &&
			      (side_of_tri_with_bond(b->prev,t0) < 3)))
		       )
		    {
			(void) printf("%s, corrupt tri list at b->start\n",
				      warn);
		        (void) printf("Bond b\n"); print_bond(b);
		        (void) printf("Bond b->prev\n"); print_bond(b->prev);
		        print_tri(tri,intfc);
			(void) printf("number of tris at point = %d\n",ntris);
			for (i = 0; i < ntris; ++i)
			{
			    (void) printf("tris[%d] - ",i);
			    print_tri(tris[i],intfc);
			}
			status = NO;
		    }
		}
	    }
	}
	return status;
}		/*end check_curve3d*/