遵循@TylerOlson 的建议,这里是一个 Octave/Matlab 脚本,它生成一个在每个三角形中有六个点的网格:三个顶点和三个中点。如果有人知道简化这种不雅代码的方法,我将不胜感激。
clear
%% Persson's routine to make simple triangles in a rectangular grid
nx=4;ny=3;
[x,y]=ndgrid(linspace(-1,1,nx),linspace(-1,1,ny)); % forms x and y lists
p=[x(:),y(:)];
t=[1,nx+2,nx+1;1,2,nx+2];
t=kron(t,ones(nx-1,1))+kron(ones(size(t)),(0:nx-2)');
t=kron(t,ones(ny-1,1))+kron(ones(size(t)),(0:ny-2)'*nx);
np=length(p(:,1));nt=length(t(:,1));
%%make a list of all sides from t; There will be redundant entries
s=zeros(3*nt,6);
for kt=1:nt
for ks=1:3
if ks==1
s(3*(kt-1)+ks,1)=min(t(kt,1:2));
s(3*(kt-1)+ks,2)=max(t(kt,1:2));
s(3*(kt-1)+ks,3)=kt;
elseif ks==2
s(3*(kt-1)+ks,1)=min(t(kt,2:3));
s(3*(kt-1)+ks,2)=max(t(kt,2:3));
s(3*(kt-1)+ks,3)=kt;
else
s(3*(kt-1)+ks,1)=min(t(kt,[1,3]));
s(3*(kt-1)+ks,2)=max(t(kt,[1,3]));
s(3*(kt-1)+ks,3)=kt;
endif
endfor
endfor
%% once this has been done for all triangles, work on s to eliminate dupes
for kk=1:max(s(:,1))
order1=find(s(:,1)==kk);%s(order1,:)
[junk,order2]=sort(s(order1,2));
dupe=find(junk(1:end-1)==junk(2:end));
n=s(order1(order2),:);
for kl=1:length(dupe)
n(dupe(end+1-kl),4)=n(dupe(end+1-kl)+1,3);% add on triangle no of dupe
endfor
[junk,order3,mojunk]=unique(n(:,2),"first");
n=n(order3,:);
if kk==1
snodupe=n;
else
snodupe=[snodupe;n];
endif
endfor
%% add to position table the position of new nodes
for kn=1:length(snodupe)
p(np+kn,1)=0.5*(p(snodupe(kn,1),1)+p(snodupe(kn,2),1));
p(np+kn,2)=0.5*(p(snodupe(kn,1),2)+p(snodupe(kn,2),2));
endfor
%% build a new connectivity table, t6
t6=zeros(nt,6);
for kt=1:nt
%t(kt,:)
for ks=1:3
if ks==1
ss=t(kt,1);
se=t(kt,2);
elseif ks==2
ss=t(kt,2);
se=t(kt,3);
else
ss=t(kt,3);
se=t(kt,1);
endif
%% where is this side in snodupe table?
%% to lookup in snodupe need ends to be in order
s1=min([ss se]);s2=max([ss se]);
ind1=find(snodupe(:,1)==s1);
ind2=find(snodupe(ind1,2)==s2);
sideno=ind1(1)-1+ind2;
t6(kt,2*ks-1)=ss;
t6(kt,2*ks)=np+sideno;
endfor
endfor