Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

dyn_external.C

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 //  dyn_external.C: functions related to external influences on the system.
00012 //.............................................................................
00013 //    version 1:  Jul 2001, Steve McMillan
00014 //    version 2:  Sep 2001, Steve McMillan
00015 //.............................................................................
00016 //
00017 // Member functions:
00018 //
00019 //      real dyn::get_external_scale_sq()
00020 //      vector dyn::get_external_center();
00021 //
00022 // Global functions:
00023 //
00024 //      void get_external_acc           (single node)
00025 //      real get_external_pot           (root node)
00026 //      real get_tidal_pot              (root node)
00027 //      real get_plummer_pot            (root node)
00028 //      real get_external_virial        (root node)
00029 //      void print_external
00030 //
00031 //.........................................................................
00032 
00033 #include "dyn.h"
00034 
00035 // NOTES:  1. This file should be the *only* place where tidal and other
00036 //            external fields are specified.
00037 //
00038 //         2. Must add consistent functions add_xxx(), de_xxx_pot(), and
00039 //            xxx_virial() for each new external field xxx introduced.
00040 //
00041 //         3. pot_external uses current positions (get_pos)
00042 //            get_external uses positions and velocities passed as
00043 //            arguments (may be pos or pred_pos, depending on the
00044 //            application)
00045 
00046 //-------------------------------------------------------------------------
00047 // Tidal field (quadrupole):
00048 //-------------------------------------------------------------------------
00049 
00050 local inline void add_tidal(dyn * b,
00051                             vector pos,
00052                             vector vel,
00053                             real& pot,
00054                             vector& acc,
00055                             vector& jerk,
00056                             bool pot_only)
00057 {
00058     // Compute the tidal components of the acceleration, jerk,
00059     // and pot of top-level node b.
00060 
00061     real a1 = b->get_alpha1();
00062     if (a1 == 0) return;
00063 
00064     real a3 = b->get_alpha3();
00065 
00066     vector dx = pos - b->get_tidal_center();
00067 
00068     if (!pot_only) {
00069 
00070         vector da_tidal_centrifugal = -vector(a1*dx[0], 0.0, a3*dx[2]);
00071         vector da_coriolis = 2 * b->get_omega()
00072                                * vector(vel[1], -vel[0], 0.0);
00073 
00074         // Must update acc BEFORE computing dj for velocity-dependent forces!
00075 
00076         acc += da_tidal_centrifugal + da_coriolis;
00077 
00078         vector dj_tidal_centrifugal = -vector(a1*vel[0], 0.0, a3*vel[2]);
00079         vector dj_coriolis = 2 * b->get_omega()
00080                                * vector(acc[1], -acc[0], 0.0);
00081 
00082         jerk += dj_tidal_centrifugal + dj_coriolis;
00083     }
00084 
00085     real x = dx[0];
00086     real z = dx[2];
00087 
00088     pot += 0.5*(a1*x*x + a3*z*z);
00089 }
00090 
00091 local inline real tidal_pot(dyn * b)
00092 {
00093     // Determine the tidal component of the potential energy
00094     // of root node b.
00095 
00096     // Add tidal and centrifugal terms for top-level nodes only.
00097     // (No potential term for the Coriolis force, note.)
00098 
00099     real a1 = b->get_alpha1();
00100     if (a1 == 0) return 0;
00101 
00102     real a3 = b->get_alpha3();
00103 
00104     real dpot = 0;
00105     for_all_daughters(dyn, b, bb) {
00106         real x = bb->get_pos()[0] - b->get_tidal_center()[0];
00107         real z = bb->get_pos()[2] - b->get_tidal_center()[0];
00108         real dp = a1*x*x + a3*z*z;
00109         dpot += bb->get_mass() * dp;
00110     }
00111 
00112     return 0.5*dpot;
00113 }
00114 
00115 //-------------------------------------------------------------------------
00116 // Plummer field:
00117 //-------------------------------------------------------------------------
00118 
00119 local inline void add_plummer(dyn * b,
00120                               vector pos,
00121                               vector vel,
00122                               real& pot,
00123                               vector& acc,
00124                               vector& jerk,
00125                               bool pot_only)
00126 {
00127     // Compute the Plummer-field components of the acceleration, jerk,
00128     // and pot of top-level node b.
00129 
00130     real M = b->get_p_mass();
00131     if (M == 0) return;
00132 
00133     real a2 = b->get_p_scale_sq();
00134 
00135     vector dx = pos - b->get_p_center();
00136     real r2 = square(dx) + a2;
00137     real r1 = sqrt(r2);
00138 
00139     if (!pot_only) {
00140         real r3i = 1/(r1*r2);
00141         acc -= M*dx*r3i;
00142         jerk += M*(3*dx*(dx*vel)/r2 - vel)*r3i;
00143     }
00144 
00145     pot -= M/r1;
00146 }
00147 
00148 local inline real plummer_pot(dyn * b)
00149 {
00150     // Determine the Plummer-field component of the potential energy
00151     // of root node b.
00152 
00153     real M = b->get_p_mass();
00154     if (M == 0) return 0;
00155 
00156     real a2 = b->get_p_scale_sq();
00157 
00158     real dpot = 0;
00159     for_all_daughters(dyn, b, bb) {
00160         vector dx = bb->get_pos() - bb->get_p_center();
00161         real r2 = square(dx) + a2;
00162         dpot += bb->get_mass() / sqrt(r2);
00163     }
00164 
00165     return -M*dpot;
00166 }
00167 
00168 local inline real plummer_virial(dyn * b)
00169 {
00170     // Determine the Plummer-field component of the virial sum
00171     // of root node b.
00172 
00173     real M = b->get_p_mass();
00174     if (M == 0) return 0;
00175 
00176     real a2 = b->get_p_scale_sq();
00177 
00178     // Don't make any assumptions about the locations of the
00179     // center of mass of the center of the Plummer field...
00180 
00181     vector com_pos, com_vel;
00182     compute_com(b, com_pos, com_vel);
00183     // PRL(com_pos);
00184 
00185     vector dR = com_pos - b->get_p_center();
00186     vector acc_com = dR * pow(square(dR)+a2, -1.5);
00187     // PRL(acc_com);
00188 
00189     // Don't actually need the acc_com term, as it should sum to zero
00190     // in the loop below...
00191 
00192     real vir = 0;
00193     for_all_daughters(dyn, b, bb) {
00194         vector dr = bb->get_pos() - com_pos;
00195         dR = bb->get_pos() - b->get_p_center();
00196         vector acc_ext = dR * pow(square(dR)+a2, -1.5);
00197         real dvir = bb->get_mass()*dr*(acc_ext - acc_com);
00198         // PRL(dvir);
00199         vir += dvir;
00200     }
00201     // PRL(vir);
00202 
00203     return -M*vir;
00204 }
00205 
00206 //-------------------------------------------------------------------------
00207 // Power-law field, M(r) = A r^x (and note that exponent = 0 reduces to
00208 // a Plummer field with mass = A):
00209 //-------------------------------------------------------------------------
00210 
00211 //-------------------------------------------------------------------------
00212 //
00213 // Notes from Steve (10/01):
00214 //
00215 // For now, handle here the bits and pieces related to dynamical friction.
00216 // The expression given by Binney & Tremaine is:
00217 //
00218 //      Afric = -4 pi log(Lambda) beta Mfric Vcm rho
00219 //                              [erf(X) - 2Xexp(-X^2)/sqrt(pi)] / |Vcm|^3
00220 //
00221 // where the non-obvious terms are defined below and Lambda ~ N(<r).
00222 // We obtain N(<r) from M(<r) assuming a mean mass of 1 Msun and using
00223 // known scalings.  The quantity "1 Msun" is defined if physical units
00224 // are enabled; if they aren't, then it is not clear what scaling we
00225 // should use, or indeed what the meaning of dyamical friction is...
00226 // Beta is a "fudge factor," = 1 according to Binney and Tremaine.
00227 // We introduce some flexibility by allowing beta to be specified on
00228 // the command line, and letting log Lambda default to 1 in the case
00229 // where no physical scale is known.
00230 //
00231 //-------------------------------------------------------------------------
00232 
00233 static real beta = 0;                           // tunable parameter;
00234 void set_friction_beta(real b) {beta = b;}      // BT say beta = 1
00235 
00236 static real Mfric = 0;                          // cluster effective mass
00237 void set_friction_mass(real m) {Mfric = m;}
00238 
00239 static vector Vcm = 0;                          // cluster CM velocity
00240 void set_friction_vel(vector v) {Vcm = v;}
00241 
00242 local real density(dyn *b, real r)              // background density
00243 {
00244     real A = b->get_pl_coeff();
00245     if (A == 0) return 0;
00246 
00247     real a2 = b->get_pl_scale_sq();
00248     real x = b->get_pl_exponent();
00249 
00250     return A*x*pow(r*r+a2, 0.5*(x-1))/(4*M_PI*r*r);
00251 }
00252 
00253 local real mass(dyn *b, real r)                 // mass interior to r
00254 {
00255     real A = b->get_pl_coeff();
00256     if (A == 0) return 0;
00257 
00258     real a2 = b->get_pl_scale_sq();
00259     real x = b->get_pl_exponent();
00260 
00261     return A*pow(r*r+a2, 0.5*x);
00262 }
00263 
00264 #define LAMBDA_FAC      1
00265 
00266 local real logLambda(dyn *b, real r)
00267 {
00268     real mass_unit = -1;
00269     if (b->get_starbase())
00270             mass_unit = b->get_starbase()->conv_m_dyn_to_star(1);
00271 
00272     // Only case where this is meaningful is the power-law field.
00273 
00274     if (beta <= 0 || !b->get_pl())
00275         return 0;
00276 
00277     if (mass <= 0)                              // no physical mass scale
00278         return 1;
00279 
00280     else
00281 
00282         // Use M(<r), assuming <m> = 1 Msun.
00283 
00284         return log(LAMBDA_FAC*mass(b, r)*mass_unit);
00285 }
00286 
00287 local real potential(dyn *b, real r)            // background potential;
00288                                                 // assume x != 1 for now...
00289 {
00290     real A = b->get_pl_coeff();
00291     if (A == 0) return 0;
00292 
00293     real a2 = b->get_pl_scale_sq();
00294     real x = b->get_pl_exponent();
00295 
00296     //#ifdef OLD_ERROR_VERSION_5OCT2001
00297     //    return -A*pow(r*r+a2, 0.5*x-1);               // *** wrong! ***
00298     //#else
00299     return -A*pow(r*r+a2, 0.5*(x-1))/(x-1);
00300     //#endif
00301 }
00302 
00303 static vector Afric = 0;                        // frictional acceleration
00304 void set_friction_acc(dyn *b, real r)
00305 {
00306     if (beta > 0) {
00307 
00308         real sigma2 = sqrt(-2*potential(b, r)/3);  // this is sqrt(2) * sigma;
00309                                                    // assume virial equilibrium
00310         real V = abs(Vcm);
00311         real X = sqrt(2-b->get_pl_exponent());
00312         // real X = V/sigma2;                   // scaled velocity; BT p. 425
00313 
00314         //#ifndef NEW_4OCT2001
00315         //      real coeff = beta;              // discard after current runs
00316         //#else
00317         real coeff = 4*M_PI*beta*logLambda(b, r);
00318         //#endif
00319 
00320         if (X > 0.1)
00321 
00322             Afric = -coeff * Mfric * Vcm * density(b, r) * pow(V, -3)
00323                            * (erf(X) - 2*X*exp(-X*X)/sqrt(M_PI));
00324         else
00325 
00326             // Expand for small X:
00327 
00328             Afric = -coeff * Mfric * Vcm * density(b, r)
00329                            * 4 / (3*sqrt(M_PI)*pow(sigma2, 3));
00330 
00331 #if 1
00332         cerr << endl << "set_friction_acc: "; PRL(Afric);
00333         PRC(beta); PRC(coeff); PRC(Mfric); PRL(density(b, r));
00334         PRL(Vcm);
00335         PRC(r); PRC(sigma2); PRC(V); PRL(X);
00336         PRL(erf(X) - 2*X*exp(-X*X)/sqrt(M_PI));
00337 #endif
00338 
00339     }
00340 }
00341 
00342 //-------------------------------------------------------------------------
00343 
00344 bool acx_set = false;           // kludge...
00345 static real acx = 0, acx1 = 0;
00346 
00347 local inline void set_acx(real A, real c2, real x)
00348 {
00349     if (c2 > 0) {
00350         acx = A*pow(c2, x/2);
00351         if (x != 1)
00352             acx1 = acx*x/(sqrt(c2)*(x-1));
00353         else
00354             acx1 = A*(1+0.5*log(c2));
00355     }
00356     acx_set = true;
00357 }
00358 
00359 local inline void add_power_law(dyn * b,
00360                                 vector pos,
00361                                 vector vel,
00362                                 real& pot,
00363                                 vector& acc,
00364                                 vector& jerk,
00365                                 bool pot_only)
00366 {
00367     // Compute the power-law-field components of the acceleration, jerk,
00368     // and pot of top-level node b.
00369 
00370     real A = b->get_pl_coeff();
00371     if (A == 0) return;
00372 
00373     real a2 = b->get_pl_scale_sq();
00374     real x = b->get_pl_exponent();
00375 
00376     real c2 = b->get_pl_cutoff_sq();
00377     real M = b->get_pl_mass();
00378     real eps2 = b->get_pl_softening_sq();
00379 
00380 #if 0
00381     PRC(A); PRC(a2); PRL(x);
00382     PRC(c2); PRC(M); PRL(eps2);
00383 #endif
00384 
00385     if (!acx_set) set_acx(A, c2, x);
00386 
00387     vector dx = pos - b->get_pl_center();
00388     real dx2 = square(dx);
00389     real r2 = dx2 + a2;
00390 
00391     real dx1i;
00392     if (M > 0 || c2 > 0) dx1i = 1/sqrt(dx2+eps2);
00393 
00394     if (x == 1) {                               // special case (acx = Ac)
00395 
00396         real dpot;
00397         if (dx2 <= c2)
00398             dpot = -M*dx1i + acx1;
00399         else {
00400             dpot = 0.5*A*log(r2);
00401             if (M > 0 || c2 > 0) dpot -= (M-acx)*dx1i;
00402         }
00403         pot += dpot;
00404     }
00405 
00406     if (x != 1 || !pot_only) {                  // ugly logic...
00407 
00408         real r1 = pow(r2, 0.5*(1-x));           // in analogy to Plummer case
00409 
00410         if (!pot_only) {
00411 
00412             real dx3i;
00413             if (M > 0 || c2 > 0) dx3i = dx1i/(dx2+eps2);
00414 
00415             vector vr = dx*(dx*vel);
00416 
00417             if (dx2 > c2) {
00418 
00419                 real r3i = A/(r1*r2);
00420                 acc -= dx*r3i;
00421                 jerk += ((3-x)*vr/r2 - vel)*r3i;
00422 
00423                 if (M > 0 || c2 > 0) {
00424                     dx3i *= M-acx;
00425                     acc -= dx*dx3i;
00426                     jerk += (3*vr/(dx2+eps2) - vel)*dx3i;
00427                 }
00428 
00429             } else if (M > 0) {
00430 
00431                 dx3i *= M;
00432                 acc -= dx*dx3i;
00433                 jerk += (3*vr/(dx2+eps2) - vel)*dx3i;
00434 
00435             }
00436         }
00437 
00438         // if (b->name_is("2481")) {
00439         //      PRC(dx2); PRC(dx*vel); PRL(dx2*abs(acc));
00440         // }
00441 
00442         if (x != 1) {
00443             real dpot;
00444             if (dx2 <= c2)
00445                 dpot = -M*dx1i + acx1;
00446             else {
00447                 real r1 = pow(r2, 0.5*(1-x));
00448                 dpot = -A/(r1*(1-x));
00449                 if (M > 0 || c2 > 0) dpot -= (M-acx)*dx1i;
00450             }
00451             pot += dpot;
00452         }
00453     }
00454 }
00455 
00456 local inline real power_law_pot(dyn * b)
00457 {
00458     // Determine the power-law-field component of the potential energy
00459     // of root node b.
00460 
00461     real A = b->get_pl_coeff();
00462     if (A == 0) return 0;
00463 
00464     real a2 = b->get_pl_scale_sq();
00465     real x = b->get_pl_exponent();
00466 
00467     real c2 = b->get_pl_cutoff_sq();
00468     real M = b->get_pl_mass();
00469     real eps2 = b->get_pl_softening_sq();
00470 
00471     if (!acx_set) set_acx(A, c2, x);    
00472 
00473     real dpot = 0;
00474     for_all_daughters(dyn, b, bb) {
00475 
00476         vector dx = bb->get_pos() - bb->get_pl_center();
00477         real dx2 = square(dx);
00478         real r2 = dx2 + a2;
00479 
00480         real dx1i;
00481         if (M > 0 || c2 > 0) dx1i = 1/sqrt(dx2+eps2);
00482 
00483         real ddpot;
00484         if (x == 1) {                           // same code as in add_power_law
00485             if (dx2 <= c2)
00486                 ddpot = -M*dx1i + acx1;
00487             else {
00488                 ddpot = 0.5*A*log(r2);
00489                 if (M > 0 || c2 > 0) ddpot -= (M-acx)*dx1i;
00490             }
00491         } else {
00492             if (dx2 <= c2)
00493                 ddpot = -M*dx1i + acx1;
00494             else {
00495                 real r1 = pow(r2, 0.5*(1-x));
00496                 ddpot = -A/(r1*(1-x));
00497                 if (M > 0 || c2 > 0) ddpot -= (M-acx)*dx1i;
00498             }
00499         }
00500 
00501         dpot += bb->get_mass()*ddpot;
00502     }
00503 
00504     return dpot;
00505 }
00506 
00507 local inline real power_law_virial(dyn * b)
00508 {
00509     // Determine the power-law-field component of the virial sum
00510     // of root node b.
00511 
00512     // *** New embedded mass/cutoff not yet implemented (Steve, 12/01). ***
00513 
00514     real A = b->get_pl_coeff();
00515     if (A == 0) return 0;
00516 
00517     real a2 = b->get_pl_scale_sq();
00518     real x = b->get_pl_exponent();
00519 
00520     // Don't make any assumptions about the locations of the
00521     // center of mass of the center of the power-law field...
00522 
00523     vector com_pos, com_vel;
00524     compute_com(b, com_pos, com_vel);
00525     // PRL(com_pos);
00526 
00527     vector dR = com_pos - b->get_pl_center();
00528     vector acc_com = dR * pow(square(dR)+a2, 0.5*(x-3));
00529     // PRL(acc_com);
00530 
00531     // We don't actually need the acc_com term, as it should sum
00532     // to zero in the loop below...
00533 
00534     real vir = 0;
00535     for_all_daughters(dyn, b, bb) {
00536         vector dr = bb->get_pos() - com_pos;
00537         dR = bb->get_pos() - b->get_pl_center();
00538         vector acc_ext = dR * pow(square(dR)+a2, 0.5*(x-3));
00539         real dvir = bb->get_mass()*dr*(acc_ext - acc_com);
00540         // PRL(dvir);
00541         vir += dvir;
00542     }
00543     // PRL(vir);
00544 
00545     return -A*vir;
00546 }
00547 
00548 //-------------------------------------------------------------------------
00549 // General "external" functions:
00550 //-------------------------------------------------------------------------
00551 
00552 // Member functions:
00553 
00554 real dyn::get_external_scale_sq()
00555 {
00556     // Just enumerate the possiblilties...
00557 
00558     if (!get_external_field())
00559         return 0;
00560     else if (get_tidal_field())
00561         return 0;
00562     else if (get_plummer())
00563         return p_scale_sq;
00564     else if (get_pl())
00565         return pl_scale_sq;
00566     else
00567         return 0;
00568 }
00569 
00570 vector dyn::get_external_center()
00571 {
00572     // Just enumerate the possiblilties...
00573 
00574     if (!get_external_field())
00575         return 0;
00576     else if (get_tidal_field())
00577         return tidal_center;
00578     else if (get_plummer())
00579         return p_center;
00580     else if (get_pl())
00581         return pl_center;
00582     else
00583         return 0;
00584 }
00585 
00586 // Other functions:
00587 
00588 void get_external_acc(dyn * b,
00589                       vector pos,
00590                       vector vel,
00591                       real& pot,
00592                       vector& acc,
00593                       vector& jerk,
00594                       bool pot_only)    // default = false
00595 {
00596     // Compute the external components of the acceleration, jerk,
00597     // and pot of top-level node b, using the pos and vel provided.
00598     // b is used only as a convenient means of passing and static
00599     // dyn data.
00600 
00601     pot = 0;
00602     if (!pot_only) acc = jerk = 0;
00603 
00604     unsigned int ext = b->get_external_field();
00605 
00606     if (ext) {
00607 
00608         // Loop through the known external fields.  Must do the
00609         // velocity-dependent tidal field last (and note that we will
00610         // have to be more careful when other velocity-dependent fields
00611         // are added, as *all* accs should be computed before jerks are
00612         // updated).
00613 
00614         if (GETBIT(ext, 1))
00615             add_plummer(b, pos, vel, pot, acc, jerk, pot_only);
00616 
00617         if (GETBIT(ext, 2))
00618             add_power_law(b, pos, vel, pot, acc, jerk, pot_only);
00619 
00620         // if (GETBIT(ext, 3))
00621         //     add_other(b, pos, vel, pot, acc, jerk, pot_only);
00622 
00623         if (GETBIT(ext, 0))
00624             add_tidal(b, pos, vel, pot, acc, jerk, pot_only);
00625 
00626         // Add dynamical friction term to non-escapers only:
00627 
00628         if (getiq(b->get_dyn_story(), "esc") == 0)              // too slow?
00629             acc += Afric;
00630     }
00631 }
00632 
00633 real vcirc(dyn *b, vector r)
00634 {
00635     // Return the circular velocity at position r.  Node b is used only
00636     // as a convenient means of passing static dyn class data.
00637 
00638     vector acc, jerk;
00639     real pot;
00640 
00641     get_external_acc(b, r, vector(0), pot, acc, jerk);
00642 
00643     real vc2 = -r*acc;
00644 
00645     if (vc2 > 0)
00646         return sqrt(vc2);
00647     else
00648         return -sqrt(-vc2);         // vcirc < 0 ==> no circular orbit exists
00649 }
00650 
00651 // Accessors:
00652 
00653 real get_tidal_pot(dyn *b) {return tidal_pot(b);}
00654 real get_plummer_pot(dyn *b) {return plummer_pot(b);}
00655 real get_power_law_pot(dyn *b) {return power_law_pot(b);}
00656 
00657 real get_external_pot(dyn * b,
00658                       void (*pot_func)(dyn *, real))    // default = NULL
00659 {
00660     // Determine the external component of the potential of root
00661     // node b, using current positions.
00662 
00663     real pot = 0;
00664     unsigned int ext = b->get_external_field();
00665 
00666     if (ext) {
00667 
00668         real dpot = 0;
00669 
00670         // Loop through the known external fields.
00671 
00672         if (GETBIT(ext, 0)) dpot += tidal_pot(b);
00673         if (GETBIT(ext, 1)) dpot += plummer_pot(b);
00674         if (GETBIT(ext, 2)) dpot += power_law_pot(b);
00675         // if (GETBIT(ext, 3)) dpot += other_pot(b);
00676 
00677         if (pot_func) (*pot_func)(b, dpot);     // used by kira to set_pot()
00678 
00679         pot += dpot;
00680     }
00681 
00682     return pot;
00683 }
00684 
00685 real get_external_virial(dyn * b)
00686 {
00687     // Determine the external component of the potential of root
00688     // node b, using current positions.
00689 
00690     real vir = 0;
00691     unsigned int ext = b->get_external_field();
00692 
00693     if (ext) {
00694 
00695         // Loop through the known external, non-tidal fields.
00696 
00697         if (GETBIT(ext, 1)) vir += plummer_virial(b);
00698         if (GETBIT(ext, 2)) vir += power_law_virial(b);
00699         // if (GETBIT(ext, 3)) vir += other_virial(b);
00700     }
00701 
00702     return vir;
00703 }
00704 
00705 static bool sep = false;
00706 
00707 local void print_ext(int n)
00708 {
00709     if (sep) cerr << ",";
00710 
00711     switch(n) {
00712         case 0:         cerr << "TIDAL";
00713                         break;
00714         case 1:         cerr << "PLUMMER";
00715                         break;
00716         case 2:         cerr << "POWER-LAW";
00717                         break;
00718         default:        cerr << "?";
00719                         break;
00720     }
00721 
00722     sep = true;
00723 }
00724 
00725 void print_external(unsigned int ext,
00726                     bool shortbits)             // default = false
00727 {
00728     if (!ext) return;
00729 
00730     if (shortbits)
00731 
00732         // Just print out ext as a binary number.
00733 
00734         printbits(ext);
00735 
00736     else {
00737 
00738         // Want to interpret the bits in ext.  Code follows printbits.C.
00739 
00740         int n = 31;
00741         while (n >= 0) {if (GETBIT(ext, n)) break; n--;}
00742         while (n >= 0) {if (GETBIT(ext, n)) print_ext(n); n--;}
00743         sep = false;
00744     }
00745 }

Generated at Sun Feb 24 09:56:59 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001