Program Listing for File PhysicalModalBody.h#
↰ Return to documentation for file (include/Karana/SOAFlexDyn/PhysicalModalBody.h)
/*
*Copyright(c)2024-2025KaranaDynamicsPtyLtd.Allrightsreserved.
*
*NOTICETOUSER:
*
*Thissourcecodeand/ordocumentation(the"LicensedMaterials")is
*theconfidentialandproprietaryinformationofKaranaDynamicsInc.
*UseoftheseLicensedMaterialsisgovernedbythetermsandconditions
*ofaseparatesoftwarelicenseagreementbetweenKaranaDynamicsandthe
*Licensee("LicenseAgreement").Unlessexpresslypermittedunderthat
*agreement,anyreproduction,modification,distribution,ordisclosure
*oftheLicensedMaterials,inwholeorinpart,toanythirdparty
*withoutthepriorwrittenconsentofKaranaDynamicsisstrictlyprohibited.
*
*THELICENSEDMATERIALSAREPROVIDED"ASIS"WITHOUTWARRANTYOFANYKIND.
*KARANADYNAMICSDISCLAIMSALLWARRANTIES,EXPRESSORIMPLIED,INCLUDING
*BUTNOTLIMITEDTOWARRANTIESOFMERCHANTABILITY,NON-INFRINGEMENT,AND
*FITNESSFORAPARTICULARPURPOSE.
*
*INNOEVENTSHALLKARANADYNAMICSBELIABLEFORANYDAMAGESWHATSOEVER,
*INCLUDINGBUTNOTLIMITEDTOLOSSOFPROFITS,DATA,ORUSE,EVENIF
*ADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGES,WHETHERINCONTRACT,TORT,
*OROTHERWISEARISINGOUTOFORINCONNECTIONWITHTHELICENSEDMATERIALS.
*
*U.S.GovernmentEndUsers:TheLicensedMaterialsarea"commercialitem"
*asdefinedat48C.F.R.2.101,andareprovidedtotheU.S.Government
*onlyasacommercialenditemunderthetermsofthislicense.
*
*AnyuseoftheLicensedMaterialsinindividualorcommercialsoftwaremust
*include,intheuserdocumentationandinternalsourcecodecomments,
*thisNotice,Disclaimer,andU.S.GovernmentUseProvision.
*/
#pragmaonce
#include"Karana/SOADyn/HingeNode.h"
#include"Karana/SOADyn/Node.h"
#include"Karana/SOADyn/PhysicalBody.h"
namespaceKarana::Dynamics{
namespacekc=Karana::Core;
structPhysicalModalBodyParams:publicPhysicalBodyParams{
size_tnmodes=4;
km::Vecstiffness=km::Vec::NullaryExpr(4,1,[](inti,intj){
return.1*(i+j+1);
});
km::Vecdamping=km::Vec::NullaryExpr(
4,1,[](inti,intj){return.01*(i+j+1);});
km::Matpnode_nodal_matrix=km::Mat::NullaryExpr(6,4,[](inti,intj){
return.1*(i+j+1);
});
km::Matonode_nodal_matrix=km::Mat::NullaryExpr(6,4,[](inti,intj){
return.2*(i+j+1);
});
PhysicalModalBodyParams&operator=(constPhysicalModalBodyParams&p){
if(this!=&p){
PhysicalBodyParams::operator=(p);
//AssignDerived-specificmembershere
nmodes=p.nmodes;
stiffness=p.stiffness;
damping=p.damping;
pnode_nodal_matrix=p.pnode_nodal_matrix;
onode_nodal_matrix=p.onode_nodal_matrix;
}
return*this;
}
};
classModalNodeDeformationProvider:publicNodeDeformationProvider{
//foraccessto_deformation_provider
friendclassPhysicalModalBody;
public:
ModalNodeDeformationProvider(std::string_viewname,kc::ks_ptr<Node>node);
~ModalNodeDeformationProvider();
std::string_viewtypeString()constnoexceptoverride{
staticstd::stringtype_string="Karana::Dynamics::ModalNodeDeformationProvider";
returntype_string;
}
voidsetNodalMatrix(constkm::Mat&nodal_matrix);
constkm::Mat6n&getNodalMatrix()const{return_nodal_matrix;}
kc::ks_ptr<kf::Frame>undeformedFrame()const{return_undeformed_frame;}
kc::ks_ptr<kf::Frame>deformedTransFrame()const{return_deformed_trans_frame;}
kc::ks_ptr<kf::Frame>deformedRotFrame()const{return_deformed_rot_frame;}
//verifythatthenodalmatrixhasbeeninitialized
boolisFinalized()constoverride;
std::stringdumpString(std::string_viewprefix,
constKarana::Core::Base::DumpOptions*options)constoverride;
structDeformationParams:publicNodeDeformationProvider::DeformationParams{
km::Matnodal_matrix;
DeformationParams()=default;
//Addingsuppression,asCodeCheckercomplainsthismethodhasthesamenameasa
//methodinthebaseversion.ThisisjustaCodeCheckerfalsepositive.
//codechecker_suppress[cppcheck-duplInheritedMember]
DeformationParams&operator=(constNodeDeformationProvider::DeformationParams*p){
if(this!=p){
NodeDeformationProvider::DeformationParams::operator=(
p);//Callbaseclassassignmentoperator
nodal_matrix=static_cast<constDeformationParams*>(p)->nodal_matrix;
}
return*this;
}
};
protected:
kc::ks_ptr<NodeDeformationProvider::DeformationParams>_getParams()constoverride;
void_setParams(constNodeDeformationProvider::DeformationParams¶ms)override;
void_discard(kc::ks_ptr<Base>&base)override;
km::HomTran_transFrameRelTransformHelper()const;
km::SpatialVector_transFrameRelSpVelHelper()const;
km::SpatialVector_transFrameRelSpAccelHelper()const;
km::HomTran_rotFrameRelTransformHelper()const;
km::SpatialVector_rotFrameRelSpVelHelper()const;
km::SpatialVector_rotFrameRelSpAccelHelper()const;
/*thefollowinghelpermethodsarethepnode'sdeformationf2f
callbacks.Becauseofthereversedconnectionforpnodes,weneedto
usethepframeversionsoftheregularnodedefomationcallbacks
*/
km::HomTran_transFrameRelTransformReversedHelper()const;
km::SpatialVector_transFrameRelSpVelReversedHelper()const;
km::SpatialVector_transFrameRelSpAccelReversedHelper()const;
km::HomTran_rotFrameRelTransformReversedHelper()const;
km::SpatialVector_rotFrameRelSpVelReversedHelper()const;
km::SpatialVector_rotFrameRelSpAccelReversedHelper()const;
protected:
km::Mat6n_nodal_matrix;
/*Normallywehavethefollowingintermediateframesbetweenthe
body'sfloatingframeandanodesframetoaccommodatethe
deformations.
Body->undeformed->deformed_trans->deformed_rot->node
TheBody->undeformedframetransformisfixedanddefinesthe
locationofthenodeintheundeformedconfiguration.The
undeformed->deformed_transtransformconsistsofthe
translationaldeformation.Notethatthebodyframe,the
undeformedframeandthedeformed_transframeareall
parallel.Thedeformed_trans->deformed_rottransformcontains
consistsoftherotationaldeformation.Thedeformed_rot->node
transformconsistsofthefixedrotationalforthenodemount.
Whilethisisthenormalattachmentsequencefromthebody
frametoanodeonthebody,oneexceptionispnodeforwhich
theattachmentsequenceisreversed.However,thetransforms
foreachoftheedgehavethesamedefinitionasfortheother
nodes.
Oneofthereasonsforseparatingoutthetrans/rotparts
acrosstwoframesisthatnodalequationsofmotionusenode
accelerationsthataredifferentiatedinthenode'slocal
deformedframe,whilethemodeshapesaredefinedinthebody
frameandindependentofbodydeformation.
*/
kc::ks_ptr<kf::Frame>_undeformed_frame=nullptr;
kc::ks_ptr<kf::Frame>_deformed_trans_frame=nullptr;
kc::ks_ptr<kf::Frame>_deformed_rot_frame=nullptr;
};
classPhysicalModalBody:publicPhysicalBody{
//Foraccesstodiscard
friendclassModalNodeDeformationProvider;
public:
statickc::ks_ptr<PhysicalModalBody>
create(std::string_viewname,kc::ks_ptr<Multibody>mbs,size_tnmodes);
PhysicalModalBody(std::string_viewname,kc::ks_ptr<Multibody>mb,size_tnmodes);
~PhysicalModalBody();
std::string_viewtypeString()constnoexceptoverride{
staticstd::stringtype_string="Karana::Dynamics::PhysicalModalBody";
returntype_string;
}
voidsetBodyToJointTransform(constkm::HomTran&t)override;
km::HomTrangetBodyToJointTransform()constoverride;
boolisFinalized()constoverride;
km::VecgetStiffnessVector()const;
voidsetStiffnessVector(constkm::Vec&stiffness);
km::VecgetDampingVector()const;
voidsetDampingVector(constkm::Vec&damping);
std::stringdumpString(std::string_viewprefix,
constKarana::Core::Base::DumpOptions*options)constoverride;
/*Thismethodassumesthattheframeisonoroutboardofthisbody's
pnodeframe.*/
km::Matjacobian(constkf::Frame&target,booloriented)constoverride;
/*Computethebodynode'sOSCMUpsilonmatrixfromthepnode's
Upsilonmatrix.Alsousedtocomputethechildonode
UpsilonPlusvalueaftercrossingthemodaldofs.Theresult
lhs/rhsareinthenodeframe.*/
km::Mat66getNodeUpsilonFromPnode(constNode&node)override;
/*Computethebodynode'sOSCMUpsilonmatrixfromthebody's
Upsilonmatrix.Alsousedtocomputethechildonode
UpsilonPlusvalueaftercrossingthemodaldofs.Theresult
lhs/rhsareinthenodeframe.*/
km::Mat66getNodeUpsilonFromBody(constNode&node)override;
km::MatgetUpsilonMatrix()override;
voidsetParams(constPhysicalBodyParams¶ms)override;
staticstd::vector<kc::ks_ptr<PhysicalBody>>
//Addingsuppression,asCodeCheckercomplainsthismethodhasthesamenameasamethodin
//thebaseversion.ThisisjustaCodeCheckerfalsepositive.
//codechecker_suppress[cppcheck-duplInheritedMember]
addSerialChain(std::string_viewname,
size_tnbodies,
PhysicalBody&root,
HingeBase::HingeTypehtype=HingeBase::HingeType::PIN,
PhysicalBodyParams*params=nullptr);
staticstd::vector<kc::ks_ptr<PhysicalBody>>
//Addingsuppression,asCodeCheckercomplainsthismethodhasthesamenameasamethodin
//thebaseversion.ThisisjustaCodeCheckerfalsepositive.
//codechecker_suppress[cppcheck-duplInheritedMember]
addTree(std::string_viewname,
size_tbranch_length,
size_tnbranches,
size_tdepth,
PhysicalBody&root,
HingeBase::HingeTypehtype=HingeBase::HingeType::PIN,
PhysicalBodyParams*params=nullptr);
constkm::MatatbiCoordMapMatrix()constoverride{
return_atbi_coord_map_matrix_cache->get();
}
protected:
constkm::Mat&_atbiCoordMapMatrix()const{return_atbi_coord_map_matrix_cache->get();}
structATBIMatrices:publicCoordBase::ATBIMatrices{
//public:
/*the(nodes+6)sizesquarePmatrixbeforecrossingthe
deformationdofs*/
km::MatP;
/*the6x6Pplusmatrixaftercrossingthedeformationdofs*/
km::Mat66Pplus;//NOLINT(readability-identifier-naming)
km::MatHP;//NOLINT(readability-identifier-naming)
km::MatD;
km::MatDinv;//NOLINT(readability-identifier-naming)
km::MatG;
km::Mattauper;
km::Matpsi;
voidresize(size_tmodal_n_u,size_tbody_n_u){
P.resize(modal_n_u+body_n_u,modal_n_u+body_n_u);
P.setZero();
HP.resize(modal_n_u,body_n_u);
D.resize(modal_n_u,modal_n_u);
Dinv.resize(modal_n_u,modal_n_u);
G.resize(body_n_u,modal_n_u);
tauper.resize(body_n_u,body_n_u+modal_n_u);
psi.resize(body_n_u,body_n_u+modal_n_u);
km::uninitialize(HP);
km::uninitialize(D);
km::uninitialize(Dinv);
km::uninitialize(G);
km::uninitialize(tauper);
km::uninitialize(psi);
}
};
structATBIFilterVectors:publicCoordBase::ATBIFilterVectors{
public:
/*the(nodes+6)sizeATBIzvectorbeforecrossingthe
deformationdofs.*/
km::Vecz;
/*thezplusATBIspatialvectoraftercrossingthe
deformationdofs-aboutandrepresentedinthepnode
frame.*/
km::SpatialVectorzplus;
km::Vecepsilon;
km::Vecnu;
voidresize(size_tmodal_n_u){
z.resize(modal_n_u+6);
epsilon.resize(modal_n_u);
nu.resize(modal_n_u);
km::uninitialize(epsilon);
km::uninitialize(nu);
}
voiddump(std::string_viewindent)const;
};
structATBISmootherVectors{
km::SpatialVectoralpha_plus;
};
protected:
structSZNodeMatrices{
km::MatS;//nUx6,therhsisinthepnodedeform
//translationalframe
km::Mat66Z;//6x6,thelhs&rhsarebothinthepnodedeform
//translationalframe
};
structModalUpsilonMatrices{
km::MatUpsilon;//NOLINT(readability-identifier-naming)
};
km::MatpframeCoordMapMatrix()constoverride;
km::MatgetATBIMatPsi()constoverride;
km::MatgetATBID()constoverride;
km::MatgetATBIDinv()constoverride;
km::MatgetATBIG()constoverride;
km::MatgetATBITauper()constoverride;
protected:
km::Mat_oframe2pframePsi()constoverride;
km::Mat_oframe2pframePhi()constoverride;
km::Mat_pframe2otherPhi(constkf::Frame&other)constoverride;
void_setupNode(Node&nd,boolforce_node)override;
void_detachNode(kc::ks_ptr<Node>&node)override;
km::Mat_getM()const;
km::Mat_getMff()const;
km::Mat_getMfr()const;
void_discardNodeDeformationProvider(kc::ks_ptr<Node>nd);
void_discardPnodeDeformationProvider();
protected:
km::SpatialVector_getPnodeATBIFilterZ()override;
km::Mat66_getPnodeATBIMatricesP()override;
km::SpatialVector_getOnodeATBISmootherAlphaPlus(constHingeOnode&ond)override;
void_processPnodeATBISmootherVectors()override;
km::SpatialVector_getPnodeInvDynForcesF()override;
SZNodeMatrices_computeSZMatrices(constNode&node);
km::Mat66_pnodeToChildNodeTransform(constNode&node)override;
km::Mat_bodyToChildNodeTransform(constNode&node,
constkf::Frame&from_frame)constoverride;
/*Cachecallbacktocomputethefull(_nU+6)x(_nU+hge_nU)
sizeHstmatrixfortheflexbodyatthepnodeframe
*/
void_computeATBICoordMapMatrix(km::Mat&)const;
km::Mat_computeHst_Mfl(constkf::Frame&at_frame)const;
constkm::Vec_externalModalForces()const;
constkm::Vec_constraintModalForces()const;
protected:
void_setupNodeDeformation(kc::ks_ptr<Node>nd);
void_setupPnodeDeformation();
void_discardHingePnode()override;
void_discardHingeOnode(kc::ks_ptr<HingeOnode>&onode)override;
/*createapnodewithmodaldeformationwithanodalmatrixandundeformed
intermediateframe.Thebodywillbeachildofthepnode.*/
kc::ks_ptr<HingePnode>_createPnode(boolfloating_frame)override;
/*createaonodewithmodaldeformationwithanodalmatrixandundeformed
intermediateframe.*/
kc::ks_ptr<HingeOnode>_createOnode(std::string_viewname)override;
void_setBodyToNodeTransform(Node&node,constkm::HomTran&t)override;
km::HomTran_getBodyToNodeTransform(constNode&node)constoverride;
/*transformthe(nU+6)x(nU+6)bodyflexmasspropertiesmatrix
fromthebodyframetothespecifiedframe(usuallypnodeor
pnode_trans*/
km::Mat_getMassAtFrame(constkf::Frame&frame)const;
void_getPnodeCRBInertiaMatrix(km::Mat&R)override;
protected:
void_oneTimeSetupDataCaches();
void_oneTimeTeardownDataCaches();
protected:
km::Vec_stiffness_vector;
km::Vec_damping_vector;
bool_using_modal_integrals=false;
//ATBIDataCaches_atbi_data_caches;
ModalUpsilonMatrices_modal_upsilon_matrices;
kc::ks_ptr<kc::DataCache<km::Mat>>_atbi_coord_map_matrix_cache=nullptr;
};
}//namespaceKarana::Dynamics