/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include "EulerArray.h" #include "FullColumn.h" #include "FullMatrix.h" #include "EulerParameters.h" //#include "CREATE.h" //Cannot use CREATE.h in subclasses of std::vector. Why? namespace MbD { template class EulerParametersDot : public EulerArray { //qE aAdot aBdot aCdot pAdotpE public: EulerParametersDot(size_t count) : EulerArray(count) {} EulerParametersDot(size_t count, const T& value) : EulerArray(count, value) {} EulerParametersDot(std::initializer_list list) : EulerArray{ list } {} static std::shared_ptr> FromqEOpAndOmegaOpO(std::shared_ptr> qe, FColDsptr omeOpO); void initialize() override; void calcAdotBdotCdot(); void calcpAdotpE(); FMatDsptr aB(); FColDsptr omeOpO(); std::shared_ptr> qE; FMatDsptr aAdot, aBdot, aCdot; FColFMatDsptr pAdotpE; void calc() override; }; template inline std::shared_ptr> EulerParametersDot::FromqEOpAndOmegaOpO(std::shared_ptr> qEOp, FColDsptr omeOpO) { //auto answer = CREATE>::With(4); //Cannot use CREATE.h in subclasses of std::vector. Why? auto answer = std::make_shared>(4); answer->initialize(); qEOp->calcABC(); auto aB = qEOp->aB; answer->equalFullColumn(aB->transposeTimesFullColumn(omeOpO->times(0.5))); answer->qE = qEOp; answer->calc(); return answer; } template inline void EulerParametersDot::initialize() { aAdot = std::make_shared>(3, 3); aBdot = std::make_shared>(3, 4); aCdot = std::make_shared>(3, 4); pAdotpE = std::make_shared>(4); for (size_t i = 0; i < 4; i++) { pAdotpE->at(i) = std::make_shared>(3, 3); } } template inline void EulerParametersDot::calcAdotBdotCdot() { //"aAdot, aBdot and aCdot are all calculated together and only here." auto aE0dot = this->at(0); auto aE1dot = this->at(1); auto aE2dot = this->at(2); auto aE3dot = this->at(3); auto mE0dot = -aE0dot; auto mE1dot = -aE1dot; auto mE2dot = -aE2dot; aBdot->at(0)->at(0) = aE3dot; aBdot->at(0)->at(1) = mE2dot; aBdot->at(0)->at(2) = aE1dot; aBdot->at(0)->at(3) = mE0dot; aBdot->at(1)->at(0) = aE2dot; aBdot->at(1)->at(1) = aE3dot; aBdot->at(1)->at(2) = mE0dot; aBdot->at(1)->at(3) = mE1dot; aBdot->at(2)->at(0) = mE1dot; aBdot->at(2)->at(1) = aE0dot; aBdot->at(2)->at(2) = aE3dot; aBdot->at(2)->at(3) = mE2dot; aCdot->at(0)->at(0) = aE3dot; aCdot->at(0)->at(1) = aE2dot; aCdot->at(0)->at(2) = mE1dot; aCdot->at(0)->at(3) = mE0dot; aCdot->at(1)->at(0) = mE2dot; aCdot->at(1)->at(1) = aE3dot; aCdot->at(1)->at(2) = aE0dot; aCdot->at(1)->at(3) = mE1dot; aCdot->at(2)->at(0) = aE1dot; aCdot->at(2)->at(1) = mE0dot; aCdot->at(2)->at(2) = aE3dot; aCdot->at(2)->at(3) = mE2dot; aAdot = this->aB()->timesTransposeFullMatrix(aCdot)->times(2.0); } template inline void EulerParametersDot::calcpAdotpE() { //"Mimic calcpApE" //"All aE's are actually aEdot's." double a2E0 = 2.0 * (this->at(0)); double a2E1 = 2.0 * (this->at(1)); double a2E2 = 2.0 * (this->at(2)); double a2E3 = 2.0 * (this->at(3)); double m2E0 = -a2E0; double m2E1 = -a2E1; double m2E2 = -a2E2; double m2E3 = -a2E3; FMatDsptr pApEk; pApEk = pAdotpE->at(0); FRowDsptr pAipEk; pAipEk = pApEk->at(0); pAipEk->at(0) = a2E0; pAipEk->at(1) = a2E1; pAipEk->at(2) = a2E2; pAipEk = pApEk->at(1); pAipEk->at(0) = a2E1; pAipEk->at(1) = m2E0; pAipEk->at(2) = m2E3; pAipEk = pApEk->at(2); pAipEk->at(0) = a2E2; pAipEk->at(1) = a2E3; pAipEk->at(2) = m2E0; // pApEk = pAdotpE->at(1); pAipEk = pApEk->at(0); pAipEk->at(0) = m2E1; pAipEk->at(1) = a2E0; pAipEk->at(2) = a2E3; pAipEk = pApEk->at(1); pAipEk->at(0) = a2E0; pAipEk->at(1) = a2E1; pAipEk->at(2) = a2E2; pAipEk = pApEk->at(2); pAipEk->at(0) = m2E3; pAipEk->at(1) = a2E2; pAipEk->at(2) = m2E1; // pApEk = pAdotpE->at(2); pAipEk = pApEk->at(0); pAipEk->at(0) = m2E2; pAipEk->at(1) = m2E3; pAipEk->at(2) = a2E0; pAipEk = pApEk->at(1); pAipEk->at(0) = a2E3; pAipEk->at(1) = m2E2; pAipEk->at(2) = a2E1; pAipEk = pApEk->at(2); pAipEk->at(0) = a2E0; pAipEk->at(1) = a2E1; pAipEk->at(2) = a2E2; // pApEk = pAdotpE->at(3); pAipEk = pApEk->at(0); pAipEk->at(0) = a2E3; pAipEk->at(1) = m2E2; pAipEk->at(2) = a2E1; pAipEk = pApEk->at(1); pAipEk->at(0) = a2E2; pAipEk->at(1) = a2E3; pAipEk->at(2) = m2E0; pAipEk = pApEk->at(2); pAipEk->at(0) = m2E1; pAipEk->at(1) = a2E0; pAipEk->at(2) = a2E3; } template inline FMatDsptr EulerParametersDot::aB() { return qE->aB; } template inline FColDsptr EulerParametersDot::omeOpO() { auto aaa = this->aB(); // auto bbb = aaa->timesFullColumn((MbD::FColsptr)this); auto bbb = aaa->timesFullColumn(this); auto ccc = bbb->times(2.0); return ccc; //return this->aB->timesFullColumn(this)->times(2.0); } template inline void EulerParametersDot::calc() { qE->calc(); this->calcAdotBdotCdot(); this->calcpAdotpE(); } }