rigid_rotation.hpp cmath stdexcept serif/discretization/forms/value.hpp serif/utils/error/errors.hpp src/include/serif/equations/angular_momentum.hpp src/include/serif/equations/barotropic_density.hpp src/include/serif/equations/companion.hpp src/include/serif/equations/equations.hpp src/include/serif/equations/surface_potential.hpp serif::equations::RigidRotation serif serif::equations An equation implementing rigid rotation. Emily M. Boudreaux #pragmaonce #include<cmath> #include<stdexcept> #include"serif/discretization/forms/value.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::equations { classRigidRotationfinal { public: usingVector=discretization::forms::VectorValue; usingMatrix=discretization::forms::MatrixValue; explicitRigidRotation( constVector&angular_velocity_vector, constVector&axis_origin={} ): m_angular_velocity_vector(angular_velocity_vector), m_axis_origin(axis_origin) { usingnamespaceutils::errors; doubleangular_speed_squared=0.0; boolfinite_axis_origin=true; //|ω|²=ωₓ²+ωᵧ²+ω_z². for(intcomponent=0;component<3;++component) { finite_axis_origin=finite_axis_origin&&std::isfinite(axis_origin[component]); angular_speed_squared+=angular_velocity_vector[component]*angular_velocity_vector[component]; } serif_ensure<SERiFErrorCode::NON_FINITE_VALUE_ERROR,std::invalid_argument>(finite_axis_origin&&std::isfinite(angular_speed_squared),"Rigidrotationrequiresfinitecentercoordinatesandfinitesquaredangularspeed;reduceoverflowingparameters."); //H=∇∇Ψ=|ω|²I−ω⊗ω. for(introw=0;row<3;++row) { for(intcolumn=0;column<3;++column) { m_potential_hessian[row][column]=(row==column?angular_speed_squared:0.0)-angular_velocity_vector[row]*angular_velocity_vector[column]; } } } [[nodiscard]]staticRigidRotationunit_rotation(Vectorrotation_axis={0.0,0.0,1.0},constVector&axis_origin={}) { usingnamespaceutils::errors; constdoubleaxis_norm=std::hypot(rotation_axis[0],rotation_axis[1],rotation_axis[2]); serif_ensure<SERiFErrorCode::INVALID_ARGUMENT,std::invalid_argument>(std::isfinite(axis_norm)&&axis_norm>0.0,"Arotationaxismustbefiniteandnonzero."); for(double&component:rotation_axis) { component/=axis_norm; } returnRigidRotation(rotation_axis,axis_origin); } [[nodiscard]]doublecentrifugal_potential(constVector&position)const { doublelinear_speed_squared=0.0; for(intcomponent=0;component<3;++component) { //Theseareallowedtocyclethroughthecomponentsofthevector. //Forsomecomponentcthiswilllooklike.Notethisis //justatricktogettheappropriateindicesfor //thecrossproduct. /* *|component|next|last| *|===========|======|======| *|0|1|2| *|1|2|0| *|2|0|1| */ constintnext=(component+1)%3; constintlast=(component+2)%3; //vᵢ=ωⱼλₖ−ωₖλⱼ,with(i,j,k)cyclic. //Gettothisbyremembering //v=ωxλ //sothen,triviallyfromthecrossproduct,vhastheform //v_x=ω_yλ_z-ω_zλ_y //v_y=ω_zλ_x-ω_xλ_z //v_z=ω_xλ_y-ω_yλ_x //Theequationforthepotentialis //φ=1/2|v|^2 //Sincewecancalculateeachcomponentofvusingthecyclicpermutationofthe //indicesitistriviallytocomputethesquaredmagnitudeofvbysummingthesquares //ofeachcomponent.Thenwesimplymultiplyby1/2(outsideoftheloop) //togetthepotential. constdoublevelocity_component=m_angular_velocity_vector[next]*(position[last]-m_axis_origin[last])-m_angular_velocity_vector[last]*(position[next]-m_axis_origin[next]); linear_speed_squared+=velocity_component*velocity_component; } return0.5*linear_speed_squared; } [[nodiscard]]Vectorcentrifugal_potential_gradient(constVector&position)const { Vectorresult{}; for(introw=0;row<3;++row) { for(intcolumn=0;column<3;++column) { result[row]+=m_potential_hessian[row][column]*(position[column]-m_axis_origin[column]); } } returnresult; } [[nodiscard]]constMatrix&centrifugal_potential_hessian()const { returnm_potential_hessian; } [[nodiscard]]constVector&angular_velocity_vector()const { returnm_angular_velocity_vector; } [[nodiscard]]constVector&axis_origin()const { returnm_axis_origin; } private: Vectorm_angular_velocity_vector; Vectorm_axis_origin; Matrixm_potential_hessian{}; }; }//namespaceserif::equations