/**
 * Scale a vector,
 * prod[i] = vec[i] * scalar
 * @return Scaled vector
 * \param[in] vec Source vector
 * \param[in] scalar Scalar
 * \param[out] prod Scaled vector
 */


/**
 * Negate vector in-place,
 * vec[i] = -vec[i]
 * @return Negated vector
 * \param[in,out] vec Vector
 */


/**
 * Negate vector,
 * copy[i] = -vec[i]
 * @return Negated vector
 * \param[in] vec Source vector
 * \param[out] copy Negated vector
 */


/**
 * Transform a column vector,
 * prod[i] = tmat[i][j]*vec[j]
 * @return Transformed vector
 * \param[in] tmat Transformation matrix
 * \param[in] vec Source vector
 * \param[out] prod Transformed vector
 */


/**
 * Transform a column vector in-place,
 * vec[i] <- tmat[i][j]*vec[j]
 * @return Transformed vector
 * \param[in] tmat Transformation matrix
 * \param[in,out] vec Transformed vector
 */


/**
 * Transform a column vector with the transpose,
 * prod[i] = tmat[j][i]*vec[j]
 * @return Transformed vector
 * \param[in] tmat Transformation matrix
 * \param[in] vec Source vector
 * \param[out] prod Transformed vector
 */


/**
 * Transform a column vector in-place with the transpose,
 * vec[i] <- tmat[j][i]*vec[j]
 * @return Transformed vector
 * \param[in] tmat Transformation matrix
 * \param[in,out] vec Transformed vector
 */


/**
 * Increment a vector,
 * vec[i] += addend[i]
 * @return Incremented vector
 * \param[in] addend Increment
 * \param[in,out] vec Vector
 */


/**
 * Increment a vector,
 * vec[i] += addend1[i] + addend2[i]
 * @return Incremented vector
 * \param[in] addend1 Increment
 * \param[in] addend2 Increment
 * \param[in,out] vec Vector
 */


/**
 * Decrement a vector,
 * vec[i] -= subtrahend[i]
 * @return Decremented vector
 * \param[in] subtrahend Decrement
 * \param[in,out] vec Vector
 */


/**
 * Decrement a vector,
 * vec[i] -= subtrahend1[i] + subtrahend2[i]
 * @return Decremented vector
 * \param[in] subtrahend1 Decrement
 * \param[in] subtrahend2 Decrement
 * \param[in,out] vec Vector
 */


/**
 * Compute the sum of two vectors,
 * vec[i] = addend1[i] + addend2[i]
 * @return Sum vector
 * \param[in] addend1 Addend
 * \param[in] addend2 Addend
 * \param[out] vec Sum vector
 */


/**
 * Compute the sum of three vectors,
 * vec[i] = addend1[i] + addend2[i] + addend3[i]
 * @return Sum vector
 * \param[in] addend1 Addend
 * \param[in] addend2 Addend
 * \param[in] addend3 Addend
 * \param[out] vec Sum vector
 */


/**
 * Compute the difference between two vectors,
 * diff[i] = minuend[i] - subtrehend[i]
 * @return Difference vector
 * \param[in] minuend Minuend
 * \param[in] subtrahend Subtrahend
 * \param[out] vec Difference vector
 */


/**
 * Compute the cross product between two vectors,
 * prod[i] = epsilon_ijk * vec_left[j] * vec_right[k]
 * @return Cross product vector
 * \param[in] vec_left Left vector
 * \param[in] vec_right Right vector
 * \param[out] prod Cross product vector
 */


/**
 * Increment a vector with a scaled vector,
 * prod[i] += scalar*vec[i]
 * @return Incremented vector
 * \param[in] vec Source vector
 * \param[in] scalar Scalar
 * \param[in,out] prod Incremented vector
 */


/**
 * Decrement a vector with a scaled vector,
 * prod[i] += scalar*vec[i]
 * @return Decremented vector
 * \param[in] vec Source vector
 * \param[in] scalar Scalar
 * \param[in,out] prod Decremented vector
 */


/**
 * Increment a vector with the the cross product between two vectors,
 * prod[i] += epsilon_ijk * vec_left[j] * vec_right[k]
 * @return Cross product vector
 * \param[in] vec_left Left vector
 * \param[in] vec_right Right vector
 * \param[in,out] prod Cross product vector
 */


/**
 * Decrement a vector with the the cross product between two vectors,
 * prod[i] -= epsilon_ijk * vec_left[j] * vec_right[k]
 * @return Decremented vector
 * \param[in] vec_left Left vector
 * \param[in] vec_right Right vector
 * \param[in,out] prod Decremented vector
 */


/**
 * Increment a vector with a transformed column vector,
 * prod[i] += tmat[i][j]*vec[j]
 * @return Incremented vector
 * \param[in] tmat Transformation matrix
 * \param[in] vec Source vector
 * \param[in,out] prod Incremented vector
 */


/**
 * Decrement a vector with a transformed column vector,
 * prod[i] += tmat[i][j]*vec[j]
 * @return Decremented vector
 * \param[in] tmat Transformation matrix
 * \param[in] vec Source vector
 * \param[in,out] prod Decremented vector
 */


/**
 * Increment a vector with a transpose-transformed column vector,
 * prod[i] += tmat[j][i]*vec[j]
 * @return Incremented vector
 * \param[in] tmat Transformation matrix
 * \param[in] vec Source vector
 * \param[in,out] prod Incremented vector
 */


/**
 * decrement a vector with a transpose-transformed column vector,
 * prod[i] -= tmat[j][i]*vec[j]
 * @return Decremented vector
 * \param[in] tmat Transformation matrix
 * \param[in] vec Source vector
 * \param[in,out] prod Decremented vector
 */


/**
     * Trigger that the pendulum should be set to its quiescent vertical state,
     */


/**
     * Default constructor.
     * Constructs a DynBodyPendulumConstraint modeled by the supplied model.
     * @param pendulum_model  Pointer to the object that models pendulum
     * parameters. The default null pointer should only be used for
     * for simulation checkpoint/restart.
     */


/**
     * Update information about the relation between this constraint
     * and the root DynBody.
     * @param vehicle_properties  Various vehicle properties.
     */


/**
     * Clear the solver for this constraint.
     */


// Dependencies:
// The constraint direction and position wrt the root structure frame
// and position wrt the root CoM must be correct.


// Get the constraint matrix element that pertains to this constrained
// object with respect to some other constrained object.


// Public non-default constructor.


// Private non-default constructor.


// Add the specified constraint to the vector of registered constraints.


// Remove the specified constraint from the vector of registered constraints.


// Remove the specified constraint from all constraints vectors.


// Add the specified constraint to the vector of active constraints.


// Remove the specified constraint from the vector of active constraints.


// Add the collect_constraints to the object's vector of constraints.


// Compute root-to-this transform and offset.


// Construct A and b in the system of equations A*x=b, where
//  - A is the matrix of partial derivatives, dx_i/dx_j,
//  - x is the vector of constraint values (not referenced here), and
//  - b is the vector of right hand side values.


// Send the solution to the constraint equation to the constraints.


// Compute the total of the get_wrench calls and the vehicle's response to it.


// Compute each constrained object's response to the total constraint wrench.


// Save the input direction and transform to the root structural frame.


// Transform the constraint direction to the root structural frame.


// Compute the vehicle's rotation acceleration in response to a torque:
// \dot{\omega} = T_{struct->body}^T (I^{-1} (T_{struct->body} torque))


// Compute the root-to-this transformation and offset given
// that the associate dyn body has attached / reattached / detached
// to / from some parent dyn body.


// Mark the constraint as inactive.


// Set the constraint matrix elements that pertain to this constrained
// object with respect to some other constrained object.


// Mark the constraint as active.


/**
     * Non-default constructor.
     * @note This can create a zero-sized view.
     * @param array_in  The 2D array that underlies this view.
     * @param row_range  A begin, end pair that denote the extent of the
     *   rows in this view.
     *   The begin value corresponds to this view's zeroth element.
     *   The end value is one past the last element indexed by this view.
     *   To be valid, the end value must not be less than the begin value
     *   and must not be greater than the underlying vector's size.
     * @param col_in  The column of the array to be represented by this view.
     *   This must reference a valid column of the underlying array.
     * @throw std::out_of_range if the range is invalid.
     */


/**
     * Create a view to a portion of the A matrix.
     */


/**
     * Non-default constructor.
     * @param array_in   The array for which a view is to be constructed.
     * @param row_range  The topmost and bottommost row of the view, plus one.
     * @param col_range  The leftmost and rightmost column of the view, plus one.
     * @throw std::out_of_range if sub-array bounds are invalid.
     */


/**
     * Non-default constructor.
     * @param array_in   The array for which a view is to be constructed.
     * @param beg_row_in  The topmost row of the view.
     * @param end_row_in  The bottommost row of the view, plus one.
     * @param beg_col_in  The leftmost column of the view.
     * @param end_col_in  The rightmost column of the view, plus one.
     * @throw std::out_of_range if sub-array bounds are invalid.
     */


/**
     * Reserve storage for at least max_elems_in elements.
     * @param max_elems_in  Amount of storage to be reserved.
     */


/**
     * Resize the array to nrows_in by n_cols_in.
     * @param n_rows_in  The number of rows in the array.
     * @param n_cols_in  The number of columns in the array.
     */


/**
     * Create a 2D view into the array.
     * Note: the end row and end column are one past the end,
     * consistent with c++ iterators and ranges.
     * @param row_range  Rows at which view begins and ends.
     * @param col_range  Columns at which view begins and ends.
     */


/**
     * Safe (bounds-checked) index operator.
     * @param i_elem Element to be indexed.
     * @return Reference to the indexed value.
     * @throw std::out_of_range if index is outside the range of the view.
     */


/**
     * Non-default constructor.
     * @param obj_in  The object that underlies this view.
     * @param range  A begin, end pair that denote the extent of the view.
     *   The begin value corresponds to this view's zeroth element.
     *   The end value is one past the last element indexed by this view.
     *   To be valid, the end value must not be less than the begin value
     *   and must not be greater than the underlying vector's size.
     * @throw std::out_of_range if the range is invalid.
     */


/**
     * Non-default constructor.
     * @note This can create a zero-sized view.
     * @param array_in  The 2D array that underlies this view.
     * @param row_in  The row of the array to be represented by this view.
     *   This must reference a valid row of the underlying array.
     * @param col_range  A begin, end pair that denote the extent of the
     *   columns in this view.
     *   The begin value corresponds to this view's zeroth element.
     *   The end value is one past the last element indexed by this view.
     *   To be valid, the end value must not be less than the begin value
     *   and must not be greater than the underlying vector's size.
     * @throw std::out_of_range if the range is invalid.
     */


/**
     * Non-default constructor.
     * @param n_rows_in  The number of rows in the view.
     * @param n_cols_in  The number of columns in the view.
     */


/**
     * Non-const safe (bounds-checked) index operator.
     * @param i_row Row number of element to be indexed.
     * @param i_col Column number of element to be indexed.
     * @return Reference to the indexed value.
     * @throw std::out_of_range if index is outside the range of the view.
     */


// This file defines:
// - Four non-template overloads of fail_simulation, which serve as base cases.
// - Three overloads of fail_simulation_helper_, which should be treated as private.
// - A variadic version of fail_simulation.
// The basic idea is to support everything from fail_simulation(__FILE__, __LINE__)
// to fail_simulation(__FILE__, __LINE__, just, about, anything, that, prints)


/**
 * Destruct a LvlhDerivedState object.
 */


/**
 * Begin initialization of a LvlhDerivedState.
 * The initialize method for all subclasses of DerivedState *nust* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Destruct a RelativeDerivedState object.
 */


/**
 * Begin initialization of a RelativeDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Initialize a RelativeDerivedState, without a DynBody. No pass up
 * the initialization chain is possible for this method, since it
 * is not inherited.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Setter for the activation flag to on or off and
 * If off, unsubscribes subject and target frames
 * /param raf  RelativeDerivedState activation flag
 * for RelKin manager
 */


/**
 * Begin initialization of a SolarBetaDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Destruct a SolarBetaDerivedState.
 */


/**
 * Begin initialization of a DerivedState.
 * The initialize method for all subclasses of DerivedState *nust* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 *
 * \par Assumptions and Limitations
 *  - g++ is being used as the compiler
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Find the Planet with the given name, failing if not found.
 * @return Found Planet
 * \param[in] dyn_manager Dynamics manager
 * \param[in] planet_name Planet name
 * \param[in] variable_name For error reporting
 */


/**
 * Begin initialization of an LvlhRelativeDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Convert from rectilinear LVLH coordinates to circular curvilinear.
 * \param[in] rect_rel_state Source state
 */


/**
 * Convert from circular curvilinear LVLH coordinates to rectilinear.
 * \param[in] curvi_rel_state Source state
 */


/**
 * Compute thetadot correction to omega.
 */


/**
 * Destruct a OrbElemDerivedState object.
 */


/**
 * Begin initialization of a OrbElemDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Compute the orbital elements for the current state.
 * \param[in] rel_trans Planet relative state.
 */


/**
 * Destruct a PlanetaryDerivedState object.
 */


/**
 * Begin initialization of a PlanetaryDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Begin initialization of a LvlhDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Update the state.
 * \param[in] rel_trans Planet relative state
 */


/**
 * Destruct a EulerDerivedState object.
 */


/**
 * Begin initialization of a EulerDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] subject_body Subject body.
 * \param[in,out] dyn_manager Dynamics manager.
 */


/**
 * Begin initialization of a EulerDerivedState.
 * The initialize method for all subclasses of DerivedState *must* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in] ref_frame Reference frame for angles.
 * \param[in,out] subject_body Subject body.
 * \param[in,out] dyn_manager Dynamics manager.
 */


/**
 * Compute the Euler angles.
 *
 * \par Assumptions and Limitations
 *  - Depends upon the Trick Euler angle math macros and routines.
 */


// Find the projection (proj and perpendicular (perp) of v relative to unit u


/**
 * Initialize the initializer.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Apply the initializer: Construct the reference LVLH frame so the
 * parent initializer can compute the vehicle's state relative to the
 * vehicle's inertial frame.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Initialize the core mass properties of the subject MassBody.
 * \param[in,out] dyn_manager Jeod manager
 */


/**
 * Indicate whether the initializer is ready to run.
 * This particular implementation is just a pass-through.
 * @return Is initializer ready?
 */


/**
 * Apply the initializer.
 * This is just a pass-through.
 * Some derived class must do the actual work.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Apply the initializer.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Ensure that a string is not trivially invalid.
 * \param[in] variable_value String to be checked
 * \param[in] variable_name For error reporting
 * \param[in] variable_type For error reporting
 */


/**
 * Allocate points.
 * \param[in] num_points number of additional points to be allocated.
 */


/**
 * Access a point in the vector.
 * \param[in] index the index of the point in the vector.
 */


/**
 * Indicate what parts of the vehicle state this object initializes.
 * This is depends on the state specified by the user: Both=position and
 * velocity, Position=position, Velocity=velocity.
 * @return States initialized
 */


/**
 * Indicate whether this initializer is ready to be applied.
 * The full state of the reference reference frame must be known
 * to compute the position and velocity of the subject reference frame.
 * @return Is initializer ready?
 */


/**
 * Initialize aspects of this object and forward the initializer
 * to the immediate parent class.
 * This class needs no initialization per se.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Indicate what parts of the vehicle state this object initializes.
 * This is depends on the state specified by the user: Both=attitude and
 * rate, Attitude=attitude, Rate=rate.
 * @return States initialized
 */


/**
 * Indicate whether this initializer is ready to be applied.
 * The full rotational state of the reference reference frame must be
 * known to compute the subject reference frame's rotational state.
 * @return Is initializer ready?
 */


/**
 * Detach the body from its parent.
 * \param[in,out] dyn_manager Jeod manager
 */


/**
 * Initialize a MassBodyAttach.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * A derived class presumably has performed the attachment, which may
 * not have worked, and forwarded the apply call to this method.
 * This method acts on the status from that child class attachment.
 * \param[in,out] dyn_manager Jeod manager
 */


/**
 * Initialize a BodyDetachSpecific.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Detach the body from its parent.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * DynBodyInitNedState default constructor.
 */


/**
 * Complete initialization of a DynBodyInit.
 * The initialize method for all subclasses of DynBodyInit *nust* pass
 * the initialize call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * In general, determine if the initializer is ready to be applied.
 * This method determines whether the self-dependencies are satisfied.
 * Dependencies on the reference reference frame are the responsibility
 * of derived classes.
 * @return Can initializer run?
 */


/**
 * Complete initialization of the subject DynBody.
 * The apply method for all subclasses of DynBodyInit *nust* pass
 * the apply call to their immediate parent class, which in turn
 * must do the same, eventually invoking this method.
 * \param[in,out] dyn_manager Jeod manager
 */


/**
 * Report on an initializer that could not be processed.
 */


/**
 * Compute the state wrt the reference reference frame,
 * incorporate the user-input items to this relative state, and
 * compute the state relative to the target frame's parent.
 */


/**
 * This method is obsolete. Use apply_user_inputs instead.
 */


/**
 * Find the DynBody with the given name, failing if not found.
 * @return Found DynBody
 * \param[in] dyn_manager Dynamics manager
 * \param[in] dyn_body_name DynBody name
 * \param[in] variable_name For error reporting
 */


/**
 * Find the RefFrame with the given name, failing if not found.
 * @return Found ref_frame
 * \param[in] dyn_manager Dynamics manager
 * \param[in] ref_frame_name RefFrame name
 * \param[in] variable_name For error reporting
 */


/**
 * Find the RefFrame with the given name, failing if not found.
 * @return Found BodyRefFrame
 * \param[in] frame_container Body containing frame
 * \param[in] body_frame_identifier BodyRefFrame identifier
 * \param[in] variable_name For error reporting
 */


/**
 * Initialization a DynBodyFrameSwitch instance.
 * \param[in,out] dyn_manager Dynamics manager
 */


/**
 * Switch reference frames.
 * \param[in,out] dyn_manager Jeod manager
 */


/**
 * Determine whether it is time to switch frames.
 * A frame-switch action is ready if it is activated and if the
 * vehicle has entered/left the appropriate sphere of influence.
 * @return Can action be applied?
 */


/**
 * Indicate whether the initializer is ready to run.
 * When the state is based on some reference body, that reference
 * vehicle's composite body frame must contain the specified required
 * items before the initializer can run.
 * @return Is initializer ready?
 */


/**
 * Apply the initializer: This is just a pass through.
 * A derived class is responsible for setting the state that the
 * DynBodyInit uses to initialize the state.
 * \param[in,out] dyn_manager Dynamics manager
 */


/*******************************************************************************
Function: PlanetSite::~PlanetSite
Purpose: (PlanetSite destructor.)
*******************************************************************************/


/*******************************************************************************
Function: PlanetSite::initialize
Purpose:  (Initialize a planet site.)
*******************************************************************************/


/**
 * CollectForce constructor that encapsulates a Force.
 * Note that this performs a shallow copy by intent.
 * \param[in,out] source_force Force to encapsulate
 */


/**
 * CollectForce constructor that encapsulates another CollectForce.
 * Note that this performs a shallow copy by intent.
 * \param[in,out] source_force Force to encapsulate
 */


/**
 * Accumulate forces acting on a vehicle.
 *
 * \param[in] vec Forces
 * \param[out] cumulation Accumulated force
 **/


/**
 * Accumulate torques acting on a vehicle.
 *
 * \param[in] vec Torques
 * \param[out] cumulation Accumulated torque
 **/


// Collect forces and torques acting on the vehicle.


// Compute the relative state between the integrated frame's mass point
// and the source frame's mass point.


// Compute a derived state given the source state and the position/
// attitude transformation from the source to the derived state.


// Compute selected aspects of the derived state.


// Compute a derived state given the source state.


// Propagate state to attached bodies.


// Propagate state to attached bodies starting from the structural frame.


// Propagate state to attached bodies starting from the composite frame.


// Propagate structure frame state to vehicle points.


// Prepare the body for initialization.


// Integrate the translational state of a StructureIntegratedDynBody.


// Integrate the rotational state of a StructureIntegratedDynBody.


// Break the logical connectivity between a parent and child DynBody.
// Returns false if unable to disconnect.


// Detach this DynBody from its parent


// Break the logical connectivity between parent DynBody and child submass.


// Remove BodyRefFrame for each MassBody point from vehicle_points recursively


// Update parent and child properties to reflect that they are detached.


// Add a mass point to the dyn body's list of such and
// make a vehicle point that corresponds to the added mass point.


// Find the vehicle point with the given name.


/**
 * Compute the state derivatives at a vehicle point.
 *
 * @param[in] vehicle_pt Vehicle point reference frame
 * @param[out] pt_derivs Computed derivatives
 */


// Set the solver.


// Add a constraint.


// Solve for and apply constraints acting on the vehicle.


// Validate whether the pending attachment is legal from a connectivity
// point of view.


// Validate whether the pending attachment is legal from a physical
// point of view.


/**
 * Validate whether the pending sub body is legal from a mass tree
 * point of view
 *
 * @note Assumptions and Limitations@n
 *  - The subject mass, child, must not belong to a child body.
 *
 * @return Validity indicator
 * @param[in] child The child body; the body to be attached to this body.
 * @param[in] generate_message Generate message if invalid?
 */


/**
 * Attach a child DynBody by point specification. See corresponding
 * DynBody::attach_to() method for more information.
 */


/**
 * Attach a child DynBody by location specification. See corresponding
 * DynBody::attach_to() method for more information. Note that the offset and
 * transformation are specified w.r.t. the parent in both attach_to() and
 * attach_child()
 */


// Attach mass body aligned at specified mass point


// Create BodyRefFrame for each MassBody point and add it to vehicle_points


// Establish the logical connectivity between parent and child.


// Set the relation between parent and child and update the mass
// properties.


// Process the attachment event of one body from another.


// Construct a DynBody.


// Destruct a DynBody.


// Returns the parent of current DynBody's tree.


// Finds & returns root of current DynBody's tree.


// Add a new GravityControls to the list in grav_interaction.


// Initialize the gravity controls of this DynBody.


// Make the frame subscriptions for each control consistent with the
// requirements for that control.


// Sort the controls in increasing acceleration magnitude order.


// Get a pointer to the DynamicsIntegrationGroup that integrates this DynBody.


// Associate an IntegrableObject to be integrated with this DynBody


// Remove an IntegrableObject from this DynBody's list


// Prepare all associated integrable objects associated
// with this dyn body to migrate to a new integration group


// Collect the local forces and torques acting on the vehicle.


// Propagate forces and torques up the kinematic chain.


// Compute the inertial torque.


// Compute the body- and structure-referenced rotational acceleration vectors.


// Compute the inertial-referenced translational acceleration vector.


/**
 * CollectTorque constructor that encapsulates a Torque.
 * Note that this performs a shallow copy by intent.
 * \param[in,out] source_torque Torque to encapsulate
 */


/**
 * CollectTorque constructor that encapsulates another CollectTorque.
 * Note that this performs a shallow copy by intent.
 * \param[in,out] source_torque Torque to encapsulate
 */


// Set the integration frame for this body and all its child bodies.


// Switch to the specified integration frame.


// Switch the integration frame for this body and all its child bodies.


/**
 * Create the translational and rotational integrators for a
 * DynBody. A DynBody integrates forces and torques
 * in the body frame and forces induced by changes in mass properties.
 * @param[in] generator  Integrator constructor to be used to create
 *                       state integrators.
 * @param[in] controls   The integration ontrols created the integrator
 *                       constructor's create_integration_controls method.
 * @param[in] time_mngr  The JEOD time manager object.
 */


/**
 * This interface is required by er7_utils::IntegrableObject. It should not be
 * used. Use DynBody::create_body_integrators instead.
 * @param[in] generator  Unused.
 * @param[in] controls   Unused.
 * @param[in] time_if    Unused.
 */


/**
 * Reset the translational and rotational integrators.
 */


/**
 * Integrate the translational and rotational state and propagate
 * the integrated state to derived states.
 * @param[in]     dyn_dt        Dynamic time step, in dynamic time seconds.
 * @param[in]     target_stage  The stage of the integration process
 *                              that the integrator should try to attain.
 * @return The status (time advance, pass/fail status) of the integration.
 */


/**
 * Integrate the translational state of a DynBody.
 * @param[in]     dyn_dt        Dynamic time step, in dynamic time seconds.
 * @param[in]     target_stage  The stage of the integration process
 *                              that the integrator should try to attain.
 * @return The status (time advance, pass/fail status) of the integration.
 */


/**
 * Integrate the rotational state of a DynBody.
 * @param[in]     dyn_dt        Dynamic time step, in dynamic time seconds.
 * @param[in]     target_stage  The stage of the integration process
 *                              that the integrator should try to attain.
 * @return The status (time advance, pass/fail status) of the integration.
 */


// Find the BodyRefFrame named by the provided identifier.


// Compute the state derivatives at a vehicle point.


/**
 * Check that the dyn_body 'owns' the subject frame.
 *
 * \param[in] frame Frame to test
 * \param[in] dyn_body Typically this
 * \param[in] file Typically __FILE__
 * \param[in] line Typically __LINE__
 */


// Set the parts of the specified reference frame as indicated by set_items.


// Set the source of aspects of the state.


// Set the position of the vehicle.


// Set the velocity of the vehicle.


// Set the attitude of the vehicle.


// Set the attitude rate of the vehicle.


// Member functions
// Initialize the attachment variables with the parent_frame and the offset from the parent_frame
// to the structure frame


/**
     * Interpret the provided value and add it to the list.
     * For a JPVCollectForce, the value should specify (in string form)
     * the address of a unique force vector pointer in active memory.
     * If the entry already exists, check and delete the "restored" CollectTorque
     */


/**
     * Interpret the provided value and add it to the list.
     * For a JPVCollectTorque, the value should specify (in string form)
     * the address of a unique torque vector pointer in active memory.
     * If the entry already exists, check and delete the "restored" CollectTorque
     */


/**
     * Non-default constructor that sets all elements.
     * @param parent_to_structure_offset_in  Reference to the vehicle's
     *   structure_point.position vector.
     * @param parent_to_structure_transform_in  Reference to the vehicle's
     *   structure_point.T_parent_this matrix.
     * @param mass_in  Reference to the vehicle's
     *   composite_properties.mass member.
     * @param structure_to_body_offset_in  Reference to the vehicle's
     *   composite_properties.position vector.
     * @param inertia_in  Reference to the vehicle's
     *   composite_properties.inertia tensor.
     * @param structure_to_body_transform_in  Reference to the vehicle's
     *   composite_properties.T_parent_this matrix.
     * @param inverse_mass_in  Reference to the vehicle's
     *   inverse_mass member.
     * @param inverse_inertia_in  Reference to the vehicle's
     *   inverse_inertia member.
     */


/**
     * Non-default constructor that sets all elements of the wrench.
     * @param torque_in    The intrinsic torque for this wrench.
     * @param force_in     The force applied at the point.
     * @param point_in     The point at which forces are applied.
     * @param active_in    True (default) indicates the wrench is active.
     */


/**
     * Non-default constructor that sets the point and active flag.
     * The torque and force and initialized to zero.
     * @param point_in     The point at which forces are applied.
     * @param active_in    True (default) indicates the wrench is active.
     */


/**
     * Set the force and torque to zero. The point remains unaltered.
     */


/**
     * Construct an equivalent Wrench about the specified point.
     * @param new_point  The point about which this is to be represented.
     * @return Equivalent wrench about the specified point.
     */


/**
     * Construct an equivalent Wrench about the current point, but
     * in a different reference frame.
     * @param point_state  Contains the position and orientation of the current
     *                    frame in the parent frame.
     * @return Equivalent wrench in the parent frame.
     */


/**
 * Construct a RelativeKinematics object.
 */


/**
 * Add a relative state to the list of ones maintained by this model.
 * \param[in] relstate Relstate to add
 */


/**
 * Remove a relative state from the list of ones maintained by this model.
 * \param[in] relstate  Relstate to remove
 */


/**
 * Find a specific relative state maintained by this model.
 * @return Void
 * \param[in] relstate_name Relstate to find
 */


/**
 * Set flag for a relative state to be activated or
 * deactivated by the RelKin manager.
 * \param[in] relstate  Relstate to activate/deactivate
 * \param[in] raf  bool Relstate activation flag
 */


/**
 * Update a single relative state maintained by this model.
 * \param[in] relstate_name Relstate to update
 */


/**
 * Update all relative states maintained by this model.
 * relstates that have been deactivated from RelKin will
 * not be update.
 */


/**
 * Each mass point has a path from the root of the mass point tree
 * to the point in question. The paths for two mass points will have
 * some initial sequence of common nodes.
 * Find the last element in this sequence.
 * @return Last common node
 * \param[in] frame Other point
 */


/**
 * Update the mass point's structure-to-point vector.
 * \param[in] pt_location New location, struct coords.\n Units: M
 */


/**
 * Update the mass point's structure-to-point frame transformation
 * matrix and items derived from it.
 * \param[in] transformation New structure-to-point xform
 */


/**
 * Update the mass point's structure-to-point frame transformation
 * matrix and items derived from it.
 * \param[in] left_quat New structure-to-point quat
 */


/**
 * Compute matrix. Someone changed the quaternion under our noses.
 */


/**
 * Copy the provided state to this.
 * \param[in] source Source state
 */


/**
 * Calculate the aggregate inertia matrix for a composite MassBody.
 *
 * \par Assumptions and Limitations
 *  - Rigid Bodies
 *  - Tree attachment structure
 *  - Must calculate from bottom to top of tree for meaningful results
 */


/**
 * Update composite mass properties for a mass tree marked for update.
 * The properties are updated from the bottom up to generate correct results.
 *
 * \par Assumptions and Limitations
 *  - Rigid bodies
 *  - Tree attachment structure
 */


/**
 * Recursively print out the data in this and its children to given file
 * \param[in,out] file_ptr Output file stream
 * \param[in,out] levels Max desired recursion level
 */


/**
 * Default constructor; constructs a MassBody object.
 */


/**
 * Destroy a MassBody object.
 */


/**
 * Initialize a MassBody object.
 * \param[in] properties Core mass ppty specs
 * \param[in] points Mass point specs
 */


/**
 * Return true if this MassBody is an offspring of provided one,
 * false if not.
 * @return Is this offspring of test_body?
 * \param[in] test_body Other MassBody
 */


/**
 * Flag mass bodies from the current body on up the mass tree
 * as in need of mass property updates.
 */


/**
 * Find the mass point with the given name.
 * @return Mass point
 * \param[in] pt_name mass point name
 */


/**
 * Add a mass point to the list of such.
 * \param[in] mass_point_init Mass point spec
 */


/**
 * Destroy a MassPoint object.
 */


/**
 * Initialize a mass point.
 */


/**
 * Compute the state of this point with respect to some reference
 * point, which may be any point in the same tree as this point.
 * \param[in] ref_point The point with respect to which the state is to be expressed
 * \param[out] rel_state The relative state
 */


/**
 * Compute the state of this point with respect to some reference
 * point, which must be at or above this point via the parent links.
 * \param[in] ref_point Reference point
 * \param[out] rel_state Point state wrt ref. pt.
 */


/**
 * Compute the state of this point with respect to some reference
 * point, which must be at or above this point via the parent links.
 * \param[in] ref_point_index Reference point index
 * \param[out] rel_state Point state wrt ref. pt.
 */


/**
 * Compute the complete state of the invoking reference
 * frame with respect to the supplied reference frame, which *must*
 * be a predecessor of the invoking frame.
 *
 * \par Assumptions and Limitations
 *  - The predecessor frame is a predecessor.
 * \param[in] ref_point The point with respect to which the state is to be expressed
 * \param[out] rel_state The relative state
 */


/**
 * Compute the state of some reference point with respect to this
 * point. The reference point must be at or above this point via the
 * parent links.
 * \param[in] ref_point_index Reference point index
 * \param[out] rel_state Relative state
 */


/*******************************************************************************
  Function: negate
  Purpose: (Copy a mass point state, negated.)
  Class: (N/A)
*******************************************************************************/


/**
 * Compute S_A:C = S_A:B + S_B:C,
 * with this initially containing S_A:B,
 * the supplied argument containing S_B:C, and
 * the resultant composition of states stored in this.
 * \param[in] s_bc Right addend
 */


/**
 * Compute the inertia tensor of a point mass.
 * \param[in] mass Mass of point mass\n Units: kg
 * \param[in] r_pt Vector to point mass\n Units: M
 * \param[out] inertia Inertia tensor\n Units: kgM2
 */


/**
 * Default constructor; constructs a MassPropertiesInit object.
 */


/**
 * Initialize the subject MassProperties.
 * \param[out] properties Properties to initialize
 */


/**
 * Default constructor; constructs a MassPointInit object.
 * \param[out] mass_point Point to initialize
 */


/**
 * Calculate the aggregate cm for a composite MassBody.
 *
 * \par Assumptions and Limitations
 *  - Rigid bodies
 *  - Must calculate from bottom to top of tree for meaningful results
 */


/**
 * Print out the MassTree members' data to a given file.
 * \param[in] file_name Desired output file name
 * \param[in,out] levels Max desired recursion level
 */


/**
 * Attach this mass body's root body as a child of the specified mass
 * body such that the specified mass points on the two bodies are
 * coincident and the frames associated with those mass points are
 * related by a 180 degree yaw.
 * @return Success indicator: true=success, false=attachment not performed.
 * \param[in] this_point_name The name of a mass point contained in this mass body's list of mass points.
 * \param[in] parent_point_name The name of a mass point contained in the new parent body's list of mass points.
 * \param[in,out] parent The new parent body; the body to which this body's root body is to be attached.
 */


/**
 * Attach this mass body's root body as a child of the specified mass
 * body such that this body's structural origin is offset from the
 * parent body's structural origin and this body's structural axes
 * are oriented with respect to the parent body's structural axes as
 * specified.
 * @return Success indicator: true=success, false=attachment not performed.
 * \param[in] offset_pstr_cstr_pstr Location of this body's structural origin with respect to the new parent body's
 * structural origin, specified in structural coordinates of the new parent body.\n Units: M \param[in] T_pstr_cstr
 * Transformation matrix from the new parent body's structural frame to this body's structural frame. \param[in,out]
 * parent The new parent body; the body to which this body's root body is to be attached.
 */


/**
 * Attach a child MassBody by point specification. See corresponding
 * MassBody::attach_to() method for more information.
 */


/**
 * Attach a child MassBody by location specification. See corresponding
 * MassBody::attach_to() method for more information. Note that the offset and
 * transformation are specified w.r.t. the parent in both attach_to() and
 * attach_child()
 */


/**
 * Attach this mass body, which must be a root body, as a child of the
 * specified mass body such that this body's structural origin is offset
 * from the parent body's structural origin and this body's structural
 * axes are oriented with repect to the parent body's structural axes as
 * specified.
 *
 * \par Assumptions and Limitations
 *  - The subject body, this, must be a root body.
 * @return Success indicator: true=success, false=attachment not performed.
 * \param[in] offset_pstr_cstr_pstr Location of this body's structural origin with respect to the new parent body's
 * structural origin, specified in structural coordinates of the new parent body.\n Units: M \param[in] T_pstr_cstr
 * Transformation matrix from the new parent body's structural frame to this body's structural frame. \param[in,out]
 * parent The new parent body; the body to which this body is to be attached.
 */


/**
 * Validate whether the pending attachment is legal.
 *
 * Extensibility comments --
 * - Overriding this method doesn't make a whole lot of sense.
 * - Any class that overrides this method must either invoke this method
 *   or perform the actions performed herein.
 *
 * \par Assumptions and Limitations
 *  - The subject body, this, must be a root body. This is not checked.
 * @return Validity indicator
 * \param[in] parent The new parent body; the body to which this body is to be attached.
 * \param[in] generate_message Generate message if invalid?
 */


/**
 * Validate whether the pending attachment is legal from a connectivity
 * point of view.
 *
 * Extensibility comments --
 * - This method determines whether invoking attach_establish_links
 *   makes sense.
 * - Any class that overrides this method must either invoke this method
 *   or perform the actions performed herein.
 *
 * \par Assumptions and Limitations
 *  - The subject body, this, must be a root body. This is not checked.
 * @return Validity indicator
 * \param[in] parent The new parent body; the body to which this body is to be attached.
 * \param[in] generate_message Generate message if invalid?
 */


/**
 * Validate whether the pending attachment is legal from a physical
 * point of view.
 *
 * Extensibility comments --
 * - This method determines whether invoking attach_update_properties
 *   makes sense.
 * - This is a free pass for a MassBody.
 *
 * @return Validity indicator
 * \param[in] child The child body; the body to be attached to this body.
 * \param[in] generate_message Generate message if invalid?
 */


/**
 * Establish the logical connectivity between parent and child.
 *
 * Extensibility comments --
 * - This method is invoked before the computing the physical relation
 *   between parent and child.
 * - The generic purpose of this method is to establish the logical
 *   connectivity between parent and child in terms of the child class.
 * - Any class that overrides this method must either invoke this method
 *   or perform the actions performed herein.
 *
 * \par Assumptions and Limitations
 *  - The attachment is valid; not checked.
 * \param[in,out] parent The new parent body; the body to which this body is to be attached.
 */


/**
 * Set the relation between parent and child and update the mass
 * properties.
 *
 * Extensibility comments --
 * - This method is sent to the parent body of the attachment after
 *   the child body has established the logical connectivity between
 *   the parent body and child body.
 * - The generic purpose of this method is to establish the physical
 *   relation between parent and child and to update any physical
 *   properties that change as a result of the attachment.
 * - Any class that overrides this method must either invoke this method
 *   or perform the actions performed herein.
 *
 * \par Assumptions and Limitations
 *  - The attachment is valid and logical connectivity has been established.
 *     Neither assumption is checked.
 * \param[in] offset_pstr_cstr_pstr Location of this body's structural origin with respect to the new parent body's
 * structural origin, specified in structural coordinates of the new parent body.\n Units: M \param[in] T_pstr_cstr
 * Transformation matrix from the new parent body's structural frame to this body's structural frame. \param[in,out]
 * child The child body; the body newly attached to this body.
 */


/**
 * Generate a message regarding failure to find mass points on a vehicle.
 *
 * \par Assumptions and Limitations
 *  - One or both of the input MassPoint pointers is null.
 * \param[in] file File name
 * \param[in] line Line number
 * \param[in] child_body_name Name of child body
 * \param[in] child_point_name Name of child mass point
 * \param[in] child_point Child mass point
 * \param[in] parent_body_name Name of parent body
 * \param[in] parent_point_name Name of parent mass point
 * \param[in] parent_point Parent mass point
 */


/**
 * Re-attach a child MassBody to a parent MassBody.
 *
 * \par Assumptions and Limitations
 *  - Rigid Bodies
 *  - Tree attachment structure
 *  - Child is known to be a root or atomic body
 *  - Re-establishing an attachment that previously existed
 * \param[in] offset Desired offset from parent struct frame to attached child's struct frame, expressed in parent
 * struct frame\n Units: M \param[in] T_pstr_cstr Desired transformation matrix from parent struct frame to attached
 * child's struct frame
 */


/**
 * Detach the two bodies, 'this' and the argument body, from each other such
 * such that the detachment occurs between the superior body and the immediate
 * child along the path from the inferior body to the superior body.
 * Returns true to indicate success, false to indicate failure.
 *
 * \par Assumptions and Limitations
 *  - Instances of more derived classes, with presumably more involved dynamics,
 *     are situated higher in the mass tree than are more basic instances.
 *     For example, a simple MassBody can be a child of a DynBody, but not the
 *     other way around.
 *  - The attachment in the mass tree between the immediate child and the superior
 *     body is assumed to reflect a real physical attachment.
 * @return Success flag
 * \param[in,out] mass_body The other body
 */


/**
 * Detach a mass body from its immediate parent.
 * Returns true to indicate success, false to indicate failure.
 *
 * \par Assumptions and Limitations
 *  - Instances of more derived classes, with presumably more involved dynamics,
 *     are situated higher in the mass tree than are more basic instances.
 *     For example, a simple MassBody can be a child of a DynBody, but not the
 *     other way around.
 *  - The attachment in the mass tree between the immediate child and the superior
 *     body is assumed to reflect a real physical attachment.
 * @return Success flag
 */


/**
 * Validate whether the pending detachment is legal.
 *
 * Extensibility comments --
 * - Overriding this method doesn't make a whole lot of sense.
 * - Any class that overrides this method must either invoke this
 *   method
 *   or perform the actions performed herein.
 *
 * \par Assumptions and Limitations
 *  - The subject body, this, must be a root body. This is not checked.
 * @return Validity indicator
 * \param[in] parent The parent body; the body from which this body is to be detached.
 * \param[in] generate_message Generate message if invalid?
 */


/**
 * Validate whether the pending detachment is legal from a connectivity
 * point of view.
 *
 * Extensibility comments --
 * - This method determines whether invoking detach_sever_links
 *   makes sense.
 * - Any class that overrides this method must either invoke this method
 *   or perform the actions performed herein.
 * @return Validity indicator
 * \param[in] parent The parent body; the body from which this body is to be detached.
 * \param[in] generate_message Generate message if invalid?
 */


/**
 * Validate whether the pending detachment is legal from a mass tree
 * point of view.
 *
 * Extensibility comments --
 * - This method determines whether invoking detach_update_properties
 *   makes sense.
 * @return Validity indicator
 * \param[in] child The child body; the body to be detached from this body.
 * \param[in] generate_message Generate message if invalid?
 */


/**
 * Update parent and child properties to reflect that they are detached.
 *
 * Extensibility comments --
 * - This method is sent to the parent body of the detachment after
 *   the child body has severed the logical connectivity between
 *   the parent body and child body.
 * - The generic purpose of this method is to update any physical
 *   properties that change as a result of the detachment.
 * - Any class that overrides this method must either invoke this method
 *   or perform the actions performed herein.
 *
 * \par Assumptions and Limitations
 *  - The detachment is valid and logical connectivity has been severed.
 *     Neither assumption is checked.
 * \param[in,out] child The child body; the body newly detached from this body.
 */


/**
 * Find the mass body with the given name.
 * @param body_name  Mass body name
 * @return Pointer to found MassBody; NULL if not found.
 */


/**
 * Add a mass body to the mass body registry.
 * @param mass_body  Mass body to be added to the registry.
 */


/**
 * DynManager default constructor.
 */


/**
 * Set the Gravity Manager to the specified reference.
 * \param[in] gravity Gravity Manager
 */


/**
 * Add a body action to the list of such.
 * \param[in,out] body_action Body action
 */


/**
 * Remove a body action to the list of such.
 * \param[in] action_name_in Name of the action to remove
 */


/*
 * Force all integrators to reset themselves.
 */


/**
 * Initialize dynamic bodies.
 */


/**
 * Initialize a specific dynamic body.
 *
 * \par Assumptions and Limitations
 *  - The body in question is assumed to be an isolated body.
 * \param[in,out] body Body to be initialized
 */


/**
 * Initialize all queued body actions that derive from MassBodyInit
 * and apply those that are immediately ready to be applied.
 * \param[in,out] body Body to be initialized
 */


/**
 * Initialize all queued body actions that derive from MassBodyAttach
 * and apply those that are immediately ready to be applied.
 */


/**
 * Initialize dynamic bodies.
 * \param[in,out] body Body to be initialized
 */


/**
 * Ensure that all of the required states have been set.
 */


/**
 * Initialize the gravity controls for each dynamic body.
 *
 * \par Assumptions and Limitations
 *  - Not called in empty space mode.
 */


/**
 * Reset the gravity controls for each dynamic body.
 *
 * \par Assumptions and Limitations
 *  - Not called in empty space mode.
 */


/**
 * Compute gravitational acceleration on each root body.
 */


/**
 * Find the dynamic body with the given name.
 * @param body_name  Dynamic body name
 * @return Pointer to found DynBody; NULL if not found.
 */


/**
 * Add a dynamic body to the dynamic body registry.
 * @param dyn_body  Dynamic body to be added to the registry.
 */


/**
 * Add an integration group to the integration group registry.
 * @param integ_group  Integration group to be added.
 */


/**
 * DynamicsIntegrationGroup default constructor, needed for checkpoint/restart.
 */


/**
 * DynamicsIntegrationGroup non-default constructor,
 *  used to create the default integration group.
 * @param[in] owner        The new group's owner
 * @param[in] integ_cotr   Integrator constructor
 * @param[in] integ_inter  Simulation engine integration interface
 * @param[in] time_mngr    Time manager
 */


/**
 * Register types and containers.
 */


/**
 * Create an integration group object that can be used as the
 * dynamic manager's default integration group.
 * @param[in] owner        The new group's owner
 * @param[in] integ_cotr   Integrator constructor
 * @param[in] integ_inter  Simulation engine integration interface
 * @param[in] time_mngr    Time manager
 * @return Created DynamicsIntegrationGroup.
 */


/**
 * Pre-initialize the group and register it with the dynamics manager.
 * This function is to be called early in the initialization process.
 * Overrides should not depend on the dyn_bodies vector having any members.
 * @param[in] dyn_manager  Dynamics manager.
 */


/**
 * Complete the initialization of the group.
 * For overriders:
 * This function is called by DynManager::initialize_simulation.
 * At the point of this call, the dyn_bodies vector is populated with the
 * bodies that are to be integrated by this group.
 * Note well: That vector can still be empty.
 */


/**
 * Add a DynBody to the set of bodies whose states are integrated by this group.
 * @param dyn_body  DynBody to be added to the group.
 */


/**
 * Remove a DynBody from the set of bodies whose states are integrated by
 * this group.
 * @param dyn_body  DynBody to be removed from the group.
 */


/**
 * Compute the gravitational acceleration of each root dynamic body.
 * @param dyn_manager    Dynamics manager.
 * @param gravity_manager  Gravity Manager.
 */


/**
 * Collect the forces and torques acting on each root dynamic body.
 */


/**
 * Force all integrators to reset themselves.
 */


/**
 * Integrate the states of the DynBody objects that comprise the group.
 * @param[in]     cycle_dyndt   Dynamic time step, in dynamic time seconds.
 * @param[in]     target_stage  The stage of the integration process
 *                              that the integrator should try to attain.
 * @return The status (time advance, pass/fail status) of the integration.
 */


/**
 * Complete initialization of the JEOD manager model.
 */


/**
 * Complete initialization of the initialization groups.
 */


/**
 * Add DynBody objects to the default integration group.
 * @param[in,out] group  Group to be updated
 */


/**
 * Perform dynamic body actions that are ready to be applied.
 */


/**
 * Begin initialization of the JEOD manager model.
 * @param[in,out] integ_if   Integrator interface
 * @param[in,out] init       Initialization data
 * @param[in,out] time_mngr  Time manager

Class:
  (initialization)
******************************************************************************/


/**
 * Begin initialization of the JEOD manager model.
 *
 * \par Assumptions and Limitations
 *  - The user-input item selection table must have at most one selection
 *     rule for a given name. This limitation is an enforced constraint.
 * \param[in,out] init Initialization data
 * \param[in,out] time_mngr Time manager
 */


/*
Purpose:
  (Compute the transformation matrix from the eigen rotation.
   Given a rotation by an angle \f$\phi\f$ about an axis
   \f$\hat{\mathbf u}\f$,
   the [i][j] element of the transformation matrix is given by
   \f[
     T_{ij} =
        \cos\phi\,\delta_{ij} +
        (1-\cos\phi)\,\hat u_i \hat u_j +
        \epsilon_{ijk}\sin\phi\,\hat u_k
   \f]
   where
     - \f$\delta_{ij}\f$ is the Kronecker delta,
     -  @e k is \f$(i+j) \bmod 3\f$, and
     - \f$\epsilon_{ijk}\f$ is the Levi-Civita symbol taken with respect
        to (0,1,2).)
Assumptions and limitations:
  ((The eigen axis is a unit vector.))
*/


/*
Purpose:
  (Compute the eigen rotation from the transformation matrix.
   There are several alternate expressions for computing the eigen rotation
   from a matrix, all of which are equivalent in infinite precision arithmetic.
   The use of finite precision arithmetic means that care must be taken
   in choosing the algorithm to be used. The starting point is the
   generic expression
   \f[
     T_{ij} =
        \cos\phi\,\delta_{ij} +
        (1-\cos\phi)\,\hat u_i \hat u_j +
        \epsilon_{ijk}\sin\phi\,\hat u_k
   \f]
   From this, the trace of the matrix and the difference between and sum of
   pairs of off-diagonal elements are
   \f{eqnarray*}{
     \mathrm{tr}(T) &=& 2\cos\phi + 1 \\
      T_{ij}-T_{ji} &=& 2\epsilon_{ijk}\sin\phi\,\hat u_k \\
      T_{ij}+T_{ji} &=& 2(1-\cos\phi)\,\hat u_i \hat u_j
   \f}

   Method 1\n
   One approach to determining the eigen rotation involves the construction
   of a vector of differences between pairs of off-diagonal elements of the
   transformation matrix,
   \f[
      d_k = T_{ij}-T_{ji} = 2 \sin\phi\,\hat u_k
   \f]
   where (i,j,k) is an even permutation of (0,1,2). With this,
   \f{eqnarray*}{
      \phi &=& \arcsin\left(\frac{||\mathbf d||} 2\right) \\
      \hat{\mathbf u} &=& \frac{\mathbf d}{||\mathbf d||}
   \f}
   Note that the above of the inverse sine will restrict the rotation angle to
   be between 0 and 90 degrees. Special processing is needed when the rotation
   angle is between 90 and 180 degrees.
   Note also that the symmetric difference vector will
   be identically zero if the rotation angle is 0 or 180 degrees and will be
   very small for rotation angles close to 0 or 180 degrees.
   The precision loss for rotation angles near 0 and 180 degrees means the
   individual components of the eigen axis will not be as precise with this
   approach compared to alternatives.

   Method 2\n
   The diagonal elements of the matrix yields another method for determining the
   single axis rotation angle and the rotation axis:
   \f{eqnarray*}{
      \phi &=& \arccos\left(\frac{\mathrm{tr}(T)-1} 2\right) \\
      |\hat u_i| &=& \sqrt{\frac{T_{ii} - \cos \phi}{1-\cos\phi}}
   \f}
   Note that this approach determines the magnitudes but not the signs of the
   components of the eigen axis vector. Because this method is based on the
   inverse cosine, the calculated phi angle will be less precise than that
   obtained by method 1 for angles near 0 or 180 degrees. The unit vector
   however will be more accurate than that obtained from method 1 for small
   rotation angles.

   Method 3\n
   Yet another alternative for computing components of the eigen axis is to
   use the sum of pairs of off-diagonal elements of the transformation metrix,
   \f{eqnarray*}{
      T_{ij}+T_{ji} &=& 2(1-\cos\phi)\,\hat u_i \hat u_j \\
      T_{ik}+T_{ki} &=& 2(1-\cos\phi)\,\hat u_i \hat u_k
   \f}
   This enables the calculation of two components of the unit vector. One
   component needs to be computed by one of the two previous methods.)

Assumptions and limitations:
  ((The matrix is a proper transformation matrix.))
*/


/**
 * SpiceEphemeris default constructor.
 */


/**
 * Nominally, activate the object. In the case of a SpiceEphemeris object,
 * an inactive object cannot be activated once the simulation starts.
 * Note that a SpiceEphemeris is active by default.
 */


/**
 * Initialize the SpiceEphemeris model.
 * This method is called before the planets have been registered
 * with the reference frame manager, so we don't know whether the
 * ephemeris items should be enabled or disabled.
 * \param[in] time_manager Time manager
 * \param[in] ephem_manager Incoming ephem manager
 */


/**
 * Initialize SpiceEphemeris timing.
 * \param[in] time_manager Time manager
 */


/**
 * Load SPICE kernel files containing ephemeris data.
 */


/**
 * Process spk objects and store array of loaded spk IDs
 */


/**
 * Load and locate all planetary orientation frames.
 */


/**
 * Populate basic attributes of a new SpiceEphemPoint.
 * \param[in,out] item Pointer to item to populate
 * \param[in] object_name Name of the item
 */


/**
 * Create a new SpiceEphemPoint.
 * @return Pointer to object
 * \param[in] object_name Name of new object
 * \param[in] spice_name SPICE lookup name
 */


/**
 * Create a new SpiceEphemOrientation.
 * @return Pointer to object
 * \param[in] jeod_name Name of new object
 */


/**
 * Initialize the SpiceEphemeris item data.
 */


/**
 * Introduce an EphemerisItem to the EphemeridesManager.
 * \param[in] item Item to introduce
 */


/**
 * Convert SPICE names to JEOD nomenclature.
 * @return JEOD-friendly name of a SPICE name
 * \param[in] spice_name Name of a SPICE object.
 */


/**
 * Convert JEOD body name to SPICE pfix frame name.
 * @return name of pfix frame that SPICE associates with the given body. Handles high precision frames for Earth and
 * Moon unless IAU is specified by user \param[in] jeod_name Name of the JEOD body.
 */


/**
 * Name all the planetary barycenters with their JEOD identifiers.
 */


/**
 * Add a barycenter corresponding to the given SPICE ID.
 * \param[in] id id of barycenter to add
 */


/**
 * Check what if any barycenters need creating and do so. Any new
 * barycenters are added to the all_loaded_items list and registered
 * with the dynamics manager.
 */


/**
 * Determine which item should be the root of the ref frame tree.
 */


/**
 * Complete the initialization process.
 * This method should be called after all other ephemeris models have
 * completed their basic initialization and after all planets have
 * registered themselves with the ephemeris manager.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/**
 * Mark appropriate items in the model as active.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/**
 * Add all offspring from a given node of the ref frame tree.
 * \param[in,out] parent Frame to attach to
 */


/**
 * Construct the ephemeris model portions of the reference frame tree.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/**
 * Update ephemerides for subscribed items.
 */


/**
 * Find a SPICE ID in the loaded list of SPICE objects.
 * @return Pointer to object
 * \param[in] id_to_find SPICE lookup name
 */


/**
 * Find the ID of the parent of a given SPICE object. Here "parent"
 * means both:
 * 1. the frame to which the object is connected in the JEOD reference
 *    frame tree (the "parent" frame).
 * 2. the object that will be used as the "observer" in the calls to
 *    SPICE to obtain the state of the given object.
 * @return of parent\n Units: ID
 * \param[in] obj_id child ID of which parent is to be found
 */


/**
 * Update ephemerides of inertial frames supplied by spk files.
 */


/**
 * Update planetary orientations.
 */


/**
 * Mute SPICE errors so that they can be handled by the MessageHandler.
 */


/**
 * Update the rotational state of the target frame
 * \param[in] time_tdb Ephemeris time (TDB)\n Units: s
 * \param[in] time_dyn dyn time for timestamp\n Units: s
 */


/**
 * Confirm that the target frame exists in the loaded SPICE kernels.
 * \param[in] time_tdb Ephemeris time (TDB)
 */


/**
 * Populate the SPICE 6 x 6 matrix via sxform_c().
 * \param[in] time_tdb Ephem time (TDB)
 * \param[out] trans6x6 Spice matrix
 */


/**
 * Nominally, activate the model. Here, reject the request.
 */


/**
 * Set the name of a SinglePointEphemeris object.
 * \param[in,out] new_name Central point name
 */


/*
Purpose:
  (Construct an EmptySpaceEphemeris object.)
*/


/**
 * Set the name of an EmptySpaceEphemeris object.
 * \param[in,out] new_name Ephemeris name
 */


/**
 * Initialize an EmptySpaceEphemeris object.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/**
 * Build the reference frame tree with the central frame as the root.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/*
Purpose:
  (Construct an SinglePlanetEphemeris object.)
*/


/**
 * Set the name of a SinglePlanetEphemeris object.
 * \param[in,out] new_name Central point name
 */


/**
 * Initialize a SinglePlanetEphemeris object.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/**
 * Augment RefFrame::set_active_status by notifying the ephemerides manager
 * that the tree might need to be rebuilt.
 * \param[in] new_status Active status
 */


/**
 * Copy rotational state from/to the body reference frame.
 * \param[in] dyn_time Dynamic time seconds\n Units: s
 */


/**
 * PropagatedEphemerisOrientation non-default constructor.
 * \param[in,out] dyn_body The DynBody that represents the planet
 * \param[in,out] frame The body reference frame
 */


/**
 * PropagatedEphemerisPlanet non-default constructor.
 * \param[in,out] dyn_body The DynBody that represents the planet
 * \param[in,out] frame The body reference frame
 */


/**
 * PropagatedPlanet default constructor.
 */


/**
 * Nominally, activate the object.
 * In the case of a PropagatedPlanet object,
 * an inactive object cannot be activated.
 */


/**
 * Initialize a PropagatedPlanet model.
 *
 * \par Assumptions and Limitations
 *  - This method must be called after the ephemeris model that defines
 *      the parent frame has been initialized.
 * \param[in] time_manager Time manager
 * \param[in,out] dyn_manager_ref Dynamics manager
 */


/**
 * Change the behavior of a PropagatedPlanet.
 */


/**
 * EphemeridesManager default constructor.
 */


/**
 * Add a planet to the planets registry.
 * @param planet  Planet to be added to the registry.
 */


/**
 * Find the planet with the given name.
 * @param name  Planet name.
 * @return Found planet; NULL if not found.
 */


/**
 * Add an ephemeris model to the list of managed models.
 *
 * ## Assumptions and limitations:
 *  - Ephemeris models must be registered with the ephemerides manager in
 *    dependency order: Models with no dependencies are registered first,
 *    followed by models that depend on these base models, and so on.
 *
 * @param ephem_if  Ephemeris model to be added to the registry.
 */


/**
 * Deactivate any registered ephemeris items and remove them from the list.
 */


/**
 * Add an ephemeris item to the set of ephemeris items known to the ephemerides
 * manager. Each ephemeris model calls this method for each ephemeris item
 * represented by that ephemeris model. The provided item is added to
 * - The ephem_items list if the provided item's name is unique or
 * - The tail of the list of items with the same name if an item with the
 *   provided item's name is already in the ephem_items list.
 *
 * Multiple ephemerides models might represent the same conceptual item. The
 * ephem_items list contains only items with unique names. These head items link
 * to other items with the same name via the items' next data members, which
 * form a singly-linked list of commonly-named items.
 *
 * ## Assumptions and limitations:
 *  - The item must have a valid name.
 *  - Only one item with a given name can be enabled.
 *
 * @param ephem_item  Ephemeris item to be added to the registry.
 */


/**
 * Find the first registered EphemerisItem with the given name.
 * @param name  Ephemeris item name
 * @return Found ephemeris item
 */


/**
 * Find the EphemerisOrientation with the given name.
 * @param name  Ephemeris angle name
 * @return Found ephemeris angle
 */


/**
 * Find the EphemerisPoint with the given name.
 * @param name  Ephemeris point name
 * @return Found ephemeris point
 */


/**
 * Add a frame to the reference frame and integration frame lists.
 * @param ref_frame  Integration frame to be added to the registries
 */


/**
 * Find the integration frame with the given name.
 * @param name  Integration frame name
 * @return Found integration frame
 */


/**
 * Determine if supplied frame is an integration frame.
 * @param ref_frame  Reference frame to test
 * @return True if the frame is a registered integration frame, false otherwise
 */


/**
 * Find the index of provided frame in the integration frames vector.
 * @param ref_frame  Reference to be found
 * @return Index of found frame
 */


/**
 * Add a reference frame to the reference frame registry.
 * @param ref_frame  Reference frame to be added to the registry
 */


/**
 * Set the target-frame reference for the ref-frame and all known EphemItems
 * with similar target-frame names.
 * @param ref_frame  Reference frame to be used as the target-frame.
 */


/**
 * Initialize the ephemeris models.
 */


/**
 * Update each ephemeris model.
 */


/**
 * Activate ephemeris items based on frame subscription status,
 * activate ephemeris models, and build the reference frame tree.
 */


/**
 * Find the planet with the given name.
 * @param name  Planet name
 * @return Found planet, as a Planet rather than a BasePlanet
 */


/**
 * Set active status to correspond with that of the inertial frame.
 * \param[in] frame Frame whose status has changed
 */


/**
 * Disconnect the associated inertial frame from the tree.
 */


/**
 * Zero-out the inertial frame's translational state.
 */


/**
 * Update the inertial frame's translational state.
 * \param[in] position Position wrt parent\n Units: M
 * \param[in] velocity Velocity wrt parent\n Units: M/s
 * \param[in] time Timestamp\n Units: s
 */


/**
 * Update the inertial frame's translational state.
 * \param[in] position Position wrt parent\n Units: M
 * \param[in] velocity Velocity wrt parent\n Units: M/s
 * \param[in] scale Scale factor
 * \param[in] time Timestamp\n Units: s
 */


/**
 * Enable a EphemerisItem object.
 */


/**
 * Null implementation.
 * \param[in] frame Frame whose status has changed
 */


/**
 * Return the Euler angles.
 * \param[out] angles Euler angles\n Units: r
 */


/**
 * Return the Euler angles.
 * \param[out] rates Euler rates\n Units: r/s
 */


/**
 * Propagate the orientation to the current time.
 *
 * \par Assumptions and Limitations
 *  - The orientation has been computed.
 *  - Rotation is constant during the update interval.
 * \param[in] to_time Target dynamic time\n Units: s
 */


/**
 * Compute a JEOD rotational state given a 3-1-3 inertial-to-planet-fixed
 * Euler sequence and the time derivatives of the Euler angles.
 * \param[in] angles zxz Euler angles\n Units: r
 * \param[in] derivs zxz Euler angle time derivatives\n Units: r/s
 * \param[in] time Update time\n Units: s
 */


/**
 * Name an ephemeris item.
 * \param[in] file Usually __FILE__
 * \param[in] line Usually __LINE__
 * \param[in] new_value Value to check
 * \param[in] old_value Current value
 * \param[in] variable_name Variable name
 */


/**
 * Name an ephemeris item.
 * \param[in] pname Planet name
 * \param[in] fname Frame name
 */


/**
 * Name an ephemeris item.
 * \param[in] new_name New name
 */


/**
 * Set the target frame.
 * All ephemeris items that share a common name must point
 * to the same target frame.
 * \param[in] frame Target frame
 */


/**
 * Enable an EphemerisItem object.
 */


/**
 * Disable an EphemerisItem object.
 */


/**
 * Activate a EphemerisItem object.
 */


/**
 * Get the item marked as enabled, if any.
 * @return Enabled item
 */


/**
 * Initialize the De4xxEphemeris model.
 * \param[in] time_manager Time manager
 * \param[in,out] dyn_manager Dynamics manager
 * \param[in] time_type time type
 */


/**
 * Nominally, activate the object.
 * In the case of a De4xxEphemeris object,
 * an inactive object cannot be activated.
 */


/**
 * Initialize the De4xxEphemeris model.
 * This method is called before the planets have been registered
 * with the reference frame manager, so we don't know whether the
 * ephemeris items should be enabled or disabled.
 * \param[in] time_manager Time manager
 * \param[in,out] ephem_manager Ephemerides manager
 * \param[in] time_type optional "tt"||"tdb" "tt" default manager
 */


/**
 * Initialize De4xxEphemeris timing.
 * \param[in] time_manager Time manager
 * \param[in] time_type time type
 */


/**
 * Initialize the De4xxEphemeris file.
 */


/**
 * Initialize the De4xxEphemeris item data.
 * \param[in,out] ephem_manager Ephemerides manager
 */


/**
 * Mark appropriate items in the model as active.
 * @return Void
 */


/**
 * Adjust Earth, Moon, and Earth-Moon barycenter activity.
 * @return Void
 * \param[in] tot_active Number active translation nodes
 */


/**
 * Propagate the lunar orientation to the current time.
 */


/**
 * Calcuate the position and velocity states of selected planetary bodies at
 * some point in time. The EphemeridesState structure embedded in the Ephemerides
 * structure contains an update indicator and state for each body. The state for
 * a body is updated if the body's indicator indicates that a state update is
 * needed.
 *
 * Body selection --
 *   The 'active_bodies' array in the  EphemeridesState structure indicates which
 *   planets' states are to be updated. The function updates the position and
 *   velocity for the selected bodies.
 *
 * Time specification --
 *   Four input variables are available for specifying the time.
 *   - tt_offset is the offset between the remaining input times and Terrestrial
 *     Time (aka Terrestrial Dynamic Time, or TDT). Set this to zero if the
 *     other input times are already expressed in Terrestrial Time.
 *   - For highest precision, set epoch_time to the Julian date at midnight of
 *     the time point of interest and set either del_day or del_time to the
 *     difference between the time point of interest and the epoch_time.
 *   - An alternative that retains full precession is to pass the time at the
 *     start of the simulation in epoch_time and del_day and the time into the
 *     simulation in del_time. In this approach, epoch_time represents the
 *     Julian date at the midnight preceding the start of the simulation and
 *     del_day represents the time between the epoch time and simulation start.
 *   - For ease of use, set epoch_time to the Julian date representing the
 *     the time point of interest and set both del_day and del_time to 0.0.
 *     Note that this approach has a machine granularity of about 0.2 msec.
 *   - An intermediate alternative is to set the epoch_time to the start time
 *     of the simulation, del_day to zero and del_time to the simulation time
 *     in seconds. This approach will result in a small temporal bias due to
 *     the precision loss in the epoch time.
 *
 * Outputs --
 *   Positions and velocities are expressed in the ICRF coordinate system.
 *   The states of the Sun and planets, including Earth-Moon barycenter, are
 *   expressed with respect to the solar system barycenter. Lunar states are
 *   expressed with respect to the center of the Earth.
 *
 * NOTA BENE --
 *   The states of unselected bodies may or may not be changed.
 *
 * \par Assumptions and Limitations
 *  - Assumption 1.
 *    Ephemeris file is open.
 *  - Assumption 2.
 *    Offset times in del_day and del_time are small. See description above.
 *  - Assumption 3.
 *    The caller will not reference the states of bodies not requested in the
 *    active_bodies array. The unselected body states are fair game and may or
 *    may not be modified by this function.
 *  - Limitation 1.
 *    No light speed time-of-travel corrections.
 *    Such corrections must be made by the caller if needed.
 *  - Limitation 2.
 *    No relativistic time corrections for the difference between Terrestrial
 *    and Barycenter Dynamic Time.
 *  - Limitation 3.
 *    The states of the sun and the major planets are expressed in ICRF
 *    coordinates relative to the Solar System barycenter.
 *    The state of the Moon is expressed in ICRF coordinates relative
 *    to the center of the Earth.
 * \param[in] time Time since reference\n Units: s
 */


/**
 * Calcuate the position and velocity states of selected planetary bodies at
 * some point in time.
 * \param[in] time Time since reference\n Units: s
 * \param[in] fblk Fractional block
 */


/**
 * Construct a De4xxFileItem object.
 * As most ephemeris file items are position vectors in kilometers,
 * this constructor sets the scale to 1000 and the number of items
 * to three.
 */


/**
 * Construct the JPL ephemeris file.
 */


/**
 * Destroy the JPL ephemeris file.
 */


/**
 * Open the JPL ephemeris file.
 *
 * \par Assumptions and Limitations
 *  - Errors are fatal
 * @return Void
 */


/**
 * Open the JPL ephemeris file on restart.
 *
 * \par Assumptions and Limitations
 *  - File spec has been reloaded.
 *  - Data has been allocated
 *  - Errors are fatal
 */


/**
 * Close the JPL ephemeris file.
 *
 * \par Assumptions and Limitations
 *  - Ephemeris file is open for input
 *  - Errors are fatal
 */


/**
 * Check whether the specified time is represented in the JPL ephemeris file.
 *
 * \par Assumptions and Limitations
 *  - Ephemeris file is open for input
 *  - Ephemeris file is blocked per value set in the ephem_file structure
 * @return True if time is in file
 * \param[in] time Time since reference\n Units: s
 */


/*******************************************************************************
Purpose: (Pre-initialize a DE4xxFile instance.)
*******************************************************************************/


/**
 * Calculate the location of the L1 point as a ratio.
 * @return Ratio of body1 to L1-point distance to body1 to body2 distance
 * \param[in] b1b2_mass_ratio Body1 to body2 mass ratio
 */


/**
 * default constructor. Initialize all data
 */


/**
 * Apply the various options, including fidelity of RNP and if
 * polar motion is enabled or not, then call the base class
 * initializer. Note that this function will still run
 * even if the active flag is set to false. Additionally,
 * note that this function does not update the rotation
 * matrix between inertial and planet fixed. It only
 * sets up the object to work with the DynManager.
 * update_rnp must be called to update the
 * RNP matrix. This function will also cache of TimeGMST
 * from the given TimeManager
 * \param[in,out] dyn_manager DynManager where the planet attitude to be updated is contained
 */


//  Function: update_rnp(TimeTT&, TimeGMST& gmst_ptr, TimeUT1&)
//  Purpose: (Update all present components of the RNP, combine them and send
//            them to the correct planet from the dyn manager in initialize)
//  Class: (environment)
// *******************************************************************************/
/*
  Purpose:
    (Updates the complete RNP and supplies it to the Dynamics Manager.)
 */


//  Function: update_axial_rotation(TimeUT1&)
//  Purpose: (Same as update_rnp, but only updates axial rotation part)
//  Class: (derivative)
// *******************************************************************************/
/*
  Purpose:
    (Updates the axial rotation portion of RNP
     and supplies the entire RNP to the Dynamics Manager.)
 */


// /*******************************************************************************
//  Function: ephem_update()
//  Purpose: (The RNPJ2000 implementation of the pure virtual EphemerisInterface
//            function. Internally calls update_axial_rotation. update_rnp
//            must be called prior to this function being called, or RNP
//            will not be correctly updated.)
//
// *******************************************************************************/


// /*******************************************************************************
//  Function: get_dyn_time_ptr(TimeGMST&)
//  Purpose: (Accesses the TimeManager through the given gmst, and
//            uses is to get the TimeDyn for the simulation)
// *******************************************************************************/


/**
 * Specific implementation of update_rotation, from the polymorphic
 * pure virtual base class PlanetRotation
 */


/**
 * J2000 specific implementation of update_rotation, from
 * PlanetRotation. For axial rotation
 */


/**
 * Precession J2000 specific implementation of update_rotation,
 * inherited from Planetrotation
 */


/**
 * PolarMotionJ2000 specific implementaiton of update_rotation from
 * PlanetRotation
 */


/**
 * NutationMars specific implementation of update_rotation, used here
 * to describe nutation effects in longitude and obliquity
 */


/**
 * PrecessionMars specific implementation of update_rotation,
 * to calculate precession.
 */


/**
 * Calculate constant rotation matrices resulting from N and J.
 */


/**
 * RotationMars specific implementation of update_rotation, for
 * axial rotation.
 */


/**
 * Perform setup of the object, then call the base class initializer.
 * \param[in,out] dyn_manager Ref to dynamics manager
 */


/**
 * Update the complete RNP and supply it to the Dynamics Manager.
 * \param[in] time_tt Current Terrestrial Time
 */


/**
 * Update rotation portion of RNP and supply RNP to dynamics manager.
 * \param[in] time_tt Current TT time
 */


/**
 * Define 'alias' to call axial update function, for polymorphism.
 */


/**
 * Get simulation time via a two-step pointer trail.
 * \param[in] time_tt Current TT time
 */


/**
 * Invokes the calculation for all rotation models contained in the
 * RNP, used on the last time set in each model through
 * PlanetRotation::set_time. Then multiplies out and updates the
 * attitude of the planet found during initialization.
 */


/**
 * Same as update_rnp, but only the axial_rotation will be updated
 */


/**
 * Multiples out the (up to) four planet rotation models (nutation,
 * precession, polar motion and rotation), leaving out models whose
 * pointers are NULL, and feeds it to the planet attitude found
 * in the dyn manager given in initialize
 */


/**
 * Goes to the dyn manager given and searches for the planet
 * indicated by the user inputted name, in the given dyn manager.
 * Will send a fail message if the named planet is not found.
 * Additionally, this will register this ephemeris interface
 * with the given DynManager, and will set up the contained
 * EphemerisOrientation to control the named planet.
 * \param[in,out] dyn_manager DynManager where the attitude will be applied
 */


/**
 * Compute the gravitational acceleration at a given position toward a
 * gravitational body assuming the body has a non-spherical mass distribution.
 * \param[in] posn Point of interest, inrtl coords\n Units: M
 * \param[out] body_grav_accel Accel for given grav body\n Units: M/s2
 * \param[out] dgdx Gradient for given grav body\n Units: 1/s2
 * \param[out] Pot Potential
 */


/**
 * Construct a GravityInteraction instance.
 */


/**
 * Destruct a GravityInteraction instance.
 */


/**
 * Add a new GravityControls to the grav_controls list.
 * \param[in] control Control to be added
 */


/**
 * Remove a GravityControls from the grav_controls list.
 * \param[in] control GravityControls to be removed.
 */


/**
 * Initialize all GravityControls in the grav_controls list.
 * \param[in] dyn_manager Ref to Dyn Manager
 * \param[in] grav_manager Ref to Gravity Manager
 */


/**
 * Reset all GravityControls in the grav_controls list.
 */


/**
 * Sort the GravityControls in the grav_controls list
 * in increasing acceleration magnitude order.
 */


/**
 * Initialize the solid body tidal model.
 * \param[in] var_init Effect init structure
 * \param[in] dyn_manager Dynamics manager
 */


/**
 * Find the given variational gravity effect if already exists.
 * @return Index number of delta-coeff; -1 if not found
 * \param[in] delta_coeff delta-coeff to be found
 */


/**
 * Add a gravitational variation effect (i.e., a delta coeffs) to the
 * vector of effects.
 * \param[in] var_init Effect init structure
 * \param[in] dyn_manager Dynamics manager
 * \param[in] var_effect Delta coeff to be added
 */


/**
 * Initialize this GravityControl.
 * \param[in] grav_man Ref to Gravity Manager
 */


/**
 * Reset subscriptions for this GravityControl.
 * \param[in] dyn_manager Ptr to dynamics manager
 */


/**
 * Compute the gravitation at a given position toward a gravity body.
 * \param[in] integ_pos Point of interest, integ coords\n Units: M
 * \param[in] integ_frame_idx Integ frame index
 * \param[out] body_grav_accel Accel for given grav body\n Units: M/s2
 * \param[out] dgdx Gradient for given grav body\n Units: 1/s2
 * \param[out] Pot Potential
 */


/**
 * Compute the gravitation at a given position toward a gravity body.
 * \param[in] point_of_interest  Point of interest, as a reference frame.
 * \param[in] integ_frame_idx  Integ frame index.
 * \param[out] body_grav_accel  Accel for given grav body.
 * \param[out] dgdx  Gradient for given grav body.
 * \param[out] pot  Specific gravitational potential for given grev body.
 */


/**
 *
 * \details
 * Implements equation 27 (Folkner) / equation 4 (Genova) to compute a
 * parameteric post-Newtonian correction to gravitation. The referenced equation
 * is of the form
 * @f{align*}{
 * \begin{split}
 *   \boldsymbol a_{\text{A,pm-pm}} =&
 *   \phantom{+} \sum_{B\ne A}
 *     \frac{GM_B}{r^3_{AB}}(\boldsymbol r_B - \boldsymbol r_A)
 *     \bigl(1+\frac {s_1} {c^2}\bigr) \\
 *   & + \frac 1 {c^2} \sum_{B\ne A}
 *       \frac{GM_B}{r^3_{AB}}(\boldsymbol v_A - \boldsymbol v_B)
 *       \Bigl(
 *         \bigl( \boldsymbol r_A - \boldsymbol r_B \bigr) \cdot
 *         \bigl( (2+2\gamma)\boldsymbol v_A - (1+2\gamma)\boldsymbol v_B \bigr)
 *       \Bigr) \\
 *   & + \frac {3+4\gamma} {2c^2}
 *       \sum_{B\ne A} \frac{GM_B}{r_{AB}} \boldsymbol a_B
 * \end{split}
 * @f}
 * where @f$ \boldsymbol a_B @f$ is the net acceleration of gravitating body *B*
 * toward the other gravitating bodies (typically taken to be the Newtonian
 * gravitational acceleration) and
 * @f{equation*}{
 *  \begin{split}
 *  s_1 =
 *    & - 2(\beta+\gamma) \sum_{C\ne A}\frac{GM_C}{r_{AC}}
 *      - (2\beta-1) \sum_{C\ne A}\frac{GM_C}{r_{BC}} \\
 *    & + \gamma v_a^2
 *      + (1+\gamma) v_b^2
 *      - 2(1+\gamma)\boldsymbol v_A \cdot \boldsymbol v_B \\
 *    & - \frac32
 *        \left(
 *          \frac{(\boldsymbol r_A - \boldsymbol r_B) \cdot \boldsymbol v_B}{r_B}
 *         \right)^2 \\
 *    & + \frac12(\boldsymbol r_B - \boldsymbol r_A)\cdot \boldsymbol a_B
 *  \end{split}
 * @f}
 * In terms of the referenced equation, the intent of this function is to compute
 * the relativistic portion of the acceleration of body *A* toward body *B*.
 * With this, the expression this function computes is
 * @f{equation*}{
 * \begin{split}
 *   \boldsymbol \Delta a_{\text{A,B}} =
 *   \frac 1 c^2 \frac {GM_B}{r_{AB}} \Biggl\{ &
 *     \phantom{+} \frac{\boldsymbol r_B - \boldsymbol r_A}{r^2_{AB}} s_1 \\
 *   & + \frac{\boldsymbol v_A - \boldsymbol v_B}{r^2_{AB}}
 *       \Bigl(
 *         \bigl( \boldsymbol r_A - \boldsymbol r_B \bigr) \cdot
 *         \bigl( (2+2\gamma)\boldsymbol v_A - (1+2\gamma)\boldsymbol v_B \bigr)
 *       \Bigr) \\
 *   & + \frac {3+4\gamma}{2} \boldsymbol a_B
 *   \Biggr\}
 * \end{split}
 * @f}
 * Note that the common factor @f$ \frac 1 c^2 \frac {GM_B}{r_{AB}} @f$
 * is unitless and thus each of the three terms in the braced expression
 * has units of acceleration.
 *
 * The referenced equations explicitly involve the parameterized post-Newtonian
 * (PPN) factors @f$ \beta @f$ and @f$ \gamma @f$. This function hardcodes both
 * of those factors as one, consistent with general relativity.
 * For example, the factor @f$ (3+4\gamma)/2 @f$ becomes 3.5 in the code.
 * Magic numbers that involve @f$ \beta @f$ or @f$ \gamma @f$, including a
 * factor of one (e.g., @f$ 2 \beta - 1 @f$), are noted in comments.
 *
 * @par References:
 *  - William M. Folkner, et al., *Planetary and Lunar Ephemerides DE430 and
 *    DE431*, IPN Progress Report 42-196, 15 February 2014.\n
 *    ftp://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/de430_and_de431.pdf
 *  - Antonio Genova, et al., *Solar system expansion and strong equivalence
 *    principle as seen by the NASA MESSENGER mission*,
 *    Nature Communications 9:289, 18 January 2018,
 *    DOI: 10.1038/s41467-017-02558-1.\n
 *    https://www.nature.com/articles/s41467-017-02558-1
 */


/**
 * Find the gravitational body with the given name.
 * @return Pointer to found body
 * \param[in] source_name Name of gravity source to be found
 */


/**
 * Create a gravitational body, initialize it with the supplied
 * gravity coefficients, and add it to the vector of bodies.
 * \param[in] source Gravity source to be added
 */


/**
 * Pass the initialize_state method to each GravitySource object registered
 * with the gravity manager.
 *
 * \par Assumptions and Limitations
 *  - Initialization phasing: The following must have been called prior to
 *       calling this method:
 *        - GravityManager::initialize_model to register the GravityManager object
 *          with the dynamics manager
 *        - GravityManager::add_grav_source to register all GravitySource objects in
 *          the simulation with the gravity manager.
 *        - Planet::register_model to associate the planet with a GravitySource.
 *        - DynamicsManager::activate_ephemerides to identify which reference
 *          frames can serve as integration frames.
 * \param[in,out] manager Dynamics manager
 */


// Compute gravitational attraction of gravitational bodies on the
// provided dynamic body.
// Note: This overload of GravityManager::gravitation is deprecated.


// Compute gravitational attraction of gravitational bodies on the
// provided dynamic body.
// Note: This overload of GravityManager::gravitation provides the ability
// to compute gravitation with a relativistic correction.


/**
 * Pure virtual update method.
 * \param[in] controls Gravity controls for planet
 */


/**
 * Output the current functional degree and order.
 * \param[out] current_degree Current degree
 * \param[out] current_order Current order
 */


/**
 * Output the current functional gradient degree and order.
 * \param[out] curr_grad_degree Current gradient degree
 * \param[out] curr_grad_order Current gradient order
 */


/**
 * Update the functional degree.
 * \param[in] new_degree New desired degree
 */


/**
 * Update the functional order.
 * \param[in] new_order New desired order
 */


/**
 * Update the functional degree and order.
 * \param[in] new_degree New desired degree
 * \param[in] new_order New desired order
 */


/**
 * Update the functional gradient degree.
 * \param[in] new_grad_degree New desired degree
 */


/**
 * Update the functional gradient order.
 * \param[in] new_grad_order New desired order
 */


/**
 * Update the functional gradient degree and order.
 * \param[in] new_grad_degree New desired degree
 * \param[in] new_grad_order New desired order
 */


/**
 * Check the validity of the gravity controls.
 */


/**
 * Command all of the gravitational variation effects to update
 * themselves.
 */


/**
 * Loop over all of the active gravitational variation effects models
 * and aggregate their changes to the gravity coefficients into the
 * top-level delta-coeffs "bin" for this gravity body.
 */


/**
 * Initialize frame states for the gravity body.
 * \param[in] integ_frames All possible integration frames
 * \param[in] gravity_manager Gravity Manager
 */


// gravitational parameter (m3/s2)


/*****************************************************************************
verify_acc_magnitude
Purpose:(comapres the magnitudes of the acceleration)
*****************************************************************************/


/*****************************************************************************
verify_grav_accel
Purpose:(verifies the gravity acceleration)
*****************************************************************************/


/*****************************************************************************
verify_grav_torque
Purpose:(Verifies the gravity torque computation)
*****************************************************************************/


/*******************************************************************************
  Function: initialize
  Purpose: (Initializes the EarthLighting object form the DynManager
            object. Will find the Earth, Sun and Moon objects and do
            the necessary setup to calculate earth lighting)
  Class: (initialization)
*******************************************************************************/


/***************************** TRICK HEADER *******************************

FUNCTION: circle_intersect
PURPOSE:
    (This routine computes the area of intersection of two overlapping
     circles.)

ASSUMPTIONS AND LIMITATIONS:
    ((epsilon comparison in if test help protect against a numerical
      singularity for d_centers = 0.0 ))

******************************************************************************/


/**
 * Calculate earth lighting effects at the given position
 * \param[in] pos_veh The position of the point of interest in the earth inertial frame\n Units: M
 */


/******************************************************************************
 Function: TimeConverter_TAI_New::TimeConverter_TAI_New
 Purpose: (Construct a TimeConverter_TAI_New)
 Class:   (N/A)
******************************************************************************/


/******************************************************************************
 Function: TimeConverter_TAI_New::initialize
 Purpose: (Initialize the converter.)
 Assumptions: (None)
 Class: (N/A)
******************************************************************************/


/**
 * Construct a TimeConverter_STD_UDE
 */


/**
 * Initialize the converter.
 *
 * \par Assumptions and Limitations
 *  - This class converts from TimeDyn to TimeUDE *only*
 * \param[in] parent_ptr Time used to initialize the converter
 * \param[in] child_ptr Other Time used to initialize the converter
 * \param[in] int_dir Conversion direction: +1 a=parent; -1 b=parent; 0 error
 */


/**
 * Construct a Time_UTC
 */


/**
 * Verify the setup.
 *
 * \par Assumptions and Limitations
 *  - None
 * \param[in] master_ptr Time used to initialize the converter
 * \param[in] sub_ptr Other time-type associated with the converter
 * \param[in] int_dir +1 a=parent; -1 b=parent; 0 error
 */


/**
 * Check whether this converter is able to handle the requested conversion(s).
 * If query is compound (e.g. CONV_ALL, CONV_A_TO_B_UPDATE|CONV_B_TO_A_UPDATE)
 * then return true only if capable of all conversions
 * @return whether this converter can do all the conversions
 * \param[in] query converter directions to check
 */


/**
 * Given a value of seconds, propagate to days and trunc_julian_time.
 *
 * \par Assumptions and Limitations
 *  - 86400 seconds = 1 day
 * \param[in] new_seconds new value for seconds\n Units: s
 */


/**
 * Given a value of days, propagate to seconds and trunc_julian_time.
 *
 * \par Assumptions and Limitations
 *  - 86400 seconds = 1 day
 * \param[in] new_days new value for days\n Units: day
 */


/**
 * Given a value of tjt, propagate to seconds and days.
 *
 * \par Assumptions and Limitations
 *  - 86400 seconds = 1 day
 * \param[in] new_tjt new value for Truncated Julian Time\n Units: day
 */


/**
 * Recursively adds elements to the initialization tree.
 * If the "parent" to a time-type is defined, adds the "parent" then
 * returns to adding the "child" type.
 * If the "parent" is not defined it searches for a suitable "parent"
 * from the types already in the tree.  If that search is successful,
 * it adds the "child" to the tree, otherwise it returns without
 * change.
 *
 * \par Assumptions and Limitations
 *  - This is vastly improved if the user defines the parent type
 *      "initialize_from" for each time representation, except the
 *      top-level initializer type.
 *  - Otherwise, the code will build the tree automatically,
 *      but it takes longer and may be less than ideal
 * \param[in] seeking_status status-value for auto-seek
 * \param[in] time_manager_init The TM initializer.
 */


/**
 * Calculate Gregorian calendar date and 24-hour clock representation
 * from Truncated Julian date/time.
 *
 * \par Assumptions and Limitations
 *  - Coverage is from March 1, 1600 onward.
 *  - Produces a time in 24-hour clock format.
 *  - Assumes that the values year, month, day, hour, minute, second, and
 *      truncated_julian_time are all present in the same class.
 */


/**
 * Calls the function that converts the Julian-type representation
 * of time (dd.xxxx days) to a calendar representation.  Makes sure that
 * the time type on which it is called is up-to-date before doing so.
 *
 * \par Assumptions and Limitations
 *  - Derived times must have a parent; this should be defined by the
 *     user, or if not, already determined when the update_tree was built.
 * \param[in] simtime Simulation elapsed time, on the simulation clock\n Units: s
 */


/**
 * Calculate Truncated Julian date/time from Gregorian calendar date and
 * 24-hour clock representation.
 *
 * \par Assumptions and Limitations
 *  - Coverage s from March 1, 1600 onward.
 *  - Assumes that time is in 24-hour clock format; 1:00:00 pm cannot be read
 *      correctly, but 13:00:00 can.
 *  - Assumes that the values year, month, day, hour, minute, second, and
 *      truncated_julian_time are all present in the same class.
 */


//  General case
//  General case


/**
 * Initialize a time type from its parent on the initialization tree
 *
 * \par Assumptions and Limitations
 *  - More than 1 time-type defined, otherwise this is not called.
 * \param[in] time_manager_init The TM initializer.
 */


/**
 * Generate the number of seconds elapsed this year
 *
 * \par Assumptions and Limitations
 *  - Relies on the accuracy of the JEOD2.0 calendar.
 * @return Current second of year.
 */


/**
 * Construct a Time_GPS
 */


/**
 * Sets the epoch for GPS time
 */


/**
 * Protection against inheriting nonsense function
 *
 * \par Assumptions and Limitations
 *  - GPS does not have a conventional calendar
 */


/**
 * Given a value of seconds, propagate to other reps.
 *
 * \par Assumptions and Limitations
 *  - 86400 seconds = 1 day
 * \param[in] new_seconds new value for seconds\n Units: s
 */


/**
 * TJT does not function in GPS.
 *
 * \par Assumptions and Limitations
 *  - 86400 seconds = 1 day
 * \param[in] new_tjt new value for Truncated Julian Time\n Units: day
 */


/**
 * Construct a Time_Dyn
 */


/**
 * Changeing time direction and/or scale factor
 * @return Void
 */


/**
 * Default attempt to add a time-type to the initialization tree
 *
 * \par Assumptions and Limitations
 *  - Fails for TimeDyn, and has to be overwritten for others.
 * \param[in] seeking_status status-value for auto-seek
 * \param[in] time_manager_init TM initializer
 */