Skip to content

Commit ecb9af3

Browse files
authored
Merge pull request #1372 from TeamCOMPAS/sharpened
Add option "--timestep-multipliers" to enable more granular, phase-dependent, timestep multipliers
2 parents a4b18ea + cc7c839 commit ecb9af3

File tree

20 files changed

+435
-222
lines changed

20 files changed

+435
-222
lines changed

compas_python_utils/preprocessing/compasConfigDefault.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
##~!!~## COMPAS option values
2-
##~!!~## File Created Tue Apr 1 17:29:43 2025 by COMPAS v03.17.00
2+
##~!!~## File Created Mon Apr 14 17:15:32 2025 by COMPAS v03.18.00
33
##~!!~##
44
##~!!~## The default COMPAS YAML file (``compasConfigDefault.yaml``), as distributed, has
55
##~!!~## all COMPAS option entries commented so that the COMPAS default value for the
@@ -88,6 +88,7 @@ numericalChoices:
8888
# --number-of-systems: 10 # Default: 10 # number of systems per batch
8989
# --radial-change-fraction: 0.100000 # Default: 0.100000 # approximate desired fractional changes in stellar radius per timestep
9090
# --timestep-multiplier: 1.000000 # Default: 1.000000 # optional multiplier relative to default time step duration
91+
# --timestep-multipliers: '{ }' # Default: '' # optional phase-dependent multipliers relative to default time step duration
9192

9293
### STELLAR PROPERTIES
9394
# --cool-wind-mass-loss-multiplier: 1.000000 # Default: 1.000000

online-docs/pages/User guide/Program options/program-options-list-defaults.rst

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ Default = 0.0
343343

344344
**--debug-classes** |br|
345345
Developer-defined debug classes to enable (vector). |br|
346+
See :doc:`Vector program options <./program-options-vector-options>` for option format. |br|
346347
Default = `All debug classes enabled (e.g. no filtering)`
347348

348349
**--debug-level** |br|
@@ -694,6 +695,7 @@ Default = HURLEY_ADD |br|
694695

695696
**--log-classes** |br|
696697
Logging classes to be enabled (vector). |br|
698+
See :doc:`Vector program options <./program-options-vector-options>` for option format. |br|
697699
Default = `All debug classes enabled (e.g. no filtering)`
698700

699701
**--logfile-common-envelopes** |br|
@@ -992,11 +994,13 @@ Default = SSE
992994

993995
**--notes** |br|
994996
Annotation strings (vector). |br|
995-
Default = ""
997+
See :doc:`Vector program options <./program-options-vector-options>` for option format. |br|
998+
Default = "" for each annotation
996999

9971000
**--notes-hdrs** |br|
9981001
Annotations header strings (vector). |br|
999-
Default = `No annotations`
1002+
See :doc:`Vector program options <./program-options-vector-options>` for option format. |br|
1003+
Default = `No annotation headers (no annotations)`
10001004

10011005
**--number-of-systems [ -n ]** |br|
10021006
The number of systems to simulate. |br|
@@ -1334,10 +1338,29 @@ User-defined timesteps filename. (See :doc:`Timestep files <../timestep-files>`)
13341338
Default = ’’ (None)
13351339

13361340
**--timestep-multiplier** |br|
1337-
Multiplicative factor for timestep duration. This multiplier is applied after the timesteps are chosen using other program options
1338-
such as ``--radial-change-fraction`` and ``--mass-change-fraction``, and will therefore override expected behaviour. This option is
1339-
primarily intended for debugging/testing of convergence issues rather than for production runs. |br|
1340-
Default = 1.0
1341+
Multiplicative factor for timestep duration. |br|
1342+
|br|
1343+
This multiplier is applied after the timesteps are chosen using other program options such as ``--radial-change-fraction``
1344+
and ``--mass-change-fraction``, and will therefore override expected behaviour. |br|
1345+
This option can be used in conjunction with ``--timestep-multipliers``, in which case this multiplier, and the appropriate
1346+
phase-dependent multiplier (specified by ``--timestep-multipliers``) are both applied. |br|
1347+
Default = 1.0 |br| |br|
1348+
This option is primarily intended for debugging/testing of convergence issues rather than for production runs. |br|
1349+
1350+
**--timestep-multipliers** |br|
1351+
Phase-dependent multiplicative factors for timestep duration. |br|
1352+
See :doc:`Vector program options <./program-options-vector-options>` for option format. |br|
1353+
A multicative factor can be specified for each phase (stellar type), where the ordinal value (zero-based) of the option value
1354+
indicates the stellar type (from ``MS_LTE_07`` to ``CHEMICALLY_HOMOGENEOUS``, see stellar type list at
1355+
:doc:`../../Developer guide/Headers/typedefs-dot-h`>). |br|
1356+
|br|
1357+
This multiplier is applied after the timesteps are chosen using other program options such as ``--radial-change-fraction`` and
1358+
``--mass-change-fraction``, and will therefore override expected behaviour. |br|
1359+
This option can be used in conjunction with ``--timestep-multiplier``, in which case that multiplier, and the appropriate
1360+
phase-dependent multiplier (specified by ``--timestep-multipliers``) are both applied. |br|
1361+
Default = 1.0 for each phase (stellar type) |br| |br|
1362+
This option is primarily intended for debugging/testing of convergence issues rather than for production runs. |br|
1363+
13411364

13421365
.. _options-props-U:
13431366

online-docs/pages/User guide/Program options/program-options-vector-options.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Currently, the only vector program options are:
1212
- --log-classes
1313
- --notes-hdrs
1414
- --notes
15+
- --timestep-multipliers
1516

1617

1718
The notation for vector program options provides for the specification of one or more values. e.g.::
@@ -26,8 +27,8 @@ for program options (to the command-line value, then to the COMPAS default) - le
2627
`log-class` had been left blank), and specifying an empty string ("") for a value would be ambiguous (as to whether the user wanted the
2728
option value to default, or just be an empty string).
2829

29-
Option values (in general, but also specifically for vector options) may not begin with the dash character ('-'), because the shell parser
30-
will parse them as option names before passing them through to COMPAS.
30+
Option values beyond the first value may not begin with the dash character ('-'), because the shell parser will parse them as option names
31+
before passing them through to COMPAS (this is a Boost limitation).
3132

3233
COMPAS imposes no limit to the length (number of characters) of an individual option values that are specified as strings, but there may
3334
be practical limits imposed by the underlying system.

online-docs/pages/User guide/Running COMPAS/running-grid.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Both option ``--grid-start-line`` and ``--grid-lines-to-process`` are ignored if
5151
Example
5252
~~~~~~~
5353

54-
We will submit a set of COMPAS runs using a grid-file ``grid_demo.txt''
54+
We will submit a set of COMPAS runs using a grid-file ``grid_demo.txt``
5555
.. code-block::
5656
5757
COMPAS --grid grid_demo.txt

online-docs/pages/User guide/docker.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ Bonus Info
140140
----------
141141

142142
Dockerfile
143-
^^^^^^^^^^
143+
~~~~~~~~~~
144144

145145
The `Dockerfile <https://docs.docker.com/engine/reference/builder/>`__ defines how the docker image is constructed.
146146

@@ -159,7 +159,7 @@ The Dockerfile for COMPAS consists of 8 layers:
159159
Dockerfiles usually end with a `CMD` directive specifying the command to run when the container starts. COMPAS does not have a `CMD` directive because some users will run the executable directly, while others will use `runSubmit.py`.
160160

161161
Makefile.docker
162-
^^^^^^^^^^^^^^^
162+
~~~~~~~~~~~~~~~
163163

164164
A separate makefile is required for Docker to:
165165
1. Separate compiled files from source files.

online-docs/pages/whats-new.rst

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,36 @@ What's new
33

44
Following is a brief list of important updates to the COMPAS code. A complete record of changes can be found in the file ``changelog.h``.
55

6-
**03.16.04 Apr 6, 2025**
6+
**03.18.00 Apr 14, 2025**
77

8-
* Neutron stars are now labelled as ``RecycledNS`` when undergoing mass transfer through common envelope (when ``--neutron-star-accretion-in-ce`` is not set to ``ZERO``).
8+
New command line option:
9+
10+
* ``--timestep-multipliers`` to enable more granular, phase-dependent, timestep multipliers
911

12+
**03.17.03 Apr 14, 2025**
13+
14+
* Neutron stars are now labelled as ``RecycledNS`` when undergoing mass transfer through common envelope (when ``--neutron-star-accretion-in-ce`` is not set to ``ZERO``).
1015
* Removed output option ``RLOF_ONTO_NS`` as it can be retrieved from existing RLOF output info.
1116

1217
**03.17.00 Mar 22, 2025**
1318

14-
* Added ENVELOPE_STATE_PRESCRIPTION::CONVECTIVE_MASS_FRACTION (default threshold of convective envelope by mass to label envelope
15-
convective is 0.1, can be set with --convective-envelope-mass-threshold)
19+
* Added ``ENVELOPE_STATE_PRESCRIPTION::CONVECTIVE_MASS_FRACTION`` (default threshold of convective envelope by mass to label envelope convective is 0.1, can be set with ``--convective-envelope-mass-threshold``)
1620
* Stable mass transfer now conserves angular momentum after accounting for the rotational angular momentum lost or gained by the stars
17-
* Imposed Keplerian rotation limit on mass-gaining stars:
18-
* Response depends on the new --response-to-spin-up option
19-
* default (TRANSFER_TO_ORBIT) allows the star to accrete, but excess angular momentum is deposited in the orbit
20-
* KEPLERIAN_LIMIT forces mass transfer to become non-conservative once star (approximately) reaches super-critical rotation
21-
* while the NO_LIMIT variation allows arbitrary super-critical accretion, to match legacy choices
21+
* Imposed Keplerian rotation limit on mass-gaining stars: response depends on the new ``--response-to-spin-up`` option, with possible values:
22+
* ``TRANSFER_TO_ORBIT`` (default) allows the star to accrete, but excess angular momentum is deposited in the orbit
23+
* ``KEPLERIAN_LIMIT`` forces mass transfer to become non-conservative once star (approximately) reaches super-critical rotation
24+
* ``NO_LIMIT`` allows arbitrary super-critical accretion, to match legacy choices
2225

2326
**03.16.02 Mar 19, 2025**
2427

25-
New output options for supernova:
28+
New output options for supernova, which allow for full characterization of the binary orientation post-SN:
2629

27-
* ORBITAL_ANGULAR_MOMENTUM_VECTOR_X, ORBITAL_ANGULAR_MOMENTUM_VECTOR_Y, ORBITAL_ANGULAR_MOMENTUM_VECTOR_Z,
28-
* SYSTEMIC_VELOCITY_X, SYSTEMIC_VELOCITY_Y, SYSTEMIC_VELOCITY_Z,
29-
* These allow for full characterization of the binary orientation post-SN
30+
* ORBITAL_ANGULAR_MOMENTUM_VECTOR_X
31+
* ORBITAL_ANGULAR_MOMENTUM_VECTOR_Y
32+
* ORBITAL_ANGULAR_MOMENTUM_VECTOR_Z
33+
* SYSTEMIC_VELOCITY_X
34+
* SYSTEMIC_VELOCITY_Y
35+
* SYSTEMIC_VELOCITY_Z
3036

3137
**03.15.00 Mar 5, 2025**
3238

src/BaseBinaryStar.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ void BaseBinaryStar::ResolveCommonEnvelopeEvent() {
15381538
m_Star2->SetPreCEEValues(); // squirrel away pre CEE stellar values for star 2
15391539
SetPreCEEValues(semiMajorAxisRsol, eccentricity, rRLd1Rsol, rRLd2Rsol); // squirrel away pre CEE binary values
15401540

1541-
m_MassTransferTimescale = MASS_TRANSFER_TIMESCALE::CE;
1541+
m_MassTransferTimescale = MT_TIMESCALE::CE;
15421542
m_MassLossRateInRLOF = DBL_MAX;
15431543

15441544
// double common envelope phase prescription (Brown 1995) to calculate new semi-major axis
@@ -2008,7 +2008,7 @@ void BaseBinaryStar::CalculateMassTransfer(const double p_Dt) {
20082008
jLoss = CalculateGammaAngularMomentumLoss(); // no - re-calculate angular momentum
20092009
}
20102010

2011-
m_MassTransferTimescale = MASS_TRANSFER_TIMESCALE::NONE; // initial reset
2011+
m_MassTransferTimescale = MT_TIMESCALE::NONE; // initial reset
20122012
double betaThermal = 0.0; // fraction of mass accreted if accretion proceeds on thermal timescale
20132013
double maximumAccretionRate = 0.0; // accretion rate if accretion proceeds on thermal timescale
20142014
double donorMassLossRateThermal = m_Donor->CalculateThermalMassLossRate();
@@ -2037,17 +2037,17 @@ void BaseBinaryStar::CalculateMassTransfer(const double p_Dt) {
20372037
double zetaLobe = CalculateZetaRocheLobe(jLoss, m_FractionAccreted);
20382038
if (utils::Compare(zetaEquilibrium, zetaLobe) > 0 && massDiffDonor > 0.0) { // yes, it's nuclear timescale mass transfer; no need for utils::Compare here
20392039
m_MassLossRateInRLOF = massDiffDonor / m_Dt;
2040-
m_MassTransferTimescale = MASS_TRANSFER_TIMESCALE::NUCLEAR;
2040+
m_MassTransferTimescale = MT_TIMESCALE::NUCLEAR;
20412041
m_ZetaStar = zetaEquilibrium;
20422042
m_ZetaLobe = zetaLobe;
20432043
}
20442044
}
2045-
if (m_MassTransferTimescale != MASS_TRANSFER_TIMESCALE::NUCLEAR) { // thermal timescale mass transfer (we will check for dynamically unstable / CE mass transfer later)
2045+
if (m_MassTransferTimescale != MT_TIMESCALE::NUCLEAR) { // thermal timescale mass transfer (we will check for dynamically unstable / CE mass transfer later)
20462046
m_ZetaLobe = CalculateZetaRocheLobe(jLoss, betaThermal);
20472047
m_ZetaStar = m_Donor->CalculateZetaAdiabatic();
20482048
m_MassLossRateInRLOF = donorMassLossRateThermal;
20492049
m_FractionAccreted = betaThermal;
2050-
m_MassTransferTimescale = MASS_TRANSFER_TIMESCALE::THERMAL;
2050+
m_MassTransferTimescale = MT_TIMESCALE::THERMAL;
20512051
massDiffDonor = MassLossToFitInsideRocheLobe(this, m_Donor, m_Accretor, betaThermal, 0.0); // use root solver to determine how much mass should be lost from the donor to allow it to fit within the Roche lobe
20522052
}
20532053

@@ -2090,7 +2090,7 @@ void BaseBinaryStar::CalculateMassTransfer(const double p_Dt) {
20902090
bool isEnvelopeRemoved = false;
20912091

20922092
if (utils::Compare(m_Donor->CoreMass(), 0.0) > 0 && utils::Compare(envMassDonor, 0.0) > 0) { // donor has a core and an envelope
2093-
if (m_MassTransferTimescale == MASS_TRANSFER_TIMESCALE::THERMAL || utils::Compare (massDiffDonor, envMassDonor) >= 0) {
2093+
if (m_MassTransferTimescale == MT_TIMESCALE::THERMAL || utils::Compare (massDiffDonor, envMassDonor) >= 0) {
20942094
// remove entire envelope if thermal timescale MT from a giant or if the amount of necessary mass loss exceeds the envelope mass
20952095
massDiffDonor = -envMassDonor;
20962096
isEnvelopeRemoved = true;
@@ -2272,7 +2272,7 @@ void BaseBinaryStar::InitialiseMassTransfer() {
22722272

22732273
m_MassTransferTrackerHistory = MT_TRACKING::NO_MASS_TRANSFER; // Initiating flag, every timestep, to NO_MASS_TRANSFER. If it undergoes to MT or CEE, it should change.
22742274

2275-
m_MassTransferTimescale = MASS_TRANSFER_TIMESCALE::NONE;
2275+
m_MassTransferTimescale = MT_TIMESCALE::NONE;
22762276
m_MassLossRateInRLOF = 0.0;
22772277

22782278
m_Star1->InitialiseMassTransfer(m_CEDetails.CEEnow, m_SemiMajorAxis, m_Eccentricity); // initialise mass transfer for star1
@@ -2955,12 +2955,15 @@ void BaseBinaryStar::EmitGravitationalWave(const double p_Dt) {
29552955
*
29562956
* double ChooseTimestep(const double p_Multiplier)
29572957
*
2958-
* @param [IN] p_Multiplier timestep multiplier
2958+
* @param [IN] p_Factor factor applied to timestep (in addition to multipliers)
29592959
* @return new timestep in Myr
29602960
*/
2961-
double BaseBinaryStar::ChooseTimestep(const double p_Multiplier) {
2961+
double BaseBinaryStar::ChooseTimestep(const double p_Factor) {
29622962

2963-
double dt = std::min(m_Star1->CalculateTimestep(), m_Star2->CalculateTimestep()); // dt = smaller of timesteps required by individual stars
2963+
double dt1 = m_Star1->CalculateTimestep() * OPTIONS->TimestepMultipliers(static_cast<int>(m_Star1->StellarType()));
2964+
double dt2 = m_Star2->CalculateTimestep() * OPTIONS->TimestepMultipliers(static_cast<int>(m_Star2->StellarType()));
2965+
2966+
double dt = std::min(dt1, dt2); // dt = smaller of timesteps required by individual stars
29642967

29652968
if (!IsUnbound()) { // check that binary is bound
29662969

@@ -3015,7 +3018,7 @@ double BaseBinaryStar::ChooseTimestep(const double p_Multiplier) {
30153018
}
30163019
}
30173020

3018-
dt *= p_Multiplier;
3021+
dt *= OPTIONS->TimestepMultiplier() * p_Factor;
30193022

30203023
return std::max(std::round(dt / TIMESTEP_QUANTUM) * TIMESTEP_QUANTUM, TIDES_MINIMUM_FRACTIONAL_NUCLEAR_TIME * NUCLEAR_MINIMUM_TIMESTEP); // quantised and not less than minimum
30213024
}
@@ -3248,7 +3251,7 @@ EVOLUTION_STATUS BaseBinaryStar::Evolve() {
32483251
}
32493252

32503253
// we want the first timestep to be small - calculate timestep and divide by 1000.0
3251-
dt = ChooseTimestep(OPTIONS->TimestepMultiplier() / 1000.0); // calculate timestep - make first step small
3254+
dt = ChooseTimestep(0.001); // calculate timestep - make first step small
32523255
}
32533256

32543257
unsigned long int stepNum = 1;
@@ -3378,7 +3381,7 @@ EVOLUTION_STATUS BaseBinaryStar::Evolve() {
33783381
dt = timesteps[stepNum];
33793382
}
33803383
else { // no - not using user-provided timesteps
3381-
dt = ChooseTimestep(OPTIONS->TimestepMultiplier());
3384+
dt = ChooseTimestep();
33823385
}
33833386

33843387
stepNum++; // increment stepNum

src/BaseBinaryStar.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class BaseBinaryStar {
344344
bool m_MassTransfer;
345345
double m_aMassTransferDiff;
346346

347-
MASS_TRANSFER_TIMESCALE m_MassTransferTimescale;
347+
MT_TIMESCALE m_MassTransferTimescale;
348348

349349
MT_TRACKING m_MassTransferTrackerHistory;
350350

@@ -418,7 +418,7 @@ class BaseBinaryStar {
418418
void CalculateGravitationalRadiation();
419419
void EmitGravitationalWave(const double p_Dt);
420420

421-
double ChooseTimestep(const double p_Multiplier);
421+
double ChooseTimestep(const double p_Factor = 1.0);
422422

423423
void CalculateEnergyAndAngularMomentum();
424424

src/HG.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ double HG::CalculateLambdaLoveridge(const double p_EnvMass, const bool p_IsMassL
134134
logBindingEnergy += 33.29866; // + logBE0
135135
double bindingEnergy = PPOW(10.0, logBindingEnergy);
136136

137-
return utils::Compare(bindingEnergy, 0.0) > 0 && utils::Compare(p_EnvMass, 0.0) > 0 ? (G_CGS * m_Mass * MSOL_TO_G * p_EnvMass * MSOL_TO_G) / (m_Radius * RSOL_TO_AU * AU_TO_CM * bindingEnergy) : 1.0; // default to 1.0 (usual lambda default) if binding energy is not sensible [should never happen] or if envelope mass is not positive [can be zero]
137+
return utils::Compare(bindingEnergy, 0.0) > 0 && utils::Compare(p_EnvMass, 0.0) > 0
138+
? (G_CGS * m_Mass * MSOL_TO_G * p_EnvMass * MSOL_TO_G) / (m_Radius * RSOL_TO_AU * AU_TO_CM * bindingEnergy)
139+
: 1.0; // default to 1.0 (usual lambda default) if binding energy is not sensible [should never happen] or if envelope mass is not positive [can be zero]
138140
}
139141

140142

0 commit comments

Comments
 (0)