Bonjour à toutes et à tous,

J'essaie de générer un maillage homogène (de type lattice en 2D) en D dimensions et récupérer la matrice d'adjacence associée pour 2 cas précis:
  • sans conditions aux bords. Pour un maillage en dimension 2, cela se traduit par des noeuds de degré 3 aux bords et 2 aux quatre coins de la lattice
  • avec conditions aux bords. Typiquement, dans un maillage de dimension 2, les noeuds du haut sont liés aux noeuds du bas et les noeuds du bord à droite sont liés au bord à gauche.


Je peux générer un maillage de dimension 2 sans conditions aux bords avec le code suivant, ou je prend en compte chaque cas (bords ou pas) et construis la matrice d’adjacence associée:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
N = 10*10; %nombre de noeuds
net_size = sqrt(N)-1;
S = linspace(0, net_size, sqrt(N));
X = ndgrid(S,S);
Y = X';
cnet.XY = [X(:), Y(:)];
 
%créer les liens:
cnet = wire(cnet);
 
%affiche le réseau:
figure;
hold on;
for i=1:size(cnet.XY,1)
    plot(cnet.XY(i,1), cnet.XY(i,2), 'k.', 'Markersize', 20);
 
    idx = find(cnet.adjm(i,:)); %trouve les noeuds connectés
 
    %affiche une ligne pour le lien
    for j=1:size(idx,2)
        plot([cnet.XY(i,1), cnet.XY(idx(j),1)], [cnet.XY(i,2), cnet.XY(idx(j),2)], 'k-', 'linewidth', 2);
    end
end
axis square;
axis off;
 
 
function cnet = wire(cnet)
%Construit la matrice d'adjacence pour un maillage sans conditions aux bords:
 
s = size(cnet.XY,1); %cnet.XY contient les coordonnées des noeuds, avec une distance unité entre les noeuds et le noeud origine en [0,0]
n = sqrt(s); %nombre de noeuds sur un bord (nombre de noeuds total N = n*n)
adjm = zeros(s, s); %pre-alloc
 
%En utilisant linspace() et l'opérateur (:), on sait que la lattice est ordonnée en zig-zag.
%Les bords se trouvent donc aux indices suivants:
%bords du bas =  [1 ... n]
%bords du haut =  [s-n+1 ... s]
%pas de bords =   [i ... i+n]
%coins = [1] [n] [s-n] [s]
 
for i=1:size(cnet.XY,1)
    if(i == 1) %coin en bas à gauche
        adjm(1, 2) = 1; adjm(2, 1) = 1; %lien vers le noeud à droite
        adjm(1, n+1) = 1; adjm(n+1, 1) = 1; %lien vers le noeud du heut
    else
        if(i == n) %coin en bas à droite
            adjm(i, n-1) = 1; adjm(n-1, i) = 1; %lien vers le noeud de gauche
            adjm(i, 2*n) = 1; adjm(2*n, i) = 1; %lien vers le noeud du haut
        else
            if(i == s-n+1) %coin en haut à gauche
                adjm(i, s-2*n+1) = 1; adjm(s-2*n+1, i) = 1; %lien vers le noeud du bas
                adjm(i, s-2*n+1) = 1; adjm(s-2*n+1, i) = 1; %lien vers le noeud de droite
            else
                if(i == s) %coin en haut à droite
                    adjm(i, s-n) = 1; adjm(s-n, i) = 1; %lien vers le noeud du bas
                    adjm(i, s-1) = 1; adjm(s-1, i) = 1; %lien vers le noeud de gauche
                else
                    %Sinon, on regarde si on est dans un bord haut ou bas en premier:
                    if(i >= 2 && i <=n-1) %bord du bas:
                        adjm(i, i-1) = 1; adjm(i-1, i) = 1; %lien noeud gauche
                        adjm(i, i+n) = 1; adjm(i+n, i) = 1; %lien noeud haut
                        adjm(i, i+1) = 1; adjm(i+1, i) = 1; %lien noeud droite
                    else
                        if(i >= s-n+2 && i <=s-1) %bord du haut
                            adjm(i, i-1) = 1; adjm(i-1, i) = 1; %lien noeud gauche
                            adjm(i, i-n) = 1; adjm(i-n, i) = 1; %lien noeud bas
                            adjm(i, i+1) = 1; adjm(i+1, i) = 1; %lien noeud droite
                        else
                            if(rem(i,n) == 1) %bord de gauche
                                adjm(i, i+n) = 1; adjm(i+n, i) = 1; %lien noeud haut
                                adjm(i, i+1) = 1; adjm(i+1, i) = 1; %lien noeud droite
                                adjm(i, i-n) = 1; adjm(i-n, i) = 1; %lien noeud bas
                            else
                                if(rem(i, n) == 0) %bord de droite
                                    adjm(i, i+n) = 1; adjm(i+n, i) = 1; %lien noeud haut
                                    adjm(i, i-1) = 1; adjm(i-1, i) = 1; %lien noeud gauche
                                    adjm(i, i-n) = 1; adjm(i-n, i) = 1; %lien noeud bas
                                else
                                    %sinon, c'est u noeud normal (4 liens)
                                    adjm(i, i-1) = 1; adjm(i-1, i) = 1; %lien noeud gauche
                                    adjm(i, i+n) = 1; adjm(i+n, i) = 1; %lien noeud haut
                                    adjm(i, i+1) = 1; adjm(i+1, i) = 1; %lien noeud droite
                                    adjm(i, i-n) = 1; adjm(i-n, i) = 1; %lien noeud bas
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
 
cnet.adjm = adjm;
 
end
Je peux adapter cette solution pour les conditions aux bords. Cependant, je trouve cette solution inélégante, et difficilement portable pour de plus grandes dimensions (on s'imagine gérer tous les bords avec D=5 ).
Auriez-vous une solution plus pratique à me proposer, dans le cas avec ou sans conditions aux bords ?

Merci!

Edit: création d'un exemple fonctionnel. Tout ce déroule dans la fonction wire(cnet).