EXPORT void oblique_propagate_at_node( Front *fr, POINTER wave, POINT *newp, O_CURVE *oldc, O_CURVE *newc, double *nor, double dt) { BOND *oldb; POINT *oldn_posn, *oldp; double save[MAXD], dposn[MAXD]; double len, t[MAXD]; double V[MAXD]; int i, dim = fr->rect_grid->dim; void (*save_impose_bc)(POINT*,BOND*,CURVE*,double*,Front*, boolean,boolean); oldb = Bond_at_node_of_o_curve(oldc); oldn_posn = Node_of_o_curve(oldc)->posn; oldp = Point_adjacent_to_node(oldc->curve,oldc->orient); for (i = 0; i < dim; ++i) { save[i] = Coords(oldp)[i]; dposn[i] = save[i] - Coords(oldn_posn)[i]; } t[0] = -nor[1]; t[1] = nor[0]; len = mag_vector(t,dim); for (i = 0; i < dim; ++i) t[i] /= len; if (scalar_product(t,dposn,dim) < 0.0) { for (i = 0; i < dim; ++i) t[i] = -t[i]; } len = 0.0; for (i = 0; i < dim; ++i) len += fabs(t[i]*fr->rect_grid->h[i]); for (i = 0; i < dim; ++i) Coords(oldp)[i] = Coords(oldn_posn)[i] + len * t[i]; save_impose_bc = fr->impose_bc; fr->impose_bc = NULL; point_propagate(fr,wave,oldn_posn,newp,oldb,oldc->curve,dt,V); if (newc->orient != oldc->orient) reverse_states_at_point(newp,fr); for (i = 0; i < dim; ++i) Coords(oldp)[i] = save[i]; fr->impose_bc = save_impose_bc; } /*end oblique_propagate_at_node*/
/*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*/
EXPORT int intersection_of_two_shock_polars( Locstate st0, Locstate st1, float *abs_v, float *p, float *pmin, float *pmax, bool Cplus_w0, bool Cplus_w1, RIEMANN_SOLVER_WAVE_TYPE *wtype0, RIEMANN_SOLVER_WAVE_TYPE *wtype1) { float v0[MAXD]; /* Velocities in the steady frame */ float v1[MAXD]; float M0sq, M1sq; /* Mach #'s squared in steady frame */ float theta01; /* turn angle vector v0 to v1 */ float v0_x_v1; float v0_d_v1; float p0, p1; float p_upper, p_lower; const float meps = 10.0*MACH_EPS;/*TOLERANCE*/ float eps_theta; float eps_pressure; #if !defined(UNRESTRICTED_THERMODYNAMICS) float min_pressure; #endif /* !defined(UNRESTRICTED_THERMODYNAMICS) */ int dim; DT_ANG_PARAMS parameters; static char yesstatus[] = "Left intersection_of_two_shock_polars() status = YES\n"; static char nostatus[] = "Left intersection_of_two_shock_polars() status = NO\n"; debug_print("shock_polar","Entered intersection_of_two_shock_polars()\n"); dim = Params(st0)->dim; p0 = pressure(st0); p1 = pressure(st1); M0sq = mach_number_squared(st0,abs_v,v0); M1sq = mach_number_squared(st1,abs_v,v1); (void) vector_product(v0,v1,&v0_x_v1,dim); v0_d_v1 = scalar_product(v0,v1,dim); theta01 = atan2(v0_x_v1,v0_d_v1); #if defined(DEBUG_GIPOLAR) if (debugging("shock_polar")) { (void) printf("abs_v = (%g, %g)\n",abs_v[0],abs_v[1]); (void) printf("Cplus_w0 = %s, Cplus_w1 = %s\n", (Cplus_w0) ? "YES" : "NO", (Cplus_w1) ? "YES" : "NO"); verbose_print_state("st0",st0); (void) printf("v0 = (%g, %g), q0 = %g, M0 = %g\n",v0[0],v0[1], mag_vector(v0,dim),sqrt(M0sq)); verbose_print_state("st1",st1); (void) printf("v1 = (%g, %g), q1 = %g, M1 = %g\n\n",v1[0],v1[1], mag_vector(v1,dim),sqrt(M1sq)); print_angle("theta01 =",theta01,"\n"); } #endif /* defined(DEBUG_GIPOLAR) */ *wtype0 = *wtype1 = UNSET_RIEMANN_SOLVER_WAVE_TYPE; if (!spolar_intersect_bounds(theta01,M0sq,M1sq,st0, st1,pmin,pmax,&p_upper,&p_lower, Cplus_w0,Cplus_w1,wtype0,wtype1)) { if (debugging("shock_polar")) { (void) printf("WARNING in intersection_of_two_shock_polars(), " "spolar_intersect_bounds() failed.\n"); debug_print("shock_polar",nostatus); } return NO; } #if !defined(UNRESTRICTED_THERMODYNAMICS) min_pressure = max(Min_pressure(st0),Min_pressure(st1)); if (p_upper < min_pressure) { *p = min_pressure; *wtype0 = *wtype1 = RAREFACTION; debug_print("shock_polar",yesstatus); return YES; } #endif /* !defined(UNRESTRICTED_THERMODYNAMICS) */ if (p_upper <= p0) *wtype0 = RAREFACTION; if (p_lower >= p0) *wtype0 = SHOCK; if (p_upper <= p1) *wtype1 = RAREFACTION; if (p_lower >= p1) *wtype1 = SHOCK; eps_theta = fabs(theta01)*EPS; eps_theta = max(meps,eps_theta); eps_pressure = max(p0,p1)*EPS; eps_pressure = max(meps,eps_pressure); set_parameters(parameters,Cplus_w0,Cplus_w1,st0,st1,M0sq,M1sq); if (find_root(diff_turn_ang,(POINTER)¶meters,theta01,p,p_lower, p_upper,eps_theta,eps_pressure) == FUNCTION_FAILED) { if (debugging("shock_polar")) { (void) printf("WARNING in intersection_of_two_shock_polars()"); (void) printf(", No intersection of shock polars.\n"); } debug_print("shock_polar",nostatus); return NO; } *wtype0 = (*p >= p0) ? SHOCK : RAREFACTION; *wtype1 = (*p >= p1) ? SHOCK : RAREFACTION; debug_print("shock_polar",yesstatus); return YES; } /*end intersection_of_two_shock_polars*/
LOCAL int i_polar_1( Locstate ahead, Locstate behind, Locstate refl_bow, Locstate refl_mach, ANGLE_DIRECTION i_to_a_dir, float *abs_v, float *refl_ang, float *cont_ang, float *mach_ang) { float p3; float theta12; /*turn angle across refl*/ float theta03; /*turn angle across mach*/ float vel0_ang; /*in steady frame*/ float vel1_ang; /* " " " */ float pmax, pmin; float M0_sq, M1_sq; float rel_v[MAXD]; bool Cplus_w0; /*wave 0 is mach stem*/ bool Cplus_w1; /*wave 1 is refl wave*/ RIEMANN_SOLVER_WAVE_TYPE wtype0; RIEMANN_SOLVER_WAVE_TYPE wtype1; int i, dim = Params(ahead)->dim; static Locstate st_0 = NULL, st_1 = NULL; static Locstate st_2 = NULL, st_3 = NULL; static bool first = YES; debug_print("ipolar1","Entered i_polar_1()\n"); if (first) { size_t sizest = Params(ahead)->sizest; first = NO; (*Params(ahead)->_alloc_state)(&st_0,sizest); (*Params(ahead)->_alloc_state)(&st_1,sizest); (*Params(ahead)->_alloc_state)(&st_2,sizest); (*Params(ahead)->_alloc_state)(&st_3,sizest); } set_state(st_0,TGAS_STATE,ahead); set_state(st_1,TGAS_STATE,behind); if (debugging("ipolar1")) { verbose_print_state("ahead",ahead); verbose_print_state("behind",behind); (void) printf("\tabs_v[0] = (%g, %g)\n",abs_v[0],abs_v[1]); print_angle_direction("\ti_to_a_dir =",i_to_a_dir,"\n"); } M0_sq = mach_number_squared(st_0,abs_v,rel_v); vel0_ang = angle(rel_v[0],rel_v[1]); if (debugging("ipolar1")) { print_angle("\tvel0 angle =",vel0_ang,"\n"); (void) printf("\tahead Mach number = %g\n", mag_vector(rel_v,dim)/sound_speed(st_0)); } if (mag_vector(rel_v,dim) < sound_speed(st_0)) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1(), "); (void) printf("ahead is subsonic in the rest frame.\n"); } debug_print("ipolar1","Left i_polar_1()\n"); return NO; } M1_sq = mach_number_squared(st_1,abs_v,rel_v); if (debugging("ipolar1")) { vel1_ang = angle(rel_v[0],rel_v[1]); print_angle("\tvel1 angle =",vel1_ang,"\n"); (void) printf("\tst1 Mach number = %g\n",sqrt(M1_sq)); } if (mag_vector(rel_v,dim) < sound_speed(st_1)) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1(), "); (void) printf("behind is subsonic in the rest frame.\n"); } debug_print("ipolar1","Left i_polar_1()\n"); return NO; } if (i_to_a_dir == CLOCKWISE) { Cplus_w0 = YES; Cplus_w1 = NO; } else { Cplus_w0 = NO; Cplus_w1 = YES; } if (pr_at_max_turn_angle(&pmin,M0_sq,st_0) == FUNCTION_FAILED) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1(), "); (void) printf("pr_at_max_turn_angle() failed\n"); } return NO; } pmax = max_behind_shock_pr(M1_sq,st_1); if (!intersection_of_two_shock_polars(st_0,st_1,abs_v,&p3, &pmin,&pmax,Cplus_w0, Cplus_w1,&wtype0,&wtype1)) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1(), "); (void) printf("unable to compute refl_mach pressure\n"); } debug_print("ipolar1","Left i_polar_1()\n"); return NO; } if ((wtype0 != SHOCK) || (wtype1 != SHOCK)) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1() -- "); (void) printf("non-shock wave types.\n"); } debug_print("ipolar1","Left i_polar_1()\n"); return NO; } if (!s_polar_3(st_1,YES,p3,Cplus_w1,YES,abs_v,st_2, refl_ang,&theta12)) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1() -- "); (void) printf("unable to compute refl_bow.\n"); } debug_print("ipolar1","Left i_polar_1()\n"); return NO; } if (!s_polar_3(st_0,YES,p3,Cplus_w0,YES,abs_v,st_3, mach_ang,&theta03)) { if (debugging("ipolar1")) { (void) printf("WARNING in i_polar_1() -- "); (void) printf("unable to compute refl_mach.\n"); } debug_print("ipolar1","Left i_polar_1()\n"); return NO; } *cont_ang = normalized_angle(vel0_ang + theta03); set_state(refl_bow,GAS_STATE,st_2); set_state(refl_mach,GAS_STATE,st_3); if (debugging("ipolar1")) { float ang; (void) printf("\n"); print_angle("\trefl angle = %g d\n",*refl_ang,"\n"); print_angle("\tcont angle = %g d\n",*cont_ang,"\n"); print_angle("\tMach angle = %g d\n",*mach_ang,"\n"); print_angle("\ttheta12 = %g d\n",theta12,"\n"); print_angle("\ttheta03 = %g d\n",theta03,"\n"); for (i = 0; i < dim; i++) rel_v[i] = vel(i,st_2) - abs_v[i]; ang = angle(rel_v[0],rel_v[1]); print_angle("\tvel2_ang =",ang,"\n"); for (i = 0; i < dim; i++) rel_v[i] = vel(i,st_3) - abs_v[i]; ang = angle(rel_v[0],rel_v[1]); print_angle("\tvel3_ang =",ang,"\n"); ang = (vel1_ang+theta12) - (vel0_ang+theta03); print_angle("(vel1_ang+theta12) - (vel0_ang+theta03) =", ang,"\n"); verbose_print_state("refl_bow",refl_bow); verbose_print_state("refl_mach",refl_mach); } debug_print("ipolar1","Left i_polar_1()\n"); return YES; } /*end i_polar_1*/