乐于分享
好东西不私藏

相控阵天线建模工具升级(附源代码)

相控阵天线建模工具升级(附源代码)

说在前面

阵列天线与载体的一体化仿真是一个十分普遍的工程问题,机载阵列天线、舰载阵列天线、弹载阵列天线以及汽车毫米波雷达天线在复杂环境下电磁仿真都属于这一类问题。

这些问题不仅仅困扰着工程界,也同样令学术界十分头疼,多少研究工作者围绕者这个话题前赴后继的开展的研究。这类电磁计算问题的特点可以概括为三点:1)电大尺寸;2)多尺度;3)强耦合。每个问题但拎出来都还好好解决,组合起来的话,问题就变得不简单。目前三大主流的仿真软件(CST、FEKO、HFSS)在处理这类问题时,均各有优势,但缺点也同样十分明显,这取决于三种软件底层算法的优缺点。

于“场”方程的CST和HFSS计算时,需要对包含目标的整个空间进行剖分,“空气盒子”的引入可以极大减小求解区域,但是对于电大尺寸的载体,空气盒子的尺寸也会异常庞大,这一问题对于基于“频域”方法的HFSS,简直是灾难,对于基于“时域”方法的CST,虽然影响会小一点,但是由于采用“正交网格”进行剖分,CST在处理含有复杂精细结构的阵列天线时,计算精度又会有所欠缺。

基于“源”方程的FEKO,仅需要对目标区域进行剖分,网格数会大幅减少,这一优点对于处理电大尺寸目标十分有利,但是对于求解含有大量复杂精细结构的阵列天线时,就会因为“近区网格”数目较多,分区质量差、耦合强,散射矩阵形态恶化等原因,导致MLFMA加速效果急剧下降,迭代求解的收敛性恶化甚至不收敛的问题。

详细了解几种电磁计算算法的底层逻辑和优劣分析,可以参考往期文章《CAE设计师的你,有必要了解计算电磁学吗?》。

综上所述,针对“阵列天线+载体”的仿真仿真问题,想要做到“一招鲜,吃遍天”多少有点“妄想”,最好的方法就是,具体问题具体分析,针对问题的特征选择合适的软件和算法。

从阵列天线阵元规模和载体电尺寸大小的角度来看,可以大致做以下划分:

  • 阵元数目少(如数目<100),载体电尺寸较小,可以使用HFSS进行计算的,尽量使用HFS进行计算,计算精度高,同时由于天线通常是基于HFSS平台进行设计,直接加载体就可进行计算,无需移植到其他平台,操作方便;

  • 阵元数目少,载体电尺寸较大,HFSS已经无法进行计算,可以利用FEKO或CST,使用全波方法进行计算,计算精度高,计算速度和内存消耗均可接受;

  • 阵元数目少,载体电尺寸非常大(如电尺寸>100倍波长),HFSS和CST均算不动,建议采用FEKO的全波算法进行计算;

  • 阵元数目较多(如数目介于100~500),载体电尺寸较大,FEKO计算出现收敛性较差、内存消耗异常大,建议使用CST的全波算法进行计算,或利用FEKO单独计算阵列天线,并提取近场与载体进行一体化计算;

  • 阵元数目特别多(如数目>500),载体电尺寸也非常大,利用FEKO的近似算法获得阵列的远场,提取远场与载体一体化计算。

上述分类,只是提供了一个大致的方向,实际工程中,还需具体问题具体分析。

除了计算方法的选择需要关注,对于该问题,还有一个比较棘手的问题需要解决,那就是阵列天线的建模问题。大规模阵元的阵列天线单元数目多、波束扫描时,每个馈电单元的相位也要相应的改变,单纯依靠手动建模,时间成本相当高,且人为操作,错误很难避免。因此,依托仿真软件进行二次开发,实现快速自动建模,十分必要。

综上所述,围绕“阵列+载体计算”的话题,按照建模和计算两个方面做如下展开,本文重点针对基于FEKO平台,进行二次开发,进行任意形式相控阵列(单元形式、阵面形状)的自动建模。

正文

围绕着阵列天线的快速建模,往期文章多有提及:

1)一种是依托FEKO自带的应用扩展功能,可以快速生成任意单元形式的阵列天线,不足就是相扫功能尚不具备

2)往期二次开发的“相控阵列天线”自动建模模块,可以实现相扫功能,主要不足在于单元形式、阵面形状以及阵元馈电形式都比较单一。

自适应微带相控阵天线建模模块

基于MATLAB-FEKO-API技术的复杂结构+相控阵天线的快速建模

作者针对着几点不足进行了改进优化,源代码点击文末“阅读原文”,自行下载

  • 针对任意形式天线单元的优化

往期文章中天线单元的建模通过“代码”实现,这种建模方式对于结构比较复杂的天线单元十分不友好,也不利于天线单元形式的扩展。本文的建模逻辑有所调整,天线单元可以通过CADFEKO先进行建模,然后再利用“代码”通过批量复制操作实现阵列建模。

%%模型导入%形参定义(文件路径,单元路径,模型名称)function ImportCFXmodel(fid,element_path,model_name)fprintf(fid,'properties = {}\n');fprintf(fid,'properties.ImportGeometryEnabled = true\n');fprintf(fid,'properties.ImportMeshEnabled = false\n');fprintf(fid,'properties.ImportMeshRulesEnabled = true\n');fprintf(fid,'properties.ImportOptimisationSearchesEnabled = false\n');fprintf(fid,'properties.ImportSolutionEntitiesEnabled = false\n');fprintf(fid,'properties.MergeIdenticalMediaEnabled = false\n');fprintf(fid,'properties.MergeIdenticalVariablesEnabled = false\n');fprintf(fid,'properties.Prefix = ""\n');fprintf(fid,'CFXImporter = project.Importer.CFXModel.Settings\n');fprintf(fid,'CFXImporter:SetProperties(properties)\n');fprintf(fid,['project.Importer.CFXModel:Import([[',element_path,model_name,'.cfx]])\n']);end
  • 针对任意形状阵面的优化

往期文章介绍的方法要求阵面的形状为圆形,而实际工程中,天线阵面的形式则更加多样,椭圆形、菱形、方形等等,本文以网格的形式提取阵面外轮廓,结合阵列参数,对阵元进行布局,可以实现任意阵面外形的阵列天线的建模。

clc;clear all;%% 导入阵面轮廓曲线网格以及天线尺寸参数filepath='C:\Users\em.liu\Desktop\lb\model\';%网格文件位置filename='elips.nas';%网格文件名称R=400;%天线口径,尺寸需大于阵面尺寸,覆盖实际阵面p=[100,80];%单元周期[x方向周期,y方向周期]%% 创建单元中心的点阵面和单元边缘点阵面r=(sqrt(p(1)^2+p(2)^2))/2;%单元半径MM=floor(R/p(1));%x方向单元数(单边)NN=floor(R/p(2));%y方向单元数(单边)mm=1:1:2*MM;nn=1:1:2*NN;len = length(mm)*length(nn);  %[x0,y0]为阵元中心坐标,原点位于阵面集合中心x0=(-MM+mm-0.5)*p(1);    %[x0,y0]为阵元中心坐标,原点位于阵面几何中心y0=(NN-nn+0.5)*p(2);xq = repmat(x0,length(y0),1);%形成点的面分布yq = repmat(y0.',1,length(x0));th1=abs(asin(yq./sqrt(xq.^2+yq.^2)));      %计算点-原点与x轴夹角(统一到第一象限)xqo=xq+r*(xq./abs(xq)).*cos(th1);%计算单元边缘的坐标yqo=yq+r*(yq./abs(yq)).*sin(th1);plot(xqo,yqo,'bo');hold on;plot(xq,yq,'r+');%% 读取阵面轮廓曲线网格数据unit_Length=1e-3;%网格单位统一fid=fopen([filepath,filename]);nNode=0;while ~feof(fid)    txtline=fgetl(fid);    if contains(txtline,'GRID*')        nNode=nNode+1;        endendfclose(fid);fid=fopen([filepath,filename]);vision= fgetl(fid); % 版本消息null  = fgetl(fid);   % null  = fgetl(fid);   % 文件名null  = fgetl(fid);   % 日期null  = fgetl(fid);   % null  = fgetl(fid);   % 线段个数ntri  = fgetl(fid);   % 三角形个数ntri  = str2double(ntri(isstrprop(ntri,'digit')));ncube = fgetl(fid);ntetr = fgetl(fid);Nodes = zeros(nNode,3);Triangles = zeros(ntri,3);for ii=1:nNode    s1=fgetl(fid);    Nodes(str2double(s1(20:24)),1:2)=[str2double(s1(40:56)),str2double(s1(57:72))];    s2=fgetl(fid);    Nodes(str2double(s1(20:24)),3)=str2double(s2(9:end));endNodes=Nodes.'*unit_Length;fclose(fid);%% 判断点的位置p=Nodes';xv=1000.*p(:,1);%按实际尺寸大小进行坐标缩放yv=1000.*p(:,2);[in,on] = inpolygon(xqo,yqo,xv,yv);%判断点阵是否在轮廓曲线内% isunit_flg=reshape(in,2*MM,2*NN); isunit_flg=in;csvwrite('isunitflg.csv',isunit_flg);%% 绘图figureplot(xv,yv) % polygonaxis equalhold onplot(xq(in),yq(in),'r+') % points insideplot(xq(~in),yq(~in),'bo') % points outsidehold off
  • 针对馈电形式拓展的优化

往期文章仅支持wire_port的批量建模和馈电,馈电形式单一,本文进行了改进,基于导入模型上的线结构或面结构,进行馈电端口设置,扩展了波端口形式,改进的建模方式降低了代码块之间的耦合,用户进行馈电形式的扩展将更加方便,从而可以根据需要,参考以下程序自行扩展诸如edge_port,FEM line Port等馈电形式。

%%添加波导端口%形参定义(文件路径,端口名称,模型名称,端口所在面名称,端口激励方向,极化转角)function AddWaveguidePort(fid,Port_name,model_name,face_name,direction,rot_angel)fprintf(fid,'-- Created port "Port1"\n');fprintf(fid,'properties = cf.WaveguidePort.GetDefaultProperties()\n');fprintf(fid,['properties.DirectionReversed =',direction,'\n']);fprintf(fid,[model_name,'= project.Geometry["',model_name,'"]\n']);fprintf(fid,[face_name,'= ',model_name,'.Faces["',face_name,'"]\n']);fprintf(fid,['properties.Face =',face_name,'\n']);fprintf(fid,['properties.Label = "',Port_name,'"\n']);fprintf(fid,['properties.ReferenceDirectionRotation = cf.Enums.WaveguidePortReferenceDirectionRotationEnum.Rotate',rot_angel,'\n']);fprintf(fid,[Port_name,'= project.Ports:AddWaveguidePort(properties)\n']);end
%%批量设置波端口%形参定义(文件路径,阵元分布表,模型名称,端口所在平面名称,端口激励方向,极化转角)function WaveguidePort_array(fid,isunitflg,model_name,face_name,direction,rot_angle)[Ny,Nx]=size(isunitflg);kk=0;for ii=1:Ny    for jj=1:Nx        if isunitflg(ii,jj)~=0            kk=kk+1;            %建立waveguidePort            AddWaveguidePort(fid,['port_',num2str(ii),'_',num2str(jj)],...                [model_name,'_',num2str(kk)],face_name,direction,rot_angle);        end    endendend
  • 详细操作步骤

step1:建立单元模型,设置材料属性(如果有需要,也可提前设置好局部剖分尺寸),并保存为.CFX格式;

step2:在主程序中输入API文件夹、建模脚本.lua、阵元.CFX文件的路径以及阵元名称;

step3:输入阵列结构参数、端口信息、近场源/远场源尺寸、波束性能参数及扫描范围;

step4:运行生成.lua文件,并将内容拷贝至脚本编辑器script,并运行,自动完成相控阵的建模;

step5:删除导入的初始单元、初始求解项以及无效端口,并按照需要设置频率、选择算法等即可。

clear; clc; close all;%% 文件路径addpath('C:\Users\em.liu\Desktop\lb\FEKO_matlab_API');%接口函数路径filepath='C:\Users\em.liu\Desktop\lb';%脚本文件路径element_path='C:/Users/em.liu/Desktop/lb/model/';%单元文件(.CFX)的路径model_name='Horn1';%天线单元名称(PS:单元文件名与文件中的模型名称须一致)%% **************************参数录入********************************%% 天线单元尺寸p=[100,80];  %单元周期(单位:mm)L=[91,71]; %单元尺寸[X向尺寸,Y向尺寸](单位:mm)freq=10;        %工作频率(单位:GHz)R=400;            %天线半径(单位:mm) lambda=300/freq; %工作波长(单位:mm)%% 端口信息%波端口face_name='Face13';%端口所在平面名称direction='ture';%端口激励方向,勾选则为ture,否则为falserot_angle='90';%端口电场极化转角%线端口% wire_name='Wire29';%端口所在线名称%% 近场源参数设置nearfield_R=[300,1,300];   %R方向尺寸[起始半径,间隔,终点半径],按照近场半球的尺寸设置nearfield_theta= [0,1,90];    %thteta方向尺寸[起始theta,间隔,终点theta],按默认设置nearfield_phi=[0,4,360];       %phi方向尺寸[起始phi,间隔,终点phi],按默认设置%% 设置波束信息nbar=4;       %有nbar个等副瓣SLL=-25;      %副瓣电平fw_th=[0,10,0];%方位面角度范围[起始角度对应列,列间隔,终止角度对应列],PS:如果起始角与终止角一致,列间隔取非0的任意数;取值范围[0,180]fy_th=[0,20,20];%俯仰面角度范围[起始角度对应列,列间隔,终止角度对应列],PS:如果起始角与终止角一致,列间隔取非0的任意数;取值范围[0,360]simulation_flag=1;%选择计算类型,1代表和波束,2代表方位差(沿x方向差),3代表俯仰差(沿y方向差)%*******************************************************************************************************%%%天线结构参数化isunitflg=importdata('isunitflg.csv');[Ny,Nx]=size(isunitflg);%贴片建模需在口径以内  (Ny:阵列行数,沿y方向;Nx:阵列列数,沿x方向)array=ant4_Array(Nx,Ny,isunitflg,p);%利用微带天线结构体存储天线结构参数%%%幅相计算sweep=auto_sweep(isunitflg,p,fw_th,fy_th,lambda,nbar,SLL);%不同波位下的幅相位计算,信息以结构体形式进行保存%% 设置波束类型if simulation_flag==1    fid=fopen('ant_fw_sum.lua','wt');   %和方向图(PS:和方向图不分方位和与俯仰和,可以通过设置fw_th控制扫描平面)elseif simulation_flag==2    fid=fopen('ant_fw_diff.lua','wt');  %方位差方向图(沿x轴方向)else    fid=fopen('ant_fy_diff.lua','wt');  %俯仰差方向图(沿y轴方向)endGetApplication(fid);Setunit(fid,'Millimetres');           %建模单位统一为mm%% 组阵ImportCFXmodel(fid,element_path,model_name);%导入单元模型element_array(fid,isunitflg,array,model_name);%通过单元复制进行组阵WaveguidePort_array(fid,isunitflg,model_name,face_name,direction,rot_angle);%批量设置波导馈电端口% WirePort_array(fid,isunitflg,model_name,wire_name);%批量设置线端口%% 波束扫描(给不同波位进行幅相馈电)SetSourcesPerConfiguration(fid); %每个求解项的馈源设置不同%依据求解标识,馈电的幅/相设置都不相同if simulation_flag==1   %和波束    for th_fw=fw_th(1):fw_th(2):fw_th(3)        for th_fy=fy_th(1):fy_th(2):fy_th(3)            %每一个扫描角,添加一个求解项            Addstandardconfiguration(fid,['sum_direction',num2str(th_fw),...                '_',num2str(th_fy)]);            %设置近场            AddNearfield(fid,['sum_direction',num2str(th_fw),'_',num2str(th_fy)],nearfield_R,nearfield_theta,...                nearfield_phi,['sum_direction',num2str(th_fw),'_',num2str(th_fy)]);            %设置远场            FarField2(fid,'farfield1',[-2,0.001,2],[0,90,90],[th_fy,th_fw],...                ['sum_direction',num2str(th_fw),'_',num2str(th_fy)]);            FarField2(fid,'farfield2',[-180,0.2,180],[0,90,90],[th_fy,th_fw],...                ['sum_direction',num2str(th_fw),'_',num2str(th_fy)]);            %给阵列馈电%           array_Wiresource(fid,isunitflg,sweep,th_fw,th_fy,simulation_flag);%给线端口馈电            array_Waveguidesource(fid,isunitflg,sweep,th_fw,th_fy,simulation_flag);%给波端口馈电        end    endelseif simulation_flag==2  %方位差波束    for th_fw=fw_th(1):fw_th(2):fw_th(3)        for th_fy=fy_th(1):fy_th(2):fy_th(3)            %每一个扫描角,添加一个求解项            Addstandardconfiguration(fid,['diff_fw_direction',num2str(th_fw),'_',num2str(th_fy)]);            %设置近场            AddNearfield(fid,['diff_fw_direction',num2str(th_fw),'_',num2str(th_fy)],nearfield_R,nearfield_theta,...                nearfield_phi,['diff_fw_direction',num2str(th_fw),'_',num2str(th_fy)]);            %设置远场            FarField2(fid,'farfield1',[-2,0.001,2],[0,90,90],[th_fy,th_fw],['diff_fw_direction',num2str(th_fw),'_',num2str(th_fy)]);            FarField2(fid,'farfield2',[-180,0.2,180],[0,90,90],[th_fy,th_fw],['diff_fw_direction',num2str(th_fw),'_',num2str(th_fy)]);            %给阵列馈电%           array_Wiresource(fid,isunitflg,sweep,th_fw,th_fy,simulation_flag);%给线端口馈电            array_Waveguidesource(fid,isunitflg,sweep,th_fw,th_fy,simulation_flag);%给波端口馈电        end    endelse       %俯仰差波束    for th_fw=fw_th(1):fw_th(2):fw_th(3)        for th_fy=fy_th(1):fy_th(2):fy_th(3)            %每一个扫描角,添加一个求解项            Addstandardconfiguration(fid,['diff_fy_direction',num2str(th_fw),'_',num2str(th_fy)]);            %设置近场            AddNearfield(fid,['diff_fy_direction',num2str(th_fw),'_',num2str(th_fy)],nearfield_R,nearfield_theta,...                nearfield_phi,['diff_fy_direction',num2str(th_fw),'_',num2str(th_fy)]);            %设置远场            FarField2(fid,'farfield1',[-2,0.001,2],[0,90,90],[th_fy,th_fw],['diff_fy_direction',num2str(th_fw),'_',num2str(th_fy)]);            FarField2(fid,'farfield2',[-180,0.2,180],[0,90,90],[th_fy,th_fw],['diff_fy_direction',num2str(th_fw),'_',num2str(th_fy)]);            %给阵列馈电%           array_Wiresource(fid,isunitflg,sweep,th_fw,th_fy,simulation_flag);%给线端口馈电            array_Waveguidesource(fid,isunitflg,sweep,th_fw,th_fy,simulation_flag);%给波端口馈电        end    endendfclose(fid);

总结

针对目前feko软件尚不能针对相扫阵列进行自动建模的问题,在原本阵列天线自动建模基础进行了改进,可以实现任意单元形式、任意阵面外形、不同馈电形式相控阵天线的自动建模,可以方便读者快速进行相扫阵列天线的建模以及阵列天线+载体的仿真建模。

阵列天线分析与综合基础(实践篇)

天线方向性的几种表示(TIPS)

阵列天线分析与综合基础(理论篇)

萌新笔记——天线(原理篇)

CAE设计师的你,有必要了解计算电磁学吗?

Hypermesh萌新笔记(一)

通俗易懂!看完你就是半个天线专家了

FEKO进阶道路上的一些常见技巧(一)网格与剖分

自适应微带相控阵天线建模模块

海平面快速建模,两种方式,双倍快乐

Altair2021使用评测(高频电磁)

更多有关电磁CAE相关内容,请关注“电磁CAEer”,将为你提供从基础理论->软件使用->算法赋能->应用场景等有关“电磁仿真”全方位的认识。

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » 相控阵天线建模工具升级(附源代码)

猜你喜欢

  • 暂无文章