表性能/综合性能/矢量化

时间:2020-01-22 10:53:41

标签: matlab performance

我在matlab中实现了4D插值,其中性能非常重要。插值方法是基于Delaunay三角剖分的最近邻插值。因为我对Matlab编码还很陌生,所以我想问一问,由于性能差,我应该使用数组还是单元格来代替表。还有一个普遍的问题,如果您看到任何东西,我可以在哪里加快代码的速度。我已经将Mat文件保存在v6中,所以这不是一个选择。在文本下方,您将看到主程序的代码。之后,将代码用于2D插值。 我加载的表格由7个列组成,其中填充了AeroDataId,X_C坐标,CP(压力导数),马赫数,升力系数,雷诺数和过渡。在大多数情况下,一个AeroDataId属于280 x_c坐标,具有不同的压力系数。 筛选所有数据似乎比使用sql查询要快。

clc
close
clear


%% ReynoldsNumbers and Transitions known in the database

ReynoldsNumbers=[1e6;1.5e6;2.5e6;5e6;8e6;14e6;25e6;50e6;100e6];
Transition=[0;0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9];

%% parameters

Ma=0.85;
C_l=0.345;
Tl=0.15;
Re=55e6;
AirfoilId=0;

delta=0.015;
delta_ini=0.15;

%% try to find the neighbours of the parameters, which already exist in the database
tic
Re_u=ReynoldsNumbers(ReynoldsNumbers==Re);
Tl_u=Transition(Transition==Tl);
Tl_o=[];
Re_o=[];


if isempty(Re_u)
    Re_u_index=nearestpoint(Re,ReynoldsNumbers,'previous');
    Re_o_index=nearestpoint(Re,ReynoldsNumbers,'next');
    Re_o=ReynoldsNumbers(Re_o_index);
    Re_u=ReynoldsNumbers(Re_u_index);
    if Re < 1e6
        Re_u=1e6;
        Re_o=1.5e6;
    elseif Re > 100e6
        Re_u=50e6;
        Re_o=100e6;
    end
end

if isempty(Tl_u)
    Tl_u_index=nearestpoint(Tl,Transition,'previous');
    Tl_o_index=nearestpoint(Tl,Transition,'next');
    Tl_u=Transition(Tl_u_index);
    Tl_o=Transition(Tl_o_index);
end
toc
%% load data based on the airfoilId size of new_upper_airfoil 25000000x7 table

if AirfoilId==0
    load('new_upper_airfoil_all_0');
    load('new_lower_airfoil_all_0');
elseif AirfoilId==1
    load('new_upper_airfoil_all_1');
    load('new_lower_airfoil_all_1');
elseif AirfoilId==2
    load('new_upper_airfoil_all_2');
    load('new_lower_airfoil_all_2');
end

%% no need to to make all the interpolation with the whole data, only a specific delta 

new_upper_airfoil=new_upper_airfoil_all(new_upper_airfoil_all.Ma < (Ma+delta_ini) & new_upper_airfoil_all.Ma > (Ma-delta_ini) & new_upper_airfoil_all.CL_res < (C_l+delta_ini) & new_upper_airfoil_all.CL_res > (C_l-delta_ini),2:7);
new_lower_airfoil=new_lower_airfoil_all(new_lower_airfoil_all.Ma < (Ma+delta_ini) & new_lower_airfoil_all.Ma > (Ma-delta_ini) & new_lower_airfoil_all.CL_res < (C_l+delta_ini) & new_lower_airfoil_all.CL_res > (C_l-delta_ini),2:7);

%% filter data for the first 2D - Interpoaltion and execute it

new_upper_airfoil1=new_upper_airfoil(new_upper_airfoil.ReynoldsNumber==Re_u & new_upper_airfoil.Transition==Tl_u,1:4);
new_lower_airfoil1=new_lower_airfoil(new_lower_airfoil.ReynoldsNumber==Re_u & new_lower_airfoil.Transition==Tl_u,1:4);
DV1=delaunay_nearest(new_upper_airfoil1, new_lower_airfoil1, Ma, C_l, delta);
DV_1=table(DV1.X_C, DV1.CP, repmat(Re_u,280,1),repmat(Tl_u,280,1),'VariableNames',{'X_C','CP','Re','Tl'});
%% secound

if ~isempty(Tl_o)
    new_upper_airfoil2=new_upper_airfoil(new_upper_airfoil.ReynoldsNumber==Re_u & new_upper_airfoil.Transition==Tl_o,1:4);
    new_lower_airfoil2=new_lower_airfoil(new_lower_airfoil.ReynoldsNumber==Re_u & new_lower_airfoil.Transition==Tl_o,1:4);
    DV2=delaunay_nearest(new_upper_airfoil2, new_lower_airfoil2, Ma, C_l, delta);
    DV_2=table(DV2.X_C, DV2.CP, repmat(Re_u,280,1), repmat(Tl_o,280,1),'VariableNames',{'X_C','CP','Re','Tl'});
else
    DV_2=[];
end

%% third

if ~isempty(Re_o)
    new_upper_airfoil3=new_upper_airfoil(new_upper_airfoil.ReynoldsNumber==Re_o & new_upper_airfoil.Transition==Tl_u,1:4);
    new_lower_airfoil3=new_lower_airfoil(new_lower_airfoil.ReynoldsNumber==Re_o & new_lower_airfoil.Transition==Tl_u,1:4);
    DV3=delaunay_nearest(new_upper_airfoil3, new_lower_airfoil3, Ma, C_l, delta);
    DV_3=table(DV3.X_C, DV3.CP, repmat(Re_o,280,1),repmat(Tl_u,280,1),'VariableNames',{'X_C','CP','Re','Tl'});
else
    DV_3=[];
end    

%% fourth

if ~isempty(Re_o) && ~isempty(Tl_o)
    new_upper_airfoil4=new_upper_airfoil(new_upper_airfoil.ReynoldsNumber==Re_o & new_upper_airfoil.Transition==Tl_o,1:4);
    new_lower_airfoil4=new_lower_airfoil(new_lower_airfoil.ReynoldsNumber==Re_o & new_lower_airfoil.Transition==Tl_o,1:4);
    DV4=delaunay_nearest(new_upper_airfoil4, new_lower_airfoil4, Ma, C_l, delta);  
    DV_4=table(DV4.X_C, DV4.CP, repmat(Re_o,280,1),repmat(Tl_o,280,1),'VariableNames',{'X_C','CP','Re','Tl'});
else
    DV_4=[];
end

%% Interpolation of the 4 2D Interpolations

DV_inter=[DV_1;DV_2;DV_3;DV_4];

if size(DV_inter,1)==280
    DV=DV_1(:,1:2);

%     figure
%     hold on
%     plot(DV.X_C,-DV.CP,'bl-');
%     grid on;
%     xlabel('X_C');
%     ylabel('Cp');
%     

else
    %% interpolation with inverse distance weighted interpoaltion
    load('x_c0');
    DV=zeros(281,2);
    for x_c=1:1:280
        x_c_inter=x_c0(x_c);
        Find=DV_inter(DV_inter.X_C==x_c_inter,:);

        cp_inter=IDW(Find.Re, Find.Tl,Find.CP,Re,Tl,-2,'ng',2);

        DV(x_c,:)=[x_c_inter,cp_inter];

    end
    DV(281,:)=DV(1,:);

    figure
    hold on
    plot(DV(:,1),-DV(:,2),'r-');
    grid on;
    xlabel('X_C');
    ylabel('Cp');
end
function DV = delaunay_nearest(new_upper_airfoil,new_lower_airfoil,Ma,C_l,delta)
Error=true;

load('x_c0');
while(Error)
    %% build table for the pressure distribution
    DV=array2table(zeros(280,2),'VariableNames',{'X_C','CP'});

    %% another smaller delta for the interpolation (if too small the exception will be catched and the interpolation is restarted with a higher delta

    new_upper_airfoil_loop=new_upper_airfoil(new_upper_airfoil.Ma < (Ma+delta) & new_upper_airfoil.Ma > (Ma-delta) & new_upper_airfoil.CL_res < (C_l+delta) & new_upper_airfoil.CL_res > (C_l-delta),:);
    new_lower_airfoil_loop=new_lower_airfoil(new_lower_airfoil.Ma < (Ma+delta) & new_lower_airfoil.Ma > (Ma-delta) & new_lower_airfoil.CL_res < (C_l+delta) & new_lower_airfoil.CL_res > (C_l-delta),:);


    %% try to build the delaunay triangulation
    try
        DT=delaunayTriangulation(new_upper_airfoil_loop.Ma,new_upper_airfoil_loop.CL_res);

%         figure
%         hold on;
%         triplot(DT);
%         plot(Ma,C_l,'ro');
        %% find nearest neighbor
        pointindex=dsearchn(DT.Points,[Ma,C_l]);
        point=DT.Points(pointindex,:);
        Error=0;
    catch
        delta=delta+0.005;
        disp('Die Deltas wurden um 0.005 erhöht, da der Bereich der Daten zu klein war.');
        continue;
    end

    %% search for the nearest neighbor
    new_upper_airfoil_loop=new_upper_airfoil_loop(new_upper_airfoil_loop.Ma==point(1,1) & new_upper_airfoil_loop.CL_res==point(1,2),1:2);
    new_lower_airfoil_loop=new_lower_airfoil_loop(new_lower_airfoil_loop.Ma==point(1,1) & new_lower_airfoil_loop.CL_res==point(1,2),1:2);

    %% 2D Interpolation for all 280 points of the airfoil with the same x/c coordinates
    for x_c=1:1:280
            x_c_inter=x_c0(x_c);

            %% upper_airfoil
            if x_c < 146
                FIND=new_upper_airfoil_loop(abs(new_upper_airfoil_loop.X_C-x_c_inter)<0.0005,:);

                if(isempty(FIND))

                    leftNeighborIndex=nearestpoint(x_c_inter,new_upper_airfoil_loop.X_C,'previous');
                    if isnan(leftNeighborIndex)
                        leftNeighborIndex=1;
                    end

                    rightNeighborIndex=leftNeighborIndex+1;

                    if rightNeighborIndex > height(new_upper_airfoil_loop)
                        rightNeighborIndex=leftNeighborIndex-1;
                    end

                    average=interp1([new_upper_airfoil_loop.X_C(leftNeighborIndex,:),new_upper_airfoil_loop.X_C(rightNeighborIndex,:)], [new_upper_airfoil_loop.CP(leftNeighborIndex,:),new_upper_airfoil_loop.CP(rightNeighborIndex,:)], x_c_inter, 'linear','extrap');
                    FIND.X_C(1,:)=x_c_inter;
                    FIND.CP(1,:)=average; 


                    DV(x_c,:)=FIND;

                else
                    FIND.X_C(1,1)=x_c_inter;
                    DV(x_c,:)=FIND(1,:);

                end 

            end
            %% lower airfoil
            if x_c > 145
                FIND=new_lower_airfoil_loop(abs(new_lower_airfoil_loop.X_C-x_c_inter)<0.00008,:);

                if(isempty(FIND))

                    leftNeighborIndex=nearestpoint(x_c_inter,new_lower_airfoil_loop.X_C,'previous');
                    if isnan(leftNeighborIndex)
                        leftNeighborIndex=height(new_lower_airfoil_loop);
                    end
                    rightNeighborIndex=leftNeighborIndex-1;

                    average=interp1([new_lower_airfoil_loop.X_C(leftNeighborIndex,:),new_lower_airfoil_loop.X_C(rightNeighborIndex,:)], [new_lower_airfoil_loop.CP(leftNeighborIndex,:),new_lower_airfoil_loop.CP(rightNeighborIndex,:)], x_c_inter, 'linear','extrap');
                    FIND.X_C(1,:)=x_c_inter;
                    FIND.CP(1,:)=average; 


                    DV(x_c,:)=FIND;

                else
                    FIND.X_C(1,1)=x_c_inter;
                    DV(x_c,:)=FIND(1,:);
                end 

            end


    end

end

end

0 个答案:

没有答案
相关问题