MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
asynchronous_machine Class Reference
Inheritance diagram for asynchronous_machine:
Collaboration diagram for asynchronous_machine:

Public Member Functions

 asynchronous_machine (unsigned uLabel, const DofOwner *pDO, DataManager *pDM, MBDynParser &HP)
 Constructs the element from the information in the input file.
More...
 
virtual ~asynchronous_machine (void)
 
virtual void Output (OutputHandler &OH) const
 Writes private data to a file at each time step. More...
 
virtual unsigned int iGetNumDof (void) const
 The number of private degrees of freedom is determined by this member function. More...
 
virtual DofOrder::Order GetDofType (unsigned int i) const
 The type of the equation of the private degrees of freedom is determined by this member function. More...
 
virtual std::ostream & DescribeDof (std::ostream &out, const char *prefix, bool bInitial) const
 This member function is called if the statement "print: dof description;" is specified in the input file. More...
 
virtual std::ostream & DescribeEq (std::ostream &out, const char *prefix, bool bInitial) const
 This member function is called if the statement "print: equation description;" is specified in the input file. More...
 
virtual unsigned int iGetNumPrivData (void) const
 This member function is called when a bind statement or a element drive is used to access private data of this element. More...
 
virtual unsigned int iGetPrivDataIdx (const char *s) const
 The following string values can be specified in a bind statement or in an element drive caller. More...
 
virtual doublereal dGetPrivData (unsigned int i) const
 This member function is called whenever a bind statement or a element drive is used to access private data. More...
 
virtual void SetInitialValue (VectorHandler &X)
 
virtual void Update (const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
 This member function is called after each iteration in the nonlinear solution phase. More...
 
virtual void AfterPredict (VectorHandler &X, VectorHandler &XP)
 
virtual void WorkSpaceDim (integer *piNumRows, integer *piNumCols) const
 The size of the contribution to the residual and the jacobian matrix is determined by this member function. More...
 
VariableSubMatrixHandlerAssJac (VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
 Computes the contribution to the jacobian matrix $\boldsymbol{Jac}$.
More...
 
SubVectorHandlerAssRes (SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
 This member function implements the equation of an asynchronous machine according to Maschinendynamik Springer 2009, Dresig, Holzweißig.
More...
 
virtual int iGetNumConnectedNodes (void) const
 This member function is called if the statement "print: node connection;" is specified in the input file. More...
 
virtual void GetConnectedNodes (std::vector< const Node * > &connectedNodes) const
 This member function is called if the statement "print: node connection;" is specified in the input file. More...
 
virtual void SetValue (DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *ph)
 This member function is called before the integration starts in order to set the initial values for the private degrees of freedom. More...
 
virtual std::ostream & Restart (std::ostream &out) const
 This member function is called if "make restart file;" is specified in the input file. More...
 
virtual unsigned int iGetInitialNumDof (void) const
 This member function must be implemented only if the initial assembly feature is requested. More...
 
virtual void InitialWorkSpaceDim (integer *piNumRows, integer *piNumCols) const
 
virtual VariableSubMatrixHandlerInitialAssJac (VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
 
virtual SubVectorHandlerInitialAssRes (SubVectorHandler &WorkVec, const VectorHandler &XCurr)
 
- Public Member Functions inherited from Elem
 Elem (unsigned int uL, flag fOut)
 
virtual ~Elem (void)
 
virtual void DescribeDof (std::vector< std::string > &desc, bool bInitial=false, int i=-1) const
 
virtual void DescribeEq (std::vector< std::string > &desc, bool bInitial=false, int i=-1) const
 
virtual void AssMats (VariableSubMatrixHandler &WorkMatA, VariableSubMatrixHandler &WorkMatB, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
 
virtual bool bInverseDynamics (void) const
 
void SetInverseDynamicsFlags (unsigned uIDF)
 
unsigned GetInverseDynamicsFlags (void) const
 
bool bIsErgonomy (void) const
 
bool bIsRightHandSide (void) const
 
virtual VariableSubMatrixHandlerAssJac (VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
 
virtual SubVectorHandlerAssRes (SubVectorHandler &WorkVec, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr, const VectorHandler &XPrimePrimeCurr, InverseDynamics::Order iOrder=InverseDynamics::INVERSE_DYNAMICS)
 
virtual int GetNumConnectedNodes (void) const
 
- Public Member Functions inherited from WithLabel
 WithLabel (unsigned int uL=0, const std::string &sN="")
 
virtual ~WithLabel (void)
 
void PutLabel (unsigned int uL)
 
void PutName (const std::string &sN)
 
unsigned int GetLabel (void) const
 
const std::string & GetName (void) const
 
- Public Member Functions inherited from SimulationEntity
 SimulationEntity (void)
 
virtual ~SimulationEntity (void)
 
virtual bool bIsValidIndex (unsigned int i) const
 
virtual DofOrder::Order GetEqType (unsigned int i) const
 
virtual HintParseHint (DataManager *pDM, const char *s) const
 
virtual void BeforePredict (VectorHandler &, VectorHandler &, VectorHandler &, VectorHandler &) const
 
virtual void DerivativesUpdate (const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
 
virtual void Update (const VectorHandler &XCurr, InverseDynamics::Order iOrder)
 
virtual void AfterConvergence (const VectorHandler &X, const VectorHandler &XP)
 
virtual void AfterConvergence (const VectorHandler &X, const VectorHandler &XP, const VectorHandler &XPP)
 
virtual std::ostream & OutputAppend (std::ostream &out) const
 
virtual void ReadInitialState (MBDynParser &HP)
 
- Public Member Functions inherited from ToBeOutput
 ToBeOutput (flag fOut=fDefaultOut)
 
virtual ~ToBeOutput (void)
 
virtual void OutputPrepare (OutputHandler &OH)
 
virtual void Output (OutputHandler &OH, const VectorHandler &X, const VectorHandler &XP) const
 
virtual flag fToBeOutput (void) const
 
virtual bool bToBeOutput (void) const
 
virtual void SetOutputFlag (flag f=flag(1))
 
- Public Member Functions inherited from UserDefinedElem
 UserDefinedElem (unsigned uLabel, const DofOwner *pDO)
 
virtual ~UserDefinedElem (void)
 
bool NeedsAirProperties (void) const
 
void NeedsAirProperties (bool yesno)
 
virtual Elem::Type GetElemType (void) const
 
virtual AerodynamicElem::Type GetAerodynamicElemType (void) const
 
- Public Member Functions inherited from InitialAssemblyElem
 InitialAssemblyElem (unsigned int uL, flag fOut)
 
virtual ~InitialAssemblyElem (void)
 
- Public Member Functions inherited from SubjectToInitialAssembly
 SubjectToInitialAssembly (void)
 
virtual ~SubjectToInitialAssembly (void)
 
- Public Member Functions inherited from AerodynamicElem
 AerodynamicElem (unsigned int uL, const DofOwner *pDO, flag fOut)
 
virtual ~AerodynamicElem (void)
 
virtual const InducedVelocitypGetInducedVelocity (void) const
 
- Public Member Functions inherited from ElemWithDofs
 ElemWithDofs (unsigned int uL, const DofOwner *pDO, flag fOut)
 
virtual ~ElemWithDofs (void)
 
- Public Member Functions inherited from DofOwnerOwner
 DofOwnerOwner (const DofOwner *pDO)
 
virtual ~DofOwnerOwner ()
 
virtual const DofOwnerpGetDofOwner (void) const
 
virtual integer iGetFirstIndex (void) const
 
- Public Member Functions inherited from AirPropOwner
 AirPropOwner (void)
 
virtual ~AirPropOwner (void)
 
virtual void PutAirProperties (const AirProperties *pAP)
 
virtual flag fGetAirVelocity (Vec3 &Velocity, const Vec3 &X) const
 
virtual doublereal dGetAirDensity (const Vec3 &X) const
 
virtual doublereal dGetAirPressure (const Vec3 &X) const
 
virtual doublereal dGetAirTemperature (const Vec3 &X) const
 
virtual doublereal dGetSoundSpeed (const Vec3 &X) const
 
virtual bool GetAirProps (const Vec3 &X, doublereal &rho, doublereal &c, doublereal &p, doublereal &T) const
 
- Public Member Functions inherited from ElemGravityOwner
 ElemGravityOwner (unsigned int uL, flag fOut)
 
virtual ~ElemGravityOwner (void)
 
virtual doublereal dGetM (void) const
 
Vec3 GetS (void) const
 
Mat3x3 GetJ (void) const
 
Vec3 GetB (void) const
 
Vec3 GetG (void) const
 
- Public Member Functions inherited from GravityOwner
 GravityOwner (void)
 
virtual ~GravityOwner (void)
 
void PutGravity (const Gravity *pG)
 
virtual bool bGetGravity (const Vec3 &X, Vec3 &Acc) const
 

Private Member Functions

bool IsMotorOn (void) const
 If a drive caller has been specified in the input file the value returned by the drive caller is used to determine if the motor is powered on. If no drive caller has been specified in the input file it is assumed that the motor is always powered on. More...
 

Private Attributes

const StructNodem_pRotorNode
 
const StructNodem_pStatorNode
 
doublereal m_MK
 
doublereal m_sK
 
DriveOwner m_OmegaS
 
DriveOwner m_MotorOn
 
doublereal m_M
 
doublereal m_dM_dt
 
doublereal m_dM_dt2
 
doublereal m_omega
 
doublereal m_domega_dt
 

Static Private Attributes

static const doublereal sm_SingTol = std::pow(std::numeric_limits<doublereal>::epsilon(), 0.9)
 

Additional Inherited Members

- Public Types inherited from Elem
enum  Type {
  UNKNOWN = -1, AIRPROPERTIES = 0, INDUCEDVELOCITY, AUTOMATICSTRUCTURAL,
  GRAVITY, BODY, JOINT, JOINT_REGULARIZATION,
  BEAM, PLATE, FORCE, INERTIA,
  ELECTRICBULK, ELECTRIC, THERMAL, HYDRAULIC,
  BULK, LOADABLE, DRIVEN, EXTERNAL,
  AEROMODAL, AERODYNAMIC, GENEL, SOCKETSTREAM_OUTPUT,
  RTAI_OUTPUT = SOCKETSTREAM_OUTPUT, LASTELEMTYPE
}
 
- Public Types inherited from SimulationEntity
typedef std::vector< Hint * > Hints
 
- Public Types inherited from ToBeOutput
enum  { OUTPUT = 0x1U, OUTPUT_MASK = 0xFU, OUTPUT_PRIVATE = 0x10U, OUTPUT_PRIVATE_MASK = ~OUTPUT_MASK }
 
- Public Types inherited from AerodynamicElem
enum  Type {
  UNKNOWN = -1, INDUCEDVELOCITY = 0, AEROMODAL, AERODYNAMICBODY,
  AERODYNAMICBEAM, AERODYNAMICEXTERNAL, AERODYNAMICEXTERNALMODAL, AERODYNAMICLOADABLE,
  AIRCRAFTINSTRUMENTS, GENERICFORCE, LASTAEROTYPE
}
 
- Protected Member Functions inherited from ElemGravityOwner
virtual Vec3 GetS_int (void) const
 
virtual Mat3x3 GetJ_int (void) const
 
virtual Vec3 GetB_int (void) const
 
virtual Vec3 GetG_int (void) const
 
- Protected Attributes inherited from WithLabel
unsigned int uLabel
 
std::string sName
 
- Protected Attributes inherited from ToBeOutput
flag fOutput
 
- Protected Attributes inherited from UserDefinedElem
bool needsAirProperties
 
- Protected Attributes inherited from AirPropOwner
const AirPropertiespAirProperties
 
- Protected Attributes inherited from GravityOwner
GravitypGravity
 

Detailed Description

This code is a simple example on how to implement a user defined element for the free multibody software MBDyn. Since no documentation exists for user defined elements in MBDyn at the time of writing I have written this document in the hope that it will be helpful for others who want to write their own user defined elements for MBDyn.

The purpose of this code is the simulation of an asynchronous electrical machine as a part of a multibody model. With this software the coupling between the mechanical and the electrical differential equations can be considered. The theoretical background is based on the book Maschinendynamik Springer 2009, Dresig, Holzweißig.
In the formulas in this book the stator resistance is neglected and the free run slip is assumed to be zero. Also small perturbations around the mean angular velocity are assumed.

The input parameters for the simulation are:
Breakdown torque $M_K$.
Slip at the breakdown torque $s_K$.
Synchronous angular velocity $\Omega_S=2\,\pi\,\frac{f}{p}$ (might be a function of the time in case of an frequency inverter).
A flag that determines whether the power supply is turned on or off $\gamma(t)$.
Optional the initial value of the motor torque $M$.
Optional the initial value of the first derivative of the motor torque $\dot{M}$.

The sense of rotation is determined by the sign of $\Omega_S$. If the sign is positive, the sense of rotation is also positive in the reference frame of the stator node.

This code is implemented as an user defined element for MBDyn. The element is connected to two structural nodes. The rotor node and the stator node. The axis of rotation is assumed to be axis three in the reference frame of the stator node. It is assumed that the axis of the rotor node is parallel to the axis of the stator node. The torque is imposed to the structural nodes in direction of axis three in the reference frame of the stator node. The synchronous angular velocity can be specified by means of a drive caller. This allows to simulate a frequency inverter.

Definition at line 84 of file module-asynchronous_machine.cc.

Constructor & Destructor Documentation

asynchronous_machine::asynchronous_machine ( unsigned  uLabel,
const DofOwner pDO,
DataManager pDM,
MBDynParser HP 
)

Constructs the element from the information in the input file.

Parameters
uLabelthe label assigned to this element in the input file
pDO
pDMpointer to the data manager (needed to read structural nodes for example)
HPreference to the math parser (needed to read from the input file) A description of the exact input file syntax can be retrieved by adding the following statement to the MBDyn input file:
user defined: 1, asynchronous_machine, help;

Definition at line 157 of file module-asynchronous_machine.cc.

References copysign(), DriveOwner::dGet(), DataManager::fReadOutput(), Mat3x3::GetCol(), MBDynParser::GetDriveCaller(), WithLabel::GetLabel(), IncludeParser::GetLineData(), DataManager::GetLogFile(), StructNode::GetRCurr(), HighParser::GetReal(), StructNode::GetWCurr(), HighParser::IsArg(), HighParser::IsKeyWord(), IsMotorOn(), Elem::LOADABLE, m_dM_dt, m_dM_dt2, m_M, m_MK, m_MotorOn, m_omega, m_OmegaS, m_pRotorNode, m_pStatorNode, m_sK, MBDYN_EXCEPT_ARGS, DataManager::ReadNode(), DriveOwner::Set(), ToBeOutput::SetOutputFlag(), and Node::STRUCTURAL.

160 : Elem(uLabel, flag(0)),
161  UserDefinedElem(uLabel, pDO),
162  m_pRotorNode(0),
163  m_pStatorNode(0),
164  m_MK(0.),
165  m_sK(0.),
166  m_OmegaS(0),
167  m_MotorOn(0),
168  m_M(0.),
169  m_dM_dt(0.),
170  m_dM_dt2(0.),
171  m_omega(0.),
172  m_domega_dt(0.)
173 {
174  if (HP.IsKeyWord("help")) {
175  silent_cout(
176  "\n"
177  "Module: asynchronous_machine\n"
178  "\n"
179  " This module implements an asynchronous electric machine\n"
180  " according to\n"
181  "\n"
182  " Maschinendynamik\n"
183  " Hans Dresig, Franz Holzweißig\n"
184  " Springer, 2009\n"
185  " page 58 equation 1.122 and 1.123\n"
186  "\n"
187  "Syntax:\n"
188  " asynchronous_machine,\n"
189  " rotor, (label) <rotor_node>,\n"
190  " stator, (label) <stator_node>,\n"
191  " MK, (real) <MK>,\n"
192  " sK, (real) <sK>,\n"
193  " OmegaS, (DriveCaller) <omega_s>\n"
194  " [ , motor on , (DriveCaller) <motor_on> ]\n"
195  " [ , M0 , (real) <M0> ]\n"
196  " [ , MP0 , (real) <MP0> ]\n"
197  "\n"
198  " MK ... breakdown torque ( MK > 0 )\n"
199  " sK ... breakdown slip ( sK > 0 )\n"
200  " OmegaS = 2 * pi * f / p * sense_of_rotation ... synchronous angular velocity\n"
201  " motor_on ... power supply is turned off when 0, on otherwise\n"
202  " M0 ... initial torque ( default 0 )\n"
203  " MP0 ... initial torque derivative ( default 0 )\n"
204  "\n"
205  " The axis of rotation is assumed to be axis 3 of the reference frame of the stator node.\n"
206  << std::endl);
207 
208  if (!HP.IsArg()) {
209  // Exit quietly if nothing else is provided
210  throw NoErr(MBDYN_EXCEPT_ARGS);
211  }
212  }
213 
214  if (!HP.IsKeyWord("rotor")) {
215  silent_cerr("asynchronous_machine(" << GetLabel() << "): keyword \"rotor\" expected at line " << HP.GetLineData() << std::endl);
217  }
218 
220 
221  if (!m_pRotorNode) {
222  silent_cerr("asynchronous_machine(" << GetLabel() << "): structural node expected at line " << HP.GetLineData() << std::endl);
224  }
225 
226  if (!HP.IsKeyWord("stator")) {
227  silent_cerr("asynchronous_machine(" << GetLabel() << "): keyword \"stator\" expected at line " << HP.GetLineData() << std::endl);
229  }
230 
232 
233  if (!m_pStatorNode) {
234  silent_cerr("asynchronous_machine(" << GetLabel() << "): structural node expected at line " << HP.GetLineData() << std::endl);
236  }
237 
238  if (!HP.IsKeyWord("MK")) {
239  silent_cerr("asynchronous_machine(" << GetLabel() << "): keyword \"MK\" expected at line " << HP.GetLineData() << std::endl);
241  }
242  m_MK = HP.GetReal();
243 
244  if (!HP.IsKeyWord("sK")) {
245  silent_cerr("asynchronous_machine(" << GetLabel() << "): keyword \"sK\" expected at line " << HP.GetLineData() << std::endl);
247  }
248  m_sK = HP.GetReal();
249 
250  if (!HP.IsKeyWord("OmegaS")) {
251  silent_cerr("asynchronous_machine(" << GetLabel() << "): keyword \"OmegaS\" expected" << std::endl);
253  }
255 
256  if (HP.IsKeyWord("motor" "on") || HP.IsKeyWord("motor_on")) {
258  } else {
260  }
261 
262  if (HP.IsKeyWord("M0")) {
263  m_M = HP.GetReal();
264  }
265 
266  if (HP.IsKeyWord("MP0")) {
267  m_dM_dt = HP.GetReal();
268  }
269 
271 
272  Vec3 e3(m_pStatorNode->GetRCurr().GetCol(3));
273  const Vec3& omega1 = m_pRotorNode->GetWCurr();
274  const Vec3& omega2 = m_pStatorNode->GetWCurr();
275 
276  m_omega = e3.Dot(omega1 - omega2);
277 
278  const doublereal OmegaS = m_OmegaS.dGet();
279 
280  pDM->GetLogFile() << "asynchronous machine: "
281  << uLabel << " "
282  << m_pRotorNode->GetLabel() << " "
283  << m_pStatorNode->GetLabel() << " "
284  << m_MK << " "
285  << m_sK << " "
286  << OmegaS << " "
287  << IsMotorOn() << " "
288  << m_M << " "
289  << m_dM_dt << " "
290  << m_omega
291  << std::endl;
292 
293  // Note: The ODE for the asynchronous machine is defined for positive sign of OmegaS only!
294  // At user level the signs of M, dM/dt and d^2M/dt^2 are defined to be positive
295  // in positive coordinate system direction in the reference frame of the stator.
296  m_M *= copysign(1., OmegaS);
297  m_dM_dt *= copysign(1., OmegaS);
298  m_dM_dt2 *= copysign(1., OmegaS);
299 }
flag fReadOutput(MBDynParser &HP, const T &t) const
Definition: dataman.h:1064
long int flag
Definition: mbdyn.h:43
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
Definition: matvec3.h:98
virtual const Mat3x3 & GetRCurr(void) const
Definition: strnode.h:1012
bool IsMotorOn(void) const
If a drive caller has been specified in the input file the value returned by the drive caller is used...
Vec3 GetCol(unsigned short int i) const
Definition: matvec3.h:903
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
virtual const Vec3 & GetWCurr(void) const
Definition: strnode.h:1030
unsigned int uLabel
Definition: withlab.h:44
Definition: except.h:79
virtual bool IsArg(void)
Definition: parser.cc:807
std::ostream & GetLogFile(void) const
Definition: dataman.h:326
void Set(const DriveCaller *pDC)
Definition: drive.cc:647
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
UserDefinedElem(unsigned uLabel, const DofOwner *pDO)
Definition: userelem.cc:152
DriveCaller * GetDriveCaller(bool bDeferred=false)
Definition: mbpar.cc:2033
virtual void SetOutputFlag(flag f=flag(1))
Definition: output.cc:896
Elem(unsigned int uL, flag fOut)
Definition: elem.cc:41
double doublereal
Definition: colamd.c:52
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
unsigned int GetLabel(void) const
Definition: withlab.cc:62
Node * ReadNode(MBDynParser &HP, Node::Type type) const
Definition: dataman3.cc:2309
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056

Here is the call graph for this function:

asynchronous_machine::~asynchronous_machine ( void  )
virtual

Definition at line 343 of file module-asynchronous_machine.cc.

344 {
345  // destroy private data
346 #ifdef DEBUG
347  std::cerr << __FILE__ << ":" << __LINE__ << ":" << __PRETTY_FUNCTION__ << std::endl;
348 #endif
349 }

Member Function Documentation

void asynchronous_machine::AfterPredict ( VectorHandler X,
VectorHandler XP 
)
virtual

Reimplemented from SimulationEntity.

Definition at line 327 of file module-asynchronous_machine.cc.

References Update().

328 {
329  Update(X, XP);
330 }
virtual void Update(const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
This member function is called after each iteration in the nonlinear solution phase.

Here is the call graph for this function:

VariableSubMatrixHandler & asynchronous_machine::AssJac ( VariableSubMatrixHandler WorkMat_,
doublereal  dCoef,
const VectorHandler XCurr,
const VectorHandler XPrimeCurr 
)
virtual

Computes the contribution to the jacobian matrix $\boldsymbol{Jac}$.

Parameters
WorkMatsparse or full submatrix which receives the contribution to the jacobian matrix $Jac$
dCoefthe derivative coefficient is defined as $\Delta\boldsymbol{y} = dCoef \, \Delta\dot{\boldsymbol{y}}$
XCurrthe vector of the global degrees of freedom $\boldsymbol{y}$ at the current iteration step
XPrimeCurrthe vector of the derivative of the global degrees of freedom $\dot{\boldsymbol{y}}$

\[\boldsymbol{Jac}=-\frac{\partial\boldsymbol{f}}{\partial\dot{\boldsymbol{y}}}-dCoef\,\frac{\partial\boldsymbol{f}}{\partial\boldsymbol{y}}\]


For the definition of $\boldsymbol{f}$ see AssRes().

\[\frac{\partial\boldsymbol{f}}{\partial\boldsymbol{y}}=\left(\begin{array}{ccccc} \frac{\partial f_{1}}{\partial y_{1}} & \frac{\partial f_{1}}{\partial y_{2}} & \frac{\partial f_{1}}{\partial\boldsymbol{y}_{3}} & \frac{\partial f_{1}}{\partial\boldsymbol{y}_{4}} & \frac{\partial f_{1}}{\partial y_{5}}\\ \frac{\partial f_{2}}{\partial y_{1}} & \frac{\partial f_{2}}{\partial y_{2}} & \frac{\partial f_{2}}{\partial\boldsymbol{y}_{3}} & \frac{\partial f_{2}}{\partial\boldsymbol{y}_{4}} & \frac{\partial f_{2}}{\partial y_{5}}\\ \frac{\partial\boldsymbol{f}_{3}}{\partial y_{1}} & \frac{\partial\boldsymbol{f}_{3}}{\partial y_{2}} & \frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{y}_{3}} & \frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{y}_{4}} & \frac{\partial\boldsymbol{f}_{3}}{\partial y_{5}}\\ \frac{\partial\boldsymbol{f}_{4}}{\partial y_{1}} & \frac{\partial\boldsymbol{f}_{4}}{\partial y_{2}} & \frac{\partial\boldsymbol{f}_{4}}{\partial\boldsymbol{y}_{3}} & \frac{\partial\boldsymbol{f}_{4}}{\partial\boldsymbol{y}_{4}} & \frac{\partial\boldsymbol{f}_{4}}{\partial y_{5}}\\ \frac{\partial f_{5}}{\partial y_{1}} & \frac{\partial f_{5}}{\partial y_{2}} & \frac{\partial f_{5}}{\partial\boldsymbol{y}_{3}} & \frac{\partial f_{5}}{\partial\boldsymbol{y}_{4}} & \frac{\partial f_{5}}{\partial y_{5}}\end{array}\right)\]


\[\frac{\partial\boldsymbol{f}}{\partial\boldsymbol{\dot{y}}}=\left(\begin{array}{ccccc} \frac{\partial f_{1}}{\partial\dot{y}_{1}} & \frac{\partial f_{1}}{\partial\dot{y}_{2}} & \frac{\partial f_{1}}{\partial\boldsymbol{\dot{y}}_{3}} & \frac{\partial f_{1}}{\partial\boldsymbol{\dot{y}}_{4}} & \frac{\partial f_{1}}{\partial\dot{y}_{5}}\\ \frac{\partial f_{2}}{\partial\dot{y}_{1}} & \frac{\partial f_{2}}{\partial\dot{y}_{2}} & \frac{\partial f_{2}}{\partial\boldsymbol{\dot{y}}_{3}} & \frac{\partial f_{2}}{\partial\boldsymbol{\dot{y}}_{4}} & \frac{\partial f_{2}}{\partial\dot{y}_{5}}\\ \frac{\partial\boldsymbol{f}_{3}}{\partial\dot{y}_{1}} & \frac{\partial\boldsymbol{f}_{3}}{\partial\dot{y}_{2}} & \frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{\dot{y}}_{3}} & \frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{\dot{y}}_{4}} & \frac{\partial\boldsymbol{f}_{3}}{\partial\dot{y}_{5}}\\ \frac{\partial\boldsymbol{f}_{4}}{\partial\dot{y}_{1}} & \frac{\partial\boldsymbol{f}_{4}}{\partial\dot{y}_{2}} & \frac{\partial\boldsymbol{f}_{4}}{\partial\boldsymbol{\dot{y}}_{3}} & \frac{\partial\boldsymbol{f}_{4}}{\partial\boldsymbol{\dot{y}}_{4}} & \frac{\partial\boldsymbol{f}_{4}}{\partial\dot{y}_{5}}\\ \frac{\partial f_{5}}{\partial\dot{y}_{1}} & \frac{\partial f_{5}}{\partial\dot{y}_{2}} & \frac{\partial f_{5}}{\partial\dot{\boldsymbol{y}}_{3}} & \frac{\partial f_{5}}{\partial\boldsymbol{\dot{y}}_{4}} & \frac{\partial f_{5}}{\partial\dot{y}_{5}}\end{array}\right)\]


\[\frac{\partial f_{1}}{\partial y_{1}}=\left(2\, s_{K}\,+\frac{sign\left(\Omega_{S}\right)\,\dot{y}_{5}}{s\,\Omega_{S}^{2}}\right)\,\left|\Omega_{S}\right|\]

\[\frac{\partial f_{1}}{\partial\dot{y}_{1}}=1\]

\[\frac{\partial f_{1}}{\partial y_{2}}=\left(s_{K}^{2}+s^{2}\right)\,\Omega_{S}^{2}+\frac{sign\left(\Omega_{S}\right)\,\dot{y}_{5}\, sK}{s}\]

\[\frac{\partial f_{1}}{\partial y_{5}}=\frac{\partial f_{1}}{\partial s}\,\frac{\partial s}{\partial y_{5}}\]

\[\frac{\partial f_{1}}{\partial s}=-\frac{y_{1}\,\dot{y}_{5}}{s^{2}\,\Omega_{S}}+\left(2\, s\,\Omega_{S}^{2}-\frac{sign\left(\Omega_{S}\right)\:\dot{y}_{5}\, s_{K}}{s^{2}}\right)\, y_{2}-2\, M_{K}\, s_{K}\,\Omega_{S}^{2}\]

\[\frac{\partial s}{\partial y_{5}}=-\frac{1}{\Omega_{S}}\]

\[\frac{\partial f_{1}}{\partial\dot{y}_{5}}=\frac{y_{1}}{s\,\Omega_{S}}+sign\left(\Omega_{S}\right)\,\frac{s_{K}}{s}\, y_{2}\]

\[\frac{\partial f_{2}}{\partial y_{1}}=-1\]

\[\frac{\partial f_{2}}{\partial\dot{y}_{2}}=1\]

\[\frac{\partial f_{3}}{\partial y_{2}}=\boldsymbol{R}_{2}\,\boldsymbol{e}_{3}\, sign\left(\Omega_{S}\right)\]

\[\frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{y}_{4}}=-\left\langle \boldsymbol{R}_{2}^{\left(0\right)}\,\boldsymbol{e}_{3}\, y_{2}\, sign\left(\Omega_{S}\right)\right\rangle \]

\[\frac{\partial\boldsymbol{f}_{4}}{\partial\boldsymbol{y}_{2}}=-\frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{y}_{2}}\]

\[\frac{\partial\boldsymbol{f}_{4}}{\partial\boldsymbol{y}_{4}}=-\frac{\partial\boldsymbol{f}_{3}}{\partial\boldsymbol{y}_{4}}\]

\[\frac{\partial f_{5}}{\partial\boldsymbol{y}_{3}}=\boldsymbol{e}_{3}^{T}\,\boldsymbol{R}_{2}^{T}\,\left\langle \boldsymbol{\omega}_{ref_{1}}\right\rangle =-\left(\left\langle \boldsymbol{\omega}_{ref_{1}}\right\rangle \,\boldsymbol{R}_{2}\,\boldsymbol{e}_{3}\right)^{T}\]

\[\frac{\partial f_{5}}{\partial\boldsymbol{y}_{4}}=-\boldsymbol{e}_{3}^{T}\,\boldsymbol{R}_{2}^{\left(0\right)^{T}}\,\left\langle \boldsymbol{\omega}_{1}-\boldsymbol{\omega}_{2}\right\rangle -\boldsymbol{e}_{3}^{T}\,\boldsymbol{R}_{2}^{T}\,\left\langle \boldsymbol{\omega}_{ref_{2}}\right\rangle =\left[\left\langle \boldsymbol{\omega}_{1}-\boldsymbol{\omega}_{2}\right\rangle \,\boldsymbol{R}_{2}^{\left(0\right)}\,\boldsymbol{e}_{3}+\left\langle \boldsymbol{\omega}_{ref_{2}}\right\rangle \,\boldsymbol{R}_{2}\,\boldsymbol{e}_{3}\right]^{T}\]

In order to compute the derivatives versus the global degrees of freedom of structural nodes the following rules can be applied:

\[\frac{\partial \left(\boldsymbol{R}_1\,\boldsymbol{v}_1\right)}{\partial \boldsymbol{g}_1}\approx-\left\langle \boldsymbol{R}^{\left(0\right)}\,\boldsymbol{v} \right\rangle \]


\[\frac{\partial \left(\boldsymbol{R}_1^{T}\,\boldsymbol{v}\right)}{\partial \boldsymbol{g}_1}\approx\boldsymbol{R}_1^{\left(0\right)T}\,\left\langle\boldsymbol{v}\right\rangle\]

\[\frac{\partial\boldsymbol{\omega}_1}{\partial\dot{\boldsymbol{g}}_1}\approx\boldsymbol{I}\]

\[\frac{\partial\boldsymbol{\omega}_1}{\partial\boldsymbol{g}_1}\approx-\left\langle\boldsymbol{\omega}_{1_{ref}}\right\rangle\]

$\boldsymbol{R}_1$ is the corrected rotation matrix of node 1 at the current iteration which can be obtained by GetRCurr().
$\boldsymbol{R}^{(0)}_1$ is the predicted rotation matrix of node 1 at the current time step which can be obtained by GetRRef().
$\boldsymbol{g}_1$ is the vector of Gibbs Rodriguez rotation parameters of node 1.
The rotation matrix $\boldsymbol{R}_1$ is internally computed as follows:

\[\boldsymbol{R}_1=\boldsymbol{R}_{1_{\Delta}}\,\boldsymbol{R}^{(0)}_1\]

$\boldsymbol{R}_{1_{\Delta}}$ is the incremental rotation matrix which can be computed by means of the Gibbs Rodriguez rotation parameters $\boldsymbol{g}_1$.

\[\boldsymbol{R}_{1_{\Delta}}=\boldsymbol{I}+\frac{4}{4+\boldsymbol{g}_1^T\,\boldsymbol{g}_1}\,\left(\left\langle\boldsymbol{g}\right\rangle+\frac{1}{2}\,\left\langle\boldsymbol{g}_1\right\rangle\,\left\langle\boldsymbol{g}_1\right\rangle\right)\]

$\boldsymbol{\omega}_1$ is the corrected angular velocity of node 1 at the current iteration which can be obtained by GetWCurr().

\[\left\langle\boldsymbol{\omega}_1\right\rangle=\dot{\boldsymbol{R}}_1\,\boldsymbol{R}_1^T\]

\[\boldsymbol{\omega}_1\approx\dot{\boldsymbol{g}}_1+\boldsymbol{R}_{1_{\Delta}}\,\boldsymbol{\omega}_{1_{ref}}\]

$\boldsymbol{\omega}_{1_{ref}}$ is the predicted angular velocity of node 1 at the current time step which can be obtained by GetWRef().

\[\left\langle\boldsymbol{\omega}_{1_{ref}}\right\rangle=\dot{\boldsymbol{R}}_1^{(0)}\,\boldsymbol{R}_1^{(0)T}\]

$\boldsymbol{v}$ is a const vector in the reference frame $\boldsymbol{R}_1$.

\[\boldsymbol{v}=\left(\begin{array}{c} v_{1}\\ v_{2}\\ v_{3}\end{array}\right)\]

$\left\langle \boldsymbol{v}\right\rangle$ is a matrix that rearranges the components of $\boldsymbol{v}$ according to the cross product rule:
$\left\langle\boldsymbol{v}\right\rangle\,\boldsymbol{a}=-\left\langle\boldsymbol{a}\right\rangle\,\boldsymbol{v}=\boldsymbol{v}\times\boldsymbol{a}=-\boldsymbol{a}\times\boldsymbol{v}$

\[\left\langle \boldsymbol{v} \right\rangle=\left(\begin{array}{ccc} 0 & -v_{3} & v_{2}\\ v_{3} & 0 & -v_{1}\\ -v_{2} & v_{1} & 0\end{array}\right)\]

Implements Elem.

Definition at line 627 of file module-asynchronous_machine.cc.

References copysign(), Vec3::Cross(), grad::Cross(), DriveOwner::dGet(), Mat3x3::GetCol(), WithLabel::GetLabel(), StructNode::GetRCurr(), StructNode::GetRRef(), StructNode::GetWCurr(), StructNode::GetWRef(), DofOwnerOwner::iGetFirstIndex(), StructDispNode::iGetFirstMomentumIndex(), StructDispNode::iGetFirstPositionIndex(), IsMotorOn(), m_MK, m_OmegaS, m_pRotorNode, m_pStatorNode, m_sK, MatCross, grad::pow(), FullSubMatrixHandler::Put(), FullSubMatrixHandler::PutCoef(), FullSubMatrixHandler::PutColIndex(), FullSubMatrixHandler::PutRowIndex(), FullSubMatrixHandler::PutT(), FullSubMatrixHandler::ResizeReset(), VariableSubMatrixHandler::SetFull(), sm_SingTol, and WorkSpaceDim().

631 {
632 #ifdef DEBUG
633  std::cerr << __FILE__ << ':' << __LINE__ << ':' << __PRETTY_FUNCTION__ << std::endl;
634 #endif
635 
636  integer iNumRows = 0;
637  integer iNumCols = 0;
638 
639  WorkSpaceDim(&iNumRows, &iNumCols);
640 
641  FullSubMatrixHandler& WorkMat = WorkMat_.SetFull();
642 
643  WorkMat.ResizeReset(iNumRows, iNumCols);
644 
645  const integer iFirstIndex = iGetFirstIndex();
646 
647  const integer intTorqueDerivativeColumnIndex = iFirstIndex + 1;
648  const integer intTorqueColumnIndex = iFirstIndex + 2;
649  const integer intOmegaColumnIndex = iFirstIndex + 3;
650 
651  const integer intTorqueDerivativeRowIndex = iFirstIndex + 1;
652  const integer intTorqueRowIndex = iFirstIndex + 2;
653  const integer intOmegaRowIndex = iFirstIndex + 3;
654 
655  const integer intRotorPositionIndex = m_pRotorNode->iGetFirstPositionIndex();
656  const integer intStatorPositionIndex = m_pStatorNode->iGetFirstPositionIndex();
657 
658  const integer intRotorMomentumIndex = m_pRotorNode->iGetFirstMomentumIndex();
659  const integer intStatorMomentumIndex = m_pStatorNode->iGetFirstMomentumIndex();
660 
661  /*
662  * M ... motor torque
663  * diff(M,t) ... derivative of the motor torque versus time
664  * g1 ... rotation parameter of the rotor
665  * g2 ... rotation parameter of the stator
666  * R2 ... rotation matrix of the stator node
667  * omega1 ... rotor angular velocity
668  * omega2 ... stator angular velocity
669  *
670  * e3 = ( 0, 0, 1 )^T ... axis of rotation in the reference frame of the stator node
671  *
672  * omega = e3^T * R2^T * ( omega1 - omega2 )
673  *
674  * s = 1 - omega / OmegaS
675  *
676  * | y1 | | diff(M,t) |
677  * | y2 | | M |
678  * y = | y3 | = | g1 |
679  * | y4 | | g2 |
680  * | y5 | | omega |
681  *
682  * | f1 | | diff(y1,t) + ( 2 * sK + sign(OmegaS) * diff(y5,t) / ( s * OmegaS^2 ) ) * y1 * abs(OmegaS) + ( ( sK^2 + s^2 ) * OmegaS^2 + sign(OmegaS) * diff(y5,t) * sK / s ) * y2 - 2 * MK * sK * s * OmegaS^2 |
683  * | f2 | | diff(y2,t) - y1 | |
684  * f = | f3 | = | R2 * e3 * y2 |
685  * | f4 | | -R2 * e3 * y2 |
686  * | f5 | | y5 - e3^T * R2^T * ( omega1 - omega2 ) |
687  *
688  * 1, 2, 3, 6, 9
689  * | df1/dy1, df1/dy2, df1/dy3, df1/dy4, df1/dy5 | 1
690  * | df2/dy1, df2/dy2, df2/dy3, df2/dy4, df2/dy5 | 2
691  * diff(f,y) = | df3/dy1, df3/dy2, df3/dy3, df3/dy4, df3/dy5 | 3
692  * | df4/dy1, df4/dy2, df4/dy3, df4/dy4, df4/dy5 | 6
693  * | df5/dy1, df5/dy2, df5/dy3, df5/dy4, df5/dy5 | 9
694  *
695  * WorkMat = -diff(f,diff(y,t)) - dCoef * diff(f,y)
696  */
697  WorkMat.PutRowIndex(1, intTorqueDerivativeRowIndex);
698  WorkMat.PutColIndex(1, intTorqueDerivativeColumnIndex);
699 
700  WorkMat.PutRowIndex(2, intTorqueRowIndex);
701  WorkMat.PutColIndex(2, intTorqueColumnIndex);
702 
703  for (int iCnt = 1; iCnt <= 3; ++iCnt) {
704  WorkMat.PutRowIndex(iCnt + 2, intRotorMomentumIndex + iCnt + 3);
705  WorkMat.PutColIndex(iCnt + 2, intRotorPositionIndex + iCnt + 3);
706 
707  WorkMat.PutRowIndex(iCnt + 5, intStatorMomentumIndex + iCnt + 3);
708  WorkMat.PutColIndex(iCnt + 5, intStatorPositionIndex + iCnt + 3);
709  }
710 
711  WorkMat.PutRowIndex(9, intOmegaRowIndex);
712  WorkMat.PutColIndex(9, intOmegaColumnIndex);
713 
714  Vec3 e3 = m_pStatorNode->GetRCurr().GetCol(3); // corrected axis of rotation of the stator node
715  Vec3 e3_0 = m_pStatorNode->GetRRef().GetCol(3); // predicted axis of rotation of the stator node
716  const Vec3& omega1 = m_pRotorNode->GetWCurr(); // corrected angular velocity of the rotor node
717  const Vec3& omega2 = m_pStatorNode->GetWCurr(); // corrected angular velocity of the rotor node
718  const Vec3& omega1_ref = m_pRotorNode->GetWRef(); // predicted angular velocity of the rotor node
719  const Vec3& omega2_ref = m_pStatorNode->GetWRef(); // predicted angular velocity of the stator node
720 
721  const doublereal OmegaS = m_OmegaS.dGet(); // synchronous angular velocity
722 
723  const doublereal y1 = XCurr(intTorqueDerivativeRowIndex);
724  const doublereal y2 = XCurr(intTorqueRowIndex);
725  const doublereal y5 = XCurr(intOmegaRowIndex);
726 #if 0 // unused
727  const doublereal y1_dot = XPrimeCurr(intTorqueDerivativeRowIndex);
728  const doublereal y2_dot = XPrimeCurr(intTorqueRowIndex);
729 #endif
730  const doublereal y5_dot = XPrimeCurr(intOmegaRowIndex);
731 
732  doublereal s = 1 - y5 / OmegaS; // slip of the rotor
733 
734  if ( std::abs(s) < sm_SingTol )
735  {
736  silent_cerr("\nasynchronous_machine(" << GetLabel() << "): warning slip rate s = " << s << " is close to machine precision!\n");
737  //FIXME: avoid division by zero
738  //FIXME: results might be inaccurate
739  s = copysign(sm_SingTol, s);
740  }
741 
742  doublereal df1_dy1, df1_dy2, df1_dy5;
743  doublereal df1_dy1_dot, df1_dy2_dot, df1_dy5_dot;
744  doublereal df2_dy1, df2_dy2_dot;
745 
746  if (IsMotorOn()) {
747  // power supply is turned on
748 
749  // df1_dy1 = diff(f1,y1)
750  df1_dy1 = ( 2 * m_sK + copysign(1., OmegaS) * y5_dot / ( s * std::pow(OmegaS,2) ) ) * abs(OmegaS);
751  // df1_dy2 = diff(f1,y2)
752  df1_dy2 = ( std::pow(m_sK,2) + std::pow(s,2) ) * std::pow(OmegaS,2) + copysign(1., OmegaS) * y5_dot * m_sK / s;
753  // df1_dy1_dot = diff(f1,diff(y1,t))
754  df1_dy1_dot = 1.;
755  // df2_dy1 = diff(f2,dy1)
756  df2_dy1 = -1.;
757  // df2_dy2_dot = diff(f2,diff(y2,t))
758  df2_dy2_dot = 1.;
759  // df1_ds = diff(f1,s)
760  const doublereal df1_ds = -y1 * y5_dot / ( std::pow(s,2) * OmegaS ) + ( 2 * s * std::pow(OmegaS,2) - copysign(1., OmegaS) * y5_dot * m_sK / std::pow(s,2) ) * y2 - 2 * m_MK * m_sK * std::pow(OmegaS,2);
761  // df1_dy5 = diff(f1,y5) = diff(f1,s) * diff(s,y5)
762  df1_dy5 = df1_ds * ( -1. / OmegaS );
763  // df1_dy5_dot = diff(f1,diff(y5,t))
764  df1_dy5_dot = y1 / ( s * OmegaS ) + copysign(1., OmegaS) * y2 * m_sK / s;
765 
766  } else {
767  // power supply is turned off
768  df1_dy1 = 0.;
769  df1_dy2 = 1.;
770  df1_dy5 = 0.;
771  df1_dy1_dot = 0.;
772  df1_dy2_dot = 0.;
773  df1_dy5_dot = 0.;
774 
775  df2_dy1 = 1.;
776  df2_dy2_dot = 0;
777  }
778 
779  // df3_dy2 = diff(f3,y2)
780  const Vec3 df3_dy2 = e3 * copysign(1., OmegaS); // df3_dy2 = R2 * e3 * sign(OmegaS)
781  // df4_dy2 = diff(f4,y2)
782  const Vec3 df4_dy2 = -df3_dy2; // df4_dy2 = -R2 * e3
783  // df3_dy4 = diff(f3,y4)
784  const Mat3x3 df3_dy4 = -Mat3x3(MatCross, e3_0 * (y2 * copysign(1., OmegaS)) ); // df3_dy4 = -skew( R2^(0) * e3 * y2 * sign(OmegaS) )
785  // df4_dy4 = diff(f4,y4)
786  const Mat3x3 df4_dy4 = -df3_dy4;
787  // df5_dy5 = diff(f5,y5)
788  const doublereal df5_dy5 = 1.;
789  // df5_dy3_dot_T = transpose(diff(f5,diff(y3,t)))
790  const Vec3 df5_dy3_dot_T = -e3; // diff(y5,diff(y3,t)) = -e3^T * R2^T
791  // df5_dy4_dot_T = transpose(diff(f5,diff(y4,t)))
792  const Vec3 df5_dy4_dot_T = -df5_dy3_dot_T; // diff(y5,diff(y4,t)) = e3^T * R2^T
793  // df5_dy3_T = transpose(diff(y5,y3))
794  const Vec3 df5_dy3_T = -omega1_ref.Cross(e3);
795  // df5_dy4_T = transpose(diff(y5,y4))
796  const Vec3 df5_dy4_T = ( omega1 - omega2 ).Cross( e3_0 ) + omega2_ref.Cross( e3 );
797 
798  WorkMat.PutCoef( 1, 1, -df1_dy1_dot - dCoef * df1_dy1 );
799  WorkMat.PutCoef( 1, 2, - dCoef * df1_dy2 );
800  WorkMat.PutCoef( 1, 9, -df1_dy5_dot - dCoef * df1_dy5 );
801  WorkMat.PutCoef( 2, 1, - dCoef * df2_dy1 );
802  WorkMat.PutCoef( 2, 2, -df2_dy2_dot );
803  WorkMat.Put( 3, 2, df3_dy2 * ( -dCoef ) );
804  WorkMat.Put( 3, 6, df3_dy4 * ( -dCoef ) );
805  WorkMat.Put( 6, 2, df4_dy2 * ( -dCoef ) );
806  WorkMat.Put( 6, 6, df4_dy4 * ( -dCoef ) );
807  WorkMat.PutT( 9, 3, -df5_dy3_dot_T + df5_dy3_T * ( -dCoef ) );
808  WorkMat.PutT( 9, 6, -df5_dy4_dot_T + df5_dy4_T * ( -dCoef ) );
809  WorkMat.PutCoef( 9, 9, df5_dy5 * ( -dCoef ) );
810 
811 #ifdef DEBUG
812  std::cerr << __FILE__ ":" << __LINE__ << ":" << __PRETTY_FUNCTION__ << std::endl;
813  std::cerr << "s = " << s << std::endl;
814  std::cerr << "WorkMat=" << std::endl
815  << WorkMat << std::endl << std::endl;
816 #endif
817 
818  return WorkMat_;
819 }
void PutColIndex(integer iSubCol, integer iCol)
Definition: submat.h:325
Vec3 Cross(const Vec3 &v) const
Definition: matvec3.h:218
virtual const Mat3x3 & GetRRef(void) const
Definition: strnode.h:1006
GradientExpression< BinaryExpr< FuncPow, LhsExpr, RhsExpr > > pow(const GradientExpression< LhsExpr > &u, const GradientExpression< RhsExpr > &v)
Definition: gradient.h:2961
Definition: matvec3.h:98
const MatCross_Manip MatCross
Definition: matvec3.cc:639
FullSubMatrixHandler & SetFull(void)
Definition: submat.h:1168
virtual const Mat3x3 & GetRCurr(void) const
Definition: strnode.h:1012
void PutT(integer iRow, integer iCol, const Vec3 &v)
Definition: submat.cc:239
bool IsMotorOn(void) const
If a drive caller has been specified in the input file the value returned by the drive caller is used...
void Put(integer iRow, integer iCol, const Vec3 &v)
Definition: submat.cc:221
void PutCoef(integer iRow, integer iCol, const doublereal &dCoef)
Definition: submat.h:672
Vec3 GetCol(unsigned short int i) const
Definition: matvec3.h:903
virtual const Vec3 & GetWRef(void) const
Definition: strnode.h:1024
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
virtual integer iGetFirstMomentumIndex(void) const =0
virtual integer iGetFirstPositionIndex(void) const
Definition: strnode.h:452
virtual const Vec3 & GetWCurr(void) const
Definition: strnode.h:1030
VectorExpression< VectorCrossExpr< VectorLhsExpr, VectorRhsExpr >, 3 > Cross(const VectorExpression< VectorLhsExpr, 3 > &u, const VectorExpression< VectorRhsExpr, 3 > &v)
Definition: matvec.h:3248
virtual void ResizeReset(integer, integer)
Definition: submat.cc:182
static const doublereal sm_SingTol
void PutRowIndex(integer iSubRow, integer iRow)
Definition: submat.h:311
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
virtual void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
The size of the contribution to the residual and the jacobian matrix is determined by this member fun...
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
unsigned int GetLabel(void) const
Definition: withlab.cc:62

Here is the call graph for this function:

SubVectorHandler & asynchronous_machine::AssRes ( SubVectorHandler WorkVec,
doublereal  dCoef,
const VectorHandler XCurr,
const VectorHandler XPrimeCurr 
)
virtual

This member function implements the equation of an asynchronous machine according to Maschinendynamik Springer 2009, Dresig, Holzweißig.

Parameters
WorkVecsubvector which receives the contribution to the residual $\boldsymbol{f}$
dCoefthe derivative coefficient is defined as $\Delta\boldsymbol{y} = dCoef \, \Delta\dot{\boldsymbol{y}}$
XCurrthe vector of the global degrees of freedom $\boldsymbol{y}$ at the current iteration step
XPrimeCurrthe vector of the derivative of the global degrees of freedom $\dot{\boldsymbol{y}}$

\[\ddot{M}+\left(2\, s_{K}+\frac{sign\left(\Omega_{S}\right)\,\ddot{\varphi}}{s\,\Omega_{S}^{2}}\right)\,\dot{M\,}\left|\Omega_{s}\right|+\left[\left(s_{K}^{2}+s^{2}\right)\,\Omega_{S}^{2}+\frac{sign\left(\Omega_{S}\right)\,\ddot{\varphi}\, s_{K}}{s}\right]\, M=2\, M_{K}\, s_{K}\, s\,\Omega_{S}^{2}\]


The term $sign\left(\Omega_{S}\right)$ and the absolute operator in $\left|\Omega_{s}\right|$ are modifications of the original formula since the formula in the literature does not handle negative synchronous angular velocities $\Omega_{S}$. If the synchronous angular velocity $\Omega_{S}$ has a negative value, the sense of rotation is assumed to be negative.
$M$ is motor torque
$M_{K}$ is the breakdown torque
$s_{K}$ is the breakdown slip
$\Omega_{S}$ is the synchronous angular velocity of the machine
$\Omega_{S}=2\,\pi\frac{f}{p}$
$f$ is the power frequency
$p$ is the number of terminal pairs
$s$ is the actual slip
$s=1-\frac{\dot{\varphi}}{\Omega_{S}}$
$\dot{\varphi}$ is the relative angular velocity of the rotor with respect to the stator
The axis of rotation is assumed to be axis 3 in the reference frame of the stator node.
$\dot{\varphi}=\boldsymbol{e}_{3}^{T}\cdot\boldsymbol{R}_{2}^{T}\cdot\left(\boldsymbol{\omega}_{1}-\boldsymbol{\omega}_{2}\right)$
$\boldsymbol{\omega}_{1}$ is the angular velocity of the rotor node in the global reference frame which can be obtained by GetWCurr()
$\boldsymbol{\omega}_{2}$ is the angular velocity of the stator node in the global reference frame
$\boldsymbol{R}_{2}$ is the rotation matrix of the stator node which can be obtained by GetRCurr()
The subvector of the global degrees of freedom XCurr used by this element is

\[\boldsymbol{y}=\left(\begin{array}{c} y_{1}\\ y_{2}\\ \boldsymbol{y}_{3}\\ \boldsymbol{y}_{4}\\ y_{5}\end{array}\right)=\left(\begin{array}{c}\dot{M}\\M\\ \boldsymbol{g}_{1}\\ \boldsymbol{g}_{2}\\ \dot{\varphi}\end{array}\right)\]


$\boldsymbol{g}_{1}$ is the vector of rotation parameters of the rotor node.
$\boldsymbol{g}_{2}$ is the vector of the rotation parameters of the stator node.
The index of $\boldsymbol{g}_1$ and $\boldsymbol{g}_2$ can be obtained by iGetFirstMomentumIndex() + 4 ... 6.
The index of $y_1$, $y_2$ and $y_5$ in the vector of the global degrees of freedom XCurr can be obtained by iGetFirstIndex() + 1 ... 3.
The subvector of the derivatives of the global degrees of freedom used by this element is

\[\dot{\boldsymbol{y}}=\left(\begin{array}{c} \dot{y_{1}}\\ \dot{y_{2}}\\ \dot{\boldsymbol{y}_{3}}\\ \dot{\boldsymbol{y}_{4}}\\ \dot{y_{5}}\end{array}\right)=\left(\begin{array}{c} \ddot{M}\\ \dot{M}\\ \dot{\boldsymbol{g}_{1}}\\ \dot{\boldsymbol{g}_{2}}\\ \ddot{\varphi}\end{array}\right)\]


The additional degree of freedom $y_{5}=\dot{\varphi}$ is needed since MBDyn does not provide the angular acceleration of a node during the nonlinear solution phase. The value returned by GetWPCurr() is updated only after convergence and can not be used for this reason. The contribution to the residual of this element is

\[\boldsymbol{f}=\left(\begin{array}{c} f_{1}\\ f_{2}\\ \boldsymbol{f}_{3}\\ \boldsymbol{f}_{4}\\ f_{5}\end{array}\right)\]


\[f_{1}=\dot{y}_{1}+\left(2\, s_{K}+\frac{sign\left(\Omega_{S}\right)\,\dot{y}_{5}}{s\,\Omega_{S}^{2}}\right)\, y_{1}\,\left|\Omega_{S}\right|+\left[\left(s_{K}^{2}+s^{2}\right)\,\Omega_{S}^{2}+\frac{sign\left(\Omega_{S}\right)\,\dot{y}_{5}\, s_{K}}{s}\right]\, y_{2}-2\, M_{K}\, s_{K}\, s\,\Omega_{S}^{2}\]


\[f_{2}=\dot{y}_{2}-y_{1}\]


$\boldsymbol{f}_3$ is the torque imposed to the rotor node.

\[\boldsymbol{f}_{3}=\boldsymbol{R}_{2}\,\boldsymbol{e}_{3}\, y_{2}\, sign\left(\Omega_{S}\right)\]


$\boldsymbol{f}_{4}$ is the torque imposed to the stator node.

\[\boldsymbol{f}_{4}=-\boldsymbol{f}_{3}\]


\[f_{5}=y_{5}-\boldsymbol{e}_{3}^{T}\,\boldsymbol{R}_{2}^{T}\,\left(\boldsymbol{\omega}_{1}-\boldsymbol{\omega}_{2}\right)\]


Implements Elem.

Definition at line 871 of file module-asynchronous_machine.cc.

References copysign(), DriveOwner::dGet(), Vec3::Dot(), Mat3x3::GetCol(), WithLabel::GetLabel(), StructNode::GetRCurr(), StructNode::GetWCurr(), DofOwnerOwner::iGetFirstIndex(), StructDispNode::iGetFirstMomentumIndex(), IsMotorOn(), m_MK, m_OmegaS, m_pRotorNode, m_pStatorNode, m_sK, grad::pow(), VectorHandler::Put(), VectorHandler::PutCoef(), SubVectorHandler::PutRowIndex(), VectorHandler::ResizeReset(), sm_SingTol, VectorHandler::Sub(), and WorkSpaceDim().

875 {
876 #ifdef DEBUG
877  std::cerr << __FILE__ << ':' << __LINE__ << ':' << __PRETTY_FUNCTION__ << std::endl;
878 #endif
879  integer iNumRows = 0;
880  integer iNumCols = 0;
881 
882  WorkSpaceDim(&iNumRows, &iNumCols);
883 
884  WorkVec.ResizeReset(iNumRows);
885 
886  const integer iFirstIndex = iGetFirstIndex();
887 
888  const integer intTorqueDerivativeRowIndex = iFirstIndex + 1;
889  const integer intTorqueRowIndex = iFirstIndex + 2;
890  const integer intOmegaRowIndex = iFirstIndex + 3;
891 
892  const integer intRotorMomentumIndex = m_pRotorNode->iGetFirstMomentumIndex();
893  const integer intStatorMomentumIndex = m_pStatorNode->iGetFirstMomentumIndex();
894 
895  WorkVec.PutRowIndex(1, intTorqueDerivativeRowIndex);
896  WorkVec.PutRowIndex(2, intTorqueRowIndex);
897 
898  for (int iCnt = 1; iCnt <= 3; ++iCnt) {
899  WorkVec.PutRowIndex(iCnt + 2, intRotorMomentumIndex + iCnt + 3);
900  WorkVec.PutRowIndex(iCnt + 5, intStatorMomentumIndex + iCnt + 3);
901  }
902 
903  WorkVec.PutRowIndex(9, intOmegaRowIndex);
904 
905  Vec3 e3 = m_pStatorNode->GetRCurr().GetCol(3);
906  const Vec3& omega1 = m_pRotorNode->GetWCurr();
907  const Vec3& omega2 = m_pStatorNode->GetWCurr();
908 
909  const doublereal OmegaS = m_OmegaS.dGet();
910 
911  const doublereal y1 = XCurr(intTorqueDerivativeRowIndex); // y1 = diff(M,t)
912  const doublereal y2 = XCurr(intTorqueRowIndex); // y2 = M
913  const doublereal y5 = XCurr(intOmegaRowIndex); // y5 = omega
914  const doublereal y1_dot = XPrimeCurr(intTorqueDerivativeRowIndex); // diff(y1,t) = diff(M,t,2)
915  const doublereal y2_dot = XPrimeCurr(intTorqueRowIndex); // diff(y2,t) = diff(M,t)
916  const doublereal y5_dot = XPrimeCurr(intOmegaRowIndex); // diff(y5,t) = diff(omega,t)
917 
918  doublereal s = 1 - y5 / OmegaS;
919 
920  if ( std::abs(s) < sm_SingTol )
921  {
922  silent_cerr("\nasynchronous_machine(" << GetLabel() << "): warning slip rate s = " << s << " is close to machine precision!\n");
923  //FIXME: avoid division by zero
924  //FIXME: results might be inaccurate
925  s = copysign(sm_SingTol, s);
926  }
927 
928  doublereal f1, f2;
929 
930  if (IsMotorOn()) {
931  // power supply is switched on
932  f1 = y1_dot + ( 2 * m_sK + copysign(1., OmegaS) * y5_dot / ( s * std::pow(OmegaS,2) ) ) * y1 * abs(OmegaS)
933  + ( ( std::pow(m_sK,2) + std::pow(s,2) ) * std::pow(OmegaS,2) + copysign(1., OmegaS) * y5_dot * m_sK / s ) * y2 - 2 * m_MK * m_sK * s * std::pow(OmegaS,2);
934  f2 = y2_dot - y1;
935 
936  } else {
937  // power supply is switched off: torque must be zero
938  f1 = y2;
939  f2 = y1;
940  }
941 
942  const Vec3 f3 = e3 * (y2 * copysign(1., OmegaS));
943  // const Vec3 f4 = -f3;
944 
945  const doublereal f5 = y5 - e3.Dot( omega1 - omega2 );
946 
947  WorkVec.PutCoef( 1, f1 );
948  WorkVec.PutCoef( 2, f2 );
949  WorkVec.Put( 3, f3 );
950  WorkVec.Sub( 6, f3 );
951  WorkVec.PutCoef( 9, f5 );
952 
953 #ifdef DEBUG
954  std::cerr
955  << __FILE__ ":" << __LINE__ << ":" << __PRETTY_FUNCTION__ << std::endl
956  << "s = " << s << std::endl
957  << "y1 = " << y1 << std::endl
958  << "y1_dot = " << y1_dot << std::endl
959  << "y2 = " << y2 << std::endl
960  << "y2_dot = " << y2_dot << std::endl
961  << "f1 = " << f1 << std::endl
962  << "f2 = " << f2 << std::endl
963  << "f3 = " << f3 << std::endl
964  << "f4 = " << -f3 << std::endl
965  << "f5 = " << f5 << std::endl
966  << "WorkVec=" << std::endl
967  << WorkVec << std::endl << std::endl;
968 #endif
969 
970  return WorkVec;
971 }
GradientExpression< BinaryExpr< FuncPow, LhsExpr, RhsExpr > > pow(const GradientExpression< LhsExpr > &u, const GradientExpression< RhsExpr > &v)
Definition: gradient.h:2961
Definition: matvec3.h:98
virtual void ResizeReset(integer)
Definition: vh.cc:55
virtual const Mat3x3 & GetRCurr(void) const
Definition: strnode.h:1012
bool IsMotorOn(void) const
If a drive caller has been specified in the input file the value returned by the drive caller is used...
doublereal Dot(const Vec3 &v) const
Definition: matvec3.h:243
virtual void Sub(integer iRow, const Vec3 &v)
Definition: vh.cc:78
Vec3 GetCol(unsigned short int i) const
Definition: matvec3.h:903
virtual void PutRowIndex(integer iSubRow, integer iRow)=0
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
virtual integer iGetFirstMomentumIndex(void) const =0
virtual const Vec3 & GetWCurr(void) const
Definition: strnode.h:1030
virtual void PutCoef(integer iRow, const doublereal &dCoef)=0
virtual void Put(integer iRow, const Vec3 &v)
Definition: vh.cc:93
static const doublereal sm_SingTol
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
virtual void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
The size of the contribution to the residual and the jacobian matrix is determined by this member fun...
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
unsigned int GetLabel(void) const
Definition: withlab.cc:62

Here is the call graph for this function:

std::ostream & asynchronous_machine::DescribeDof ( std::ostream &  out,
const char *  prefix,
bool  bInitial 
) const
virtual

This member function is called if the statement "print: dof description;" is specified in the input file.

Parameters
outoutput stream that receives the formated output
prefixshould be output in the first column

It prints a short description of the private degrees of freedom $M$, $\dot{M}$ and $\dot{\varphi}$.

Reimplemented from Elem.

Definition at line 452 of file module-asynchronous_machine.cc.

References DofOwnerOwner::iGetFirstIndex().

453 {
454  integer iIndex = iGetFirstIndex();
455 
456  out
457  << prefix << iIndex + 1 << ": motor torque derivative [MP]" << std::endl
458  << prefix << iIndex + 2 << ": motor torque [M]" << std::endl
459  << prefix << iIndex + 3 << ": relative angular velocity [omega]" << std::endl;
460 
461  return out;
462 }
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
long int integer
Definition: colamd.c:51

Here is the call graph for this function:

std::ostream & asynchronous_machine::DescribeEq ( std::ostream &  out,
const char *  prefix,
bool  bInitial 
) const
virtual

This member function is called if the statement "print: equation description;" is specified in the input file.

Parameters
outoutput stream that receives the formated output
prefixshould be output in the first column

It prints a short description of the residual of the private degrees of freedom $f_1$, $f_2$ and $f_9$.

Reimplemented from Elem.

Definition at line 473 of file module-asynchronous_machine.cc.

References DofOwnerOwner::iGetFirstIndex().

474 {
475  integer iIndex = iGetFirstIndex();
476 
477  out
478  << prefix << iIndex + 1 << ": motor DAE [f1]" << std::endl
479  << prefix << iIndex + 2 << ": motor torque derivative [f2]" << std::endl
480  << prefix << iIndex + 3 << ": angular velocity derivative [f9]" << std::endl;
481 
482  return out;
483 }
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
long int integer
Definition: colamd.c:51

Here is the call graph for this function:

doublereal asynchronous_machine::dGetPrivData ( unsigned int  i) const
virtual

This member function is called whenever a bind statement or a element drive is used to access private data.

Parameters
ithe one based index of the private data
Returns
returns the value of the private data addressed by i.

Reimplemented from SimulationEntity.

Definition at line 544 of file module-asynchronous_machine.cc.

References copysign(), DriveOwner::dGet(), m_dM_dt, m_dM_dt2, m_domega_dt, m_M, m_omega, m_OmegaS, and MBDYN_EXCEPT_ARGS.

545 {
546  // Note: The ODE for the asynchronous machine is defined for positive sign of OmegaS only!
547  // At user level the signs of M, dM/dt and d^2M/dt^2 are defined to be positive
548  // in positive coordinate system direction in the reference frame of the stator.
549 
550  const doublereal OmegaS = m_OmegaS.dGet();
551 
552  switch (i) {
553  case 1:
554  return m_M*copysign(1., OmegaS);
555  case 2:
556  return m_dM_dt*copysign(1., OmegaS);
557  case 3:
558  return m_dM_dt2*copysign(1., OmegaS);
559  case 4:
560  return m_omega;
561  case 5:
562  return m_domega_dt;
563  }
564 
566 }
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
double doublereal
Definition: colamd.c:52

Here is the call graph for this function:

void asynchronous_machine::GetConnectedNodes ( std::vector< const Node * > &  connectedNodes) const
virtual

This member function is called if the statement "print: node connection;" is specified in the input file.

Parameters
connectedNodesvector which receives pointers to the connected nodes

Reimplemented from Elem.

Definition at line 987 of file module-asynchronous_machine.cc.

References iGetNumConnectedNodes(), m_pRotorNode, and m_pStatorNode.

988 {
989  connectedNodes.resize(iGetNumConnectedNodes());
990  connectedNodes[0] = m_pRotorNode;
991  connectedNodes[1] = m_pStatorNode;
992 }
virtual int iGetNumConnectedNodes(void) const
This member function is called if the statement "print: node connection;" is specified in the input f...

Here is the call graph for this function:

DofOrder::Order asynchronous_machine::GetDofType ( unsigned int  i) const
virtual

The type of the equation of the private degrees of freedom is determined by this member function.

Parameters
izero based index of the private degree of freedom (zero for the first private degree of freedom, one for second ...)
Returns
Returns if the private degrees of freedom specified by i refer to differential or algebraic variables. In our case all private degrees of freedom are differential variables.

Reimplemented from Elem.

Definition at line 437 of file module-asynchronous_machine.cc.

References DofOrder::DIFFERENTIAL.

438 {
439 
440  return DofOrder::DIFFERENTIAL;
441 }
unsigned int asynchronous_machine::iGetInitialNumDof ( void  ) const
virtual

This member function must be implemented only if the initial assembly feature is requested.

The initial assembly phase is needed only if initial values are provided which are not consistent with the algebraic constraints. Since this element does not use algebraic constraints we do not have to implement iGetInitialNumDof(), InitialWorkSpaceDim(), InitialAssJac(), InitialAssRes() and SetInitialValue().

Implements SubjectToInitialAssembly.

Definition at line 1046 of file module-asynchronous_machine.cc.

1047 {
1048  return 0;
1049 }
int asynchronous_machine::iGetNumConnectedNodes ( void  ) const
virtual

This member function is called if the statement "print: node connection;" is specified in the input file.

Returns
returns the number of connected nodes.

Definition at line 977 of file module-asynchronous_machine.cc.

Referenced by GetConnectedNodes().

978 {
979  return 2;
980 }
unsigned int asynchronous_machine::iGetNumDof ( void  ) const
virtual

The number of private degrees of freedom is determined by this member function.

Returns
Returns the number of private degrees of freedom. In our case $M$, $\dot{M}$ and $\dot{\varphi}$ are private degrees of freedom only accessible to this element.

Reimplemented from Elem.

Definition at line 426 of file module-asynchronous_machine.cc.

427 {
428  return 3;
429 }
unsigned int asynchronous_machine::iGetNumPrivData ( void  ) const
virtual

This member function is called when a bind statement or a element drive is used to access private data of this element.

Returns
Returns the number of private data available for this element. In our case $M$, $\dot{M}$, $\ddot{M}$, $\dot{\varphi}$ and $\ddot{\varphi}$ are available.

Reimplemented from SimulationEntity.

Definition at line 492 of file module-asynchronous_machine.cc.

493 {
494  return 5;
495 }
unsigned int asynchronous_machine::iGetPrivDataIdx ( const char *  s) const
virtual

The following string values can be specified in a bind statement or in an element drive caller.

Parameters
sspecifies the name of the private data to be accessed by a bind statement or an element drive caller.
Returns
returns the one based index of the private data.
index string variable
1 M $M$
2 MP $\dot{M}$
3 MPP $\ddot{M}$
4 omega $\dot{\varphi}$
5 omegaP $\ddot{\varphi}$

Reimplemented from SimulationEntity.

Definition at line 512 of file module-asynchronous_machine.cc.

References WithLabel::GetLabel().

513 {
514  static const struct {
515  int index;
516  char name[7];
517  }
518 
519  data[] = {
520  { 1, "M" }, // motor torque
521  { 2, "MP"}, // derivative of the motor torque versus time diff(M,t) (named MP instead of dM_dt for compatibility with other elements)
522  { 3, "MPP"}, // second derivative of the motor torque versus time diff(M,t,2) (named MPP instead of dM_dt2 for compatibility with other elements)
523  { 4, "omega"}, // angular velocity of the rotor node relative to the stator node
524  { 5, "omegaP"} // angular acceleration of the rotor node relative to the stator node (named omegaP instead of domega_dt for compatibility with other elements)
525  };
526 
527  for (unsigned i = 0; i < sizeof(data) / sizeof(data[0]); ++i ) {
528  if (0 == strcmp(data[i].name,s)) {
529  return data[i].index;
530  }
531  }
532 
533  silent_cerr("asynchronous_machine(" << GetLabel() << "): no private data \"" << s << "\"" << std::endl);
534 
535  return 0;
536 }
unsigned int GetLabel(void) const
Definition: withlab.cc:62

Here is the call graph for this function:

VariableSubMatrixHandler & asynchronous_machine::InitialAssJac ( VariableSubMatrixHandler WorkMat,
const VectorHandler XCurr 
)
virtual

See iGetInitialNumDof().

Implements SubjectToInitialAssembly.

Definition at line 1067 of file module-asynchronous_machine.cc.

References VariableSubMatrixHandler::SetNullMatrix().

1070 {
1071  WorkMat.SetNullMatrix();
1072 
1073  return WorkMat;
1074 }
void SetNullMatrix(void)
Definition: submat.h:1159

Here is the call graph for this function:

SubVectorHandler & asynchronous_machine::InitialAssRes ( SubVectorHandler WorkVec,
const VectorHandler XCurr 
)
virtual

See iGetInitialNumDof().

Implements SubjectToInitialAssembly.

Definition at line 1080 of file module-asynchronous_machine.cc.

References VectorHandler::ResizeReset().

1083 {
1084  WorkVec.ResizeReset(0);
1085 
1086  return WorkVec;
1087 }
virtual void ResizeReset(integer)
Definition: vh.cc:55

Here is the call graph for this function:

void asynchronous_machine::InitialWorkSpaceDim ( integer piNumRows,
integer piNumCols 
) const
virtual

See iGetInitialNumDof().

Implements SubjectToInitialAssembly.

Definition at line 1055 of file module-asynchronous_machine.cc.

1058 {
1059  *piNumRows = 0;
1060  *piNumCols = 0;
1061 }
bool asynchronous_machine::IsMotorOn ( void  ) const
private

If a drive caller has been specified in the input file the value returned by the drive caller is used to determine if the motor is powered on. If no drive caller has been specified in the input file it is assumed that the motor is always powered on.

Returns
Returns true if the motor is powered on.

Definition at line 338 of file module-asynchronous_machine.cc.

References DriveOwner::dGet(), and m_MotorOn.

Referenced by AssJac(), AssRes(), asynchronous_machine(), and Output().

339 {
340  return (m_MotorOn.dGet() != 0.);
341 }
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664

Here is the call graph for this function:

void asynchronous_machine::Output ( OutputHandler OH) const
virtual

Writes private data to a file at each time step.

Parameters
OHOH.Loadable() returns a reference to the stream intended for the output of loadable elements.
The output format is as follows:
Column Value Description
1 GetLabel() The label of the element.
2 $M$ motor torque
3 $\dot{M}$ derivative of the motor torque versus time
4 $\ddot{M}$ second derivative of the motor torque versus time
5 $\dot{\varphi}$ the angular velocity of the rotor node with respect to the stator node
6 $\ddot{\varphi}$ the angular acceleration of the rotor node with respect to the stator node
7 $\Omega_S$ the synchronous angular velocity specified by the a drive
8 $\gamma$ a flag which specifies if the motor is powered on

Reimplemented from ToBeOutput.

Definition at line 370 of file module-asynchronous_machine.cc.

References ToBeOutput::bToBeOutput(), copysign(), DriveOwner::dGet(), WithLabel::GetLabel(), IsMotorOn(), OutputHandler::LOADABLE, OutputHandler::Loadable(), m_dM_dt, m_dM_dt2, m_domega_dt, m_M, m_omega, m_OmegaS, and OutputHandler::UseText().

371 {
372  if (bToBeOutput()) {
373  // Note: The ODE for the asynchronous machine is defined for positive sign of OmegaS only!
374  // At user level the signs of M, dM/dt and d^2M/dt^2 are defined to be positive
375  // in positive coordinate system direction in the reference frame of the stator.
376  doublereal OmegaS = m_OmegaS.dGet();
377  doublereal M = m_M*copysign(1., OmegaS);
378  doublereal dM_dt = m_dM_dt*copysign(1., OmegaS);
379  doublereal dM_dt2 = m_dM_dt2*copysign(1., OmegaS);
380 
382  // output the current state: the column layout is as follows
383 
384  // 1 2 3 4 5 6 7
385  // M dM_dt dM_dt2 omega domega_dt OmegaS gamma
386  //
387  // 0 label of the element
388  // 1 motor torque
389  // 2 derivative of the motor torque versus time
390  // 3 second derivative of the motor torque versus time
391  // 4 angular velocity of the rotor node relative to the stator node around axis 3
392  // 5 angular acceleration of the rotor node relative to the stator node around axis 3
393  // 6 synchronous angular velocity (might be a function of the time in case of an frequency inverter)
394  // 7 power supply is turned on or off
395 
396  OH.Loadable() << GetLabel()
397  << " " << M
398  << " " << dM_dt
399  << " " << dM_dt2
400  << " " << m_omega
401  << " " << m_domega_dt
402  << " " << OmegaS
403  << " " << IsMotorOn()
404  << std::endl;
405  }
406  }
407 }
virtual bool bToBeOutput(void) const
Definition: output.cc:890
bool IsMotorOn(void) const
If a drive caller has been specified in the input file the value returned by the drive caller is used...
std::ostream & Loadable(void) const
Definition: output.h:506
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
double doublereal
Definition: colamd.c:52
unsigned int GetLabel(void) const
Definition: withlab.cc:62
bool UseText(int out) const
Definition: output.cc:446

Here is the call graph for this function:

std::ostream & asynchronous_machine::Restart ( std::ostream &  out) const
virtual

This member function is called if "make restart file;" is specified in the input file.

Parameters
outstream of the restart file It should reproduce the syntax in the input file used to create this element.

Implements Elem.

Definition at line 1020 of file module-asynchronous_machine.cc.

References copysign(), DriveOwner::dGet(), WithLabel::GetLabel(), m_dM_dt, m_M, m_MK, m_MotorOn, m_OmegaS, m_pRotorNode, m_pStatorNode, m_sK, DriveOwner::pGetDriveCaller(), and DriveCaller::Restart().

1021 {
1022  // FIXME: mbdyn crashes when "make restart file;" is specified in the input file before this member function is invoked!
1023  out << "asynchronous_machine, "
1024  "rotor, " << m_pRotorNode->GetLabel() << ", "
1025  "stator, " << m_pStatorNode->GetLabel() << ", "
1026  "MK, " << m_MK << ", "
1027  "sK, " << m_sK << ", "
1028  "OmegaS, ";
1029  m_OmegaS.pGetDriveCaller()->Restart(out) << ", "
1030  "motor on, ";
1031  m_MotorOn.pGetDriveCaller()->Restart(out) << ", "
1032  "M0, " << m_M * copysign(1., m_OmegaS.dGet()) << ", "
1033  "MP0, " << m_dM_dt * copysign(1., m_OmegaS.dGet()) << ";" << std::endl;
1034 
1035  return out;
1036 }
virtual std::ostream & Restart(std::ostream &out) const =0
doublereal copysign(doublereal x, doublereal y)
Definition: gradient.h:97
DriveCaller * pGetDriveCaller(void) const
Definition: drive.cc:658
doublereal dGet(const doublereal &dVar) const
Definition: drive.cc:664
unsigned int GetLabel(void) const
Definition: withlab.cc:62

Here is the call graph for this function:

void asynchronous_machine::SetInitialValue ( VectorHandler X)
virtual

See iGetInitialNumDof().

Reimplemented from DofOwnerOwner.

Definition at line 572 of file module-asynchronous_machine.cc.

573 {
574  return;
575 }
void asynchronous_machine::SetValue ( DataManager pDM,
VectorHandler X,
VectorHandler XP,
SimulationEntity::Hints ph 
)
virtual

This member function is called before the integration starts in order to set the initial values for the private degrees of freedom.

Parameters
Xvector of global degrees of freedom $\boldsymbol{y}$ that receives the initial values provided by this element.
XPvector of the derivative of the global degrees of freedom $\dot{\boldsymbol{y}}$ In our case the initial values for $M$, $\dot{M}$ and $\dot{\varphi}$ are set in this routine to the values specified in the input file.

Reimplemented from SimulationEntity.

Definition at line 1002 of file module-asynchronous_machine.cc.

References DofOwnerOwner::iGetFirstIndex(), m_dM_dt, m_M, m_omega, and VectorHandler::Put().

1005 {
1006  const integer intFirstIndex = iGetFirstIndex();
1007 
1008  // 1 2 3
1009  X.Put( intFirstIndex + 1, Vec3(m_dM_dt, m_M, m_omega) );
1010  XP.Put(intFirstIndex + 1, Vec3( 0., m_dM_dt, 0.) );
1011 }
Definition: matvec3.h:98
virtual void Put(integer iRow, const Vec3 &v)
Definition: vh.cc:93
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
long int integer
Definition: colamd.c:51

Here is the call graph for this function:

void asynchronous_machine::Update ( const VectorHandler X,
const VectorHandler XP 
)
virtual

This member function is called after each iteration in the nonlinear solution phase.

Parameters
Xvector of global degrees of freedom $\boldsymbol{y}$ after convergence at the current time step.
XPderivative of the global degrees of freedom $\dot{\boldsymbol{y}}$ after convergence at the current time step.
In our element this member function saves the current state of the private degrees of freedom. This is needed for the implementation of the Output() and the dGetPrivData() member functions. If the private degrees of freedom are needed just for Output(), the code that saves it's state should be moved to AfterPredict() since this member function is called only once per time step.

Reimplemented from SimulationEntity.

Definition at line 311 of file module-asynchronous_machine.cc.

References DofOwnerOwner::iGetFirstIndex(), m_dM_dt, m_dM_dt2, m_domega_dt, m_M, and m_omega.

Referenced by AfterPredict().

312 {
313  const integer iFirstIndex = iGetFirstIndex();
314 
315  const integer intTorqueDerivativeRowIndex = iFirstIndex + 1;
316  const integer intTorqueRowIndex = iFirstIndex + 2;
317  const integer intOmegaRowIndex = iFirstIndex + 3;
318 
319  // save the current state needed by dGetPrivData() and Output()
320  m_M = X(intTorqueRowIndex);
321  m_dM_dt = X(intTorqueDerivativeRowIndex);
322  m_dM_dt2 = XP(intTorqueDerivativeRowIndex);
323  m_omega = X(intOmegaRowIndex);
324  m_domega_dt = XP(intOmegaRowIndex);
325 }
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
long int integer
Definition: colamd.c:51

Here is the call graph for this function:

void asynchronous_machine::WorkSpaceDim ( integer piNumRows,
integer piNumCols 
) const
virtual

The size of the contribution to the residual and the jacobian matrix is determined by this member function.

Parameters
piNumRowspointer to a variable which receives the number of rows of the contribution to the residual vector and the jacobian matrix
piNumColspointer to a variable which receives the number of columns of the contribution to the jacobian matrix

Implements Elem.

Definition at line 415 of file module-asynchronous_machine.cc.

Referenced by AssJac(), and AssRes().

416 {
417  *piNumRows = 9;
418  *piNumCols = 9;
419 }

Member Data Documentation

doublereal asynchronous_machine::m_dM_dt
private

holds the first derivative of the motor torque $\dot{M}$ after convergence

Definition at line 138 of file module-asynchronous_machine.cc.

Referenced by asynchronous_machine(), dGetPrivData(), Output(), Restart(), SetValue(), and Update().

doublereal asynchronous_machine::m_dM_dt2
private

holds the second derivative of the motor torque $\ddot{M}$ after convergence

Definition at line 139 of file module-asynchronous_machine.cc.

Referenced by asynchronous_machine(), dGetPrivData(), Output(), and Update().

doublereal asynchronous_machine::m_domega_dt
private

holds the angular acceleration $\ddot{\varphi}$ of the rotor node relative to the stator node after convergence

Definition at line 141 of file module-asynchronous_machine.cc.

Referenced by dGetPrivData(), Output(), and Update().

doublereal asynchronous_machine::m_M
private

holds the motor torque $M$ after convergence for convenience

Definition at line 137 of file module-asynchronous_machine.cc.

Referenced by asynchronous_machine(), dGetPrivData(), Output(), Restart(), SetValue(), and Update().

doublereal asynchronous_machine::m_MK
private

breakdown torque $M_K$

Definition at line 133 of file module-asynchronous_machine.cc.

Referenced by AssJac(), AssRes(), asynchronous_machine(), and Restart().

DriveOwner asynchronous_machine::m_MotorOn
private

drive that returns whether the power supply is turned on or off $\gamma(t)$

Definition at line 136 of file module-asynchronous_machine.cc.

Referenced by asynchronous_machine(), IsMotorOn(), and Restart().

doublereal asynchronous_machine::m_omega
private

holds the angular velocity $\dot{\varphi}$ of the rotor relative to the stator around axis 3 of the stator node after convergence

Definition at line 140 of file module-asynchronous_machine.cc.

Referenced by asynchronous_machine(), dGetPrivData(), Output(), SetValue(), and Update().

DriveOwner asynchronous_machine::m_OmegaS
private

drive that returns the synchronous angular velocity $\Omega_S=2\,\pi\,\frac{f}{p}$ (might be a function of the time in case of an frequency inverter)

Definition at line 135 of file module-asynchronous_machine.cc.

Referenced by AssJac(), AssRes(), asynchronous_machine(), dGetPrivData(), Output(), and Restart().

const StructNode* asynchronous_machine::m_pRotorNode
private

node of the rotor where the torque $\boldsymbol{f}_3$ is imposed and the angular velocity $\dot{\boldsymbol{\varphi}}_1$ is determined

Definition at line 131 of file module-asynchronous_machine.cc.

Referenced by AssJac(), AssRes(), asynchronous_machine(), GetConnectedNodes(), and Restart().

const StructNode* asynchronous_machine::m_pStatorNode
private

node of the stator where the torque $\boldsymbol{f}_4$ is applied and the angular velocity $\dot{\boldsymbol{\varphi}}_2$ is determined (axis 3 of the stator node is assumed to be the axis of rotation)

Definition at line 132 of file module-asynchronous_machine.cc.

Referenced by AssJac(), AssRes(), asynchronous_machine(), GetConnectedNodes(), and Restart().

doublereal asynchronous_machine::m_sK
private

slip at the breakdown torque $s_K$

Definition at line 134 of file module-asynchronous_machine.cc.

Referenced by AssJac(), AssRes(), asynchronous_machine(), and Restart().

const doublereal asynchronous_machine::sm_SingTol = std::pow(std::numeric_limits<doublereal>::epsilon(), 0.9)
staticprivate

Definition at line 142 of file module-asynchronous_machine.cc.

Referenced by AssJac(), and AssRes().


The documentation for this class was generated from the following file: