t_stat dtc_setnl (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { int32 newln, i, t; t_stat r; if (cptr == NULL) return SCPE_ARG; newln = (int32) get_uint (cptr, 10, DTC_MLINES, &r); if ((r != SCPE_OK) || (newln == dtc_desc.lines)) return r; if ((newln == 0) || (newln > DTC_MLINES)) return SCPE_ARG; if (newln < dtc_desc.lines) { for (i = newln-1, t = 0; i < dtc_desc.lines; i++) t = t | dtc_ldsc[i].conn; if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) return SCPE_OK; for (i = newln-1; i < dtc_desc.lines; i++) { if (dtc_ldsc[i].conn) { tmxr_linemsg (&dtc_ldsc[i], "\r\nOperator disconnected line\r\n"); tmxr_send_buffered_data (&dtc_ldsc[i]); } tmxr_detach_ln (&dtc_ldsc[i]); /* completely reset line */ } } if (dtc_desc.lines < newln) memset (dtc_ldsc + dtc_desc.lines, 0, sizeof(*dtc_ldsc)*(newln-dtc_desc.lines)); dtc_desc.lines = newln; return dtc_reset (&dtc_dev); /* setup lines and auto config */ }
//------------------------------------------------------------------------------------------------- int ConsoleMenu::DeleteMsgs(tty_save_state& tty, MsgList& lst) const { for (;;) { Message *msg(SelectFromMsg(lst)); if (msg) { for (MsgList::iterator itr(lst.begin()); itr != lst.end(); ++itr) { if (*itr == msg) { if (get_yn("Delete msg? (y/n):", true)) { delete *itr; lst.erase(itr); } break; } } } else break; } return lst.size(); }
t_stat mux_vlines (UNIT *uptr, int32 val, char *cptr, void *desc) { int32 newln, i, t; t_stat r; if (cptr == NULL) return SCPE_ARG; newln = get_uint (cptr, 10, MUX_LINES, &r); if ((r != SCPE_OK) || (newln == MUX_NUMLIN)) return r; if (newln == 0) return SCPE_ARG; if (newln < MUX_NUMLIN) { for (i = newln, t = 0; i < MUX_NUMLIN; i++) t = t | mux_ldsc[i].conn; if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) return SCPE_OK; for (i = newln; i < MUX_NUMLIN; i++) { if (mux_ldsc[i].conn) { tmxr_linemsg (&mux_ldsc[i], "\r\nOperator disconnected line\r\n"); tmxr_reset_ln (&mux_ldsc[i]); /* reset line */ } muxl_unit[i].flags = muxl_unit[i].flags | UNIT_DIS; mux_reset_ln (i); } } else { for (i = MUX_NUMLIN; i < newln; i++) { muxl_unit[i].flags = muxl_unit[i].flags & ~UNIT_DIS; mux_reset_ln (i); } } MUX_NUMLIN = newln; return SCPE_OK; }
//------------------------------------------------------------------------------------------------- void ConsoleMenu::EditMsg(tty_save_state& tty, const FieldTable::Pair *fld, Message *msg) const { string txt; int rval(-1); if (fld->_value._rlm) rval = SelectRealm(fld->_key, fld->_value._rlm); else { _os << endl << fld->_value._name << ": " << flush; GetString(tty, txt); if (msg->get_fp().is_group(fld->_key)) { int cnt(GetValue<int>(txt)); GroupBase *gb(msg->find_group(fld->_key)); if (gb && cnt) { for (int ii(0); ii < cnt; ++ii) { Message *gmsg(static_cast<Message *>(gb->create_group())); const FieldTable::Pair *fld; while((fld = SelectField(gmsg, ii + 1))) EditMsg(tty, fld, gmsg); _os << endl << endl << *static_cast<MessageBase *>(gmsg) << endl; if (get_yn("Add group to msg? (y/n):", true)) *gb += gmsg; } } } } BaseField *bf(fld->_value._create(txt, fld->_value._rlm, rval)); msg->add_field(bf->get_tag(), msg->get_fp().get_presence().end(), 0, bf, true); }
/* * Set the number of lines for the PORTS mux. This will add or remove * cards as necessary. The number of lines must be a multiple of 4. */ t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { int32 newln, i, t; t_stat r = SCPE_OK; if (cptr == NULL) { return SCPE_ARG; } newln = (int32) get_uint(cptr, 10, (MAX_PORTS_CARDS * PORTS_LINES), &r); if ((r != SCPE_OK) || (newln == ports_desc.lines)) { return r; } if ((newln == 0) || LPORT(newln) != 0) { return SCPE_ARG; } if (newln < ports_desc.lines) { for (i = newln, t = 0; i < ports_desc.lines; i++) { t = t | ports_ldsc[i].conn; } if (t && !get_yn("This will disconnect users; proceed [N]?", FALSE)) { return SCPE_OK; } for (i = newln; i < ports_desc.lines; i++) { if (ports_ldsc[i].conn) { tmxr_linemsg(&ports_ldsc[i], "\r\nOperator disconnected line\r\n"); tmxr_send_buffered_data(&ports_ldsc[i]); } /* completely reset line */ tmxr_detach_ln(&ports_ldsc[i]); if (LPORT(i) == (PORTS_LINES - 1)) { /* Also drop the corresponding card from the CIO array */ cio_clear(LCID(i)); } } } ports_desc.ldsc = ports_ldsc = (TMLN *)realloc(ports_ldsc, newln*sizeof(*ports_ldsc)); ports_state = (PORTS_LINE_STATE *)realloc(ports_state, newln*sizeof(*ports_state)); if (ports_desc.lines < newln) { memset(ports_ldsc + ports_desc.lines, 0, sizeof(*ports_ldsc)*(newln-ports_desc.lines)); memset(ports_state + ports_desc.lines, 0, sizeof(*ports_state)*(newln-ports_desc.lines)); } ports_desc.lines = newln; /* setup lines and auto config */ ports_conf = FALSE; return ports_reset(&ports_dev); }
t_stat dp_setformat (UNIT *uptr, int32 val, char *cptr, void *desc) { uint32 h, c, cntr, rptr; int32 i, nr, nw, inp; uint16 tbuf[DP_TRKLEN]; float finp; t_stat r; if (uptr == NULL) return SCPE_IERR; if (cptr == NULL) return SCPE_ARG; if (!(uptr->flags & UNIT_ATT)) return SCPE_UNATT; inp = (int32) get_uint (cptr, 10, 2048, &r); if (r != SCPE_OK) return r; if (inp == 0) return SCPE_ARG; finp = (float) inp; if (sim_switches & SWMASK ('R')) { /* format records? */ nr = inp; nw = (int32) ((dp_tab[dp_ctype].wrds / (finp + ((finp - 1.0) / 20.0))) - REC_OVHD_WRDS); if (nw <= 0) return SCPE_ARG; } else { nw = inp; /* format words */ nr = (int32) ((((20.0 * dp_tab[dp_ctype].wrds) / (finp + REC_OVHD_WRDS)) + 1.0) / 21.0); if (nr <= 0) return SCPE_ARG; } printf ("Proposed format: records/track = %d, record size = %d\n", nr, nw); if (!get_yn ("Formatting will destroy all data on this disk; proceed? [N]", FALSE)) return SCPE_OK; for (c = cntr = 0; c < dp_tab[dp_ctype].cyl; c++) { for (h = 0; h < dp_tab[dp_ctype].surf; h++) { for (i = 0; i < DP_TRKLEN; i++) tbuf[i] = 0; rptr = 0; for (i = 0; i < nr; i++) { tbuf[rptr + REC_LNT] = nw & DMASK; if (sim_switches & SWMASK ('S')) tbuf[rptr + REC_ADDR] = cntr++; else tbuf[rptr + REC_ADDR] = (c << 8) + (h << 3) + i; rptr = rptr + nw + REC_OVHD; } if (r = dp_wrtrk (uptr, tbuf, c, h)) return r; } } printf ("Formatting complete\n"); return SCPE_OK; }
static int ok_to_clear_tset( TrainingSet **tset ) { if (*tset == NULL) return 1 ; if (get_yn ( "Existing training set must be cleared. OK" )) { MEMTEXT ( "NEURAL: delete tset" ) ; delete *tset ; *tset = NULL ; return 1 ; } else return 0 ; }
static int ok_to_clear_weights( Network **network ) { if (*network == NULL) return 1 ; if (get_yn ( "Existing learned weights must be cleared. OK" )) { MEMTEXT ( "NEURAL: delete network" ) ; delete *network ; *network = NULL ; return 1 ; } else return 0 ; }
t_stat qty_setnl( UNIT * uptr, int32 val, char * cptr, void * desc ) { int32 newln, i, t ; t_stat r ; if ( cptr == NULL ) { return ( SCPE_ARG ) ; } newln = (int32) get_uint( cptr, 10, QTY_MAX, &r ) ; if ( (r != SCPE_OK) || (newln == qty_desc.lines) ) { return ( r ) ; } if ( (newln == 0) || (newln > QTY_MAX) ) { return ( SCPE_ARG ) ; } if ( newln < qty_desc.lines ) { for ( i = newln, t = 0 ; i < qty_desc.lines ; ++i ) { t = t | qty_ldsc[i].conn ; } if ( t && ! get_yn("This will disconnect users; proceed [N]?", FALSE) ) { return ( SCPE_OK ) ; } for ( i = newln ; i < qty_desc.lines ; ++i ) { if ( qty_ldsc[i].conn ) { /* reset line */ tmxr_msg( qty_ldsc[i].conn, "\r\nOperator disconnected line\r\n" ) ; tmxr_reset_ln( &qty_ldsc[i] ) ; } qty_clear( TRUE ) ; /* reset mux */ } } qty_max = qty_desc.lines = newln ; /* Huh, I don't understand this yet... qty_max = ((qty_dev.flags & DEV_DIS)? 0 : (qty_desc.lines / QTY_MAX)) ; */ return ( SCPE_OK ) ; } /* end of 'qty_setnl' */
/* * Name: save_strokes * Purpose: save strokes to a file * Date: April 1, 1992 * Passed: window: pointer to current window */ int save_strokes( WINDOW *window ) { FILE *fp; /* file to be written */ char name[MAX_COLS+2]; /* file name */ char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */ register int rc; int prompt_line; int fattr; name[0] = '\0'; prompt_line = window->bottom_line; save_screen_line( 0, prompt_line, line_buff ); /* * name for macro file */ if ((rc = get_name( main19, prompt_line, name, g_display.message_color )) == OK && *name != '\0') { /* * make sure it is OK to overwrite any existing file */ rc = get_fattr( name, &fattr ); if (rc == OK) { /* * overwrite existing file */ set_prompt( main20, prompt_line ); if (get_yn( ) != A_YES || change_mode( name, prompt_line ) == ERROR) rc = ERROR; } if (rc != ERROR) { if ((fp = fopen( name, "wb" )) != NULL) { fwrite( ¯o.first_stroke[0], sizeof(int), MAX_KEYS, fp ); fwrite( ¯o.strokes[0], sizeof(STROKES), STROKE_LIMIT, fp ); fclose( fp ); } } } restore_screen_line( 0, prompt_line, line_buff ); return( OK ); }
//------------------------------------------------------------------------------------------------- int ConsoleMenu::CreateMsgs(tty_save_state& tty, MsgList& lst) const { for (;;) { const BaseMsgEntry *mc(SelectMsg()); if (mc) { Message *msg(mc->_create()); const FieldTable::Pair *fld; while((fld = SelectField(msg))) EditMsg(tty, fld, msg); _os << endl << endl << *static_cast<MessageBase *>(msg) << endl; if (get_yn("Add to list? (y/n):", true)) lst.push_back(msg); } else break; } return lst.size(); }
int process(void) { PARAMS params; DERIVED derived; FILE *fp = NULL; BOOLEAN bTest; double d; int iChoice,i; params.bPKDUnits = get_yn("Use PKDGRAV units (AU, M_sun, etc.)","n"); params.dMass = 4.0/3.0*M_PI/1.0e3; /* kg (1 cm radius @ 1 g/cc) */ params.dRadius = 0.01; /* m (1 cm) */ params.dVmax = 0.01; /* m/s (1 cm/s) */ params.dXmaxOverR = 0.01; params.dGravAcc = 9.8; /* m/s^2 */ params.dHeight = 1.0; /* m */ params.dPackEff = 0.65; params.nStepsPerOverlap = 30; while (/*CONSTCOND*/1) { analyze(¶ms,&derived); printf("\n"); show_menu(¶ms,&derived,stdout); printf("\n"); printf("Enter number to change (or 0 when done): "); scanf("%i",&iChoice); getchar(); /* chomp \n since getchar() may be needed later */ switch (iChoice) { case Quit: fp = fopen(LOGFILE,"w"); assert(fp != NULL); show_menu(¶ms,&derived,fp); fclose(fp); return 0; } switch (iChoice) { case Mass: bTest = get_yn("Keep particle density constant","n"); do { printf("Enter new mass (-ve ==> scale mass instead): "); scanf("%lf",&d); if (d == 0.0) printf("Mass cannot be zero.\n"); } while (d == 0.0); getchar(); if (d < 0.0) d *= -params.dMass; else { if (params.bPKDUnits) d *= M_SCALE; /* M_Sun -> kg */ else d /= 1000.0; /* g -> kg */ } if (bTest) params.dRadius *= pow(d/params.dMass,1.0/3.0); params.dMass = d; break; case Radius: bTest = get_yn("Keep particle density constant","n"); do { printf("Enter new radius (-ve ==> scale radius instead): "); scanf("%lf",&d); if (d == 0.0) printf("Radius cannot be zero.\n"); } while (d == 0.0); getchar(); if (d < 0.0) d *= -params.dRadius; else { if (params.bPKDUnits) d *= L_SCALE; /* AU -> m */ else d /= 100.0; /* cm -> m */ } if (bTest) params.dMass *= CUBE(d/params.dRadius); params.dRadius = d; break; case Density: bTest = get_yn("Keep radius constant","y"); do { printf("Enter new density (-ve ==> scale density instead): "); scanf("%lf",&d); if (d == 0.0) printf("Density cannot be zero.\n"); } while (d == 0); getchar(); if (d < 0.0) d *= -derived.dDensity; else { if (params.bPKDUnits) d *= D_SCALE; /* M_Sun/AU^3 -> kg/m^3 */ else d *= 1000.0; /* g/cc -> kg/m^3 */ } if (bTest) params.dMass *= d/derived.dDensity; else params.dRadius *= pow(d/derived.dDensity,1.0/3.0); break; case Speed: printf("Enter new speed (-ve ==> scale speed instead): "); scanf("%lf",&d); getchar(); if (d < 0.0) d *= -params.dVmax; else { if (params.bPKDUnits) d *= V_SCALE; /* AU/(yr/2pi) -> m/s */ else d /= 100.0; /* cm/s -> m/s */ } params.dVmax = d; break; case Overlap: do { printf("Enter new fractional overlap: "); scanf("%lf",&d); if (d <= 0.0) printf("Fraction overlap must be positive.\n"); } while (d <= 0.0); getchar(); params.dXmaxOverR = d; break; case Gravity: printf("Enter new gravitational acceleration (-ve ==> scale gravity instead): "); scanf("%lf",&d); getchar(); if (d < 0.0) d *= -params.dGravAcc; else if (params.bPKDUnits) d *= L_SCALE/SQ(T_SCALE); /* AU/(yr/2pi)^2 --> m/s^2 */ params.dGravAcc = d; break; case Height: printf("Enter new system height/bulk radius (-ve ==> scale instead): "); scanf("%lf",&d); getchar(); if (d < 0.0) d *= -params.dHeight; else { if (params.bPKDUnits) d *= L_SCALE; /* AU --> m */ else d /= 100.0; /* cm -> m */ } params.dHeight = d; break; case Packing: do { printf("Enter new packing efficiency: "); scanf("%lf",&d); if (d < 0.0 || d > 1.0) printf("Packing efficiency must be between 0 and 1.\n"); } while (d < 0.0 || d > 1.0); getchar(); params.dPackEff = d; break; case BulkDensity: bTest = get_yn("OK to change packing efficiency","y"); if (!bTest) break; do { printf("Enter new bulk density (-ve ==> scale instead): "); scanf("%lf",&d); if (d == 0.0) printf("Bulk density cannot be zero.\n"); } while (d == 0); getchar(); if (d < 0.0) d *= -derived.dBulkDensity; else { if (params.bPKDUnits) d *= D_SCALE; /* M_Sun/AU^3 -> kg/m^3 */ else d *= 1000.0; /* g/cc -> kg/m^3 */ } params.dPackEff = d/derived.dDensity; break; case Steps: do { printf("Enter new number of steps per overlap: "); scanf("%i",&i); if (i < 1) printf("Number of steps must be positive.\n"); } while (i < 1); getchar(); params.nStepsPerOverlap = i; break; default: printf("Invalid menu choice.\n"); } } }
/* * Name: record_on_off * Purpose: save keystrokes in keystroke buffer * Date: April 1, 1992 * Passed: window: pointer to current window * Notes: -1 in .next field indicates the end of a recording * -1 in .key field indicates the initial, unassigned macro key * STROKE_LIMIT+1 in .next field indicates an unused space. */ int record_on_off( WINDOW *window ) { register int next; int prev; int line; int key; int func; char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute */ mode.record = !mode.record; if (mode.record == TRUE) { line = window->bottom_line; show_avail_strokes( ); save_screen_line( 0, line, line_buff ); /* * press key that will play back recording */ set_prompt( main11, line ); /* * get the candidate macro key and look up the function assigned to it. */ key = getkey( ); func = getfunc( key ); /* * the key must be an unused, recognized function key or a function * key assigned to a previously defined macro. we also need room * in the macro structure. */ if (key <= 256 || (func != 0 && func != PlayBack)) { /* * cannot assign a recording to this key */ error( WARNING, line, main12 ); mode.record = FALSE; } else if (g_status.stroke_count == 0) { /* * no more room in recording buffer */ error( WARNING, line, main13 ); mode.record = FALSE; } else { /* * everything is everything so far, just check for a prev macro */ prev = OK; if (func == PlayBack) { /* * overwrite recording (y/n)? */ set_prompt( main14, line ); if (get_yn( ) == A_NO) { prev = ERROR; mode.record = FALSE; } } if (prev == OK) { g_status.recording_key = key; next = macro.first_stroke[key-256]; /* * if key has already been assigned to a macro, clear macro def. */ if (next != STROKE_LIMIT+1) { do { prev = next; next = macro.strokes[next].next; macro.strokes[prev].key = MAX_KEYS+1; macro.strokes[prev].next = STROKE_LIMIT+1; ++g_status.stroke_count; } while (next != -1); show_avail_strokes( ); } /* * find the first open space and initialize */ for (next=0; macro.strokes[next].next != STROKE_LIMIT+1;) next++; macro.first_stroke[key-256] = next; macro.strokes[next].key = -1; macro.strokes[next].next = -1; key_func.key[key-256] = PlayBack; /* * recording */ s_output( main15, g_display.mode_line, 22, g_display.mode_color | 0x80 ); } } restore_screen_line( 0, line, line_buff ); } /* * the flashing "Recording" and the stroke count write over the modes. * when we get thru defining a macro, redisplay the modes. */ if (mode.record == FALSE) { memset( line_buff, ' ', 36 ); line_buff[36] = '\0'; s_output( line_buff, g_display.mode_line, 22, g_display.mode_color ); show_tab_modes( ); show_indent_mode( ); show_sync_mode( ); show_search_case( ); show_wordwrap_mode( ); /* * let's look at the macro. if the first .key of the macro is * still -1, which is the initial unassigned key in a macro, reset * the macro so other keys may be assigned to this node. */ key = g_status.recording_key; if (key != 0) { next = macro.first_stroke[key-256]; if (macro.strokes[next].key == -1) { macro.strokes[next].key = MAX_KEYS+1; macro.strokes[next].next = STROKE_LIMIT+1; macro.first_stroke[key-256] = STROKE_LIMIT+1; if (getfunc( key ) == PlayBack) key_func.key[key-256] = 0; } } g_status.recording_key = 0; } return( OK ); }
static void process(SSDATA *d,int n,double *t) { PROPERTIES p; int choice; enum {Next,Time,Mass,Bounds,ComPos,ComVel,AngMom,VelDsp,Color,Units, Offsets,Masses,Radii,End}; while (/*CONSTCOND*/1) { ss_analyze(d,n,&p); (void) printf("%2i. Time = %g\n",Time,*t); (void) printf("%2i. Total mass = %g\n",Mass,p.total_mass); (void) printf("%2i. Bounds: x=[%g,%g]\n" " y=[%g,%g]\n" " z=[%g,%g]\n",Bounds, p.bnd_min[X],p.bnd_max[X], p.bnd_min[Y],p.bnd_max[Y], p.bnd_min[Z],p.bnd_max[Z]); (void) printf("%2i. Centre-of-mass position = %g %g %g\n",ComPos, p.com_pos[X],p.com_pos[Y],p.com_pos[Z]); (void) printf("%2i. Centre-of-mass velocity = %g %g %g\n",ComVel, p.com_vel[X],p.com_vel[Y],p.com_vel[Z]); (void) printf("%2i. Specific angular momentum = %g %g %g\n",AngMom, p.ang_mom[X],p.ang_mom[Y],p.ang_mom[Z]); (void) printf("%2i. Velocity dispersion = %g %g %g\n",VelDsp, p.vel_dsp[X],p.vel_dsp[Y],p.vel_dsp[Z]); (void) printf("%2i. Dominant color = %i (%s)\n",Color,p.color, color_str(p.color)); (void) printf("%2i. Units\n",Units); (void) printf("%2i. Offsets\n",Offsets); (void) printf("%2i. Particle masses\n",Masses); (void) printf("%2i. Particle radii\n",Radii); do { (void) printf("Enter number to change (or 0 to continue): "); (void) scanf("%i",&choice); } while (choice < Next || choice >= End); (void) getchar(); if (choice == Next) return; switch(choice) { case Time: do { (void) printf("Enter new time: "); (void) scanf("%lf",t); (void) getchar(); } while (*t < 0); break; case Mass: { double f; do get_scaling(&f,NegativeOK); while (f == 0); if (f < 0) f = -f/p.total_mass; scale_mass(d,n,f); break; } case Bounds: { double f,min,max; int i,choice; do { do { (void) printf("%i. Change x bounds (now [%g,%g])\n",X + 1, p.bnd_min[X],p.bnd_max[X]); (void) printf("%i. Change y bounds (now [%g,%g])\n",Y + 1, p.bnd_min[Y],p.bnd_max[Y]); (void) printf("%i. Change z bounds (now [%g,%g])\n",Z + 1, p.bnd_min[Z],p.bnd_max[Z]); (void) printf("Your choice (or 0 when done): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < 0 || choice > N_DIM); if (choice == 0) break; --choice; /* put back in range [X,Z] */ if (p.bnd_min[choice] == p.bnd_max[choice]) { (void) printf("Chosen dimension is degenerate\n"); continue; } do { (void) printf("Enter new bounds (min max): "); (void) scanf("%lf%lf",&min,&max); (void) getchar(); } while (min > max); if (min == max && get_yn("Zero velocities for this component","y")) for (i=0;i<n;i++) d[i].vel[choice] = 0; f = (max - min)/(p.bnd_max[choice] - p.bnd_min[choice]); for (i=0;i<n;i++) d[i].pos[choice] = (d[i].pos[choice] - p.bnd_min[choice])*f + min; p.bnd_min[choice] = min; p.bnd_max[choice] = max; } while (/*CONSTCOND*/1); break; } case ComPos: { VECTOR v; if (MAG(p.com_pos) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.com_pos,v); if (f < 0) f = -f/MAG(v); SCALE_VEC(v,f); } else get_components(v); adj_com_pos(d,n,&p,v); break; } case ComVel: { VECTOR v; if (MAG(p.com_vel) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.com_vel,v); if (f < 0) f = -f/MAG(v); SCALE_VEC(v,f); } else get_components(v); adj_com_vel(d,n,&p,v); break; } case AngMom: { VECTOR v; (void) printf("NOTE: specific angular momentum is measured with\n" "respect to fixed space frame centred at (0,0,0)\n" "and does not take particle spins into account\n"); if (MAG(p.ang_mom) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.ang_mom,v); if (f < 0) f = -f/MAG(p.ang_mom); SCALE_VEC(v,f); } else if (get_yn("Scale the components","y")) { VECTOR u; int k; get_component_scaling(u); for (k=0;k<N_DIM;k++) v[k] = u[k]*p.ang_mom[k]; } else get_components(v); adj_ang_mom(d,n,&p,v); break; } case VelDsp: { VECTOR v; (void) printf("NOTE: velocity dispersion is context dependent,\n" "for now relative ONLY to center-of-mass velocity,\n" "i.e. without considering bulk rotation or shear\n"); if (!MAG(p.vel_dsp)) { (void) printf("Zero velocity dispersion -- cannot adjust\n"); break; } if (get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); if (f < 0) f = -f/MAG(p.vel_dsp); SET_VEC(v,f,f,f); } else get_component_scaling(v); scale_vel_dsp(d,n,&p,v); break; } case Color: { int c; (void) printf("Color scheme:\n"); for (c=BLACK;c<FIRST_GRAY;c++) (void) printf("%2i. %s\n",c,color_str(c)); (void) printf("[values from %i to %i are levels of gray]\n", FIRST_GRAY,LAST_GRAY); do { (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); } while (c < 0 || c >= NUM_COLORS); change_color(d,n,c); break; } case Units: { enum {N,M,L,T,V,E}; double f; int i,choice; (void) printf("NOTE: It is up to you to ensure dimensions are\n" "internally consistent. pkdgrav assumes G == 1.\n"); do { do { (void) printf("%i. Mass (particle masses)\n",M); (void) printf("%i. Length (particle radii, pos'ns)\n",L); (void) printf("%i. Time (time,particle spins)\n",T); (void) printf("%i. Velocity (particle velocities)\n",V); (void) printf("Select dimension to scale " "(or 0 when done): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < N || choice >= E); if (choice == N) break; switch (choice) { case M: (void) printf("M_Sun = 1.9891e30 kg\n" "M_Earth = 5.9742e24 kg\n" "M_Jupiter = 1.8992e27 kg\n" "M_Saturn = 5.6864e26 kg\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) d[i].mass *= f; break; case L: (void) printf("1 AU = 1.49597892e11 m\n" "R_Earth = 6.37814e6 m\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) { d[i].radius *= f; SCALE_VEC(d[i].pos,f); } break; case T: (void) printf("1 yr = 3.15576e7 s\n" "1 yr / 2 pi = 5.02255e6 s\n"); get_scaling(&f,PositiveOnly); *t *= f; for (i=0;i<n;i++) NORM_VEC(d[i].spin,f); break; case V: (void) printf("V_Earth = 2.97852586e4 m/s\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) SCALE_VEC(d[i].vel,f); break; default: assert(0); } } while (/*CONSTCOND*/1); break; } case Offsets: { VECTOR v; int i; (void) printf("POSITION OFFSET (0 0 0 for none)...\n"); get_components(v); for (i=0;i<n;i++) ADD_VEC(d[i].pos,v,d[i].pos); (void) printf("VELOCITY OFFSET (0 0 0 for none)...\n"); get_components(v); for (i=0;i<n;i++) ADD_VEC(d[i].vel,v,d[i].vel); break; } case Masses: { double f; do get_scaling(&f,NegativeOK); while (f == 0); scale_masses(d,n,f); break; } case Radii: { double f; do get_scaling(&f,NegativeOK); while (f == 0); scale_radii(d,n,f); break; } default: assert(0); } } }
static int read_data(char *filename,SSDATA **d,int *n,double *t,int mode) { SSIO ssio; SSHEAD h; int i; if (ssioOpen(filename,&ssio,SSIO_READ)) { (void) fprintf(stderr,"Unable to open \"%s\"\n",filename); return 1; } if (ssioHead(&ssio,&h) || h.n_data < 0) { (void) fprintf(stderr,"Corrupt header\n"); (void) ssioClose(&ssio); return 1; } if (h.n_data == 0) { (void) fprintf(stderr,"No data found!"); (void) ssioClose(&ssio); return 1; } switch(h.iMagicNumber) { case SSIO_MAGIC_STANDARD: break; case SSIO_MAGIC_REDUCED: (void) fprintf(stderr,"Reduced ss format not supported.\n"); ssioClose(&ssio); return 1; default: (void) fprintf(stderr,"Unrecognized ss file magic number (%i).\n",h.iMagicNumber); ssioClose(&ssio); return 1; } if (mode == FirstFile) { *d = NULL; *n = *t = 0; } (void) printf("Number of particles = %i, time %g\n",h.n_data,h.time); if (mode == MergeFile && h.time != *t && !get_yn("Keep old time","y")) { if (get_yn("Use time of merged file","y")) *t = h.time; else { (void) printf("Enter new time (old time was %g): ",*t); (void) scanf("%lf",t); } } *d = (SSDATA *) realloc(*d,(*n + h.n_data)*sizeof(SSDATA)); assert(*d != NULL); for (i=*n;i<*n + h.n_data;i++) if (ssioData(&ssio,&((*d)[i]))) { (void) fprintf(stderr,"Corrupt data\n"); (void) ssioClose(&ssio); return 1; } (void) ssioClose(&ssio); *n += h.n_data; return 0; }
/* * Name: define_diff * Purpose: get info needed to initialize diff * Date: October 31, 1992 * Passed: window: pointer to current window * Notes: allow the user to start the diff at the beginning of the * file or at the current cursor location. once the diff * has been defined, the user may press one key to diff again. * user may diff any two visible windows on the screen. */ int define_diff( WINDOW *window ) { int rc; char temp[MAX_COLS]; int num1; int let1; int num2; int let2; int start; char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */ char buff[MAX_COLS*2]; /* buffer for char and attribute */ /* * get window number and letter of the first diff window. then, * verify that window - does it exit? is it visible? */ *temp = '\0'; rc = get_name( diff_prompt1, window->bottom_line, temp, g_display.message_color ); if (rc == OK) { rc = verify_number( temp, &num1 ); if (rc == OK) rc = verify_letter( temp, &let1, &diff.w1 ); } else return( ERROR ); if (rc == ERROR) { combine_strings( buff, diff_prompt6a, temp, diff_prompt6b ); error( WARNING, window->bottom_line, buff ); return( ERROR ); } /* * get and verify the next window number and letter to diff. */ *temp = '\0'; rc = get_name( diff_prompt2, window->bottom_line, temp, g_display.message_color ); if (rc == OK) { rc = verify_number( temp, &num2 ); if (rc == OK) rc = verify_letter( temp, &let2, &diff.w2 ); } else return( ERROR ); if (rc == ERROR) { combine_strings( buff, diff_prompt6a, temp, diff_prompt6b ); error( WARNING, window->bottom_line, buff ); return( ERROR ); } /* * are leading spaces significant? */ save_screen_line( 0, window->bottom_line, line_buff ); set_prompt( diff_prompt7a, window->bottom_line ); start = get_yn( ); restore_screen_line( 0, window->bottom_line, line_buff ); if (start != ERROR) diff.leading = start == A_YES ? TRUE : FALSE; else return( ERROR ); /* * are all spaces significant? */ save_screen_line( 0, window->bottom_line, line_buff ); set_prompt( diff_prompt7b, window->bottom_line ); start = get_yn( ); restore_screen_line( 0, window->bottom_line, line_buff ); if (start != ERROR) { if (start == A_YES) diff.leading = diff.all_space = TRUE; else diff.all_space = FALSE; } else return( ERROR ); /* * are blank lines significant? */ save_screen_line( 0, window->bottom_line, line_buff ); set_prompt( diff_prompt7c, window->bottom_line ); start = get_yn( ); restore_screen_line( 0, window->bottom_line, line_buff ); if (start != ERROR) diff.blank_lines = start == A_YES ? TRUE : FALSE; else return( ERROR ); /* * is end of line significant? */ save_screen_line( 0, window->bottom_line, line_buff ); set_prompt( diff_prompt7d, window->bottom_line ); start = get_yn( ); restore_screen_line( 0, window->bottom_line, line_buff ); if (start != ERROR) diff.ignore_eol = start == A_YES ? TRUE : FALSE; else return( ERROR ); /* * now, find out were to start the diff -- beginning of file or * current cursor location. */ save_screen_line( 0, window->bottom_line, line_buff ); set_prompt( diff_prompt3, window->bottom_line ); start = get_bc( ); restore_screen_line( 0, window->bottom_line, line_buff ); if (start != ERROR) { entab_linebuff( ); if (un_copy_line( window->ll, window, TRUE ) == ERROR) return( ERROR ); /* * if everything is everything, initialize the diff pointers. */ diff.defined = TRUE; if (start == BEGINNING) { diff.d1 = diff.w1->file_info->line_list; diff.d2 = diff.w2->file_info->line_list; diff.rline1 = 1L; diff.rline2 = 1L; diff.bin_offset1 = 0; diff.bin_offset2 = 0; rc = differ( 0, 0, window->bottom_line ); } else { diff.d1 = diff.w1->ll; diff.d2 = diff.w2->ll; diff.rline1 = diff.w1->rline; diff.rline2 = diff.w2->rline; diff.bin_offset1 = diff.w1->bin_offset; diff.bin_offset2 = diff.w2->bin_offset; rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line ); } } return( rc ); }
int main(int argc,char *argv[]) { FILE *fp; BOOLEAN sim_units; RUBBLE_PILE rp[MAX_NUM_FILES],*p; char infile[MAXPATHLEN],last_infile[MAXPATHLEN],outfile[MAXPATHLEN]; double time = 0.0,old_time = 0.0; int n_files; setbuf(stdout,(char *)NULL); srand(getpid()); if (argc > 1) { (void) fprintf(stderr,"%s takes no arguments\n",argv[0]); return 1; } fp = fopen(LOG_FILE,"r"); if (fp) { (void) fclose(fp); if (!get_yn("Overwrite log file","y")) return 0; } fp = fopen(LOG_FILE,"w"); if (!fp) { (void) fprintf(stderr,"Unable to open %s for writing\n",LOG_FILE); return 1; } sim_units = get_yn("Use simulation units (AU, M_sun, etc.)","n"); n_files = 0; while (n_files < MAX_NUM_FILES) { infile[0] = '\0'; (void) printf("File %i [or RETURN to quit]: ",n_files + 1); (void) fgets(infile,MAXPATHLEN,stdin); assert(strlen(infile)); infile[strlen(infile) - 1] = '\0'; /* get rid of newline at end */ if (!strlen(infile)) break; p = &rp[n_files]; if (process(infile,p,sim_units,&time)) continue; if (n_files == 0) old_time = time; else if (time != old_time) time = 0.0; /* unless all times are the same, set to zero */ (void) fprintf(fp, "File number\t\t%i\n" "Filename\t\t%s\n" "Mass\t\t\t%e\n" "Bulk radius\t\t%e\n" "Bulk density\t\t%e\n" "Position\t\t%+e\t%+e\t%+e\n" "Velocity\t\t%+e\t%+e\t%+e\n" "Spin\t\t\t%+e\t%+e\t%+e\n" "Major axis\t\t%+f\t%+f\t%+f\n" "Inter axis\t\t%+f\t%+f\t%+f\n" "Minor axis\t\t%+f\t%+f\t%+f\n" "Color\t\t\t%i\n" "Aggregate ID\t\t%i\n\n", n_files,infile,p->mass,p->radius,p->density, p->pos[X],p->pos[Y],p->pos[Z], p->vel[X],p->vel[Y],p->vel[Z], p->spin[X],p->spin[Y],p->spin[Z], p->axes[rp->axis_ord[X]][X], p->axes[rp->axis_ord[X]][Y], p->axes[rp->axis_ord[X]][Z], p->axes[rp->axis_ord[Y]][X], p->axes[rp->axis_ord[Y]][Y], p->axes[rp->axis_ord[Y]][Z], p->axes[rp->axis_ord[Z]][X], p->axes[rp->axis_ord[Z]][Y], p->axes[rp->axis_ord[Z]][Z], p->color,p->agg_id); (void) strcpy(last_infile,infile); if (++n_files == MAX_NUM_FILES) (void) printf("File limit reached\n"); } if (n_files == 0) { (void) fprintf(stderr,"No files specified!\n"); return 1; } if (get_yn("Recenter barycentric position and velocity","y")) { VECTOR pos,vel,r,v; double total_mass; int i; total_mass = 0; ZERO_VEC(pos); ZERO_VEC(vel); for (i=0;i<n_files;i++) { COPY_VEC(rp[i].pos,r); SCALE_VEC(rp[i].pos,-1); rpuApplyPos(&rp[i]); SCALE_VEC(r,rp[i].mass); ADD_VEC(pos,r,pos); COPY_VEC(rp[i].vel,v); SCALE_VEC(rp[i].vel,-1); rpuApplyVel(&rp[i]); SCALE_VEC(v,rp[i].mass); ADD_VEC(vel,v,vel); total_mass += rp[i].mass; } NORM_VEC(pos,total_mass); NORM_VEC(vel,total_mass); for (i=0;i<n_files;i++) { SCALE_VEC(rp[i].pos,-1); SUB_VEC(rp[i].pos,pos,rp[i].pos); rpuApplyPos(&rp[i]); SCALE_VEC(rp[i].vel,-1); SUB_VEC(rp[i].vel,vel,rp[i].vel); rpuApplyVel(&rp[i]); } (void) fprintf(fp,"BARYCENTRIC CORRECTION APPLIED\n"); } (void) fclose(fp); if (n_files == 2) show_encounter(rp,n_files,sim_units); do { (void) printf("Output file [default %s]: ",last_infile); (void) fgets(outfile,MAXPATHLEN,stdin); assert(strlen(outfile)); outfile[strlen(outfile) - 1] = '\0'; if (!strlen(outfile)) (void) strcpy(outfile,last_infile); outfile[MAXPATHLEN - 1] = '\0'; if ((fp = fopen(outfile,"r"))) { (void) fclose(fp); if (!get_yn("Output file already exists...overwrite","n")) continue; } break; } while (/*CONSTCOND*/1); write_data(outfile,rp,n_files,time); for (--n_files;n_files>=0;n_files--) rpuFree(&rp[n_files]); (void) printf("Done!\n"); return 0; }
static int process(char *filename,RUBBLE_PILE *rp,BOOLEAN sim_units,double *time) { enum {next,mass,radius,density,pos,vel,orient,spin,color,agg_id,par_id}; SSIO ssio; SSHEAD h; int i,choice; assert(rp != NULL); *time = 0.0; if (ssioOpen(filename,&ssio,SSIO_READ)) { (void) fprintf(stderr,"Unable to open \"%s\"\n",filename); return 1; } if (ssioHead(&ssio,&h) || h.n_data < 0) { (void) fprintf(stderr,"Corrupt header\n"); (void) ssioClose(&ssio); return 1; } if (h.n_data == 0) { (void) fprintf(stderr,"No data found!"); (void) ssioClose(&ssio); return 1; } switch(h.iMagicNumber) { case SSIO_MAGIC_STANDARD: break; case SSIO_MAGIC_REDUCED: (void) fprintf(stderr,"Reduced ss format not supported.\n"); ssioClose(&ssio); return 1; default: (void) fprintf(stderr,"Unrecognized ss file magic number (%i).\n",h.iMagicNumber); ssioClose(&ssio); return 1; } rp->n_particles = h.n_data; *time = h.time; (void) printf("Number of particles = %i (time %g)\n",rp->n_particles,*time); rpuMalloc(rp); for (i=0;i<rp->n_particles;i++) if (ssioData(&ssio,&rp->data[i])) { (void) fprintf(stderr,"Corrupt data\n"); (void) ssioClose(&ssio); return 1; } (void) ssioClose(&ssio); while (/*CONSTCOND*/1) { rpuAnalyze(rp); (void) printf("%i. Total mass = ",mass); if (sim_units) (void) printf("%g M_sun",rp->mass); else (void) printf("%g kg",rp->mass*M_SCALE); (void) printf("\n"); (void) printf("%i. Bulk radius = ",radius); if (sim_units) (void) printf("%g AU",rp->radius); else (void) printf("%g km",rp->radius*0.001*L_SCALE); (void) printf("\n"); (void) printf(" [Bulk semi-axes: "); if (sim_units) (void) printf("%g %g %g AU", rp->axis_len[rp->axis_ord[X]], rp->axis_len[rp->axis_ord[Y]], rp->axis_len[rp->axis_ord[Z]]); else (void) printf("%g %g %g km", rp->axis_len[rp->axis_ord[X]]*0.001*L_SCALE, rp->axis_len[rp->axis_ord[Y]]*0.001*L_SCALE, rp->axis_len[rp->axis_ord[Z]]*0.001*L_SCALE); (void) printf("]\n"); (void) printf("%i. Bulk density = ",density); if (sim_units) (void) printf("%g M_sun/AU^3",rp->density); else (void) printf("%g g/cc",rp->density*0.001*D_SCALE); (void) printf("\n"); (void) printf("%i. Centre-of-mass position = ",pos); if (sim_units) (void) printf("%g %g %g AU",rp->pos[X],rp->pos[Y], rp->pos[Z]); else (void) printf("%.2f %.2f %.2f km",rp->pos[X]*0.001*L_SCALE, rp->pos[Y]*0.001*L_SCALE,rp->pos[Z]*0.001*L_SCALE); (void) printf("\n"); (void) printf("%i. Centre-of-mass velocity = ",vel); if (sim_units) (void) printf("%g %g %g x 30 km/s",rp->vel[X],rp->vel[Y], rp->vel[Z]); else (void) printf("%.2f %.2f %.2f m/s",rp->vel[X]*V_SCALE, rp->vel[Y]*V_SCALE,rp->vel[Z]*V_SCALE); (void) printf("\n"); (void) printf("%i. Orientation: a1 = %6.3f %6.3f %6.3f\n",orient, rp->axes[rp->axis_ord[X]][X], rp->axes[rp->axis_ord[X]][Y], rp->axes[rp->axis_ord[X]][Z]); (void) printf(" a2 = %6.3f %6.3f %6.3f\n", rp->axes[rp->axis_ord[Y]][X], rp->axes[rp->axis_ord[Y]][Y], rp->axes[rp->axis_ord[Y]][Z]); (void) printf(" a3 = %6.3f %6.3f %6.3f\n", rp->axes[rp->axis_ord[Z]][X], rp->axes[rp->axis_ord[Z]][Y], rp->axes[rp->axis_ord[Z]][Z]); (void) printf("%i. Spin = ",spin); if (sim_units) (void) printf("%g %g %g x 2pi rad/yr", rp->spin[X],rp->spin[Y],rp->spin[Z]); else { double scale = 3600/(TWO_PI*T_SCALE),w; (void) printf("%.2f %.2f %.2f 1/h (",rp->spin[X]*scale, rp->spin[Y]*scale,rp->spin[Z]*scale); w = MAG(rp->spin); if (w) (void) printf("period %g h",1/(w*scale)); else (void) printf("no spin"); (void) printf(")"); } (void) printf("\n"); (void) printf(" [Ang mom = "); if (sim_units) (void) printf("%g %g %g (sys units)",rp->ang_mom[X], rp->ang_mom[Y],rp->ang_mom[Z]); else { double scale = M_SCALE*SQ(L_SCALE)/T_SCALE; (void) printf("%.5e %.5e %.5e N m/s",rp->ang_mom[X]*scale, rp->ang_mom[Y]*scale,rp->ang_mom[Z]*scale); } (void) printf("]\n"); (void) printf(" [Effective spin = "); if (sim_units) (void) printf("%g x 2pi rad/yr",rp->eff_spin); else { double scale = 3600/(TWO_PI*T_SCALE); (void) printf("%.2f 1/h (",rp->eff_spin*scale); if (rp->eff_spin) printf("period %g h",1/(rp->eff_spin*scale)); else (void) printf("no spin"); (void) printf(")"); } (void) printf("]\n"); (void) printf(" [Rotation index = %.2f (",rp->rot_idx); if (rp->eff_spin == 0.0) (void) printf("undefined"); else if (rp->rot_idx == 1.0) (void) printf("unif rot about max moment"); else if (rp->rot_idx < 1.0 && rp->rot_idx > 0.0) (void) printf("SAM"); else if (rp->rot_idx == 0.0) (void) printf("unif rot about mid moment"); else if (rp->rot_idx < 0.0 && rp->rot_idx > -1.0) (void) printf("LAM"); else if (rp->rot_idx == -1.0) (void) printf("unif rot about min moment"); else assert(0); (void) printf(")]\n"); (void) printf("%i. Color = %i (%s)\n",color,(int) rp->color, color_str(rp->color)); (void) printf("%i. Aggregate ID = ",agg_id); if (rp->agg_id < 0) (void) printf("N/A"); else (void) printf("%i",(int) rp->agg_id); (void) printf("\n"); (void) printf("%i. Particle ID\n",par_id); do { (void) printf("Enter number to change (or 0 to continue): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < next || choice > par_id); if (choice == next) return 0; switch(choice) { case mass: { double f; BOOLEAN const_den = get_yn("Keep bulk density constant","n"),proceed=TRUE; do { (void) printf("Enter mass scaling factor (-ve ==> abs val): "); (void) scanf("%lf",&f); if (f == 0.0) { getchar(); proceed = get_yn("WARNING: This will set all particle masses to zero...continue","n"); } } while (!proceed); if (f < 0) { if (!sim_units) f /= M_SCALE; f = -f/rp->mass; } rpuScaleMass(rp,f); if (const_den) rpuScaleRadius(rp,pow(f,1.0/3),FALSE); break; } case radius: { double f; BOOLEAN just_particles = get_yn("Just scale particles","n"),const_den = FALSE; if (!just_particles) const_den = get_yn("Keep bulk density constant","n"); do { (void) printf("Enter radius scaling factor " "(-ve ==> abs val): "); (void) scanf("%lf",&f); } while (f == 0); getchar(); if (f < 0) { if (!sim_units) f *= 1000/L_SCALE; if (!just_particles) f = -f/rp->radius; } rpuScaleRadius(rp,f,just_particles); if (just_particles) rpuCalcRadius(rp); /* because outer edge may have changed */ if (const_den) rpuScaleMass(rp,CUBE(f)); break; } case density: { double f; BOOLEAN const_radius = get_yn("Keep radius constant","y"); do { (void) printf("Enter density scaling factor (-ve ==> abs val): "); (void) scanf("%lf",&f); } while (f == 0); getchar(); if (f < 0) { if (!sim_units) f *= 1000/D_SCALE; f = -f/rp->density; } if (const_radius) rpuScaleMass(rp,f); else rpuScaleRadius(rp,pow(f,-1.0/3),FALSE); break; } case pos: { BOOLEAN absolute = get_yn("Specify absolute position","y"); if (absolute) { SCALE_VEC(rp->pos,-1.0); rpuApplyPos(rp); /* reset COM to (0,0,0) first */ (void) printf("Enter new position [x y z in "); } else (void) printf("Enter position offset [x y z in "); if (sim_units) (void) printf("AU"); else (void) printf("km"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&rp->pos[X],&rp->pos[Y],&rp->pos[Z]); (void) getchar(); if (!sim_units) NORM_VEC(rp->pos,0.001*L_SCALE); rpuApplyPos(rp); break; } case vel: { BOOLEAN absolute = get_yn("Specify absolute velocity","y"); if (absolute) { SCALE_VEC(rp->vel,-1.0); rpuApplyVel(rp); (void) printf("Enter new velocity [vx vy vz in "); } else (void) printf("Enter velocity offset [vx vy vz in "); if (sim_units) (void) printf("units of 30 km/s"); else (void) printf("m/s"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&rp->vel[X],&rp->vel[Y],&rp->vel[Z]); (void) getchar(); if (!sim_units) NORM_VEC(rp->vel,V_SCALE); rpuApplyVel(rp); break; } case orient: { enum {x=1,y,z}; MATRIX rot; double angle; BOOLEAN align,body,rndm; int choice; align = get_yn("Align body axes with coordinate axes","n"); if (align) { MATRIX m; COPY_VEC(rp->axes[MAJOR(rp)],m[X]); COPY_VEC(rp->axes[INTER(rp)],m[Y]); COPY_VEC(rp->axes[MINOR(rp)],m[Z]); rpuRotate(rp,m,FALSE); break; } body = get_yn("Use body axes","n"); (void) printf("%i. Rotate about %s axis\n",x,body?"major":"x"); (void) printf("%i. Rotate about %s axis\n",y,body?"intermediate":"y"); (void) printf("%i. Rotate about %s axis\n",z,body?"minor":"z"); do { (void) printf("Enter choice: "); (void) scanf("%i",&choice); } while (choice < x || choice > z); --choice; /* to conform with X,Y,Z macros */ (void) getchar(); rndm = get_yn("Use random angle","n"); if (rndm) angle = TWO_PI*rand()/RAND_MAX; else { (void) printf("Enter rotation angle in "); if (sim_units) (void) printf("radians"); else (void) printf("degrees"); (void) printf(" (-ve=clockwise): "); (void) scanf("%lf",&angle); (void) getchar(); if (!sim_units) angle *= DEG_TO_RAD; } UNIT_MAT(rot); if (body) choice = rp->axis_ord[choice]; switch (choice) { case X: rot[Y][Y] = cos(angle); rot[Y][Z] = -sin(angle); rot[Z][Y] = -rot[Y][Z]; rot[Z][Z] = rot[Y][Y]; break; case Y: rot[X][X] = cos(angle); rot[X][Z] = sin(angle); rot[Z][X] = -rot[X][Z]; rot[Z][Z] = rot[X][X]; break; case Z: rot[X][X] = cos(angle); rot[X][Y] = -sin(angle); rot[Y][X] = -rot[X][Y]; rot[Y][Y] = rot[X][X]; break; default: assert(0); } rpuRotate(rp,rot,body); break; } case spin: { VECTOR old_spin,d; double w_max = 2*PI/sqrt(3*PI/rp->density); BOOLEAN incr_only,ang_mom,body; COPY_VEC(rp->spin,old_spin); /* needed for spin increment */ /*DEBUG following only removes net spin---it does not ensure that every particle has wxr_i = 0 and w_i = 0*/ SCALE_VEC(rp->spin,-1.0); rpuAddSpin(rp,FALSE); /* remove current spin */ (void) printf("Classical breakup limit for measured density = "); if (sim_units) (void) printf("%g x 2pi rad/yr",w_max); else (void) printf("%g 1/h (P_min = %g h)", 3600*w_max/(TWO_PI*T_SCALE), TWO_PI*T_SCALE/(3600*w_max)); (void) printf("\n"); incr_only = get_yn("Specify increment only, instead of absolute value","n"); if (incr_only) ang_mom = get_yn("Specify angular momentum increment","n"); else ang_mom = get_yn("Specify angular momentum","n"); if (ang_mom) { if (incr_only) (void) printf("Enter angular momentum increment [dlx dly dlz in "); else (void) printf("Enter new angular momentum [lx ly lz in "); if (sim_units) (void) printf("sys units"); else (void) printf("N m/s"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&d[X],&d[Y],&d[Z]); (void) getchar(); if (!sim_units) SCALE_VEC(d,T_SCALE/(SQ(L_SCALE)*M_SCALE)); if (incr_only) { ADD_VEC(rp->ang_mom,d,rp->ang_mom); } else { COPY_VEC(d,rp->ang_mom); } rpuAddAngMom(rp); if (MAG(rp->spin) > w_max) (void) printf("WARNING: exceeds classical breakup limit\n"); break; } body = get_yn("Use body axes","n"); if (incr_only) (void) printf("Enter spin increment [dwx dwy dwz in "); else (void) printf("Enter new spin [wx wy wz in "); if (sim_units) (void) printf("units of 2pi rad/yr"); else (void) printf("1/h"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&d[X],&d[Y],&d[Z]); (void) getchar(); if (!sim_units) SCALE_VEC(d,TWO_PI*T_SCALE/3600); if (incr_only) { ADD_VEC(old_spin,d,rp->spin); } else { COPY_VEC(d,rp->spin); } if (MAG(rp->spin) > w_max) (void) printf("WARNING: exceeds classical breakup limit\n"); rpuAddSpin(rp,body); break; } case color: { BOOLEAN invalid_color; int c; (void) printf("Color scheme:\n"); for (i=BLACK;i<FIRST_GRAY;i++) (void) printf("%2i. %s\n",i,color_str(i)); do { invalid_color = FALSE; (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); if (c >= NUM_COLORS) { /* allow negative colors */ (void) printf("Invalid color\n"); invalid_color = TRUE; continue; } if (c == BLACK || c == FIRST_GRAY) (void) printf("WARNING: Particles may be invisible!\n"); } while (invalid_color); rp->color = c; rpuApplyColor(rp); break; } case agg_id: { do { (void) printf("Enter new aggregate ID (or -1 to reset): "); (void) scanf("%i",&rp->agg_id); (void) getchar(); if (rp->agg_id < -1) (void) printf("Invalid ID\n"); else rpuApplyAggID(rp); } while(rp->agg_id < -1); break; } case par_id: { SSDATA *p,*pmax; VECTOR r; double lng,lat,dmax,d; int c; (void) printf("Enter angular coordinates [lng lat in deg]: "); (void) scanf("%lf%lf",&lng,&lat); (void) getchar(); lng *= DEG_TO_RAD; lat *= DEG_TO_RAD; SET_VEC(r,cos(lng)*cos(lat),sin(lng)*cos(lat),sin(lat)); dmax = 0.0; pmax = NULL; for (i=0;i<rp->n_particles;i++) { p = &rp->data[i]; /* projected distance along vector minus distance perpendicular to vector favors particles closest to vector */ d = DOT(p->pos,r) - sqrt(MAG_SQ(p->pos) - SQ(DOT(p->pos,r))); if (d > dmax) { dmax = d; pmax = p; } } if (!pmax) { (void) printf("No particle found.\n"); continue; } (void) printf("Found particle (original index %i, color %i [%s])\n", pmax->org_idx,pmax->color,color_str(pmax->color)); while (/*CONSTCOND*/1) { (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); if (c >= NUM_COLORS) { /* allow negative colors */ (void) printf("Invalid color\n"); goto invalid; } if (c == BLACK || c == RED || c == YELLOW || c == MAGENTA || c == CYAN || c == KHAKI || c == FIRST_GRAY) { (void) printf("Color %i is reserved\n",c); goto invalid; } break; invalid: (void) printf("Color scheme:\n"); for (i=BLACK;i<FIRST_GRAY;i++) (void) printf("%2i. %s\n",i,color_str(i)); }; /* while */ pmax->color = c; break; } default: assert(0); } } }
int main(int argc,char *argv[]) { SSDATA *d; double t; int n; FILE *fp; char file[MAXPATHLEN],first_file[MAXPATHLEN]; setbuf(stdout,(char *)NULL); srand(getpid()); if (argc > 1) { (void) fprintf(stderr,"%s takes no arguments\n",argv[0]); return 1; } do { file[0] = '\0'; (void) printf("Enter file to process: "); (void) fgets(file,MAXPATHLEN,stdin); assert(strlen(file)); file[strlen(file) - 1] = '\0'; /* get rid of newline at end */ } while (!strlen(file) || read_data(file,&d,&n,&t,FirstFile)); process(d,n,&t); (void) strcpy(first_file,file); do { file[0] = '\0'; (void) printf("Enter file to merge [or ENTER if done]: "); (void) fgets(file,MAXPATHLEN,stdin); assert(strlen(file)); file[strlen(file) - 1] = '\0'; if (!strlen(file)) break; if (!read_data(file,&d,&n,&t,MergeFile)) (void) printf("Total number of particles read so far = %i\n",n); process(d,n,&t); } while (/*CONSTCOND*/1); do { (void) printf("Output file [default %s]: ",first_file); (void) fgets(file,MAXPATHLEN,stdin); assert(strlen(file)); file[strlen(file) - 1] = '\0'; if (!strlen(file)) (void) strcpy(file,first_file); if (!(fp = fopen(file,"r"))) break; (void) fclose(fp); if (get_yn("Output file already exists...overwrite","n")) break; } while (/*CONSTCOND*/1); write_data(file,d,n,t); if (d) free((void *) d); (void) printf("Done!\n"); return 0; }