设计仿真 | 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用户子程序一般流程,需要相关编译环境支持)。

文章来源:海克斯康工业软件

默认 最新
当前暂无评论,小编等你评论哦!
点赞 评论 收藏
关注