Program Listing for File PhysicalModalBody.h

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&params)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&params)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