4.8.2.6. MODAL_FORCE_EXT
The MODAL FORCE EXT subroutine generates a user - defined RFlex Modal Force like FFLEX Nodal Force. The outputted data is here.
MODAL FORCE EXT is different with Modal force. It is not easy that the user wants to make MODAL FORCE using USUB. Because of, there are so many arguments.
However, MODALF FORCE EXT have same definition with NODAL FORCE EXT. If user want to make RFLEX MODAL FORCE, considering only NODAL FORCE.
The RecurDyn solver convert NODAL FORCE into MODAL FORCE.
Language type |
Subroutine |
FORTRAN |
modal_force_ext (ID, TIME, UPAR, NPAR, IFBODY, NODARR, NONDE, JFLAG, IFLAG, RESULT) |
C/C++ |
modal_force_ext (int id, double time, double upar[], int npar, int ifbody, int nodarr[], int nonde, int jflag, int iflag, double result[]) |
Variable Name |
Size |
Description |
id |
int |
Modal Force sequential identification |
time |
double |
Current simulation time of RecurDyn/Solver. |
upar |
double* |
Parameters defined by the user. There is no limit about the maximum size of array. |
npar |
int |
Number of user parameters. |
ifbody |
int |
RFLEX body sequential identification defined in RecurDyn/Solver. |
nodarr |
int[nnode] |
Node ID array of input node set. |
nnode |
int |
Number of node of node set. |
jflag |
int |
When RecurDyn/Solver evaluates Jacobian, the flag is true. Otherwise, the flag is false. |
iflag |
int |
When RecurDyn/Solver makes its initial call to this routine, the flag is true. Otherwise, the flag is false. |
result |
double[nonde*6] |
Nodal forces. Acting point of the nodal force is each center of each node. Reference frame of each force vector must be Ground.InertiaMarker. |
Example
![../_images/image321.gif](../_images/image321.gif)
Figure 4.110 Modal force model applying air resistance effect using modal force ext USUB.
C---- SUB. MODAL_FORCE_EXT
SUBROUTINE MODAL_FORCE_EXT
& (ID,TIME,UPAR,NPAR,IFBODY,NODARR,NONDE,
& JFLAG,IFLAG,RESULT)
C---- TO EXPORT * SUBROUTINE
!DEC$ ATTRIBUTES DLLEXPORT,C::MODAL_FORCE_EXT
C---- INCLUDE SYSTEM CALL
INCLUDE 'SYSCAL.F'
C---- DEFINE VARIABLES
C Parameter Information
C ID : Modal force sequential identification. (Input)
C TIME : Simulation time of RD/Solver. (Input)
C UPAR : Parameters defined by user. (Input)
C NPAR : Number of user parameters. (Input)
C IFBODY : RFLEX Body sequential ID. (Input)
C NODARR : Node ID array of input node set. (Input)
C NONDE : Number of node of node set. (Input)
C JFLAG : When RD/Solver evaluates a Jacobian, the flag is true. (Input)
C JFLAG : When RD/Solver initializes arrays, the flag is true. (Input)
C RESULT : Returned nodal force vector. Acting point of the nodal force is each center of each node.
C Reference frame of each force vector must be Ground.InertiaMarker (Output, Size: nonde * 6)
DOUBLE PRECISION TIME, UPAR(*)
INTEGER ID, NPAR, IFBODY, NODARR(*), NONDE
LOGICAL JFLAG, IFLAG
DOUBLE PRECISION RESULT(*)
C---- USER STATEMENT
integer i,j,errflg
double precision Area, Cd, rho
double precision vn(3), vn_mag, ucf, scale
integer MKID(2), nMK
integer nodeseq
Cd = upar(2)
rho = upar(3)
scale = upar(4)
call rd_ucf(ucf)
MKID(1) = 0
MKID(2) = 0
nMK = 0
if(nodarr(i) .eq. 50004 .or. nodarr(i) .eq. 50007) then
Area = 100
else if (nodarr(i) .lt. 50010 .and. nodarr(i) .gt. 50075 ) then
Area = 200
else if(nodarr(i) .gt. 50076) then
Area = 400
endif
do i=1, nonde
call get_rflex_nodeseqid(ifbody,nodarr(i),nodeseq,errflg)
call get_rflex_nodetvel(ifbody,nodeseq,MKID,nMK,vn,errflg)
vn_mag = dsqrt(vn(1)**2+vn(2)**2+vn(3)**2)
do j=1, 3
if(vn_mag .eq. 0.0d0) then
result((i-1)*6+j) = 0.0d0
else
result((i-1)*6+j)=-1.0d0/2.0d0*Cd*rho*vn_mag*vn_mag*Area
& *(vn(j)/vn_mag) ! direction
& /ucf ! making force unit
& *scale ! an amplifier
result((i-1)*6+j+3) = 0.0;
endif
enddo
enddo
RETURN
END
#include "stdafx.h"
#include "DllFunc.h"
#include "math.h"
ModalForceExt_API void __cdecl modal_force_ext
(int id, double time, double upar[], int npar, int ifbody, int nodarr[], int nonde, int jflag, int iflag, double result[])
{
using namespace rd_syscall;
// Parameter Information
// id : Modal force sequential identification. (Input)
// time : Simulation time of RD/Solver. (Input)
// upar : Parameters defined by user. (Input)
// npar : Number of user parameters. (Input)
// ifbody : RFLEX Body sequential ID. (Input)
// nodarr : Node ID array of input node set. (Input)
// nonde : Number of node of node set. (Input)
// jflag : When RD/Solver evaluates a Jacobian, the flag is true. (Input)
// iflag : When RD/Solver initializes arrays, the flag is true. (Input)
// result : Returned nodal force vector. Acting point of the nodal force is each center of each node.
// Reference frame of each force vector must be Ground.InertiaMarker (Output, Size: nonde * 6)
// User Statement
int i, j, errflg;
int nodeseq;
double Area, Cd, rho;
double vn[3], vn_mag, ucf, scale;
WCHAR NodeName[256];
char strNodeName[256];
Cd = upar[0];
rho = upar[1];
scale = upar[2];
rd_ucf(&ucf);
for(i=0;i<nonde;i++){
if(nodarr[i] == 50004 || nodarr[i] == 50007) Area = 100;
else if (nodarr[i] >=50010 && nodarr[i] <= 50075 ) Area = 200;
else if(nodarr[i] > 50075) Area =400;
// Set velocity vector of node
get_rflex_nodeseqid(ifbody,nodarr[i],&nodeseq,&errflg);
get_rflex_nodetvel(ifbody,nodeseq,NULL,0,vn,&errflg);
vn_mag = sqrt(pow(vn[0],2)+pow(vn[1],2)+pow(vn[2],2));
for(j=0;j<3;j++){
if(vn_mag == 0.0)
result[i*6+j] = 0.0;
else
result[i*6+j] = -1.0/2.0*Cd*rho*vn_mag*vn_mag*Area
*(vn[j]/vn_mag) // Set negative direction of the nodal velocity
/ucf // Making force unit
*scale; //
result[i*6+j+3] = 0.0;
}
}
}