I have a set of elements from Abaqus modelling software, each of them has 8 nodes ( as in the picture https://postimg.cc/Mfy7zjsc). They are represented by a 53x9 matrix where the first column stores the names (numbers) of the elements and the other 8 store node numbers. I need to sort these elements ordering them as they appear in the model, as they are given pretty much random numbers (and so are nodes). I would then like my Matlab script to identify which of the rows in the matrix is either of the borderline elements (the one that only has 4 node numbers that are repeated in one of the other rows), set it at the start of a result matrix, and then find elements that are touching it (share the other 4 nodes) and follow later.
I haven't done programming in a while and I'm struggling with writing the loops correctly. I'm trying to get Matlab to first take one row of the matrix, take an element and go through all other to find duplicates. If it doesn't find any AND the row number is different to the one that is being worked on, it should increase a counter variable. If the variable reaches 4 then the script should return the number of the row, which will be the starting element. Right now I'm getting pretty random results and are finding it hard to debug it. 'elem' is the matrix with all values I have, 'nodess' is the same matrix with the column including element values deleted (i know it's probably stupid and useless but nvm). 'E' was supposed to be the result matrix.
% input data
in = [135346 135912 135913 20605 20606 51236 51237 8677 8678;...
135347 135913 135914 20604 20605 51237 51238 8676 8677;...
135348 135914 135915 20603 20604 51238 51239 8675 8676;...
135349 135915 135916 20602 20603 51239 51240 8674 8675;...
135350 135916 135917 20601 20602 51240 51241 8673 8674;...
135351 135917 135918 20600 20601 51241 51242 8672 8673;...
135352 135918 5057 107 20600 51242 5229 111 8672;...
135697 136514 20982 421 20868 136213 8585 184 20881;...
135698 136515 136514 20868 20869 136214 136213 20881 20880;...
135699 136516 136515 20869 20870 136215 136214 20880 20879;...
135700 136517 136516 20870 20871 136216 136215 20879 20878;...
135701 136518 136517 20871 20872 136217 136216 20878 20877;...
135702 136519 136518 20872 20873 136218 136217 20877 20876;...
135703 136520 136519 20873 20874 136219 136218 20876 20875;...
135704 20981 136520 20874 424 20896 136219 20875 425;...
232453 20982 192131 20715 421 8585 50247 8526 184;...
232454 192131 192132 20714 20715 50247 50248 8525 8526;...
232455 192132 192133 20713 20714 50248 50249 8524 8525;...
232456 192133 192134 20712 20713 50249 50250 8523 8524;...
232457 192134 192135 20711 20712 50250 50251 8522 8523;...
232458 192135 192136 20710 20711 50251 50252 8521 8522;...
232459 192136 192137 20709 20710 50252 50253 8520 8521;...
232460 192137 192138 20708 20709 50253 50254 8519 8520;...
232461 192138 192139 20707 20708 50254 50255 8518 8519;...
232462 192139 192140 20706 20707 50255 50256 8517 8518;...
232463 192140 192141 20705 20706 50256 50257 8516 8517;...
232464 192141 192142 20704 20705 50257 50258 8515 8516;...
232465 192142 192143 20703 20704 50258 50259 8514 8515;...
232466 192143 192144 20702 20703 50259 50260 8513 8514;...
232467 192144 192145 20701 20702 50260 50261 8512 8513;...
232468 192145 192146 20700 20701 50261 50262 8511 8512;...
232469 192146 20867 419 20700 50262 8628 183 8511;...
295505 2511 47 312217 297117 2683 51 312275 300385;...
295549 297117 312217 312216 297160 300385 312275 312276 300428;...
295593 297160 312216 312215 297203 300428 312276 312277 300471;...
295637 297203 312215 312214 297246 300471 312277 312278 300514;...
295681 297246 312214 312213 297289 300514 312278 312279 300557;...
295725 297289 312213 312212 297332 300557 312279 312280 300600;...
295769 297332 312212 312211 297375 300600 312280 312281 300643;...
295813 297375 312211 312210 297418 300643 312281 312282 300686;...
295857 297418 312210 312209 297461 300686 312282 312283 300729;...
295901 297461 312209 312208 297504 300729 312283 312284 300772;...
295945 297504 312208 312207 297547 300772 312284 312285 300815;...
295989 297547 312207 312206 297590 300815 312285 312286 300858;...
296033 297590 312206 312205 297633 300858 312286 312287 300901;...
296077 297633 312205 312204 297676 300901 312287 312288 300944;...
296121 297676 312204 312203 297719 300944 312288 312289 300987;...
296165 297719 312203 312202 297762 300987 312289 312290 301030;...
296209 297762 312202 312201 297805 301030 312290 312291 301073;...
296253 297805 312201 312200 297848 301073 312291 312292 301116;...
296297 297848 312200 312199 297891 301116 312292 312293 301159;...
296341 297891 312199 107 5057 301159 312293 111 5229];
E=0
for i=linspace(1,y,y)
EL=elem(i,1);
ns=nodess(i,:);
for j=linspace(1,size(ns,2),size(ns,2))
a=0;
for k=linspace(1,y,y)
for l=linspace(1,size(ns,2),size(ns,2))
wn=nodess(k,l);
if k~=i && wn==ns(l)
a=a 1
end
end
end
if a==4
E(1)=elem(i,1)
end
end
end
CodePudding user response:
Since the question is not completely clear, I am going to make several assumptions:
- There is no element connected to 0 other element
- There is no element connected to more than 2 elements
- Elements share 4 nodes and 4 nodes only (i.e. your input is correct)
- Note that I cannot assume that there is only one group of connected elements, since it is not the case in your example
The algorithm is in two parts. The first parts computes the adjacency matrix of the elements of your model. It basically checks if element ii
and jj
share elements.
n = size(in,1);
adj_matrix = zeros(n);
for ii=1:n
for jj=(ii 1):n
% adjacency matrix. 1 when node ii is connected to node jj
adj_matrix(ii,jj) = ~isempty(intersect(in(ii,2:end),in(jj,2:end)));
end
end
% fill lower triangular block
adj_matrix = adj_matrix adj_matrix.';
Now, you can check which elements are "tail" elements. The amount of 1s in row k
is the amount of elements connected to element k
. The "tail" elements are elements connected to only one other element:
% find the index of the elements that are linked only to one other element
id_tails = find(sum(adj_matrix,2)==1);
The core of the last part of the algorithm is to travel through the adjacency matrix to build your output vector of indexes one at a time. When your current element is element k
, and it is connected to 2 elements, one is already in your output vector, so you just pick the other one. Now since you have more than 2 "tail" elements in your example, you need a bit more magic to make it work. Basically, if your current element is a "tail" element, you just hop to the next tail:
% start building output index vector, with a randomly picked tail
idx_out = id_tails(1);
% Remove first tail from list
id_tails = setdiff(id_tails,idx_out);
while length(idx_out) < n
if ismember(idx_out(end),id_tails)
% If current index is a tail, next index is the next tail
idx_out(end 1) = id_tails(1);
% Remove first tail from list
id_tails = setdiff(id_tails,idx_out);
else
% If not a tail, then next index is the only one that is not yet in
% idx_out
idx_out(end 1) = setdiff(find(adj_matrix(idx_out(end),:)),idx_out);
end
end
Finally, you can use these indexes to sort your input matrix:
E = in(idx_out,:);