@@ -1446,39 +1446,37 @@ double fdAtmEscXi(BODY *body, int iBody) {
1446
1446
return dXi ;
1447
1447
}
1448
1448
1449
- double fdKTide (BODY * body , IO * io , int iBody ) {
1449
+ double fdKTide (BODY * body , IO * io , int iNumBodies , int iBody ) {
1450
1450
double dKTide ;
1451
1451
1452
1452
// For stars and circumbinary planets, assume no Ktide enhancement
1453
1453
if (body [iBody ].bBinary && body [iBody ].iBodyType == 0 ) {
1454
1454
dKTide = 1.0 ;
1455
1455
} else {
1456
- if (body [iBody ].dAtmEscXi > 1 ) {
1457
- dKTide = (1 - 3 / (2 * body [iBody ].dAtmEscXi ) +
1458
- 1 / (2 * pow (body [iBody ].dAtmEscXi , 3 )));
1459
- /*
1460
- fprintf(stderr,"%.5e: ",evolve->dTime/YEARSEC);
1461
- fprintf(stderr,"%.5e ",xi);
1462
- fprintf(stderr,"%.5e\n",body[iBody].dKTide);
1463
- */
1464
- if (dKTide < body [iBody ].dMinKTide ) {
1465
- dKTide = body [iBody ].dMinKTide ;
1456
+ if (iNumBodies > 1 ) {
1457
+ if (body [iBody ].dAtmEscXi > 1 ) {
1458
+ dKTide = (1 - 3 / (2 * body [iBody ].dAtmEscXi ) +
1459
+ 1 / (2 * pow (body [iBody ].dAtmEscXi , 3 )));
1460
+ if (dKTide < body [iBody ].dMinKTide ) {
1461
+ dKTide = body [iBody ].dMinKTide ;
1462
+ }
1463
+ } else {
1464
+ if (!io -> baRocheMessage [iBody ] && io -> iVerbose >= VERBINPUT &&
1465
+ (!body [iBody ].bUseBondiLimited && !body [iBody ].bAtmEscAuto )) {
1466
+ fprintf (stderr ,
1467
+ "WARNING: Roche lobe radius is larger than %s's XUV radius. "
1468
+ "Evolution may not be accurate.\n" ,
1469
+ body [iBody ].cName );
1470
+ fprintf (stderr , "Consider setting bUseBondiLimited = 1 or bAtmEscAuto "
1471
+ "= 1 to limit envelope mass loss.\n" );
1472
+ io -> baRocheMessage [iBody ] = 1 ;
1473
+ }
1474
+ // Fix dKTide to prevent infs when in Roche Lobe overflow
1475
+ dKTide = 1.0 ;
1466
1476
}
1467
1477
} else {
1468
- if (!io -> baRocheMessage [iBody ] && io -> iVerbose >= VERBINPUT &&
1469
- (!body [iBody ].bUseBondiLimited && !body [iBody ].bAtmEscAuto )) {
1470
- fprintf (stderr ,
1471
- "WARNING: Roche lobe radius is larger than %s's XUV radius. "
1472
- "Evolution may not be accurate.\n" ,
1473
- body [iBody ].cName );
1474
- fprintf (stderr , "Consider setting bUseBondiLimited = 1 or bAtmEscAuto "
1475
- "= 1 to limit envelope mass loss.\n" );
1476
- io -> baRocheMessage [iBody ] = 1 ;
1477
- }
1478
- // Fix dKTide to prevent infs when in Roche Lobe overflow
1479
1478
dKTide = 1.0 ;
1480
1479
}
1481
- // body[iBody].dKTide = 1.0;
1482
1480
}
1483
1481
1484
1482
return dKTide ;
@@ -1694,7 +1692,7 @@ void fnForceBehaviorAtmEsc(BODY *body, MODULE *module, EVOLVE *evolve, IO *io,
1694
1692
}
1695
1693
}
1696
1694
1697
- void AuxPropsLehmer17 (BODY * body , int iBody ) {
1695
+ void AuxPropsLehmer17 (BODY * body , EVOLVE * evolve , int iBody ) {
1698
1696
if (body [iBody ].bAutoThermTemp ) {
1699
1697
body [iBody ].dThermTemp = fdThermalTemp (body , iBody );
1700
1698
}
@@ -1706,7 +1704,7 @@ void AuxPropsLehmer17(BODY *body, int iBody) {
1706
1704
body [iBody ].dPresSurf =
1707
1705
fdLehmerPres (body [iBody ].dEnvelopeMass , body [iBody ].dGravAccel ,
1708
1706
body [iBody ].dRadSolid );
1709
- body [iBody ].dRadXUV = fdLehmerRadius (body , iBody );
1707
+ body [iBody ].dRadXUV = fdLehmerRadius (body , evolve -> iNumBodies , iBody );
1710
1708
body [iBody ].dRadius = body [iBody ].dRadXUV / body [iBody ].dXFrac ;
1711
1709
}
1712
1710
@@ -1726,14 +1724,14 @@ void fnPropsAuxAtmEsc(BODY *body, EVOLVE *evolve, IO *io, UPDATE *update,
1726
1724
int iBody ) {
1727
1725
1728
1726
if (body [iBody ].iPlanetRadiusModel == ATMESC_LEHMER17 ) {
1729
- AuxPropsLehmer17 (body , iBody );
1727
+ AuxPropsLehmer17 (body , evolve , iBody );
1730
1728
}
1731
1729
1732
1730
// Compute various radii of interest
1733
1731
body [iBody ].dBondiRadius = fdBondiRadius (body , iBody );
1734
- body [iBody ].dRocheRadius = fdRocheRadius (body , iBody );
1732
+ body [iBody ].dRocheRadius = fdRocheRadius (body , evolve -> iNumBodies , iBody );
1735
1733
body [iBody ].dAtmEscXi = fdAtmEscXi (body , iBody );
1736
- body [iBody ].dKTide = fdKTide (body , io , iBody );
1734
+ body [iBody ].dKTide = fdKTide (body , io , evolve -> iNumBodies , iBody );
1737
1735
1738
1736
// The XUV flux
1739
1737
if (body [iBody ].bCalcFXUV ) {
@@ -2133,7 +2131,7 @@ void VerifyAtmEsc(BODY *body, CONTROL *control, FILES *files, OPTIONS *options,
2133
2131
2134
2132
// Calculate auxiliary properties
2135
2133
body [iBody ].dRadSolid = fdMassToRad_LehmerCatling17 (body [iBody ].dMass - body [iBody ].dEnvelopeMass );
2136
- AuxPropsLehmer17 (body ,iBody );
2134
+ AuxPropsLehmer17 (body ,& ( control -> Evolve ), iBody );
2137
2135
} else {
2138
2136
fprintf (stderr ,
2139
2137
"ERROR: The Lehmer & Catling (2017) model requires a star.\n" );
@@ -2312,7 +2310,7 @@ void VerifyAtmEsc(BODY *body, CONTROL *control, FILES *files, OPTIONS *options,
2312
2310
// Setup radius and other radii of interest
2313
2311
VerifyRadiusAtmEsc (body , control , options , update , body [iBody ].dAge , iBody );
2314
2312
body [iBody ].dBondiRadius = fdBondiRadius (body , iBody );
2315
- body [iBody ].dRocheRadius = fdRocheRadius (body , iBody );
2313
+ body [iBody ].dRocheRadius = fdRocheRadius (body , control -> Evolve . iNumBodies , iBody );
2316
2314
2317
2315
control -> fnForceBehavior [iBody ][iModule ] = & fnForceBehaviorAtmEsc ;
2318
2316
control -> fnPropsAux [iBody ][iModule ] = & fnPropsAuxAtmEsc ;
@@ -3429,11 +3427,15 @@ Modifier for H Ref Flux to include oxygen drag at a snapshot in time
3429
3427
void WriteHRefODragMod (BODY * body , CONTROL * control , OUTPUT * output ,
3430
3428
SYSTEM * system , UNITS * units , UPDATE * update , int iBody ,
3431
3429
double * dTmp , char cUnit []) {
3432
- double rat = (body [iBody ].dCrossoverMass / ATOMMASS - QOH ) /
3433
- (body [iBody ].dCrossoverMass / ATOMMASS - 1. );
3434
- double XO = fdAtomicOxygenMixingRatio (body [iBody ].dSurfaceWaterMass ,
3435
- body [iBody ].dOxygenMass );
3436
- * dTmp = pow (1. + (XO / (1. - XO )) * QOH * rat , -1 );
3430
+ if (body [iBody ].dCrossoverMass / ATOMMASS - 1. != 0 ) {
3431
+ double rat = (body [iBody ].dCrossoverMass / ATOMMASS - QOH ) /
3432
+ (body [iBody ].dCrossoverMass / ATOMMASS - 1. );
3433
+ double XO = fdAtomicOxygenMixingRatio (body [iBody ].dSurfaceWaterMass ,
3434
+ body [iBody ].dOxygenMass );
3435
+ * dTmp = pow (1. + (XO / (1. - XO )) * QOH * rat , -1 );
3436
+ } else {
3437
+ * dTmp = -1 ;
3438
+ }
3437
3439
strcpy (cUnit , "" );
3438
3440
}
3439
3441
@@ -4082,7 +4084,7 @@ double fdPlanetRadius(BODY *body, SYSTEM *system, int *iaBody) {
4082
4084
body [iaBody [0 ]].dPresSurf =
4083
4085
fdLehmerPres (body [iaBody [0 ]].dEnvelopeMass ,
4084
4086
body [iaBody [0 ]].dGravAccel , body [iaBody [0 ]].dRadSolid );
4085
- body [iaBody [0 ]].dRadXUV = fdLehmerRadius (body , iaBody [0 ]);
4087
+ body [iaBody [0 ]].dRadXUV = fdLehmerRadius (body , system -> iNumBodies , iaBody [0 ]);
4086
4088
}
4087
4089
4088
4090
double foo ;
@@ -4134,6 +4136,11 @@ int fbDoesWaterEscape(BODY *body, EVOLVE *evolve, IO *io, int iBody) {
4134
4136
return 0 ;
4135
4137
}
4136
4138
4139
+ /* If the central body is not a star, then allow water to escape */
4140
+ if (!body [0 ].bStellar ) {
4141
+ return 1 ;
4142
+ }
4143
+
4137
4144
// 2. Check if planet is beyond RG limit; if user requested water loss to stop
4138
4145
// (the cold trap prevents water loss) then water does not escape.
4139
4146
// NOTE: The RG flux limit below is calculated based on body zero's
@@ -4363,62 +4370,7 @@ void fvLinearFit(double *x, double *y, int iLen, double *daCoeffs) {
4363
4370
daCoeffs [1 ] = yavg - daCoeffs [0 ] * xavg ; // Intercept
4364
4371
}
4365
4372
4366
- /**
4367
- Calculate sound speed of a diatomic H (H2) isothermal gaseous atmosphere in
4368
- which the temperature is set by the local equilibrium temperature.
4369
4373
4370
- @param dTemp double stellar effective temperature
4371
- @param dRad double stellar radius
4372
- @param dSemi double planetary semi-major axis
4373
-
4374
- @return sound speed
4375
- */
4376
- double fdEqH2AtmosphereSoundSpeed (double dTemp , double dRad , double dSemi ) {
4377
-
4378
- double dCS = 2300.0 * sqrt (dTemp / 5800.0 ) * pow (dRad / RSUN , 0.25 ) *
4379
- pow (dSemi / (0.1 * AUM ), 0.25 );
4380
- return dCS ;
4381
- }
4382
-
4383
- /**
4384
- Calculate the Roche radius assuming body 0 is the host star using Eqn. 8 from
4385
- Luger et al. (2015)
4386
-
4387
- @param body BODY struct
4388
- @param iBody int body indentifier
4389
-
4390
- @return Body's Roche radius
4391
- */
4392
- double fdRocheRadius (BODY * body , int iBody ) {
4393
- double dRoche = pow (body [iBody ].dMass / (3.0 * body [0 ].dMass ), 1. / 3. ) *
4394
- body [iBody ].dSemi ;
4395
- return dRoche ;
4396
- }
4397
-
4398
- /**
4399
- Calculate the Bondi radius assuming body 0 is the host star and that the
4400
- planetary atmosphere at the Bondi radius is diatomic H2 at the blackbody
4401
- equilibrium temperature set by thermal emission from the host star adapting
4402
- equation. Adapted from equations 2 and 4 from Owen & Wu (2016)
4403
-
4404
- @param body BODY struct
4405
- @param iBody int body indentifier
4406
-
4407
- @return Body's Bondi radius
4408
- */
4409
- double fdBondiRadius (BODY * body , int iBody ) {
4410
- double dBondiRadius ;
4411
- // Compute sound speed in planet's atmosphere assuming a diatomic H atmosphere
4412
- // assuming body 0 is the star
4413
- if (body [0 ].bStellar ) {
4414
- double dSoundSpeed = fdEqH2AtmosphereSoundSpeed (body [0 ].dTemperature , body [0 ].dRadius ,
4415
- body [iBody ].dSemi );
4416
- dBondiRadius = BIGG * body [iBody ].dMass / (2.0 * dSoundSpeed * dSoundSpeed );
4417
- } else {
4418
- dBondiRadius = -1 ;
4419
- }
4420
- return dBondiRadius ;
4421
- }
4422
4374
4423
4375
/**
4424
4376
Calculate the whether or not incident XUV flux exceeds critical flux between
0 commit comments