Appendice D
Macro_slidings
Descrizione della macro:
La prima parte della macro viene fatta girare sul modello prima di effettuare l’analisi numerica e, come prima operazione, costruisce le matrici dei nodi e degli elementi contact. Successivamente descrive la corrispondenza fra nodi contact e nodi target, cioè viene definito un ARRAY , la prima colonna del quale contiene i nodi contact, la seconda i nodi target e nella terza, alla fine della macro, verranno messi i micromovimenti.
La seconda parte è, invece, fatta girare sul file dei risultati e crea un ARRAY (composto da tre piani) che contiene gli spostamenti dei nodi contact (piano 1), dei nodi target (piano 2) e gli spostamenti differenze (piano3). Vengono poi calcolati i micromovimenti nodali per ottenere , poi, quelli degli elementi. Infine sono calcolati anche i valori del gap e della penetrazione.
!* !*
!* Macro per il calcolo degli slidings cinematici !* che descrivono il moto di due corpi a
!* prescindere se siano o meno in contatto fra loro. !*
!*
/PREP7 ALLSEL,ALL
!* seleziono gli elementi contact ESEL, S, ENAME, , 174, , ,
!* seleziono i nodi contact NSLE, S, ALL,
!* numero di elem contact
*GET, n_el_c, ELEM, 0, COUNT
!* numero di nodi contact
*GET, n_node_c, NODE, 0, COUNT
! Le matrici dei nodi e degli elementi CONTACT sono state costruite a mano ! perchè non ordinati
/INPUT,'A_T','txt','C:\Documents and Settings\Windows
XP\Documenti\Matteo\SETTEMBRE/MODELLO_24SETT\',, 0 /INPUT,'E_T','txt','C:\Documents and Settings\Windows
XP\Documenti\Matteo\SETTEMBRE/MODELLO_24SETT\',, 0
! *vwrite, %A_C(7215,1,1)% scrive l'elemento che voglio della matrice !(F6.0) scrive un elemento per linea
!* creo l'array che descrive la corrispondenza fra nodi contact e nodi target !* nella prima colonna metto i nodi contact, nella seconda i target e nella terza !* metterò i micromovimenti (alla fine della macro)
*DIM, node_cor, ARRAY, n_node_c, 3, , , ,
!* imposto a 0 il contatore di riga dell'array row_arr=0
*DO, I, 1, n_node_c, 1
!* seleziono i nodi contact
ESEL, S, ENAME, , 174, , , NSLE, S, ALL,
!* seleziono all'interno dei nodi contact il nodo I NSEL, R, NODE, , %A_T(I,1,1)%
!* cerco il nodo target vicino al nodo contact I
*IF, NSEL(%A_T(I,1,1)%), EQ, 1, THEN row_arr= row_arr+1
node_cor(row_arr, 1)= %A_T(I,1,1)%
!* aggiungo alla selezione i nodi target ESEL, S, ENAME, , 170, , ,
NSLE, A, ALL,
!* tolgo dalla selezione il nodo I NSEL, U, NODE, , %A_T(I,1,1)%
node_cor(row_arr, 2)=NNEAR(%A_T(I,1,1)%)
*ENDIF *ENDDO
/POST1
!* leggo il file di risultati FILE, modello_24sett, rst
RSYS, 0 SET, LAST INRES, ALL
!* creo l'array che contiene spostamenti nodi contact (piano 1), spostamenti nodi !* target (piano 2) e spostamenti differenze (piano 3)
!* per ogni piano ho nelle 3 colonne rispettivamente le componenti X, Y, Z.
*DIM, spost, ARRAY, n_node_c, 3, 3, , ,
*DO, I, 1, n_node_c, 1 spost(I,1,1)=UX(node_cor(I, 1)) spost(I,2,1)=UY(node_cor(I, 1)) spost(I,3,1)=UZ(node_cor(I, 1)) spost(I,1,2)=UX(node_cor(I, 2)) spost(I,2,2)=UY(node_cor(I, 2)) spost(I,3,2)=UZ(node_cor(I, 2))
!* riempio (calcolando i valori) il piano relativo alle differenze. In questa macro ! lo spostamento relativo e' calcolato come contact-target e' quindi un vettore la ! cui direzione positiva va dal target (protesi) al contact (osso)
spost(I,1,3)=spost(I,1,2)-spost(I,1,1) spost(I,2,3)=spost(I,2,2)-spost(I,2,1) spost(I,3,3)=spost(I,3,2)-spost(I,3,1)
!* riempio (calcolando i valori) la colonna con i micromovimenti
node_cor(I, 3)= (spost(I,1,3)**2+spost(I,2,3)**2+spost(I,3,3)**2)**0.5
*ENDDO
!* il ciclo seguente sostituisce gli spostamenti UX, UY, UZ calcolati dal solutore con i !* valori DELTAUX, DELTAUY, DELTAUZ calcolati dalla macro; così facendo basta plottare
!* lo spostamento totale nodale per plottare in realtà i micromovimenti
ALLSEL, ALL
*DO, I, 1, n_node_c, 1
DNSOL, %node_cor(I, 1)%, U, Y, %spost(I,2,3)%, , , , , DNSOL, %node_cor(I, 1)%, U, Z, %spost(I,3,3)%, , , , ,
*ENDDO
RSYS, SOLU
!* creo l'array che descrive la corrispondenza fra elementi contact e nodi contact ! Questo vettore ha tante righe quanti sono gli elementi contact. Ha inoltre 7 colonne ! perche' ad ogni elemento contact, che e' in questo caso triangolare, sono associati ! 6 nodi. In realta' l'elemento CONTA174 ha 8 nodi definiti, perche' la forma triangolare
! e' una forma degenerata, l'elemento nasce quadrangolare.
! I nodi associati agli elementi sono solo i 6 nodi non ripetuti, ovvero, facendo
! riferimento all'elemento, sono i nodi: I,J,K,M,N,P I nodi L e O sono dei duplicati del nodo
! K
*DIM, el_top, ARRAY, n_el_c, 7, 2, , ,
!* imposto a 0 il contatore di riga dell'array row_arr=0
*DO, I, 1, n_el_c, 1
ALLSEL, ALL, NODE
/GOPR !se non metto questo gopr non mi riempie la tabella !* seleziono gli elementi contact
ESEL, S, ENAME, , 174, , ,
!* seleziono all'interno degli elementi CONTACT l'elemento I ESEL, R, ELEM, , %E_T(I,1,1)%
*IF, ESEL(E_T(I,1,1)), EQ, 1, THEN row_arr= row_arr+1
el_top(row_arr, 1, 1)=%E_T(I,1,1)%
NSLE, S, POS, 1
*GET, el_top(row_arr, 2, 1), NODE, , NUM, MIN NSLE, S, POS, 2
*GET, el_top(row_arr, 3, 1), NODE, , NUM, MIN NSLE, S, POS, 3
*GET, el_top(row_arr, 4, 1), NODE, , NUM, MIN NSLE, S, POS, 5
*GET, el_top(row_arr, 5, 1), NODE, , NUM, MIN NSLE, S, POS, 6
*GET, el_top(row_arr, 6, 1), NODE, , NUM, MIN NSLE, S, POS, 8
*GET, el_top(row_arr, 7, 1), NODE, , NUM, MIN
*ENDIF *ENDDO
!* calcolo le componenti del micromovimento medio dell'elemento come media delle !* componenti dei micromovimenti dei nodi ad esso
!* appartenenti e li metto nel piano 2 dell'array el_top
*DO, I, 1, n_el_c, 1
D_UX_m=0 D_UY_m=0 D_UZ_m=0 n_nodes=0
!* parto da una configurazione in cui non ho nessun nodo selezionato NSEL, NONE
*DO, J, 2, 7, 1
!* controllo se il prossimo nodo è già stato selezionato in questo elemento
*IF, NSEL(%el_top(I, J, 1)%), NE, 1, THEN
NSEL, A, NODE, , %el_top(I, J, 1)%
n_nodes=n_nodes+1 D_UX_m=D_UX_m+(%UX(el_top(I, J, 1))%) D_UY_m=D_UY_m+(%UY(el_top(I, J, 1))%) D_UZ_m=D_UZ_m+(%UZ(el_top(I, J, 1))%) *ENDIF *ENDDO el_top(I, 1, 2)= D_UX_m/n_nodes el_top(I, 2, 2)= D_UY_m/n_nodes el_top(I, 3, 2)= D_UZ_m/n_nodes el_top(I, 4, 2)= ((D_UX_m**2+D_UY_m**2+D_UZ_m**2)**0.5)/n_nodes *ENDDO
!* creo una Element Table con i micromovimenti degli elementi
ESEL, S, ENAME, , 174, , , ETABLE, ABS_SPOS, *DO, I, 1, n_el_c, 1
*ENDDO
!* cancello i parametri scalari usati nella macro *SET, I *SET, J *SET, D_UX_m *SET, D_UY_m *SET, D_UZ_m *SET, n_nodes *SET, row_arr !/INPUT,'4_Macro3_MAT','txt','F:\Users\Pucciani\PROVA_4_2-4\',,0 SAVE, risultati_MODELLO_24SETT,,,ALL
!* calcolo la normale di un elemento quadrangolare come media delle 4 normali !* che si ottengono scartando uno dei 4 nodi alla volta.
!* se l'elemento è triangolare, la media delle 4 normali naturalmente è uguale a una qualunque
!* delle 4 normali: non è molto efficiente ma conviene lasciarlo così (gli elem triangolari
!* se ci sono sono pochi)
!* il passo successivo è il calcolo delle normali ai nodi, determinate facendo la media !* delle normali degli elementi comuni al nodo
!* creo l'array che conterrà i coseni direttori delle normali degli elementi !* nelle colonne metto ID elemento contact, Xcomp, Ycomp, Zcomp *DIM, el_norm, ARRAY, n_el_c, 4, , , ,
ALLSEL, ALL *DO, I, 1, n_el_c, 1 x_cos=0 y_cos=0 z_cos=0 mod_norm=0
!* considero un elem di contatto e ne calcolo le 4 normali
x_cos=NORMNX(%el_top(I, 4, 1)%,%el_top(I, 3, 1)%,%el_top(I, 2, 1)%) y_cos=NORMNY(%el_top(I, 4, 1)%,%el_top(I, 3, 1)%,%el_top(I, 2, 1)%) z_cos=NORMNZ(%el_top(I, 4, 1)%,%el_top(I, 3, 1)%,%el_top(I, 2, 1)%)
el_norm(I,1)=%el_top(I,1,1)% el_norm(I,2)=x_cos
el_norm(I,3)=y_cos el_norm(I,4)=z_cos
*ENDDO
!* determino il gap fra gli elementi come prodotto scalare fra micromovimento e normale
!* dell'elemento contact
!* lo sliding è calcolato come ipotenusa (micromovimento) meno cateto (gap)
*DIM, el_gap, ARRAY, n_el_c, 3, , , ,
*DO, I, 1, n_el_c, 1
el_gap(I, 2)=el_norm(I, 2)*el_top(I, 1, 2)+el_norm(I, 3)*el_top(I, 2, 2)+el_norm(I, 4)*el_top(I, 3, 2)
el_gap(I, 3)=(el_top(I, 4, 2)**2-el_gap(I, 2)**2)**0.5
*ENDDO
/POST1
!* creo le element table con i due risultati appena trovati RSYS, 0 ESEL, S, ENAME, , 174, , , ETABLE, ABS_SPOS, ETABLE, ABS_U_NR, ETABLE, ABS_SLID, ETABLE, ABS_PENE, ETABLE, ABS_GAP, *DO, A, 1, n_el_c, 1
*IF, el_gap(A, 2), GT, O, THEN
DETAB, el_gap(A, 1), ABS_PENE, 0
DETAB, el_gap(A, 1), ABS_GAP, el_gap(A, 2)
*ELSE
DETAB, el_gap(A, 1), ABS_PENE, el_gap(A, 2) DETAB, el_gap(A, 1), ABS_GAP, 0
*ENDIF
DETAB, el_gap(A, 1), ABS_U_NR, el_gap(A, 2) DETAB, el_gap(A, 1), ABS_SLID, el_gap(A, 3)
*SET, I
*SET, mod_norm *SET, x_cos *SET, y_cos *SET, z_cos