From 1f1b6bb9fee295a215896051c5c53c67bc3a7c4a Mon Sep 17 00:00:00 2001 From: Jeff Riley Date: Sun, 14 Apr 2024 20:59:09 +1000 Subject: [PATCH 1/3] Defect repair, some code cleanup: - Defect repair: Issue #1084 - modified code to record desired persistence of obejcts so that cloned stars don't participate in logging etc. - Removed some unused code (as a result of the defect repair) - Some Code cleanup --- src/BH.h | 6 - src/BaseBinaryStar.cpp | 73 +++++----- src/BaseBinaryStar.h | 34 +++-- src/BaseStar.cpp | 12 +- src/BaseStar.h | 61 +++++++- src/BinaryConstituentStar.h | 78 +++++++++-- src/BinaryStar.cpp | 23 +-- src/BinaryStar.h | 28 ++-- src/CH.h | 6 - src/CHeB.h | 6 - src/COWD.h | 6 - src/EAGB.h | 6 - src/FGB.h | 6 - src/GiantBranch.cpp | 50 ++++--- src/GiantBranch.h | 1 - src/HG.cpp | 14 +- src/HG.h | 24 ++-- src/HeGB.h | 6 - src/HeHG.h | 6 - src/HeMS.h | 6 - src/HeWD.h | 6 - src/Log.h | 46 ++++-- src/MR.h | 6 - src/MS_gt_07.h | 6 - src/MS_lte_07.h | 6 - src/MainSequence.cpp | 16 ++- src/MainSequence.h | 1 - src/NS.h | 6 - src/ONeWD.h | 5 - src/Remnants.h | 2 - src/Star.cpp | 76 ++++++---- src/Star.h | 23 +-- src/TPAGB.h | 6 - src/WhiteDwarfs.h | 2 - src/changelog.h | 10 +- src/constants.h | 12 +- src/main.cpp | 7 +- src/profiling.h | 9 +- src/utils.h | 7 +- src/vector3d.cpp | 269 ++++++------------------------------ src/vector3d.h | 149 +++++++++++--------- 41 files changed, 526 insertions(+), 596 deletions(-) diff --git a/src/BH.h b/src/BH.h index f5e62165f..51869fe04 100755 --- a/src/BH.h +++ b/src/BH.h @@ -19,12 +19,6 @@ class BH: virtual public BaseStar, public Remnants { if (p_Initialise) Initialise(); } - BH& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions - alphabetically static DBL_DBL_DBL CalculateCoreCollapseSNParams_Static(const double p_Mass); diff --git a/src/BaseBinaryStar.cpp b/src/BaseBinaryStar.cpp index 87abf60d9..4724a217b 100644 --- a/src/BaseBinaryStar.cpp +++ b/src/BaseBinaryStar.cpp @@ -233,13 +233,14 @@ void BaseBinaryStar::SetInitialValues(const unsigned long int p_Seed, const long m_Error = ERROR::NONE; - m_ObjectId = globalObjectId++; - m_ObjectType = OBJECT_TYPE::BASE_BINARY_STAR; - m_StellarType = STELLAR_TYPE::BINARY_STAR; - m_RandomSeed = p_Seed; - m_Id = p_Id; + m_ObjectId = globalObjectId++; + m_ObjectType = OBJECT_TYPE::BASE_BINARY_STAR; + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; + m_StellarType = STELLAR_TYPE::BINARY_STAR; + m_RandomSeed = p_Seed; + m_Id = p_Id; - m_EvolutionStatus = EVOLUTION_STATUS::CONTINUE; + m_EvolutionStatus = EVOLUTION_STATUS::CONTINUE; if (OPTIONS->PopulationDataPrinting()) { // user wants to see details of binary? SAY("Using supplied random seed " << m_RandomSeed << " for Binary Star id = " << m_ObjectId); // yes - show them @@ -1161,6 +1162,13 @@ void BaseBinaryStar::ResolveCoalescence() { * @return True if a supernova event occurred, otherwise false */ bool BaseBinaryStar::ResolveSupernova() { +// Functions defined in vector3d.h +// Defined here for convenience - undefined later +#define cross(x,y) Vector3d::Cross(x, y) +#define dot(x,y) Vector3d::Dot(x, y) +#define angleBetween(x,y) Vector3d::AngleBetween(x, y) +#define mag Magnitude() +#define hat UnitVector() if (!m_Supernova->IsSNevent()) { SHOW_WARN(ERROR::RESOLVE_SUPERNOVA_IMPROPERLY_CALLED); @@ -1178,12 +1186,9 @@ bool BaseBinaryStar::ResolveSupernova() { // Define the natal kick vector (see above for precise definitions of the angles) double theta = m_Supernova->SN_Theta(); // angle out of the binary plane double phi = m_Supernova->SN_Phi(); // angle in the binary plane - Vector3d natalKickVector = m_Supernova->SN_KickMagnitude() *Vector3d(cos(theta) * cos(phi), - cos(theta) * sin(phi), - sin(theta)); - // Check if the system is already unbound - if (IsUnbound()) { // is system already unbound? + Vector3d natalKickVector = m_Supernova->SN_KickMagnitude() * Vector3d(cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)); + if (IsUnbound()) { // is system already unbound? m_Supernova->UpdateComponentVelocity( natalKickVector.RotateVector(m_ThetaE, m_PhiE, m_PsiE)); // yes - only need to update the velocity of the star undergoing SN // The quantities below are meaningless in this context, so they are set to nan to avoid misuse @@ -1193,14 +1198,6 @@ bool BaseBinaryStar::ResolveSupernova() { else { // no - evaluate orbital changes and calculate velocities // Evolve SN out of binary - // Functions defined in vector3d.h - // Defined here for convenience - undefined later - #define cross(x,y) linalg::cross(x,y) - #define dot(x,y) linalg::dot(x,y) - #define angleBetween(x,y) linalg::angleBetween(x,y) - #define mag Magnitude() - #define hat UnitVector() - // Pre-SN parameters double semiMajorAxisPrev_km = m_SemiMajorAxis * AU_TO_KM; // km - Semi-Major axis double eccentricityPrev = m_Eccentricity; // -- - Eccentricity, written with a prev to distinguish from later use @@ -1216,29 +1213,23 @@ bool BaseBinaryStar::ResolveSupernova() { double sinEccAnomaly = sin(m_Supernova->SN_EccentricAnomaly()); // Derived quantities - double aPrev = semiMajorAxisPrev_km; - double aPrev_2 = aPrev * aPrev; - double aPrev_3 = aPrev_2 * aPrev; - - double omega = std::sqrt(G_km_Msol_s * totalMassPrev / aPrev_3); // rad/s - Keplerian orbital frequency + double aPrev = semiMajorAxisPrev_km; + double aPrev_2 = aPrev * aPrev; + double aPrev_3 = aPrev_2 * aPrev; - Vector3d separationVectorPrev = Vector3d(aPrev * (cosEccAnomaly - eccentricityPrev), - aPrev * (sinEccAnomaly) * sqrt1MinusEccPrevSquared, - 0.0); // km - Relative position vector, from m1Prev to m2Prev - double separationPrev = separationVectorPrev.mag; // km - Instantaneous Separation - double fact1 = aPrev_2 * omega / separationPrev; + double omega = std::sqrt(G_km_Msol_s * totalMassPrev / aPrev_3); // rad/s - Keplerian orbital frequency - Vector3d relativeVelocityVectorPrev = Vector3d(-fact1 * sinEccAnomaly, - fact1 * cosEccAnomaly * sqrt1MinusEccPrevSquared, - 0.0); // km/s - Relative velocity vector, in the m1Prev rest frame + Vector3d separationVectorPrev = Vector3d(aPrev * (cosEccAnomaly - eccentricityPrev), aPrev * (sinEccAnomaly) * sqrt1MinusEccPrevSquared, 0.0); // km - Relative position vector, from m1Prev to m2Prev + double separationPrev = separationVectorPrev.mag; // km - Instantaneous Separation + double fact1 = aPrev_2 * omega / separationPrev; + Vector3d relativeVelocityVectorPrev = Vector3d(-fact1 * sinEccAnomaly, fact1 * cosEccAnomaly * sqrt1MinusEccPrevSquared, 0.0); // km/s - Relative velocity vector, in the m1Prev rest frame Vector3d orbitalAngularMomentumVectorPrev = cross(separationVectorPrev, relativeVelocityVectorPrev); // km^2 s^-1 - Specific orbital angular momentum vector - Vector3d eccentricityVectorPrev = cross(relativeVelocityVectorPrev, orbitalAngularMomentumVectorPrev) / (G_km_Msol_s * totalMassPrev) - separationVectorPrev.hat; // -- - Laplace-Runge-Lenz vector (magnitude = eccentricity) - m_OrbitalVelocityPreSN = relativeVelocityVectorPrev.mag; // km/s - Set the Pre-SN orbital velocity and - m_uK = m_Supernova->SN_KickMagnitude() / m_OrbitalVelocityPreSN; // -- - Dimensionless kick magnitude + m_OrbitalVelocityPreSN = relativeVelocityVectorPrev.mag; // km/s - Set the Pre-SN orbital velocity and + m_uK = m_Supernova->SN_KickMagnitude() / m_OrbitalVelocityPreSN; // -- - Dimensionless kick magnitude // Note: In the following, // orbitalAngularMomentumVectorPrev defines the Z-axis, @@ -1365,12 +1356,6 @@ bool BaseBinaryStar::ResolveSupernova() { // the angle of periapsis around the new orbital angular momentum, (i.e, Psi) - RTW 15/05/20 m_PsiE = _2_PI * RAND->Random(); } - - #undef hat - #undef mag - #undef angleBetween - #undef dot - #undef cross } // Set remaining post-SN values @@ -1385,6 +1370,12 @@ bool BaseBinaryStar::ResolveSupernova() { m_Supernova->ClearCurrentSNEvent(); return true; + +#undef hat +#undef mag +#undef angleBetween +#undef dot +#undef cross } diff --git a/src/BaseBinaryStar.h b/src/BaseBinaryStar.h index 4f90e3f27..01979582f 100644 --- a/src/BaseBinaryStar.h +++ b/src/BaseBinaryStar.h @@ -142,9 +142,10 @@ class BaseBinaryStar { // Copy constructor BaseBinaryStar(const BaseBinaryStar& p_Star) { - m_ObjectId = globalObjectId++; // get unique object id (don't copy source) - m_ObjectType = OBJECT_TYPE::BASE_BINARY_STAR; // can only copy from BASE_BINARY_STAR - m_StellarType = STELLAR_TYPE::BINARY_STAR; // always + m_ObjectId = globalObjectId++; // get unique object id (don't copy source) + m_ObjectType = OBJECT_TYPE::BASE_BINARY_STAR; // can only copy from BASE_BINARY_STAR + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // permanent - not an ephemeral clone + m_StellarType = STELLAR_TYPE::BINARY_STAR; // always CopyMemberVariables(p_Star); // copy member variables } @@ -155,9 +156,10 @@ class BaseBinaryStar { if (this != &p_Star) { // make sure we're not not copying ourselves... - m_ObjectId = globalObjectId++; // get unique object id (don't copy source) - m_ObjectType = OBJECT_TYPE::BASE_BINARY_STAR; // can only copy from BASE_BINARY_STAR - m_StellarType = STELLAR_TYPE::BINARY_STAR; // always + m_ObjectId = globalObjectId++; // get unique object id (don't copy source) + m_ObjectType = OBJECT_TYPE::BASE_BINARY_STAR; // can only copy from BASE_BINARY_STAR + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // permanent - not an ephemeral clone + m_StellarType = STELLAR_TYPE::BINARY_STAR; // always CopyMemberVariables(p_Star); // copy member variables } @@ -171,6 +173,7 @@ class BaseBinaryStar { // object identifiers - all classes have these OBJECT_ID ObjectId() const { return m_ObjectId; } OBJECT_TYPE ObjectType() const { return m_ObjectType; } + OBJECT_PERSISTENCE ObjectPersistence() const { return m_ObjectPersistence; } STELLAR_TYPE StellarType() const { return m_StellarType; } long int Id() const { return m_Id; } @@ -271,6 +274,9 @@ class BaseBinaryStar { double ZetaLobe() const { return m_ZetaLobe; } double ZetaStar() const { return m_ZetaStar; } + // setters + void SetObjectId(const OBJECT_ID p_ObjectId) { m_ObjectId = p_ObjectId; } + void SetPersistence(const OBJECT_PERSISTENCE p_Persistence) { m_ObjectPersistence = p_Persistence; } // member functions - alphabetically COMPAS_VARIABLE BinaryPropertyValue(const T_ANY_PROPERTY p_Property) const; @@ -279,7 +285,7 @@ class BaseBinaryStar { EVOLUTION_STATUS Evolve(); - bool PrintSwitchLog(const bool p_PrimarySwitching) { return OPTIONS->SwitchLog() ? LOGGING->LogBSESwitchLog(this, p_PrimarySwitching) : true; } + bool PrintSwitchLog(const bool p_PrimarySwitching) { return OPTIONS->SwitchLog() ? (LOGGING->ObjectSwitchingPersistence() == OBJECT_PERSISTENCE::PERMANENT ? LOGGING->LogBSESwitchLog(this, p_PrimarySwitching) : true) : true; } COMPAS_VARIABLE PropertyValue(const T_ANY_PROPERTY p_Property) const; @@ -290,12 +296,13 @@ class BaseBinaryStar { BaseBinaryStar() { } - OBJECT_ID m_ObjectId; // Instantiated object's unique object id - OBJECT_TYPE m_ObjectType; // Instantiated object's object type - STELLAR_TYPE m_StellarType; // Stellar type defined in Hurley et al. 2000 - long int m_Id; // Id used to name detailed output file - uses p_Id as passed (usually the index number of multiple binaries being produced) + OBJECT_ID m_ObjectId; // Instantiated object's unique object id + OBJECT_TYPE m_ObjectType; // Instantiated object's object type + OBJECT_PERSISTENCE m_ObjectPersistence; // Instantiated object's persistence (permanent or ephemeral) + STELLAR_TYPE m_StellarType; // Stellar type defined in Hurley et al. 2000 + long int m_Id; // Id used to name detailed output file - uses p_Id as passed (usually the index number of multiple binaries being produced) - ERROR m_Error; // Records most recent error encountered for this binary + ERROR m_Error; // Records most recent error encountered for this binary // member variables - alphabetical in groups (sort of...) @@ -556,7 +563,8 @@ class BaseBinaryStar { double donorMass = m_Donor->Mass(); double accretorMass = m_Accretor->Mass(); - BinaryConstituentStar* donorCopy = new BinaryConstituentStar(*m_Donor); + BinaryConstituentStar *donorCopy = BinaryConstituentStar::Clone(*m_Donor, OBJECT_PERSISTENCE::EPHEMERAL); + double semiMajorAxis = m_Binary->CalculateMassTransferOrbit(donorCopy->Mass(), -p_dM , *m_Accretor, m_FractionAccreted); double RLRadius = semiMajorAxis * (1.0 - m_Binary->Eccentricity()) * CalculateRocheLobeRadius_Static(donorMass - p_dM, accretorMass + (m_Binary->FractionAccreted() * p_dM)) * AU_TO_RSOL; diff --git a/src/BaseStar.cpp b/src/BaseStar.cpp index c1b8fe2ac..7d6db37ce 100755 --- a/src/BaseStar.cpp +++ b/src/BaseStar.cpp @@ -17,12 +17,13 @@ BaseStar::BaseStar() { // initialise member variables - m_ObjectId = globalObjectId++; // unique object id - remains for life of star (even through evolution to other phases) - m_ObjectType = OBJECT_TYPE::BASE_STAR; // object type - remains for life of star (even through evolution to other phases) - m_InitialStellarType = STELLAR_TYPE::STAR; // stellar type - changes throughout life of star (through evolution to other phases) - m_StellarType = STELLAR_TYPE::STAR; // stellar type - changes throughout life of star (through evolution to other phases) + m_ObjectId = globalObjectId++; // unique object id - remains for life of star (even through evolution to other phases) + m_ObjectType = OBJECT_TYPE::BASE_STAR; // object type - remains for life of star (even through evolution to other phases) + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // object persistence - permanent or ephemeral (ephemeral used for ephemeral clones) + m_InitialStellarType = STELLAR_TYPE::STAR; // stellar type - changes throughout life of star (through evolution to other phases) + m_StellarType = STELLAR_TYPE::STAR; // stellar type - changes throughout life of star (through evolution to other phases) - m_Error = ERROR::NOT_INITIALISED; // clear error flag + m_Error = ERROR::NOT_INITIALISED; // clear error flag } @@ -36,6 +37,7 @@ BaseStar::BaseStar(const unsigned long int p_RandomSeed, m_ObjectId = globalObjectId++; // unique object id - remains for life of star (even through evolution to other phases) m_ObjectType = OBJECT_TYPE::BASE_STAR; // object type - remains for life of star (even through evolution to other phases) + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // object persistence - permanent or ephemeral (ephemeral used for ephemeral clones) m_InitialStellarType = STELLAR_TYPE::STAR; // stellar type - changes throughout life of star (through evolution to other phases) m_StellarType = STELLAR_TYPE::STAR; // stellar type - changes throughout life of star (through evolution to other phases) diff --git a/src/BaseStar.h b/src/BaseStar.h index b5a5c7f1c..99ce0d9c4 100644 --- a/src/BaseStar.h +++ b/src/BaseStar.h @@ -14,6 +14,13 @@ #include "Log.h" #include "Errors.h" +#include + +#include +#include +#include + +class MainSequence; class BaseStar { @@ -27,12 +34,52 @@ class BaseStar { const KickParameters p_KickParameters, const double p_RotationalVelocity = -1.0); + // This signature is required for Clone() (below) + // p_initialise is ignored + BaseStar(const BaseStar &p_BaseStar, const bool p_Initialise = false) { *this = p_BaseStar; } + + /* + * This function should be used to clone a star - any steller type, including BaseStar. + * + * Important: + * + * This function returns a pointer, created by the 'new' operator. The 'new' operator dynamically allocates + * memory on the heap, not the stack, which is why it is available to the caller of this function after this + * function has exited and its stack frame collapsed. It is the responsibility of the caller of this function + * to delete the pointer returned when it is no longer required so that the allocated memory is return to the + * pool of available memory - failing to do so will cause a memory leak and the program will eventually exhaust + * available memory and fail. The preferred usage pattern is: + * + * T* ptr = Clone(obj, persistence) + * ... + * ... + * delete ptr; ptr = nullptr; + * + * + * template + * static T1* Clone(T1& p_Star, const OBJECT_PERSISTENCE p_Persistence = OBJECT_PERSISTENCE::EPHEMERAL) + * + * @param [IN] p_Star (address of) The star to be cloned + * Must be BaseStar or one of the stellar type classes derived from the BaseStar class + * @param [IN] p_Persistence Specifies the object persistence to be assigned to the cloned star. + * If the cloned star is intended to be used temporarily (e.g. for hypothesis testing), + * persistence should be EPHEMERAL (the default), otherwise PERMANENT. + * @return (pointer to) The cloned star + */ + template + static T1* Clone(T1& p_Star, const OBJECT_PERSISTENCE p_Persistence = OBJECT_PERSISTENCE::EPHEMERAL) { + T1* clone = new T1(static_cast(p_Star), false); + clone->SetPersistence(p_Persistence); + return clone; + } + virtual ~BaseStar() {} // object identifiers - all classes have these OBJECT_ID ObjectId() const { return m_ObjectId; } OBJECT_TYPE ObjectType() const { return m_ObjectType; } + OBJECT_PERSISTENCE ObjectPersistence() const { return m_ObjectPersistence; } STELLAR_TYPE InitialStellarType() const { return m_InitialStellarType; } STELLAR_TYPE StellarType() const { return m_StellarType; } STELLAR_TYPE StellarTypePrev() const { return m_StellarTypePrev; } @@ -143,13 +190,16 @@ class BaseStar { // setters - void SetInitialType(STELLAR_TYPE p_InitialType) { m_InitialStellarType = p_InitialType; } // JR Could do some sanity checks here + void SetInitialType(const STELLAR_TYPE p_InitialType) { m_InitialStellarType = p_InitialType; } // JR Could do some sanity checks here + void SetObjectId(const OBJECT_ID p_ObjectId) { m_ObjectId = p_ObjectId; } + void SetPersistence(const OBJECT_PERSISTENCE p_Persistence) { m_ObjectPersistence = p_Persistence; } + void SetOmega(double p_vRot) { if (p_vRot >= 0.0) m_Omega = p_vRot; }; // Do nothing if sanity check fails (JR: I don't really like this, but I think unavoidable - at least for now) - void SetSNCurrentEvent(SN_EVENT p_SNEvent) { m_SupernovaDetails.events.current |= p_SNEvent; } // Set supernova primary event/state for current timestep + void SetSNCurrentEvent(const SN_EVENT p_SNEvent) { m_SupernovaDetails.events.current |= p_SNEvent; } // Set supernova primary event/state for current timestep void SetSNPastEvent(const SN_EVENT p_SNEvent) { m_SupernovaDetails.events.past |= p_SNEvent; } // Set supernova primary event/state for any past timestep - void SetEvolutionStatus(EVOLUTION_STATUS p_EvolutionStatus) { m_EvolutionStatus = p_EvolutionStatus; } // Set evolution status (typically final outcome) for star + void SetEvolutionStatus(const EVOLUTION_STATUS p_EvolutionStatus) { m_EvolutionStatus = p_EvolutionStatus; } // Set evolution status (typically final outcome) for star void UpdateComponentVelocity(const Vector3d p_newVelocity); void UpdateMassTransferDonorHistory(); @@ -279,7 +329,7 @@ class BaseStar { } bool PrintSwitchLog() const { - return OPTIONS->SwitchLog() ? LOGGING->LogSSESwitchLog(this) : true; // Write record to SSE Switchlog log file + return OPTIONS->SwitchLog() ? (LOGGING->ObjectSwitchingPersistence() == OBJECT_PERSISTENCE::PERMANENT ? LOGGING->LogSSESwitchLog(this) : true) : true; // Write record to SSE Switchlog log file } bool PrintSystemParameters(const SSE_SYSPARMS_RECORD_TYPE p_RecordType = SSE_SYSPARMS_RECORD_TYPE::DEFAULT) const { @@ -290,6 +340,7 @@ class BaseStar { OBJECT_ID m_ObjectId; // Instantiated object's unique object id OBJECT_TYPE m_ObjectType; // Instantiated object's object type + OBJECT_PERSISTENCE m_ObjectPersistence; // Instantiated object's persistence (permanent or ephemeral) STELLAR_TYPE m_InitialStellarType; // Stellar type at birth, defined in Hurley et al. 2000 STELLAR_TYPE m_StellarType; // Stellar type defined in Hurley et al. 2000 @@ -445,7 +496,7 @@ class BaseStar { virtual double CalculateLambdaDewi() const { SHOW_WARN(ERROR::NO_LAMBDA_DEWI, "Default used: 1.0"); return 1.0; } // Not supported: show error double CalculateLambdaKruckow(const double p_Radius, const double p_Alpha) const; double CalculateLambdaLoveridgeEnergyFormalism(const double p_EnvMass, const double p_IsMassLoss = false) const; - virtual double CalculateLambdaNanjingStarTrack(const double p_Mass, const double p_Metallicity) const { SHOW_WARN(ERROR::NO_LAMBDA_NANJING, "Default used: 1.0"); return 1.0; } // Not supported: show error + virtual double CalculateLambdaNanjingStarTrack(const double p_Mass, const double p_Metallicity) const { SHOW_WARN(ERROR::NO_LAMBDA_NANJING, "Default used: 1.0"); return 1.0; } // Not supported: show error virtual double CalculateLambdaNanjingEnhanced(const int p_MassInd, const int p_Zind) const { SHOW_WARN(ERROR::NO_LAMBDA_NANJING, "Default used: 1.0"); return 1.0; } // Not supported: show error void CalculateLCoefficients(const double p_LogMetallicityXi, DBL_VECTOR &p_LCoefficients); diff --git a/src/BinaryConstituentStar.h b/src/BinaryConstituentStar.h index e9cc3bd83..b7e265caf 100644 --- a/src/BinaryConstituentStar.h +++ b/src/BinaryConstituentStar.h @@ -16,10 +16,10 @@ class BinaryConstituentStar: virtual public Star { public: - BinaryConstituentStar() : Star() { - m_ObjectId = globalObjectId++; - m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; + m_ObjectId = globalObjectId++; + m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; }; BinaryConstituentStar(const unsigned long int p_RandomSeed, @@ -28,10 +28,11 @@ class BinaryConstituentStar: virtual public Star { const KickParameters p_KickParameters, const double p_RotationalVelocity = -1.0) : Star(p_RandomSeed, p_Mass, p_Metallicity, p_KickParameters, p_RotationalVelocity) { - m_ObjectId = globalObjectId++; - m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; + m_ObjectId = globalObjectId++; + m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; - m_Companion = nullptr; + m_Companion = nullptr; m_CEDetails.bindingEnergy = DEFAULT_INITIAL_DOUBLE_VALUE; @@ -82,8 +83,7 @@ class BinaryConstituentStar: virtual public Star { m_ObjectId = globalObjectId++; // get unique object id (don't copy source) m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; // can only copy from BINARY_CONSTITUENT_STAR - - m_Companion = nullptr; // don't point at source companion - this can be updated separately later + m_ObjectPersistence = p_Star.m_ObjectPersistence; // object persistence m_CEDetails = p_Star.m_CEDetails; @@ -100,6 +100,13 @@ class BinaryConstituentStar: virtual public Star { m_OmegaTidesIndividualDiff = p_Star.m_OmegaTidesIndividualDiff; m_RLOFDetails = p_Star.m_RLOFDetails; + + // This BinaryConstituentStar's companion is an instance of the BinaryConstituentStar class + // Here we copy the pointer to the companion object - note that it could be a nullptr if the + // companion object has not yet been set. Also note that when this BinaryConstituentStar + // star object is deleted (if it is deleted), the object to which m_Companion points will not + // be deleted as a result. + m_Companion = p_Star.m_Companion; } @@ -110,8 +117,7 @@ class BinaryConstituentStar: virtual public Star { m_ObjectId = globalObjectId++; // get unique object id (don't copy source) m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; // can only copy from BINARY_CONSTITUENT_STAR - - m_Companion = nullptr; // don't point at source companion - this can be updated separately later + m_ObjectPersistence = p_Star.m_ObjectPersistence; // object persistence m_CEDetails = p_Star.m_CEDetails; @@ -128,16 +134,59 @@ class BinaryConstituentStar: virtual public Star { m_OmegaTidesIndividualDiff = p_Star.m_OmegaTidesIndividualDiff; m_RLOFDetails = p_Star.m_RLOFDetails; + + // This BinaryConstituentStar's companion is an instance of the BinaryConstituentStar class + // Here we copy the pointer to the companion object - note that it could be a nullptr if the + // companion object has not yet been set. Also note that when this BinaryConstituentStar + // star object is deleted (if it is deleted), the object to which m_Companion points will not + // be deleted as a result. + m_Companion = p_Star.m_Companion; } return *this; } + + /* + * This function should be used to clone a BinaryConstituentStar. + * + * Important: + * + * This function returns a pointer, created by the 'new' operator. The 'new' operator dynamically allocates + * memory on the heap, not the stack, which is why it is available to the caller of this function after this + * function has exited and its stack frame collapsed. It is the responsibility of the caller of this function + * to delete the pointer returned when it is no longer required so that the allocated memory is return to the + * pool of available memory - failing to do so will cause a memory leak and the program will eventually exhaust + * available memory and fail. The preferred usage pattern is: + * + * T* ptr = Clone(obj, persistence) + * ... + * ... + * delete ptr; ptr = nullptr; + * + * + * template + * static BinaryConstituentStar* Clone(BinaryConstituentStar& p_Star, const OBJECT_PERSISTENCE p_Persistence) + * + * @param [IN] p_Star (address of) The star to be cloned + * @param [IN] p_Persistence Specifies the object persistence to be assigned to the cloned star. + * If the cloned star is intended to be used temporarily (e.g. for hypothesis testing), + * persistence should be EPHEMERAL, otherwise PERMANENT. + * @return (pointer to) The cloned star + */ + static BinaryConstituentStar* Clone(BinaryConstituentStar& p_Star, const OBJECT_PERSISTENCE p_Persistence) { + BinaryConstituentStar* ptr = new BinaryConstituentStar(p_Star); + ptr->SetPersistence(p_Persistence); + return ptr; + } + static BinaryConstituentStar* Clone(BinaryConstituentStar& p_Star) { return Clone(p_Star, p_Star.ObjectPersistence()); } + ~BinaryConstituentStar() { } // object identifiers - all classes have these - OBJECT_ID ObjectId() const { return m_ObjectId; } - OBJECT_TYPE ObjectType() const { return m_ObjectType; } + OBJECT_ID ObjectId() const { return m_ObjectId; } + OBJECT_TYPE ObjectType() const { return m_ObjectType; } + OBJECT_PERSISTENCE ObjectPersistence() const { return m_ObjectPersistence; } // getters - alphabetically @@ -232,11 +281,16 @@ class BinaryConstituentStar: virtual public Star { p_Stepsize, m_MassTransferDiff * MSOL_TO_KG, p_Epsilon); } // JR: todo: revisit this + // setters + void SetObjectId(const OBJECT_ID p_ObjectId) { m_ObjectId = p_ObjectId; } + void SetPersistence(const OBJECT_PERSISTENCE p_Persistence) { m_ObjectPersistence = p_Persistence; } + private: OBJECT_ID m_ObjectId; // Instantiated object's unique object id OBJECT_TYPE m_ObjectType; // Instantiated object's object type + OBJECT_PERSISTENCE m_ObjectPersistence; // Instantiated object's persistence (permanent or ephemeral) // member variables - alphabetically diff --git a/src/BinaryStar.cpp b/src/BinaryStar.cpp index aa23fccd1..999721961 100644 --- a/src/BinaryStar.cpp +++ b/src/BinaryStar.cpp @@ -4,11 +4,12 @@ // binary is generated according to distributions specified in program options BinaryStar::BinaryStar(const unsigned long int p_Seed, const long int p_Id) : m_BinaryStar(new BaseBinaryStar(p_Seed, p_Id)) { - m_ObjectId = globalObjectId++; - m_ObjectType = OBJECT_TYPE::BINARY_STAR; - m_StellarType = STELLAR_TYPE::BINARY_STAR; + m_ObjectId = globalObjectId++; + m_ObjectType = OBJECT_TYPE::BINARY_STAR; + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; + m_StellarType = STELLAR_TYPE::BINARY_STAR; - m_SaveBinaryStar = nullptr; + m_SaveBinaryStar = nullptr; } @@ -68,17 +69,19 @@ bool BinaryStar::RevertState() { * @return Boolean flag indicating success/failure (true = success) */ bool BinaryStar::PrintSwitchLog() { - + bool result = true; - OBJECT_ID primaryObjectId = m_BinaryStar->Star1()->StarObjectId(); - OBJECT_ID secondaryObjectId = m_BinaryStar->Star2()->StarObjectId(); - OBJECT_ID objectIdSwitching = LOGGING->ObjectIdSwitching(); + if (LOGGING->ObjectSwitchingPersistence() != OBJECT_PERSISTENCE::PERMANENT) return result; // do nothing if object switching is not a permanent object + + OBJECT_ID primaryObjectId = m_BinaryStar->Star1()->StarObjectId(); + OBJECT_ID secondaryObjectId = m_BinaryStar->Star2()->StarObjectId(); + OBJECT_ID objectIdSwitching = LOGGING->ObjectIdSwitching(); if (objectIdSwitching == primaryObjectId ) result = m_BinaryStar->PrintSwitchLog(true); // primary else if (objectIdSwitching == secondaryObjectId) result = m_BinaryStar->PrintSwitchLog(false); // secondary - else { // otherwise... - SHOW_ERROR(ERROR::OUT_OF_BOUNDS, "Expected primary or secondary for BSE Switch Log"); // announce error + else if (LOGGING->ObjectSwitchingPersistence() == OBJECT_PERSISTENCE::PERMANENT) { // permenent object (i.e not a clone)? + SHOW_ERROR(ERROR::OUT_OF_BOUNDS, "Expected primary or secondary for BSE Switch Log"); // yes - announce error result = false; } diff --git a/src/BinaryStar.h b/src/BinaryStar.h index 9a7af2df1..b99e24924 100755 --- a/src/BinaryStar.h +++ b/src/BinaryStar.h @@ -9,7 +9,6 @@ class BaseBinaryStar; - class BinaryStar { public: @@ -29,8 +28,9 @@ class BinaryStar { // Copy constructor BinaryStar(const BinaryStar& p_Star) { - m_ObjectId = globalObjectId++; // get unique object id (don't copy source) - m_ObjectType = OBJECT_TYPE::BINARY_STAR; // can only copy from BINARY_STAR + m_ObjectId = globalObjectId++; // get unique object id (don't copy source) + m_ObjectType = OBJECT_TYPE::BINARY_STAR; // can only copy from BINARY_STAR + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // permanent - not an ephemeral clone m_BinaryStar = new BaseBinaryStar(*(p_Star.m_BinaryStar)); // copy underlying BaseBinaryStar m_SaveBinaryStar = new BaseBinaryStar(*(p_Star.m_SaveBinaryStar)); // copy underlying Saved BaseBinaryStar @@ -42,8 +42,9 @@ class BinaryStar { if (this != &p_Star) { // make sure we're not not copying ourselves... - m_ObjectId = globalObjectId++; // get unique object id (don't copy source) - m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; // can only copy from BINARY_CONSTITUENT_STAR + m_ObjectId = globalObjectId++; // get unique object id (don't copy source) + m_ObjectType = OBJECT_TYPE::BINARY_CONSTITUENT_STAR; // can only copy from BINARY_CONSTITUENT_STAR + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // permanent - not an ephemeral clone delete m_BinaryStar; // delete existing m_BinaryStar = new BaseBinaryStar(*(p_Star.m_BinaryStar)); // copy underlying BaseBinaryStar @@ -60,6 +61,7 @@ class BinaryStar { // object identifiers - all classes have these OBJECT_ID ObjectId() const { return m_ObjectId; } OBJECT_TYPE ObjectType() const { return m_ObjectType; } + OBJECT_PERSISTENCE ObjectPersistence() const { return m_ObjectPersistence; } STELLAR_TYPE StellarType() const { return m_StellarType; } @@ -75,16 +77,22 @@ class BinaryStar { bool PrintSwitchLog(); + // setters + void SetObjectId(const OBJECT_ID p_ObjectId) { m_ObjectId = p_ObjectId; } + void SetPersistence(OBJECT_PERSISTENCE p_Persistence) { m_ObjectPersistence = p_Persistence; } + + private: BinaryStar() { } - OBJECT_ID m_ObjectId; // Instantiated object's unique object id - OBJECT_TYPE m_ObjectType; // Instantiated object's object type - STELLAR_TYPE m_StellarType; // Stellar type defined in Hurley et al. 2000 + OBJECT_ID m_ObjectId; // Instantiated object's unique object id + OBJECT_TYPE m_ObjectType; // Instantiated object's object type + OBJECT_PERSISTENCE m_ObjectPersistence; // Instantiated object's persistence (permanent or ephemeral) + STELLAR_TYPE m_StellarType; // Stellar type defined in Hurley et al. 2000 - BaseBinaryStar *m_BinaryStar; // Pointer to current binary star - BaseBinaryStar *m_SaveBinaryStar; // Pointer to saved binary star + BaseBinaryStar *m_BinaryStar; // Pointer to current binary star + BaseBinaryStar *m_SaveBinaryStar; // Pointer to saved binary star }; diff --git a/src/CH.h b/src/CH.h index 37ee163a9..73e2b9d9e 100755 --- a/src/CH.h +++ b/src/CH.h @@ -20,12 +20,6 @@ class CH: virtual public BaseStar, public MS_gt_07 { if (p_Initialise) Initialise(); } - CH& operator = (const BaseStar &baseStar) { - static_cast(*this) = baseStar; - Initialise(); - return *this; - } - protected: diff --git a/src/CHeB.h b/src/CHeB.h index 187cd5fa7..13156d647 100755 --- a/src/CHeB.h +++ b/src/CHeB.h @@ -20,12 +20,6 @@ class CHeB: virtual public BaseStar, public FGB { if (p_Initialise) Initialise(); } - CHeB& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions - alphabetically diff --git a/src/COWD.h b/src/COWD.h index c0f799d7c..6d3457a52 100755 --- a/src/COWD.h +++ b/src/COWD.h @@ -18,12 +18,6 @@ class COWD: virtual public BaseStar, public WhiteDwarfs { if (p_Initialise) Initialise(); } - COWD& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions diff --git a/src/EAGB.h b/src/EAGB.h index 85dc59373..83710b221 100755 --- a/src/EAGB.h +++ b/src/EAGB.h @@ -20,12 +20,6 @@ class EAGB: virtual public BaseStar, public CHeB { if (p_Initialise) Initialise(); } - EAGB& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions static double CalculateRadiusOnPhase_Static(const double p_Mass, diff --git a/src/FGB.h b/src/FGB.h index d189b6c95..7e48bc106 100755 --- a/src/FGB.h +++ b/src/FGB.h @@ -20,12 +20,6 @@ class FGB: virtual public BaseStar, public HG { if (p_Initialise) Initialise(); } - FGB& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - protected: diff --git a/src/GiantBranch.cpp b/src/GiantBranch.cpp index 936d76f4d..ef1b88150 100644 --- a/src/GiantBranch.cpp +++ b/src/GiantBranch.cpp @@ -685,8 +685,6 @@ double GiantBranch::CalculateRemnantRadius() const { * * Hurley et al. 2000, sec. 2.3, particularly subsec. 2.3.1, eqs 36-40 * - * (Technically not a radius calculation I suppose, but "radial extent" is close enough to put it with the radius calculations...) - * * * double CalculateRadialExtentConvectiveEnvelope() * @@ -694,10 +692,17 @@ double GiantBranch::CalculateRemnantRadius() const { */ double GiantBranch::CalculateRadialExtentConvectiveEnvelope() const { - BaseStar clone = *this; // clone this star so can manipulate without changes persisiting - clone.ResolveEnvelopeLoss(true); // update clone's attributes after envelope is lost + // 'this' is const in this function, and it is an instantiation of the 'GiantBranch' class. + // We want to clone this object and access it as a BaseStar object, so we first remove its + // const-ness (required for Clone()), then cast it as BaseStar, then clone it. + BaseStar *clone = Clone(static_cast(const_cast(*this))); + + clone->ResolveEnvelopeLoss(true); // update clone's attributes after envelope is lost + double cloneRadius = clone->Radius(); // get the radius of the updated clone + + delete clone; clone = nullptr; // return the memory allocated for the clone - return m_Radius - clone.Radius(); + return m_Radius - cloneRadius; } @@ -1053,19 +1058,30 @@ double GiantBranch::CalculateZetaConstantsByEnvelope(ZETA_PRESCRIPTION p_ZetaPre */ double GiantBranch::CalculateConvectiveEnvelopeMass() const { - double log10Z = log10 (m_Metallicity); - HG clone = *this; // Create an HG star clone to query its core mass just after TAMS - double log10Ltams = log10 (clone.Luminosity()); + // 'this' is const in this function, and it is an instantiation of the 'GiantBranch' class. + // We want to clone this object and access it as an HG object, so we first remove its + // const-ness (required for Clone()), then cast it as HG, then clone it. + HG *clone = Clone(static_cast(const_cast(*this))); + + double log10Ltams = log10(clone->Luminosity()); // get luminosity of clone + + delete clone; clone = nullptr; // return the memory allocated for the clone + double Mcorefinal = CalculateCoreMassAtBAGB(m_Mass); - double Mconvmax = m_Mass - 1.1 * Mcorefinal; - double b1 = 14.4 * log10Z * log10Z + 57.4 * log10Z + 95.7; - double a2 = -16.9 * log10Z * log10Z - 81.9 * log10Z - 47.9; - double b2 = 184.0 * log10Z * log10Z + 872.2 * log10Z + 370.0; - double c2 = -660.1 * log10Z * log10Z - 3482.0 * log10Z + 1489.0; - double Tnorm = a2 * log10Ltams * log10Ltams + b2 * log10Ltams + c2; - double convectiveEnvelopeMass = Mconvmax / (1+exp(b1*(m_Temperature*TSOL-Tnorm)/Tnorm)); - convectiveEnvelopeMass = std::max(std::min(convectiveEnvelopeMass, (m_Mass - m_CoreMass)), 0.0); // Ensure that convective envelope mass is limited to [0, envelope mass] - + double Mconvmax = m_Mass - 1.1 * Mcorefinal; + + double log10Z = log10 (m_Metallicity); + double log10Z_2 = log10Z * log10Z; + + double b1 = 14.4 * log10Z_2 + 57.4 * log10Z + 95.7; + double a2 = -16.9 * log10Z_2 - 81.9 * log10Z - 47.9; + double b2 = 184.0 * log10Z_2 + 872.2 * log10Z + 370.0; + double c2 = -660.1 * log10Z_2 - 3482.0 * log10Z + 1489.0; + double Tnorm = a2 * log10Ltams * log10Ltams + b2 * log10Ltams + c2; + + double convectiveEnvelopeMass = Mconvmax / (1.0 + exp(b1 * (m_Temperature * TSOL - Tnorm) / Tnorm)); + convectiveEnvelopeMass = std::max(std::min(convectiveEnvelopeMass, (m_Mass - m_CoreMass)), 0.0); // ensure that convective envelope mass is limited to [0, envelope mass] + return convectiveEnvelopeMass; } diff --git a/src/GiantBranch.h b/src/GiantBranch.h index 3630cd043..43329889d 100755 --- a/src/GiantBranch.h +++ b/src/GiantBranch.h @@ -18,7 +18,6 @@ class GiantBranch: virtual public BaseStar, public MainSequence { public: GiantBranch(const BaseStar &baseStar) : BaseStar(baseStar), MainSequence(baseStar) {} - GiantBranch& operator = (const BaseStar &baseStar) { static_cast(*this) = baseStar; return *this; } protected: diff --git a/src/HG.cpp b/src/HG.cpp index 8240b6b9f..2593f69b5 100755 --- a/src/HG.cpp +++ b/src/HG.cpp @@ -798,19 +798,22 @@ double HG::CalculateRadiusOnPhase(const double p_Mass, const double p_Tau, const * * Hurley et al. 2000, sec. 2.3, particularly subsec. 2.3.1, eqs 36-40 * - * (Technically not a radius calculation I suppose, but "radial extent" is close enough to put it with the radius calculations...) - * * * double CalculateRadialExtentConvectiveEnvelope() * * @return Radial extent of the star's convective envelope in Rsol */ double HG::CalculateRadialExtentConvectiveEnvelope() const { + + // 'this' is const in this function, so we remove its const-ness (required for Clone()) + HG *clone = Clone(const_cast(*this)); - BaseStar clone = *this; // clone this star so can manipulate without changes persisiting - clone.ResolveEnvelopeLoss(true); // update clone's attributes after envelope is lost + clone->ResolveEnvelopeLoss(true); // update clone's attributes after envelope is lost + double cloneRadius = clone->Radius(); // get the radius of the updated clone - return std::sqrt(m_Tau) * (m_Radius - clone.Radius()); + delete clone; clone = nullptr; // return the memory allocated for the clone + + return std::sqrt(m_Tau) * (m_Radius - cloneRadius); } @@ -821,7 +824,6 @@ double HG::CalculateRadialExtentConvectiveEnvelope() const { /////////////////////////////////////////////////////////////////////////////////////// - /* * Calculate core mass at the end of the Hertzsprung Gap * diff --git a/src/HG.h b/src/HG.h index d631284f2..a24e89ecf 100755 --- a/src/HG.h +++ b/src/HG.h @@ -25,12 +25,6 @@ class HG: virtual public BaseStar, public GiantBranch { if (p_Initialise) Initialise(); } - HG& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - protected: @@ -149,14 +143,18 @@ class HG: virtual public BaseStar, public GiantBranch { m_DesiredCoreMass = p_DesiredCoreMass; } T operator()(double const& p_GuessMass0) { - HG *copy = new HG(*m_Star, false); - copy->UpdateAttributesAndAgeOneTimestep(0.0, p_GuessMass0 - copy->Mass0(), 0.0, true); - double coreMassEstimate = copy->CalculateCoreMassOnPhase(p_GuessMass0, copy->Age()); - delete copy; copy = nullptr; + + HG *clone = Clone(*m_Star); // clone the star + + clone->UpdateAttributesAndAgeOneTimestep(0.0, p_GuessMass0 - clone->Mass0(), 0.0, true); // update clone's mass and age it one timestep + double coreMassEstimate = clone->CalculateCoreMassOnPhase(p_GuessMass0, clone->Age()); // get clone's core mass + + delete clone; clone = nullptr; // return the memory allocated for the clone + return (coreMassEstimate - m_DesiredCoreMass); } private: - HG *m_Star; + HG *m_Star; double m_DesiredCoreMass; }; @@ -167,13 +165,13 @@ class HG: virtual public BaseStar, public GiantBranch { * Uses boost::math::tools::bracket_and_solve_root() * * - * double Mass0ToMatchDesiredCoreMass(HG * p_Star, double p_DesiredCoreMass) + * double Mass0ToMatchDesiredCoreMass(HG *p_Star, double p_DesiredCoreMass) * * @param [IN] p_Star (Pointer to) The star under examination * @param [IN] p_DesiredCoreMass The desired core mass * @return Root found: will be -1.0 if no acceptable real root found */ - double Mass0ToMatchDesiredCoreMass(HG * p_Star, double p_DesiredCoreMass) { + double Mass0ToMatchDesiredCoreMass(HG *p_Star, double p_DesiredCoreMass) { const boost::uintmax_t maxit = ADAPTIVE_MASS0_MAX_ITERATIONS; // Limit to maximum iterations. boost::uintmax_t it = maxit; // Initially our chosen max iterations, but updated with actual. diff --git a/src/HeGB.h b/src/HeGB.h index 15c619c2b..699818da7 100755 --- a/src/HeGB.h +++ b/src/HeGB.h @@ -20,12 +20,6 @@ class HeGB: virtual public BaseStar, public HeHG { if (p_Initialise) Initialise(); } - HeGB& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions - alphabetically static double CalculateAgeOnPhase_Static(const double p_Mass, const double p_CoreMass, const double p_tHeMS, const DBL_VECTOR &p_GBParams); diff --git a/src/HeHG.h b/src/HeHG.h index cc711e14f..1eee2b11d 100755 --- a/src/HeHG.h +++ b/src/HeHG.h @@ -20,12 +20,6 @@ class HeHG: virtual public BaseStar, public HeMS { if (p_Initialise) Initialise(); } - HeHG& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - static void CalculateGBParams_Static(const double p_Mass0, const double p_Mass, const double p_LogMetallicityXi, const DBL_VECTOR &p_MassCutoffs, const DBL_VECTOR &p_AnCoefficients, const DBL_VECTOR &p_BnCoefficients, DBL_VECTOR &p_GBParams); diff --git a/src/HeMS.h b/src/HeMS.h index 806fdeb20..fab18bb2b 100644 --- a/src/HeMS.h +++ b/src/HeMS.h @@ -23,12 +23,6 @@ class HeMS: virtual public BaseStar, public TPAGB { if (p_Initialise) Initialise(); } - HeMS& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions - alphabetically static double CalculateLifetimeOnPhase_Static(const double p_Mass); diff --git a/src/HeWD.h b/src/HeWD.h index 7726c819f..93a2c356c 100755 --- a/src/HeWD.h +++ b/src/HeWD.h @@ -20,12 +20,6 @@ class HeWD: virtual public BaseStar, public WhiteDwarfs { if (p_Initialise) Initialise(); } - HeWD& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions static double CalculateLuminosityOnPhase_Static(const double p_Mass, diff --git a/src/Log.h b/src/Log.h index 2610dec71..8b599759d 100755 --- a/src/Log.h +++ b/src/Log.h @@ -459,10 +459,12 @@ class Log { m_Logfiles.empty(); // default is no log files m_OpenStandardLogFileIds = {}; // no open COMPAS standard log files - m_ObjectIdSwitching = -1L; // object id of Star object switching stellar type - default none - m_TypeSwitchingFrom = STELLAR_TYPE::NONE; // stellar type from which Star object is switching - default NONE - m_TypeSwitchingTo = STELLAR_TYPE::NONE; // stellar type to which Star object is switching - default NONE - m_PrimarySwitching = false; // Star switching is primary star of binary - default false + m_ObjectIdSwitching = -1L; // object id of the Star object switching stellar type - default none + m_ObjectSwitchingType = OBJECT_TYPE::NONE; // object type of the Star object switching stellar type - default NONE + m_ObjectSwitchingPersistence = OBJECT_PERSISTENCE::PERMANENT; // object persistence of the Star object switching stellar type - default permanent + m_TypeSwitchingFrom = STELLAR_TYPE::NONE; // stellar type from which the Star object is switching - default NONE + m_TypeSwitchingTo = STELLAR_TYPE::NONE; // stellar type to which the Star object is switching - default NONE + m_PrimarySwitching = false; // Star switching is primary star of binary - default false m_SSESupernovae_DelayedWrite.logRecordType = 0; // delayed log record type for SSE_Supernovae file - initially 0 (set later) m_SSESupernovae_DelayedWrite.logRecordString = ""; // delayed log record (string) for SSE_Supernovae file - initially empty @@ -596,10 +598,12 @@ class Log { // the following block of variables support the BSE Switch Log file - OBJECT_ID m_ObjectIdSwitching; // the object id of the Star object switching stellar type - STELLAR_TYPE m_TypeSwitchingFrom; // the stellar type from which the Star object is switching - STELLAR_TYPE m_TypeSwitchingTo; // the stellar type to which the Star object is switching - bool m_PrimarySwitching; // flag to indicate whether the primary star of the binary is switching + OBJECT_ID m_ObjectIdSwitching; // the object id of the Star object switching stellar type + OBJECT_TYPE m_ObjectSwitchingType; // the object type of the Star object switching stellar type + OBJECT_PERSISTENCE m_ObjectSwitchingPersistence; // the object persistence of the Star object switching stellar type + STELLAR_TYPE m_TypeSwitchingFrom; // the stellar type from which the Star object is switching + STELLAR_TYPE m_TypeSwitchingTo; // the stellar type to which the Star object is switching + bool m_PrimarySwitching; // flag to indicate whether the primary star of the binary is switching // the following struct supports delayed writes to logfiles @@ -989,6 +993,8 @@ class Log { bool ok = true; // initially + if (p_Star->ObjectPersistence() != OBJECT_PERSISTENCE::PERMANENT) return ok; // do nothing if not a permanent object + LogfileDetailsT fileDetails = StandardLogFileDetails(p_LogFile, p_FileSuffix); // get record details - open file (if necessary) if (fileDetails.id >= 0) { // file open? if (((1 << (p_RecordType - 1)) & fileDetails.recordTypes) > 0) { // yes - record type enabled? @@ -1035,6 +1041,8 @@ class Log { bool ok = true; // initially + if (p_Star->ObjectPersistence() != OBJECT_PERSISTENCE::PERMANENT) return ok; // do nothing if not a permanent object + LogfileDetailsT fileDetails = StandardLogFileDetails(p_LogFile, p_FileSuffix); // get record details - open file (if necessary) if (fileDetails.id >= 0) { // file open? if ((p_RecordType & fileDetails.recordTypes) > 0) { // yes - record type enabled? @@ -1067,6 +1075,8 @@ class Log { bool ok = true; // initially + if (p_Star->ObjectPersistence() != OBJECT_PERSISTENCE::PERMANENT) return ok; // do nothing if not a permanent object + LogfileDetailsT fileDetails = StandardLogFileDetails(p_LogFile, p_FileSuffix); // get record details - open file (if necessary) if (fileDetails.id >= 0) { // file open? if ((p_RecordType & fileDetails.recordTypes) > 0) { // yes - record type enabled? @@ -1145,15 +1155,21 @@ class Log { // SetSwitchParameters is called by Star::SwitchTo to set the parameters // to be written to the BSE Switch Log file - void SetSwitchParameters(const OBJECT_ID p_ObjectIdSwitching, - const STELLAR_TYPE p_TypeSwitchingFrom, - const STELLAR_TYPE p_TypeSwitchingTo) { - m_ObjectIdSwitching = p_ObjectIdSwitching; // the object id of the Star object switching stellar type - m_TypeSwitchingFrom = p_TypeSwitchingFrom; // the stellar type from which the Star object is switching - m_TypeSwitchingTo = p_TypeSwitchingTo; // the stellar type to which the Star object is switching + void SetSwitchParameters(const OBJECT_ID p_ObjectIdSwitching, + const OBJECT_TYPE p_ObjectSwitchingType, + const OBJECT_PERSISTENCE p_ObjectSwitchingPersistence, + const STELLAR_TYPE p_TypeSwitchingFrom, + const STELLAR_TYPE p_TypeSwitchingTo) { + m_ObjectIdSwitching = p_ObjectIdSwitching; // the object id of the Star object switching stellar type + m_ObjectSwitchingType = p_ObjectSwitchingType; // the object type of the Star object switching stellar type + m_ObjectSwitchingPersistence = p_ObjectSwitchingPersistence; // the object persistence of the Star object switching stellar type + m_TypeSwitchingFrom = p_TypeSwitchingFrom; // the stellar type from which the Star object is switching + m_TypeSwitchingTo = p_TypeSwitchingTo; // the stellar type to which the Star object is switching } - OBJECT_ID ObjectIdSwitching() { return m_ObjectIdSwitching; } + OBJECT_ID ObjectIdSwitching() { return m_ObjectIdSwitching; } + OBJECT_TYPE ObjectSwitchingType() { return m_ObjectSwitchingType; } + OBJECT_PERSISTENCE ObjectSwitchingPersistence() { return m_ObjectSwitchingPersistence; } diff --git a/src/MR.h b/src/MR.h index 67490b91e..6828169dd 100755 --- a/src/MR.h +++ b/src/MR.h @@ -17,12 +17,6 @@ class MR: virtual public BaseStar, public Remnants { if (p_Initialise) Initialise(); } - MR& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - protected: diff --git a/src/MS_gt_07.h b/src/MS_gt_07.h index eb071816f..3b217b23a 100755 --- a/src/MS_gt_07.h +++ b/src/MS_gt_07.h @@ -20,12 +20,6 @@ class MS_gt_07: virtual public BaseStar, public MainSequence { if (p_Initialise) Initialise(); } - MS_gt_07& operator = (const BaseStar &baseStar) { - static_cast(*this) = baseStar; - Initialise(); - return *this; - } - protected: diff --git a/src/MS_lte_07.h b/src/MS_lte_07.h index d55c8547a..53538ace1 100755 --- a/src/MS_lte_07.h +++ b/src/MS_lte_07.h @@ -20,12 +20,6 @@ class MS_lte_07: virtual public BaseStar, public MainSequence { if (p_Initialise) Initialise(); } - MS_lte_07& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - protected: diff --git a/src/MainSequence.cpp b/src/MainSequence.cpp index 58b4b3659..b81085cd6 100644 --- a/src/MainSequence.cpp +++ b/src/MainSequence.cpp @@ -659,9 +659,17 @@ STELLAR_TYPE MainSequence::ResolveEnvelopeLoss(bool p_NoCheck) { void MainSequence::UpdateMinimumCoreMass() { if (OPTIONS->RetainCoreMassDuringCaseAMassTransfer()) { - double fractionalAge =CalculateTauOnPhase(); - HG clone = *this; //create an HG star clone to query its core mass just after TAMS - double TAMSCoreMass = clone.CoreMass(); - m_MinimumCoreMass = std::max(m_MinimumCoreMass, fractionalAge * TAMSCoreMass); + + // 'this' is an instantiation of the 'MainSequence' class. + // We want to clone this object and access it as an HG object, + // so we cast it as HG, then clone it. + HG *clone = Clone(static_cast(*this)); + + double TAMSCoreMass = clone->CoreMass(); // get core mass from clone + + delete clone; clone = nullptr; // return the memory allocated for the clone + + double fractionalAge = CalculateTauOnPhase(); // get age on phase + m_MinimumCoreMass = std::max(m_MinimumCoreMass, fractionalAge * TAMSCoreMass); // update minimum core mass } } diff --git a/src/MainSequence.h b/src/MainSequence.h index a5ce35fa2..ee8d28d65 100644 --- a/src/MainSequence.h +++ b/src/MainSequence.h @@ -15,7 +15,6 @@ class MainSequence: virtual public BaseStar { public: MainSequence(const BaseStar& baseStar) : BaseStar(baseStar) {} - MainSequence& operator = (const BaseStar& baseStar) { static_cast(*this) = baseStar; return *this; } protected: diff --git a/src/NS.h b/src/NS.h index 9d5f0b2e8..07fad832d 100755 --- a/src/NS.h +++ b/src/NS.h @@ -21,12 +21,6 @@ class NS: virtual public BaseStar, public Remnants { if (p_Initialise) Initialise(); } - NS& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - // member functions - alphabetically static DBL_DBL_DBL CalculateCoreCollapseSNParams_Static(const double p_Mass); diff --git a/src/ONeWD.h b/src/ONeWD.h index fdaea2aa3..ca3d1b206 100755 --- a/src/ONeWD.h +++ b/src/ONeWD.h @@ -18,11 +18,6 @@ class ONeWD: virtual public BaseStar, public WhiteDwarfs { if (p_Initialise) Initialise(); } - ONeWD& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } // member functions static double CalculateLuminosityOnPhase_Static(const double p_Mass, diff --git a/src/Remnants.h b/src/Remnants.h index 284315988..70598f058 100644 --- a/src/Remnants.h +++ b/src/Remnants.h @@ -20,8 +20,6 @@ class Remnants: virtual public BaseStar, public HeGB { if (p_Initialise) Initialise(); } - Remnants& operator = (const BaseStar &p_BaseStar) { static_cast(*this) = p_BaseStar; return *this; } - // member functions diff --git a/src/Star.cpp b/src/Star.cpp index 4bf414010..4c35e1a63 100644 --- a/src/Star.cpp +++ b/src/Star.cpp @@ -5,23 +5,24 @@ // Default constructor Star::Star() : m_Star(new BaseStar()) { - m_ObjectId = globalObjectId++; // set object id - m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectId = globalObjectId++; // set object id + m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // set object persistence m_SaveStar = nullptr; } // Regular constructor - with parameters for RandomSeed, MZAMS, Metallicity, and KickParameters - Star::Star(const unsigned long int p_RandomSeed, const double p_MZAMS, const double p_Metallicity, const KickParameters p_KickParameters, const double p_RotationalVelocity) { - m_ObjectId = globalObjectId++; // set object id - m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectId = globalObjectId++; // set object id + m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectPersistence = OBJECT_PERSISTENCE::PERMANENT; // set object persistence m_Star = new BaseStar(p_RandomSeed, p_MZAMS, p_Metallicity, p_KickParameters, p_RotationalVelocity); // create underlying BaseStar object @@ -45,15 +46,31 @@ Star::Star(const unsigned long int p_RandomSeed, /* * Clone underlying BaseStar * - * Instantiates new object of current underlying star class and initialises - * it with the star object passed as p_Star - * - * - * BaseStar* Clone() + * Instantiates new object of the current underlying star class and initialises + * it with the star object passed as p_Star. + * + * This function is used to clone stars when we want to save state etc., but + * can also be used to create a temporary, or "ephemeral", copy of a star to + * be used for hypothesis testing in the code, in which case the 'p_Persistence' + * parameter should be passed as 'OBJECT_PERSISTENCE::EPHEMERAL' (default is + * 'OBJECT_PERSISTENCE::PERMANENT'). Objects with persistence 'ephmeral' will + * not participate in logging, and the 'ephemeral' indication is sometimes used + * to determine if error and/or warnings should be displayed for that object. + * + * + * BaseStar* CloneStar(const BaseStar& p_Star, const OBJECT_PERSISTENCE OBJECT_PERSISTENCE::PERMANENT) + * + * @param [IN] p_Star (address of) The star to be cloned + * @param [IN] p_Persistence The persistence to be assigned to the cloned object + * @return Pointer to the cloned star + * */ -BaseStar* Star::Clone(const BaseStar& p_Star) { +BaseStar* Star::CloneStar(BaseStar& p_Star, const OBJECT_PERSISTENCE p_Persistence) { - BaseStar *ptr = nullptr; + BaseStar *ptr = BaseStar::Clone(p_Star, p_Persistence); + +/* + BaseStar *ptr; switch (p_Star.StellarType()) { case STELLAR_TYPE::MS_LTE_07 : {ptr = new MS_lte_07(p_Star, false);} break; @@ -75,18 +92,19 @@ BaseStar* Star::Clone(const BaseStar& p_Star) { case STELLAR_TYPE::MASSLESS_REMNANT : {ptr = new MR(p_Star, false);} break; default: break; // avoids compiler warning - this should never happen } - +*/ return ptr; } // Copy constructor - deep copy so dynamic variables are also copied Star::Star(const Star& p_Star) { - m_ObjectId = globalObjectId++; // set object id - m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectId = globalObjectId++; // set object id + m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectPersistence = p_Star.ObjectPersistence(); // set object persistence - m_Star = p_Star.m_Star ? Clone(*(p_Star.m_Star)) : nullptr; // copy underlying BaseStar object - m_SaveStar = p_Star.m_SaveStar ? Clone(*(p_Star.m_Star)) : nullptr; // and the saved copy + m_Star = p_Star.m_Star ? CloneStar(*(p_Star.m_Star)) : nullptr; // copy underlying BaseStar object + m_SaveStar = p_Star.m_SaveStar ? CloneStar(*(p_Star.m_Star)) : nullptr; // and the saved copy } @@ -95,14 +113,15 @@ Star& Star::operator = (const Star& p_Star) { if (this != &p_Star) { // make sure we're not not copying ourselves... - m_ObjectId = globalObjectId++; // set object id - m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectId = globalObjectId++; // set object id + m_ObjectType = OBJECT_TYPE::STAR; // set object type + m_ObjectPersistence = p_Star.ObjectPersistence(); // set object persistence delete m_Star; - m_Star = p_Star.m_Star ? Clone(*(p_Star.m_Star)) : nullptr; // copy underlying BaseStar object + m_Star = p_Star.m_Star ? CloneStar(*(p_Star.m_Star)) : nullptr; // copy underlying BaseStar object delete m_SaveStar; - m_SaveStar = p_Star.m_SaveStar ? Clone(*(p_Star.m_SaveStar)) : nullptr; // and the saved copy + m_SaveStar = p_Star.m_SaveStar ? CloneStar(*(p_Star.m_SaveStar)) : nullptr; // and the saved copy } return *this; } @@ -162,14 +181,15 @@ STELLAR_TYPE Star::SwitchTo(const STELLAR_TYPE p_StellarType, bool p_SetInitialT // write to switch log file if required - if (utils::IsOneOf(stellarTypePrev, EVOLVABLE_TYPES) && OPTIONS->SwitchLog()) { // star should be evolving from one of the evolvable types (We don't want the initial switch from Star->MS. Not necessary for BSE (handled differently), but no harm) + if (utils::IsOneOf(stellarTypePrev, EVOLVABLE_TYPES) && OPTIONS->SwitchLog()) { // star should be evolving from one of the evolvable types (We don't want the initial switch from Star->MS. Not necessary for BSE (handled differently), but no harm) - LOGGING->SetSwitchParameters(m_ObjectId, stellarTypePrev, p_StellarType); // store switch details to LOGGING service - if (OPTIONS->EvolutionMode() == EVOLUTION_MODE::BSE) { // BSE? - raise(SIGUSR1); // signal to BSE that switch is occurring +// LOGGING->SetSwitchParameters(m_Star->ObjectId(), m_Star->ObjectType(), m_Star->ObjectPersistence(), stellarTypePrev, p_StellarType); // store switch details to LOGGING service + LOGGING->SetSwitchParameters(m_ObjectId, m_ObjectType, m_ObjectPersistence, stellarTypePrev, p_StellarType); // store switch details to LOGGING service + if (OPTIONS->EvolutionMode() == EVOLUTION_MODE::BSE) { // BSE? + raise(SIGUSR1); // signal to BSE that switch is occurring } - else { // SSE - (void)m_Star->PrintSwitchLog(); // no need for the BSE signal shenanigans - just call the function + else { // SSE + (void)m_Star->PrintSwitchLog(); // no need for the BSE signal shenanigans - just call the function } } } @@ -190,7 +210,7 @@ STELLAR_TYPE Star::SwitchTo(const STELLAR_TYPE p_StellarType, bool p_SetInitialT void Star::SaveState() { delete m_SaveStar; - m_SaveStar = Clone(*m_Star); + m_SaveStar = CloneStar(*m_Star); } diff --git a/src/Star.h b/src/Star.h index fc1c79416..2db842ffc 100755 --- a/src/Star.h +++ b/src/Star.h @@ -63,6 +63,9 @@ class Star { Star& operator = (const Star& p_Star); + static BaseStar* CloneStar(BaseStar& p_Star, const OBJECT_PERSISTENCE p_Persistence); + static BaseStar* CloneStar(BaseStar& p_Star) { return CloneStar(p_Star, p_Star.ObjectPersistence()); } + virtual ~Star() { delete m_Star; delete m_SaveStar; } @@ -70,6 +73,7 @@ class Star { OBJECT_ID ObjectId() const { return m_ObjectId; } OBJECT_ID StarObjectId() const { return m_ObjectId; } OBJECT_TYPE ObjectType() const { return m_ObjectType; } + OBJECT_PERSISTENCE ObjectPersistence() const { return m_ObjectPersistence; } STELLAR_TYPE InitialStellarType() const { return m_Star->InitialStellarType(); } STELLAR_TYPE StellarType() const { return m_Star->StellarType(); } @@ -137,11 +141,11 @@ class Star { double XExponent() const { return m_Star->XExponent(); } - // setters (JR: I don't really like this, but I think unavoidable - at least for now) + // setters void SetOmega(double p_vRot) { m_Star->SetOmega(p_vRot); } - + void SetObjectId(const OBJECT_ID p_ObjectId) { m_ObjectId = p_ObjectId; } + void SetPersistence(const OBJECT_PERSISTENCE p_Persistence) { m_ObjectPersistence = p_Persistence; } void UpdateMassTransferDonorHistory() { m_Star->UpdateMassTransferDonorHistory(); } - void ResetEnvelopeExpulsationByPulsations() { m_Star->ResetEnvelopeExpulsationByPulsations(); } @@ -195,8 +199,6 @@ class Star { void ClearCurrentSNEvent() { m_Star->ClearCurrentSNEvent(); } - BaseStar* Clone(const BaseStar& p_Star); - ACCRETION_REGIME DetermineAccretionRegime(const bool p_HeRich, const double p_DonorThermalMassLossRate) { return m_Star->DetermineAccretionRegime(p_HeRich, p_DonorThermalMassLossRate); } // Used in WDs @@ -261,12 +263,13 @@ class Star { private: - OBJECT_ID m_ObjectId; // instantiated object's unique object id - OBJECT_TYPE m_ObjectType; // instantiated object's object type - long int m_Id; // id used to name output files - uses p_Id as passed (usually the step number of multiple single stars being produced) + OBJECT_ID m_ObjectId; // instantiated object's unique object id + OBJECT_TYPE m_ObjectType; // instantiated object's object type + OBJECT_PERSISTENCE m_ObjectPersistence; // instantiated object's persistence + long int m_Id; // id used to name output files - uses p_Id as passed (usually the step number of multiple single stars being produced) - BaseStar *m_Star; // pointer to current star - BaseStar *m_SaveStar; // pointer to saved star + BaseStar *m_Star; // pointer to current star + BaseStar *m_SaveStar; // pointer to saved star std::vector m_Timesteps; // timesteps vector - for debugging/testing diff --git a/src/TPAGB.h b/src/TPAGB.h index 06cd85cc3..6926c1ffc 100755 --- a/src/TPAGB.h +++ b/src/TPAGB.h @@ -20,12 +20,6 @@ class TPAGB: virtual public BaseStar, public EAGB { if (p_Initialise) Initialise(); } - TPAGB& operator = (const BaseStar &p_BaseStar) { - static_cast(*this) = p_BaseStar; - Initialise(); - return *this; - } - protected: diff --git a/src/WhiteDwarfs.h b/src/WhiteDwarfs.h index 671e19e14..59c92d5f6 100644 --- a/src/WhiteDwarfs.h +++ b/src/WhiteDwarfs.h @@ -20,8 +20,6 @@ class WhiteDwarfs: virtual public BaseStar, public Remnants { if (p_Initialise) Initialise(); } - WhiteDwarfs& operator = (const BaseStar &p_BaseStar) { static_cast(*this) = p_BaseStar; return *this; } - // member functions static double CalculateLuminosityOnPhase_Static(const double p_Mass, diff --git a/src/changelog.h b/src/changelog.h index 262acc8bf..1eb82d65b 100644 --- a/src/changelog.h +++ b/src/changelog.h @@ -1095,14 +1095,14 @@ // HeMS::CalculateMomentOfInertia() falls back to MainSequence::CalculateMomentOfInertia() // HeHG::CalculateMomentOfInertia() falls back to GiantBranch::CalculateMomentOfInertia() // - Added sanity checks for mass and luminosity where necessary in variants of CalculateRadiusOnPhase_Static() -// 02.42.00 JR - Jan 08, 2024 - Enhancements, defect repair, a little cleanup +// 02.42.00 JR - Feb 20, 2024 - Enhancements, defect repair, a little cleanup // - added `timesteps-filename` option to allow users to provide preset timesteps for both SSE and BSE // - updated documentation for new option; updated `What's New` // - SSE vs BSE consistency: modified SSE to evolve a single star exactly as the primary in a wide binary with small companion // - quantised timesteps to an integral multiple of 1E-12Myr - new constant `TIMESTEP_QUANTUM` in constants.h // - little bit of code cleanup // - added warning for stellar type switch not taken - just a diagnostic for now -// 02.42.01 JR - Jan 21, 2024 - Defect repair +// 02.42.01 JR - Feb 25, 2024 - Defect repair // - fix for issue 1066 - see issue/PR for explanation // - cleaned up root solvers OmegaAfterSynchronisation(), MassLossToFitInsideRocheLobe(), and Mass0ToMatchDesiredCoreMass(), and their respective functors // - MassLossToFitInsideRocheLobe(), and Mass0ToMatchDesiredCoreMass() now return -1.0 if no acceptable root found @@ -1113,7 +1113,11 @@ // - Defect repair : Added explicit definition `bool isUnstable = false` to avoid confusion in BaseBinaryStar.cpp // - Defect repair : Fixed erroneous core mass values in ResolveSNIa in WhiteDwarfs.cpp. Was previously 0 for all core masses. // - Enhancement: Added output parameter TZAMS for internal variable m_TZAMS +// 02.42.03 JR - Apr 14, 2024 - Defect repair, some code cleanup: +// - Defect repair: Issue #1084 - modified code to record desired persistence of obejcts so that cloned stars don't participate in logging etc. +// - Removed some unused code (as a result of the defect repair) +// - Some Code cleanup -const std::string VERSION_STRING = "02.42.02"; +const std::string VERSION_STRING = "02.42.03"; # endif // __changelog_h__ diff --git a/src/constants.h b/src/constants.h index 96f9122b9..5aa4a65e3 100755 --- a/src/constants.h +++ b/src/constants.h @@ -535,9 +535,15 @@ const COMPASUnorderedMap OBJECT_TYPE_LABEL = { { OBJECT_TYPE::BASE_STAR, "BaseStar" }, { OBJECT_TYPE::BINARY_STAR, "BinaryStar" }, { OBJECT_TYPE::BASE_BINARY_STAR, "BaseBinaryStar" }, - { OBJECT_TYPE::BINARY_CONSTITUENT_STAR, "BinaryConstituentStar" }, + { OBJECT_TYPE::BINARY_CONSTITUENT_STAR, "BinaryConstituentStar" } }; +// object persistence +enum class OBJECT_PERSISTENCE: int { PERMANENT, EPHEMERAL }; +const COMPASUnorderedMap OBJECT_PERSISTENCE_LABEL = { + { OBJECT_PERSISTENCE::PERMANENT, "Permanent" }, + { OBJECT_PERSISTENCE::EPHEMERAL, "Ephemeral" } +}; // Commandline Status constants enum class PROGRAM_STATUS: int { SUCCESS, CONTINUE, STOPPED, ERROR_IN_COMMAND_LINE, LOGGING_FAILED, ERROR_UNHANDLED_EXCEPTION }; @@ -578,6 +584,7 @@ enum class ERROR: int { ERROR, // unspecified error ERROR_PROCESSING_CMDLINE_OPTIONS, // an error occurred while processing commandline options ERROR_PROCESSING_GRIDLINE_OPTIONS, // an error occurred while processing grid file options + EXPECTED_3D_VECTOR, // expected a vector of size 3 EXPECTED_ASSIGNMENT_OPERATOR, // expected assignment operator EXPECTED_BINARY_PROPERTY, // expected a binary property (STAR_1_, STAR_2_, SUPERNOVA_, COMPANION_, or BINARY_PROPERTY) EXPECTED_COMMA_OR_CLOSE_BRACE, // expected a comma or close brace @@ -596,6 +603,7 @@ enum class ERROR: int { FILE_WRITE_ERROR, // error writing to file - data not written GRID_OPTIONS_ERROR, // grid file options error HIGH_TEFF_WINDS, // winds being used at high temperature + INDEX_OUT_OF_RANGE, // index supplied is out of range INVALID_DATA_TYPE, // invalid data type INVALID_ENVELOPE_TYPE, // invalid envelope type INVALID_INITIAL_ATTRIBUTES, // initial values of stellar or binary attributes are not valid - can't evolve star or binary @@ -729,6 +737,7 @@ const COMPASUnorderedMap> ERROR_CATA { ERROR::ERROR, { ERROR_SCOPE::ALWAYS, "Error!" }}, { ERROR::ERROR_PROCESSING_CMDLINE_OPTIONS, { ERROR_SCOPE::ALWAYS, "An error occurred while processing commandline options" }}, { ERROR::ERROR_PROCESSING_GRIDLINE_OPTIONS, { ERROR_SCOPE::ALWAYS, "An error occurred while processing grid file options" }}, + { ERROR::EXPECTED_3D_VECTOR, { ERROR_SCOPE::ALWAYS, "Expected a vector of size 3" }}, { ERROR::EXPECTED_ASSIGNMENT_OPERATOR, { ERROR_SCOPE::ALWAYS, "Expected assignment operator: one of { '=', '-=', '+=' }" }}, { ERROR::EXPECTED_BINARY_PROPERTY, { ERROR_SCOPE::ALWAYS, "Expected binary logfile property: one of { (STAR_1|STAR_2|SUPERNOVA|COMPANION|BINARY)_PROPERTY, PROGRAM_OPTION }" }}, { ERROR::EXPECTED_COMMA_OR_CLOSE_BRACE, { ERROR_SCOPE::ALWAYS, "Expected a comma ',' or close brace '}'" }}, @@ -747,6 +756,7 @@ const COMPASUnorderedMap> ERROR_CATA { ERROR::FILE_WRITE_ERROR, { ERROR_SCOPE::ALWAYS, "Error writing to file - data not written" }}, { ERROR::GRID_OPTIONS_ERROR, { ERROR_SCOPE::ALWAYS, "Grid File Options error" }}, { ERROR::HIGH_TEFF_WINDS, { ERROR_SCOPE::ALWAYS, "Winds being used at high temperature" }}, + { ERROR::INDEX_OUT_OF_RANGE, { ERROR_SCOPE::ALWAYS, "Index out of range" }}, { ERROR::INVALID_DATA_TYPE, { ERROR_SCOPE::ALWAYS, "Invalid data type" }}, { ERROR::INVALID_ENVELOPE_TYPE, { ERROR_SCOPE::ALWAYS, "Invalid envelope type" }}, { ERROR::INVALID_INITIAL_ATTRIBUTES, { ERROR_SCOPE::ALWAYS, "Initial attributes are not valid - evolution not possible" }}, diff --git a/src/main.cpp b/src/main.cpp index a5805383e..150cebea1 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,9 +34,10 @@ OBJECT_ID m_ObjectId = 0; // object id for class Star; class BinaryStar; -OBJECT_ID ObjectId() { return m_ObjectId; } -OBJECT_TYPE ObjectType() { return OBJECT_TYPE::MAIN; } -STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } +OBJECT_ID ObjectId() { return m_ObjectId; } +OBJECT_TYPE ObjectType() { return OBJECT_TYPE::MAIN; } +OBJECT_PERSISTENCE ObjectPersistence() { return OBJECT_PERSISTENCE::PERMANENT; } +STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // The following global variables support the BSE Switch Log file diff --git a/src/profiling.h b/src/profiling.h index 21f8be4dc..923f1ecbe 100644 --- a/src/profiling.h +++ b/src/profiling.h @@ -35,9 +35,10 @@ namespace profiling { // object identifiers - all classes have these (adding here (no class) for error handling) - inline OBJECT_ID ObjectId() { return static_cast(OBJECT_TYPE::PROFILING); } // object id for profiling - ordinal value from enum - inline OBJECT_TYPE ObjectType() { return OBJECT_TYPE::PROFILING; } // object type for profiling - always "UTILS" - inline STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // stellar type for profiling - always "NONE" + inline OBJECT_ID ObjectId() { return static_cast(OBJECT_TYPE::PROFILING); } // object id for profiling - ordinal value from enum + inline OBJECT_TYPE ObjectType() { return OBJECT_TYPE::PROFILING; } // object type for profiling - always "PROFILING" + inline OBJECT_PERSISTENCE ObjectPersistence() { return OBJECT_PERSISTENCE::PERMANENT; } // object persistence for profiling - always "PERMANENT" + inline STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // stellar type for profiling - always "NONE" // namespace functions @@ -71,4 +72,4 @@ namespace profiling { #endif // DOPROFILING -#endif // __profiling_h__ +#endif // __profiling_h__ diff --git a/src/utils.h b/src/utils.h index b6414c609..4a481067b 100755 --- a/src/utils.h +++ b/src/utils.h @@ -8,9 +8,10 @@ namespace utils { // object identifiers - all classes have these (adding here (no class) for error handling) - inline OBJECT_ID ObjectId() { return static_cast(OBJECT_TYPE::UTILS); } // object id for utils - ordinal value from enum - inline OBJECT_TYPE ObjectType() { return OBJECT_TYPE::UTILS; } // object type for utils - always "UTILS" - inline STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // stellar type for utils - always "NONE" + inline OBJECT_ID ObjectId() { return static_cast(OBJECT_TYPE::UTILS); } // object id for utils - ordinal value from enum + inline OBJECT_TYPE ObjectType() { return OBJECT_TYPE::UTILS; } // object type for utils - always "UTILS" + inline OBJECT_PERSISTENCE ObjectPersistence() { return OBJECT_PERSISTENCE::PERMANENT; } // object persistence for utils - always "PERMANENT" + inline STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // stellar type for utils - always "NONE" // namespace functions - alphabetical (sort of) diff --git a/src/vector3d.cpp b/src/vector3d.cpp index 42721f888..89a2aeb07 100644 --- a/src/vector3d.cpp +++ b/src/vector3d.cpp @@ -3,28 +3,19 @@ #include "vector3d.h" #include "constants.h" -/////////////////////////////////////////////////////////// -// -// Initialize Vector3d object -// -/////////////////////////////////////////////////////////// // Default constructor Vector3d::Vector3d() { - // Initialize member variables - m_ObjectId = globalObjectId++; m_x = 0.0; m_y = 0.0; m_z = 0.0; - } -// Initialize from values - -Vector3d::Vector3d(double p_x, double p_y, double p_z) { +// Regular constructor - with parameters for x, y, and z +Vector3d::Vector3d(const double p_x, const double p_y, const double p_z) { m_ObjectId = globalObjectId++; @@ -33,132 +24,35 @@ Vector3d::Vector3d(double p_x, double p_y, double p_z) { m_z = p_z; } -Vector3d::Vector3d(DBL_VECTOR p_v) { +// Regular constructor - initialise from std:vector +Vector3d::Vector3d(const DBL_VECTOR p_Vec) { m_ObjectId = globalObjectId++; - m_x = p_v[0]; - m_y = p_v[1]; - m_z = p_v[2]; -} + int numValuesSupplied = p_Vec.size(); -// Update after initialization -void Vector3d::UpdateVector(const double p_x, const double p_y, const double p_z) { - m_x = p_x; - m_y = p_y; - m_z = p_z; -} - -/////////////////////////////// -// Overload operators + SHOW_WARN_IF(numValuesSupplied != 3, ERROR::EXPECTED_3D_VECTOR); -// Indexing Operator -double& Vector3d::operator[] (size_t p_i) { - switch (p_i) { - case 0: return m_x; - case 1: return m_y; - case 2: return m_z; - default: throw "Not an index!\n"; // JR: we should fix this one day - the error should be handled rather than just stopping the program with an exception - } -} - -// Overload setting operator -void Vector3d::operator =(Vector3d p_SourceVec) { - UpdateVector(p_SourceVec[0], p_SourceVec[1], p_SourceVec[2]); -} - -// Overload vector addition operator -Vector3d Vector3d::operator +(Vector3d p_Vec) { - Vector3d newVect; - - for (size_t i=0; i<3; i++) { - newVect[i] = (*this)[i] + p_Vec[i]; - } - return newVect; -} - -// Overload vector subtraction operator -Vector3d Vector3d::operator -(Vector3d p_Vec) { - Vector3d newVect; - - for (size_t i=0; i<3; i++) { - newVect[i] = (*this)[i] - p_Vec[i]; - } - return newVect; -} - -// Overload scalar multiplication operator... -Vector3d Vector3d::operator *(const double p_Scalar) { - Vector3d newVect; - - for (size_t i=0; i<3; i++) { - newVect[i] = (*this)[i] * p_Scalar; - } - return newVect; -} -// ...and in reverse order (need the reverser to be a free function) -Vector3d operator *(double p_Scalar, Vector3d p_Vec) { return p_Vec * p_Scalar; } - -// Overload scalar division operator -Vector3d Vector3d::operator /(const double p_Scalar) { - Vector3d newVect; - - for (size_t i=0; i<3; i++) { - newVect[i] = (*this)[i] / p_Scalar; - } - return newVect; -} - - -// Overload output << operator for Vector3d -std::ostream &operator <<(std::ostream &os, Vector3d const p_Vec) { - return os << "{" << p_Vec[0] << ", " << p_Vec[1] << ", " << p_Vec[2] << "}"; -} - - -////////////////////////////////// -// Add in common vector calculations - -/* - * Calculate the magnitude of a velocity vector, the speed. - * - * - * @return The magnitude of the velocity vector (speed) - */ -double Vector3d::Magnitude() const { - // Straightforward application of pythagorean theorem - return std::sqrt(linalg::dot((*this), (*this))); + m_x = numValuesSupplied >= 1 ? p_Vec[0] : 0.0; + m_y = numValuesSupplied >= 2 ? p_Vec[1] : 0.0; + m_z = numValuesSupplied >= 3 ? p_Vec[2] : 0.0; } /* - * Convert the Vector3d to a DBL_VECTOR - * - * - * @return The analogous DBL_VECTOR - */ -DBL_VECTOR Vector3d::asDBL_VECTOR() { - - Vector3d v = (*this); - DBL_VECTOR vFinal = { v[0], v[1], v[2] }; - - return vFinal; - -} - - -/* - * Redefines a vector from one coordinate basis to another using Euler Angles + * Redefine a vector from one coordinate basis to another using Euler Angles * * For a vector defined in a new coordinate basis, (X',Y',Z'), we want to * find it's values in a previous coordinate basis (X,Y,Z) so that we can * add the new vector to vectors defined in the previous basis. * - * For a change of basis from (X,Y,Z)->(X',Y',Z'), - * ThetaE [0, pi] is the angle between Z and Z', - * Vector N := Z x Z' (cross product) - * PhiE [0, 2pi) is the angle between X and N - * PsiE [0, 2pi) is the angle between X' and N + * For a change of basis from (X,Y,Z)->(X',Y',Z') + * + * ThetaE [0, pi] is the angle between Z and Z', + * Vector N := Z x Z' (cross product) + * PhiE [0, 2pi) is the angle between X and N + * PsiE [0, 2pi) is the angle between X' and N + * * These angles uniquely determine the change of basis, which is applied * in the form of a rotation matrix R as a function of these angles. * @@ -168,118 +62,45 @@ DBL_VECTOR Vector3d::asDBL_VECTOR() { * https://en.wikipedia.org/wiki/Euler_angles * https://en.wikipedia.org/wiki/Change_of_basis * - * + * + * Vector3d::RotateVector(const double p_ThetaE, const double p_PhiE, const double p_PsiE) + * * @param [IN] p_ThetaE Euler angle Theta (rad) * @param [IN] p_PhiE Euler angle Phi (rad) * @param [IN] p_PsiE Euler angle Psi (rad) * @return Vector in previous basis */ Vector3d Vector3d::RotateVector(const double p_ThetaE, const double p_PhiE, const double p_PsiE) { +// Replace for convenience, undefined below +#define cTheta cos(p_ThetaE) +#define cPhi cos(p_PhiE) +#define cPsi cos(p_PsiE) +#define sTheta sin(p_ThetaE) +#define sPhi sin(p_PhiE) +#define sPsi sin(p_PsiE) - // Replace for convenience, undefine below - #define cTheta cos(p_ThetaE) - #define cPhi cos(p_PhiE) - #define cPsi cos(p_PsiE) - #define sTheta sin(p_ThetaE) - #define sPhi sin(p_PhiE) - #define sPsi sin(p_PsiE) + Vector3d result = *this; // default return is this vector // Define the Rotation Matrix - std::vector RotationMatrix = { - { cPhi*cPsi - sPhi*cTheta*sPsi , -cPhi*sPsi - sPhi*cTheta*cPsi , sTheta*sPhi }, - { sPhi*cPsi + cPhi*cTheta*sPsi , -sPhi*sPsi + cPhi*cTheta*cPsi , -sTheta*cPhi }, - { sTheta*sPsi , sTheta*cPsi , cTheta }}; - - #undef cTheta - #undef cPhi - #undef cPsi - #undef sTheta - #undef sPhi - #undef sPsi - - // Multiply RotationMatrix * p_oldVector - Vector3d oldVector = (*this); - Vector3d newVector = Vector3d(0.0, 0.0, 0.0); - - for (size_t i=0; i< 3; i++) { - for (size_t j=0; j<3; j++) { - newVector[i] += RotationMatrix[i][j] * oldVector[j]; + std::vector rotationMatrix = { + { cPhi * cPsi - sPhi * cTheta * sPsi , -cPhi * sPsi - sPhi * cTheta * cPsi , sTheta * sPhi }, + { sPhi * cPsi + cPhi * cTheta * sPsi , -sPhi * sPsi + cPhi * cTheta * cPsi , -sTheta * cPhi }, + { sTheta * sPsi , sTheta * cPsi , cTheta } + }; + + // Apply rotation + for (size_t row = 0; row < 3; row++) { + for (size_t col = 0; col < 3; col++) { + result[row] += result[col] * rotationMatrix[row][col]; } } - return newVector; -} - - -/* - * Returns the unit vector in the direction of the given vector - * - * - * @return Unit vector of input - */ -Vector3d Vector3d::UnitVector() { - - Vector3d newVector = (*this)/(*this).Magnitude(); - - return newVector; -} - - -/////////////////////////////////////////////////////////// -// -// Linear Algebra Functions -// -/////////////////////////////////////////////////////////// -namespace linalg { - - /* - * Calculate the standard dot product of two vectors - * - * - * @param [IN] a first vector - * @param [IN] b second vector - * @return dot product - */ - double dot(const Vector3d& p_a, const Vector3d& p_b) { - - double c = 0; - for (size_t i=0; i<3; i++) { - c += p_a[i] * p_b[i]; - } - return c; - } - - - /* - * Calculate the standard cross product of two vectors - * - * - * @param [IN] a first vector - * @param [IN] b second vector - * @return cross product - */ - Vector3d cross(const Vector3d& p_a, const Vector3d& p_b) { - - Vector3d c = Vector3d(0, 0, 0); - - c[0] = p_a[1] * p_b[2] - p_a[2] * p_b[1]; - c[1] = p_a[2] * p_b[0] - p_a[0] * p_b[2]; - c[2] = p_a[0] * p_b[1] - p_a[1] * p_b[0]; - - return c; - } + return result; - /* - * Calculate the angle between two vectors. - * - * - * @param [IN] a first vector - * @param [IN] b second vector - * @return angle between them, in radians - */ - double angleBetween(const Vector3d& p_a, const Vector3d& p_b) { - // Angle between 2 vectors, between [0, pi] - return std::acos(linalg::dot(p_a, p_b) / (p_a.Magnitude() * p_b.Magnitude())); - } +#undef cTheta +#undef cPhi +#undef cPsi +#undef sTheta +#undef sPhi +#undef sPsi } - diff --git a/src/vector3d.h b/src/vector3d.h index 78bb291c3..8149f6d81 100644 --- a/src/vector3d.h +++ b/src/vector3d.h @@ -2,75 +2,111 @@ #define __vector3d_h__ #include "constants.h" +#include "errors.h" #include #include -/////////////////////////////////////////////////////////// -// -// Vector3d object -// -/////////////////////////////////////////////////////////// class Vector3d { public: - // constructors & initializers + // constructors Vector3d(); - Vector3d(const double p_x, - const double p_y, - const double p_z); - Vector3d(DBL_VECTOR p_v); - - // object identifiers - all classes have these - OBJECT_ID ObjectId() { return m_ObjectId; } // object id for vectors - ordinal value from enum - OBJECT_TYPE ObjectType() { return OBJECT_TYPE::NONE; } // object type for vectors - always "NONE" - STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // stellar type for vectors - always "NONE" + Vector3d(const double p_x, const double p_y, const double p_z); + Vector3d(DBL_VECTOR p_Vec); // destructor virtual ~Vector3d() {} + + // object identifiers - all classes have these + OBJECT_ID ObjectId() { return m_ObjectId; } // object id for vectors - ordinal value from enum + OBJECT_TYPE ObjectType() { return OBJECT_TYPE::NONE; } // object type for vectors - always "NONE" + OBJECT_PERSISTENCE ObjectPersistence() { return OBJECT_PERSISTENCE::PERMANENT; } // object persistence for vectors - always "PERMANENT" + STELLAR_TYPE StellarType() { return STELLAR_TYPE::NONE; } // stellar type for vectors - always "NONE" + + // getters double xValue() const { return m_x; } double yValue() const { return m_y; } double zValue() const { return m_z; } - double Magnitude() const; - - DBL_VECTOR asDBL_VECTOR(); + double Magnitude() const { return std::sqrt(Dot((*this), (*this))); } + DBL_VECTOR asDBL_VECTOR() const { return { (*this)[0], (*this)[1] , (*this)[2]} ; } + + // Operator overloads + double operator [] (const size_t p_i) const { return (*const_cast(this))[p_i]; } + double& operator [] (const size_t p_i) { + + // check that supplied index is in range. + // if index is not in range, issue a warning and use index modulo 3 + size_t index = p_i; + if (index > 2) { + SHOW_WARN(ERROR::INDEX_OUT_OF_RANGE, "Using index modulo 3"); // index out of range + index %= 3; // use index modulo 3 + } + + if (index == 1) return m_x; + else if (index == 2) return m_y; + else return m_z; + } + + void operator = (const Vector3d p_Vec) { UpdateVector(p_Vec[0], p_Vec[1], p_Vec[2]); } + + void operator += (const Vector3d p_Vec) { (*this) = (*this) + p_Vec; } + + Vector3d operator + (const Vector3d p_Vec) { + Vector3d vec; + for (size_t i=0; i<3; i++) vec[i] = (*this)[i] + p_Vec[i]; + return vec; + } - // member functions - Vector3d RotateVector( const double p_ThetaE, - const double p_PhiE, - const double p_PsiE); - Vector3d UnitVector(); - - // Overload operators + Vector3d operator - (const Vector3d p_Vec) { + Vector3d vec; + for (size_t i = 0; i < 3; i++) vec[i] = (*this)[i] - p_Vec[i]; + return vec; + } - // Overload Indexing operator - double& operator[] (size_t p_i); - double operator[] (size_t p_i) const { return (*const_cast(this))[p_i]; } - - // Overload setting operator - void operator =(Vector3d p_NewVec); + Vector3d operator * (const double p_Scalar) { // for Vector3d * scalar + Vector3d vec; + for (size_t i = 0; i < 3; i++) vec[i] = (*this)[i] * p_Scalar; + return vec; + } + friend Vector3d operator * (const double p_Scalar, Vector3d p_Vec) { return p_Vec * p_Scalar; }; // for scalar * Vector3d - // Overload += setting vector - void operator +=(Vector3d p_Vec) { (*this) = (*this) + p_Vec; } + Vector3d operator / (const double p_Scalar) { // for Vector3d / scalar + Vector3d vec; + for (size_t i = 0; i < 3; i++) vec[i] = (*this)[i] / p_Scalar; + return vec; + } + + friend std::ostream &operator << (std::ostream &p_os, Vector3d const p_Vec) { return p_os << "{" << p_Vec[0] << ", " << p_Vec[1] << ", " << p_Vec[2] << "}"; } - // Overload vector addition operator - Vector3d operator +(Vector3d p_Vec); - - // Overload vector subtraction operator - Vector3d operator -(Vector3d p_Vec); - - // Overload scalar multiplication operator (only works as v*s, see below for s*v) - Vector3d operator *(const double p_Scalar); - // Overload scalar division operator - Vector3d operator /(const double p_Scalar); + // member functions + Vector3d RotateVector(const double p_ThetaE, const double p_PhiE, const double p_PsiE); + static double AngleBetween(const Vector3d& p_Vec1, const Vector3d& p_Vec2) { return std::acos(Dot(p_Vec1, p_Vec2) / (p_Vec1.Magnitude() * p_Vec2.Magnitude())); } + static Vector3d Cross(const Vector3d& p_a, const Vector3d& p_b) { + Vector3d result = Vector3d(0.0, 0.0, 0.0); + result[0] = p_a[1] * p_b[2] - p_a[2] * p_b[1]; + result[1] = p_a[2] * p_b[0] - p_a[0] * p_b[2]; + result[2] = p_a[0] * p_b[1] - p_a[1] * p_b[0]; + + return result; + } + + static double Dot(const Vector3d& p_Vec1, const Vector3d& p_Vec2) { + double result = 0.0; + for (size_t i = 0; i < 3; i++) result += p_Vec1[i] * p_Vec2[i]; + return result; + } + + Vector3d UnitVector() { return (*this) / (*this).Magnitude(); } + protected: @@ -81,32 +117,9 @@ class Vector3d { double m_y; double m_z; + // member functions - void UpdateVector(const double p_x, const double p_y, const double p_z); + void UpdateVector(const double p_x, const double p_y, const double p_z) { m_x = p_x; m_y = p_y; m_z = p_z; } }; -// Free functions, -// Overload * with reversed order of inputs -Vector3d operator *(double p_Scalar, Vector3d p_Vec); - -// Overload output << operator for Vector3d -std::ostream &operator <<(std::ostream &os, Vector3d const p_Vec); - - - -/////////////////////////////////////////////////////////// -// -// Linear Algebra Functions -// -/////////////////////////////////////////////////////////// - -namespace linalg { - - double dot(const Vector3d& p_a, const Vector3d& p_b); - - Vector3d cross(const Vector3d& p_a, const Vector3d& p_b); - - double angleBetween(const Vector3d& p_a, const Vector3d& p_b); -} - #endif // __vector3d_h__ From 56457394529cfb55c1cab4df3f7f193fddc19771 Mon Sep 17 00:00:00 2001 From: Jeff Riley Date: Sun, 14 Apr 2024 21:12:10 +1000 Subject: [PATCH 2/3] Remove diagnostics etc. --- src/BaseStar.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/BaseStar.h b/src/BaseStar.h index 99ce0d9c4..2afecdd2d 100644 --- a/src/BaseStar.h +++ b/src/BaseStar.h @@ -14,12 +14,6 @@ #include "Log.h" #include "Errors.h" -#include - -#include -#include -#include - class MainSequence; class BaseStar { From 3f0af9fd449dab7f27d1df29dcfa537c912c8f3e Mon Sep 17 00:00:00 2001 From: Jeff Riley Date: Sun, 14 Apr 2024 22:22:47 +1000 Subject: [PATCH 3/3] Fix typos; cleanup --- src/changelog.h | 2 +- src/vector3d.cpp | 1 + src/vector3d.h | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/changelog.h b/src/changelog.h index bdc6b9fcb..e9d3b370a 100644 --- a/src/changelog.h +++ b/src/changelog.h @@ -1118,7 +1118,7 @@ // 02.43.01 SS - Apr 8, 2024 - Defect repair // - Fix CalculateMassLossRateBjorklundEddingtonFactor to use LSOLW (in SI) rather than LSOL (in cgs) // 02.43.02 JR - Apr 14, 2024 - Defect repair, some code cleanup: -// - Defect repair: Issue #1084 - modified code to record desired persistence of obejcts so that cloned stars don't participate in logging etc. +// - Defect repair: Issue #1084 - modified code to record desired persistence of objects so that cloned stars don't participate in logging etc. // - Removed some unused code (as a result of the defect repair) // - Some Code cleanup diff --git a/src/vector3d.cpp b/src/vector3d.cpp index ddc347284..a42f22de3 100644 --- a/src/vector3d.cpp +++ b/src/vector3d.cpp @@ -1,5 +1,6 @@ #include #include + #include "vector3d.h" #include "constants.h" diff --git a/src/vector3d.h b/src/vector3d.h index f82e4757a..6ad54b3a6 100644 --- a/src/vector3d.h +++ b/src/vector3d.h @@ -1,11 +1,12 @@ #ifndef __vector3d_h__ #define __vector3d_h__ -#include "constants.h" -#include "errors.h" #include #include +#include "constants.h" +#include "Errors.h" + class Vector3d {