Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 311c757da1fd
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a834b4b1d49c
Choose a head ref
  • 15 commits
  • 8 files changed
  • 1 contributor

Commits on Jan 5, 2020

  1. A new class

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    920df46 View commit details
  2. com

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    d0cd42e View commit details
  3. A test

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    bbb21b3 View commit details
  4. test all accessors

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    2e94313 View commit details
  5. eggrobin committed Jan 5, 2020
    Copy the full SHA
    c123028 View commit details
  6. energy

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    e882f74 View commit details
  7. another test

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    88bb996 View commit details
  8. iwyu

    eggrobin committed Jan 5, 2020
    Copy the full SHA
    6d5b1da View commit details

Commits on Jan 18, 2020

  1. Copy the full SHA
    dfdf8ce View commit details
  2. Copy the full SHA
    f40dfa7 View commit details
  3. Copy the full SHA
    c221d40 View commit details
  4. lint

    eggrobin committed Jan 18, 2020
    Copy the full SHA
    b13bc68 View commit details

Commits on Jan 19, 2020

  1. after pleroy's review

    eggrobin committed Jan 19, 2020
    Copy the full SHA
    73d833d View commit details
  2. comment

    eggrobin committed Jan 19, 2020
    Copy the full SHA
    0056712 View commit details
  3. Merge pull request #2435 from eggrobin/closed-system

    Closed system
    eggrobin authored Jan 19, 2020
    Copy the full SHA
    a834b4b View commit details
3 changes: 3 additions & 0 deletions geometry/r3x3_matrix.hpp
Original file line number Diff line number Diff line change
@@ -29,10 +29,13 @@ using quantities::Quotient;
template<typename Scalar>
class R3x3Matrix final {
public:
R3x3Matrix() = default;
R3x3Matrix(R3Element<Scalar> const& row_x,
R3Element<Scalar> const& row_y,
R3Element<Scalar> const& row_z);

static R3x3Matrix Diagonal(R3Element<Scalar> const& diagonal);

Scalar Trace() const;
Cube<Scalar> Determinant() const;
R3x3Matrix Transpose() const;
10 changes: 10 additions & 0 deletions geometry/r3x3_matrix_body.hpp
Original file line number Diff line number Diff line change
@@ -23,6 +23,16 @@ R3x3Matrix<Scalar>::R3x3Matrix(R3Element<Scalar> const& row_x,
R3Element<Scalar> const& row_z)
: row_x_(row_x), row_y_(row_y), row_z_(row_z) {}

template<typename Scalar>
R3x3Matrix<Scalar> R3x3Matrix<Scalar>::Diagonal(
R3Element<Scalar> const& diagonal) {
return {
{diagonal.x, {}, {}},
{{}, diagonal.y, {}},
{{}, {}, diagonal.z},
};
}

template<typename Scalar>
Scalar R3x3Matrix<Scalar>::Trace() const {
return row_x_.x + row_y_.y + row_z_.z;
1 change: 1 addition & 0 deletions geometry/symmetric_bilinear_form.hpp
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ template<typename Scalar,
template<typename, typename> typename Multivector>
class SymmetricBilinearForm {
public:
SymmetricBilinearForm() = default;
explicit SymmetricBilinearForm(R3x3Matrix<Scalar> const& matrix);
explicit SymmetricBilinearForm(R3x3Matrix<Scalar>&& matrix);

101 changes: 101 additions & 0 deletions physics/closed_system.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#pragma once

#include <optional>
#include <utility>
#include <vector>

#include "physics/inertia_tensor.hpp"
#include "physics/rigid_motion.hpp"

namespace principia {
namespace physics {
namespace internal_closed_system {

using geometry::BarycentreCalculator;
using geometry::Bivector;
using geometry::Frame;
using geometry::OrthogonalMap;
using geometry::SymmetricBilinearForm;
using geometry::Vector;
using quantities::AngularMomentum;
using quantities::Mass;
using quantities::MomentOfInertia;

// Computes the instantaneous overall properties of a mechanical system.
// Effectively an extension of
// |BarycentreCalculator<DegreesOfFreedom<InertialFrame>, Mass>| that also
// handles rotational motion.
// |InertialFrame| is an inertial frame in which the motion of the member bodies
// is given; |SystemFrame| is a non-rotating frame with the same axes as
// |InertialFrame| and whose origin is the centre of mass of the system.
template<typename InertialFrame, typename SystemFrame>
class ClosedSystem {
public:
static_assert(InertialFrame::is_inertial);

ClosedSystem() = default;

template<typename BodyFrame>
void AddRigidBody(
RigidMotion<BodyFrame, InertialFrame> const& motion,
Mass const& mass,
SymmetricBilinearForm<MomentOfInertia, BodyFrame, Bivector> const&
inertia_tensor);

// The motion of a non-rotating frame whose origin is the centre of mass of
// the system, and whose axes are those of |InertialFrame|.
RigidMotion<SystemFrame, InertialFrame> LinearMotion() const;
// The total mass.
Mass const& mass() const;
// The total angular momentum of the system, with respect to the origin of
// |SystemFrame|, i.e., the centre of mass of the system.
Bivector<AngularMomentum, SystemFrame> AngularMomentum() const;
// The moments of inertia of the system, with respect to the origin of
// |SystemFrame|, i.e., the centre of mass of the system.
SymmetricBilinearForm<MomentOfInertia, SystemFrame, Bivector> InertiaTensor()
const;

private:
BarycentreCalculator<DegreesOfFreedom<InertialFrame>, Mass> centre_of_mass_;
std::vector<std::pair<DegreesOfFreedom<InertialFrame>, Mass>>
body_linear_motions_;
// The sum of the intrinsic angular momenta of the bodies, i.e., of the
// angular momenta with respect to their individual centres of mass. This is
// not the total angular momentum, to which the linear motions of the bodies
// with respect to the centre of mass of the system also contribute.
Bivector<quantities::AngularMomentum, InertialFrame>
sum_of_intrinsic_angular_momenta_;
// The sum of the inertia tensors of the bodies with respect to their
// individual centres of mass. This is not the inertia tensor of the system
// unless all bodies are at the same location, as their point masses also
// contribute to the overall inertia.
//
// Note: It is more natural to manipulate the inertia tensor as a
// |SymmetricBilinearForm<MomentOfInertia, Frame, Vector>| than a
// |SymmetricBilinearForm<MomentOfInertia, Frame, Bivector>|.
// The former has coordinates
// ⎛ ∑x² ∑xy ∑xy ⎞
// ⎜ ∑yx ∑y² ∑yz ⎟
// ⎝ ∑zx ∑zy ∑z² ⎠
// whereas the latter (obtained from the former by |Anticommutator()| has the
// coordinates
// ⎛ ∑(y² + z²) -∑xy -∑xy ⎞
// ⎜ -∑yx ∑(x² + z²) -∑yz ⎟
// ⎝ -∑zx -∑zy ∑(x² + y²) ⎠
// It is however common practice in physics to use the bilinear form on
// bivectors, and to call its eigenvalues the principal moments of inertia.
// This class thus exposes the form on bivectors in its API, and uses
// |AnticommutatorInverse()| and |Anticommutator()| to convert between it and
// the form on vectors used internally.
SymmetricBilinearForm<MomentOfInertia, InertialFrame, Vector>
sum_of_inertia_tensors_;
};

} // namespace internal_closed_system

using internal_closed_system::ClosedSystem;

} // namespace physics
} // namespace principia

#include "physics/closed_system_body.hpp"
96 changes: 96 additions & 0 deletions physics/closed_system_body.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#pragma once

#include "physics/closed_system.hpp"

namespace principia {
namespace physics {
namespace internal_closed_system {

using geometry::Displacement;
using geometry::OrthogonalMap;
using geometry::SymmetricProduct;
using geometry::Vector;
using geometry::Velocity;
using geometry::Wedge;
using physics::Anticommutator;
using quantities::Momentum;
using quantities::si::Radian;

template<typename InertialFrame, typename SystemFrame>
template<typename BodyFrame>
void ClosedSystem<InertialFrame, SystemFrame>::AddRigidBody(
RigidMotion<BodyFrame, InertialFrame> const& motion,
Mass const& mass,
SymmetricBilinearForm<MomentOfInertia, BodyFrame, Bivector> const&
inertia_tensor) {
DegreesOfFreedom<InertialFrame> const degrees_of_freedom =
motion({BodyFrame::origin, BodyFrame::unmoving});
SymmetricBilinearForm<MomentOfInertia, InertialFrame, Vector> const
inertia_tensor_in_inertial_axes =
motion.orthogonal_map()(inertia_tensor.AnticommutatorInverse());
centre_of_mass_.Add(degrees_of_freedom, mass);
body_linear_motions_.emplace_back(degrees_of_freedom, mass);
sum_of_inertia_tensors_ += inertia_tensor_in_inertial_axes;
sum_of_intrinsic_angular_momenta_ +=
Anticommutator(inertia_tensor_in_inertial_axes,
motion.Inverse().angular_velocity_of_to_frame());
}

template<typename InertialFrame, typename SystemFrame>
RigidMotion<SystemFrame, InertialFrame>
ClosedSystem<InertialFrame, SystemFrame>::LinearMotion() const {
DegreesOfFreedom<InertialFrame> const centre_of_mass = centre_of_mass_.Get();
return RigidMotion<SystemFrame, InertialFrame>(
RigidTransformation<SystemFrame, InertialFrame>(
SystemFrame::origin,
centre_of_mass.position(),
OrthogonalMap<SystemFrame, InertialFrame>::Identity()),
InertialFrame::nonrotating,
centre_of_mass.velocity());
}

template<typename InertialFrame, typename SystemFrame>
Mass const& ClosedSystem<InertialFrame, SystemFrame>::mass() const {
return centre_of_mass_.weight();
}

template<typename InertialFrame, typename SystemFrame>
Bivector<AngularMomentum, SystemFrame>
ClosedSystem<InertialFrame, SystemFrame>::AngularMomentum() const {
RigidMotion<InertialFrame, SystemFrame> const to_system_frame =
LinearMotion().Inverse();
Bivector<quantities::AngularMomentum, SystemFrame> result =
to_system_frame.orthogonal_map()(sum_of_intrinsic_angular_momenta_);
for (auto const& [degrees_of_freedom, m] : body_linear_motions_) {
DegreesOfFreedom<SystemFrame> const degrees_of_freedom_in_system_frame =
to_system_frame(degrees_of_freedom);
Displacement<SystemFrame> const r =
degrees_of_freedom_in_system_frame.position() - SystemFrame::origin;
Velocity<SystemFrame> const v =
degrees_of_freedom_in_system_frame.velocity();
Vector<Momentum, SystemFrame> const p = m * v;
result += Wedge(r, p) * Radian;
}
return result;
}

template<typename InertialFrame, typename SystemFrame>
SymmetricBilinearForm<MomentOfInertia, SystemFrame, Bivector>
ClosedSystem<InertialFrame, SystemFrame>::InertiaTensor() const {
RigidMotion<InertialFrame, SystemFrame> const to_system_frame =
LinearMotion().Inverse();
SymmetricBilinearForm<MomentOfInertia, SystemFrame, Vector> result =
to_system_frame.orthogonal_map()(sum_of_inertia_tensors_);
for (auto const& [degrees_of_freedom, m] : body_linear_motions_) {
DegreesOfFreedom<SystemFrame> const degrees_of_freedom_in_system_frame =
to_system_frame(degrees_of_freedom);
Displacement<SystemFrame> const r =
degrees_of_freedom_in_system_frame.position() - SystemFrame::origin;
result += m * SymmetricProduct(r, r);
}
return result.Anticommutator();
}

} // namespace internal_closed_system
} // namespace physics
} // namespace principia
Loading