Beispiel #1
0
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 */
}
Beispiel #2
0
//-------------------------------------------------------------------------------------------------
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();
}
Beispiel #3
0
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;
}
Beispiel #4
0
//-------------------------------------------------------------------------------------------------
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);
}
Beispiel #5
0
/*
 * 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);
}
Beispiel #6
0
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;
}
Beispiel #7
0
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 ;
}
Beispiel #8
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 ;
}
Beispiel #9
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'  */
Beispiel #10
0
/*
 * 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( &macro.first_stroke[0], sizeof(int), MAX_KEYS, fp );
            fwrite( &macro.strokes[0], sizeof(STROKES), STROKE_LIMIT, fp );
            fclose( fp );
         }
      }
   }
   restore_screen_line( 0, prompt_line, line_buff );
   return( OK );
}
Beispiel #11
0
//-------------------------------------------------------------------------------------------------
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();
}
Beispiel #12
0
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(&params,&derived);

		printf("\n");

		show_menu(&params,&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(&params,&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");
			}
		}
	}
Beispiel #13
0
/*
 * 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 );
}
Beispiel #14
0
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);
			}
		}
	}
Beispiel #15
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;
	}
Beispiel #16
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 );
}
Beispiel #17
0
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;
	}
Beispiel #18
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);
			}
		}
	}
Beispiel #19
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;
	}