設計仿真 | Adams線性化分析子程序應用


導讀本文主要說明Adams 2022.1版本新增的、關于子程序中的c_get_linear_mat_states功能函數的綜合應用。對于多體動力學中的線性化分析,其實是非常重要的一塊內容,尤其在獲取系統頻率特性與控制系統耦合時非常有用,為此,在新版Adams中,提供了專門的c_get_mat_states函數,方便高級用戶在調用CONSUB子程序時進行關聯調用實現更為靈活高效的使用。


01

多體系統的線性化分析

設計仿真 | Adams線性化分析子程序應用的圖1


Adams的線性化分析功能,在一般的應用中主要有四種形式:

?Linear/eigensol,獲取系統本征解,研究系統穩定性,基于復平面工具針對實部與虛部的落點進行具體研究;

?Linear/statemat,獲取系統對應的狀態空間矩陣,是一種標準形式;

?Linear/mkb,獲取系統對應的狀態空間矩陣,是一種Nastran對應的形式;

?Linear/export,獲取Nastran對應格式的輸入文件,比如BDF;

設計仿真 | Adams線性化分析子程序應用的圖2

上圖針對一個自由度的彈簧振子系統,進行線性化分析獲得系統的特征頻率以及復平面對應數據,當然也可以獲得對應的模態振型動畫形式。這里采用的是linear/eigensol命令實現的求解,而該命令還可以同初始化、靜平衡、運動學、動力學相關的命令結合起來操作,可以對系統任意狀態點進行模型的線性化處理。


02

線性化分析子程序功能

設計仿真 | Adams線性化分析子程序應用的圖3


新版添加的c_get_linear_mat_states函數,可以使得工程師進行更加方便的用戶子程序綜合應用。之前,為了獲取系統的狀態空間矩陣,比如標準的ABCD矩陣形式,只能通過Linear/statemat命令實現,沒有其它的功能可以獲取該類數據。因此,當工程師需要在自己編寫的用戶子程序進行狀態空間矩陣數據調用時,只能通過先將這些數據求解并存儲于指定文件中,然后再通過編程讀取這些數據,非常的不方便。

有了c_get_linear_mat_states功能后,工程師可以通過子程序CONSUB進行狀態空間矩陣的求解后,直接進行其數據的調用,也就是狀態空間矩陣求解以及狀態向量獲取可以直接在用戶子程序中完成,不再需要額外的輸入輸出工作。

設計仿真 | Adams線性化分析子程序應用的圖4

上圖仍舊是單自由度彈簧振子模型,只不過在本模型中,剛度和阻尼會隨時間變化,并且將會在0s,1s,5s通過子程序CONSUB分別對系統進行線性化處理,當然在子程序中有c_get_linear_mat_states函數的調用。另外,模型上施加的外部載荷、彈簧力都是通過Gforce實現的,通過函數的綜合應用實現更靈活的設置。

為了實現上述所要求的仿真工況,必須借助腳本命令來完成,在初始階段首先對模型進行初始化求解,接著完成靜平衡計算,然后才進行第一次線性化求解,進而進行動態求解,在1秒完成時,進行第二次線性化求解,以此類推。仿真腳本命令如下所示:

設計仿真 | Adams線性化分析子程序應用的圖5
設計仿真 | Adams線性化分析子程序應用的圖6
設計仿真 | Adams線性化分析子程序應用的圖7

上圖分別為變化的剛度和阻尼參數

下面著重對CONSUB及c_get_linear_mat_states函數進行說明。需要注意該函數只能基于C使用,Fortran不支持。

#include

#include

#include "slv_c_utils.h"

#include

adams_c_Consub    Consub;

void printVec(FILE *fp, double *vec, int nrow, int ncol) {

   if (vec)

   {

      int nele = nrow * ncol;

      int i;

      for (i = 0; i < nele; i++) {

         fprintf(fp, "%25.17e", vec[i]);

         if ((i+1)%3 == 0)

         {

            fprintf(fp, "\n");

         }

      }

      fprintf(fp, "\n");

   }

   else

   {

      fprintf(fp, "There is no matrix generated!\n");

   }

}

void printInfo(FILE *fp, struct sAdamsLinearDataOut *out, int rm, char *msg)

{

   fprintf(fp, "%s\n", msg);

   fprintf(fp, "Number of differential states ND = %d, Number of kinematic states NK = %d\n", out->ND, out->NK);

   fprintf(fp, "A matrix, nrow = %5d, ncol = %5d->\n", out->NS, out->NS);

   printVec(fp, out->A, out->NS, out->NS);

   fprintf(fp, "B matrix, nrow = %5d, ncol = %5d->\n", out->NS, out->NI);

   printVec(fp, out->B, out->NS, out->NI);

   fprintf(fp, "C matrix, nrow = %5d, ncol = %5d->\n", out->NO, out->NS);

   printVec(fp, out->C, out->NO, out->NS);

   fprintf(fp, "D matrix, nrow = %5d, ncol = %5d->\n", out->NO, out->NI);

   printVec(fp, out->D, out->NO, out->NI);

   if (rm)

   {

     fprintf(fp, "State vector, nrow = %5d, ncol=%5d->\n", 3, out->NS + 1);

     printVec(fp, out->STATESINFO, out->NS + 1, 3);

   }

   else

   {

     fprintf(fp, "State vector, nrow = %5d, ncol=%5d->\n", 3, out->NS);

     printVec(fp, out->STATESINFO, out->NS, 3);

   }

   fprintf(fp, "Values of the state vector->\n");

   printVec(fp, out->STATES, out->NS, 1);

}

void Consub(const struct sAdamsControl* con)

{

   int errflg=1;

   int id=0;

   int npar;

   int par[8];

   int type;

   int i;

      npar = con->NPAR;

   for (i = 0; i < npar; i++)

   {

      par[i] = (int)con->PAR[i];

   }

   if (npar == 6)

   {

      par[6] = 0;

   }

   struct sAdamsLinearDataIn dataIn;

   dataIn.PINPUT     = par[0];

   dataIn.POUTPUT    = par[1];

   dataIn.PSTATE     = par[2];

   dataIn.RM         = par[3];

   dataIn.NODAMPIN   = par[4];

   dataIn.ORIGINAL   = par[5];

   dataIn.USEPBCS    = par[6];

      FILE *fp;

   char fileName[40] = "linear_utility_res";

   char num[] = {par[7] + '0', '\0'};

   strcat(fileName, num);

   fp = fopen(fileName, "w");

   struct sAdamsLinearDataOut out;

   type = 1;

   c_get_linear_mat_states(&dataIn, &out, &type);

   type = 0;

   c_get_linear_mat_states(&dataIn, &out, &type);

   printInfo(fp, &out, dataIn.RM, "Evaluation stage");

   type = 5;

   c_get_linear_mat_states(&dataIn, &out, &type);

   fclose(fp);

   c_usrmes(errflg, "\n\nCalled from consub.\n\n", id, "INFO_NOPAD");

}

上述代碼中核心是Consub程序,另外的兩個print函數只是為了輸出結果到文件中。可以看到在Consub中,c_get_linear_mat_states函數的使用就像其它獲取狀態變量的函數一樣非常方便。Par[]對應了Consub的8個輸入參數,前面的7個輸入參數傳輸給dataIn結構體,而c_get_linear_mat_states()的基本形式如下所示:

void c_get_linear_mat_states(struct sAdamsLinearDataIn *dataIn, struct sAdamsLinearDataOut *dataOut, int *type);

具體的dataIn和dataOut所包含的具體內容可以在幫助中查看。

另外,需要注意,當一個Consub中有多次該函數的調用,只需要一次初始化和一次內存清理,而c_get_linear_mat_states()只能在Consub子程序中調用。

下面為第一次的輸出結果:

Evaluation stage

Number of differential states ND = 0, Number of kinematic states NK = 2

A matrix, nrow =     2, ncol =     2->

-4.00000000000000022e-01  1.00000000000000000e+00

-4.00000000000000000e+02  0.00000000000000000e+00

B matrix, nrow =     2, ncol =     1->

  4.00000000000000000e+01  0.00000000000000000e+00

C matrix, nrow =     1, ncol =     2->

 -4.00000000000000022e-01 -4.00000000000000000e+02

D matrix, nrow =     1, ncol =     1->

  4.00000000000000000e+01

State vector, nrow =     3, ncol=    2->

1.00000000000000000e+00  2.00000000000000000e+00 

8.00000000000000000e+00  1.00000000000000000e+00 

2.00000000000000000e+00  2.00000000000000000e+00

Values of the state vector->

  0.00000000000000000e+00  4.00000000000000000e+02


03

總結

設計仿真 | Adams線性化分析子程序應用的圖8


Adams新版提供的c_get_linear_mat_states()函數可方便地獲得狀態空間矩陣及狀態矢量,方便Consub程序的綜合應用,極大拓展了多體線性化仿真以及同其它應用的結合,方便完成更高級、更復雜的工程分析。

文件路徑為E:\MSC.Software\Adams\2022_1_875404\solver\samples

Linear_utility.acf, Linear_utility.adm,Linear_utility.c(c碼轉化為dll需要參考Adams用戶子程序一般流程,需要相關編譯環境支持)。

此文摘自海克斯康工業軟件

登錄后免費查看全文
立即登錄
App下載
技術鄰APP
工程師必備
  • 項目客服
  • 培訓客服
  • 平臺客服

TOP