text: // =============================================================================
  // PROJECT CHRONO - http://projectchrono.org
  //
  // Copyright (c) 2014 projectchrono.org
  // All rights reserved.
  //
  // Use of this source code is governed by a BSD-style license that can be found
  // in the LICENSE file at the top level of the distribution and at
  // http://projectchrono.org/license-chrono.txt.
  //
  // =============================================================================
  // Authors: Alessandro Tasora
  // =============================================================================
  
  #ifndef CHBEAMSECTIONTAPEREDTIMOSHENKOFPM_H
  #define CHBEAMSECTIONTAPEREDTIMOSHENKOFPM_H
  
  #include "chrono/core/ChMath.h"
  #include "chrono/fea/ChBeamSectionTaperedTimoshenko.h"
  
  namespace chrono {
  namespace fea {
  
  /// @addtogroup fea_utils
  /// @{
  
  /// Base class for all constitutive models of sections of Euler beams.
  /// To be used with ChElementBeamEuler.
  /// For practical purposes, either you use the concrete inherited classes like ChBeamSectionEulerSimple,
  /// ChBeamSectionEulerAdvanced etc., or you inherit your class from this.
  class ChApi ChBeamSectionTimoshenkoAdvancedGenericFPM : public ChBeamSectionTimoshenkoAdvancedGeneric {
  protected:
  	// material stiffness matrix of cross-section, 
  	// given at elastic center and elastic principal axis orientation,
  	// the shear principal axis orientation is assumed same as elastic one.
  	ChMatrixNM<double, 6, 6> Klaw;
  
  public:
  	ChBeamSectionTimoshenkoAdvancedGenericFPM() : Klaw(ChMatrixNM<double, 6, 6>::Identity(6, 6)) {}
  
  	ChBeamSectionTimoshenkoAdvancedGenericFPM(
  		const ChMatrixNM<double, 6, 6> mKlaw,
  		const double malpha,  ///< section rotation about elastic center [rad]
  		const double mCy,     ///< elastic center y displacement respect to centerline
  		const double mCz,     ///< elastic center z displacement respect to centerline
  		const double mSy,     ///< shear center y displacement respect to centerline
  		const double mSz,     ///< shear center z displacement respect to centerline
  		const double mmu,     ///< mass per unit length
  		const double
  		mJyy,  ///< inertia Jyy per unit lenght, in centerline reference, measured along centerline main axes
  		const double
  		mJzz,  ///< inertia Jzz per unit lenght, in centerline reference, measured along centerline main axes
  		const double
  		mJyz = 0,  ///< inertia Jyz per unit lenght, in centerline reference, measured along centerline main axes const
  		const double mQy = 0,  ///< inertia Qy per unit lenght, in centerline reference, measured along centerline main axes
  		const double mQz = 0,  ///< inertia Qz per unit lenght, in centerline reference, measured along centerline main axes
  		const double mMy = 0,  ///< mass center y displacement respect to centerline
  		const double mMz = 0)  ///< mass center z displacement respect to centerline
  	{
  		Klaw = mKlaw;
  		Ax = mKlaw(0, 0);
  		GAyy = mKlaw(1, 1);
  		GAzz = mKlaw(2, 2);
  		Txx = mKlaw(3, 3);
  		Byy = mKlaw(4, 4);
  		Bzz = mKlaw(5, 5);
  		alpha = malpha;
  		Cy = mCy;
  		Cz = mCz;
  		Sy = mSy;
  		Sz = mSz;
  		mu = mmu;
  		Jyy = mJyy;
  		Jzz = mJzz;
  		Jyz = mJyz;
  		Qy = mQy;
  		Qz = mQz;
  		My = mMy;
  		Mz = mMz;
  	}
  
  	virtual ~ChBeamSectionTimoshenkoAdvancedGenericFPM() {}
  
  	virtual void SetFullyPopulatedMaterialStiffnessMatrix(const ChMatrixNM<double, 6, 6> mKlaw) {
  		this->Klaw = mKlaw;
  		this->Ax = mKlaw(0, 0);
  		this->GAyy = mKlaw(1, 1);
  		this->GAzz = mKlaw(2, 2);
  		this->Txx = mKlaw(3, 3);
  		this->Byy = mKlaw(4, 4);
  		this->Bzz = mKlaw(5, 5);
  	}
  
  	virtual ChMatrixNM<double, 6, 6>& GetFullyPopulatedMaterialStiffnessMatrix() { return this->Klaw; }
  
  };
  
  class ChApi ChBeamSectionTaperedTimoshenkoAdvancedGenericFPM : public ChBeamSectionTaperedTimoshenkoAdvancedGeneric {
  public:
  
  	ChBeamSectionTaperedTimoshenkoAdvancedGenericFPM() {}
  	virtual ~ChBeamSectionTaperedTimoshenkoAdvancedGenericFPM() {}
  
  
  	/// Set the section & material of beam element .
  	/// It is a shared property, so it can be shared between other beams.
      void SetSectionA(std::shared_ptr<ChBeamSectionTimoshenkoAdvancedGenericFPM> my_material) {
          section_fpmA = my_material;
          sectionA = std::dynamic_pointer_cast<ChBeamSectionTimoshenkoAdvancedGeneric>(my_material);
      }
      void SetSectionB(std::shared_ptr<ChBeamSectionTimoshenkoAdvancedGenericFPM> my_material) {
          section_fpmB = my_material;
          sectionB = std::dynamic_pointer_cast<ChBeamSectionTimoshenkoAdvancedGeneric>(my_material);
      }
  
  	/// Get the section & material of the element
      std::shared_ptr<ChBeamSectionTimoshenkoAdvancedGenericFPM> GetSectionA() { return section_fpmA; }
      std::shared_ptr<ChBeamSectionTimoshenkoAdvancedGenericFPM> GetSectionB() { return section_fpmB; }
  
  	ChMatrixNM<double, 6, 6>& GetAverageFPM() { return average_fpm; }
  
  	/// Compute the 12x12 sectional inertia matrix, as in  {x_momentum,w_momentum}=[Mm]{xvel,wvel}
      /// The matrix is computed in the material reference (i.e. it is the sectional mass matrix)
      virtual void ComputeInertiaMatrix(ChMatrixDynamic<>& M  ///< 12x12 sectional mass matrix values here
      );
  
  protected:
  	std::shared_ptr<ChBeamSectionTimoshenkoAdvancedGenericFPM> section_fpmA;
  	std::shared_ptr<ChBeamSectionTimoshenkoAdvancedGenericFPM> section_fpmB;
  
  	// Some important average section parameters, to calculate once, enable to access them conveniently.
  	ChMatrixNM<double, 6, 6> average_fpm;
  
  	virtual void ComputeAverageFPM();
  
  };
  
  	/// @} fea_utils
  
  }  // end namespace fea
  }  // end namespace chrono
  
  #endif
  