Le API di NextFEM Designer danno la possibilità di creare un modello ad elementi finiti attraverso alcune righe di codice, che richiamano direttamente i comandi di modellazione e forniscono l’accesso completo ai risultati dell’analisi a elementi finiti. In questo esempio verrà trattata una pensilina ancorata a 45°, modellata attraverso il linguaggio Python.
Per il presente tutorial utilizzeremo Visual Studio 2019, che implementa Python 3.7. Una volta all’interno dell’ambiente di sviluppo Python, è necessario verificare di aver caricato tutti i pacchetti necessari al nostro scopo. Le API di NextFEM sono state create in linguaggio .NET, di conseguenza nell’ambiente Python dovrà essere presente il pacchetto “Python for NET” che consente l’interoperabilità tra i due linguaggi. Accedendo alla finestra di interfaccia di Python da Strumenti / Python / Ambienti Python sarà possibile installare, se non già presente, il pacchetto pythonnet digitandolo nella barra di ricerca di Pacchetti (PyPI) e lanciando il comando suggerito pip install pythonnet.
Per prima cosa, importare il modulo sys, che ci consentirà di interagire con l’interprete del sistema operativo che stiamo utilizzando.
import sys
Le API di NextFEM potranno essere caricate nell’ambiente di progetto utilizzando il metodo AddReference dell’istanza clr di PythonNET, specificando il percorso nel quale si trova il file NextFEMapi.dll. Se si utilizza NextFEM Designer a 32bit il percorso da utilizzare è C:\Program Files (x86)\NextFEM\NextFEM Designer 32bit\NextFEMapi.dll, mentre per il 64bit è C:\Program Files\NextFEM\NextFEM Designer 64bit\NextFEMapi.dll. Si ricorda che in Python il backslash (\) nei percorsi deve essere raddoppiato, oppure deve essere sostituito con lo slash (/).
import clr
clr.AddReference("C:\\Program Files\\NextFEM\\NextFEM Designer 64bit\\NextFEMapi.dll")
Sarà ora possibile creare un’istanza che consenta di utilizzare i metodi delle API, definita nell’esempio corrente come nf.
import NextFEMapi
nf=NextFEMapi.API()
E’ opportuno iniziare sempre con un controllo sull’attivazione della licenza delle API, che in caso negativo riporterà a schermo un errore e terminerà l’applicativo.
I metodi delle API di NextFEM sono elencati ed esemplificati alla pagina www.nextfem.it/api. Il metodo scelto potrà essere richiamato nell’ambiente Python con la sintassi istanza.metodo. Nel caso in esame, per la creazione di un nuovo modello si utilizzerà la seguente riga di codice:
nf.newModel
Per visualizzare le unità di misura del modello si possono creare due varabili, che chiameremo Lu per lunghezza e Fu per unità di forza, e stamparle a schermo mediante la serie di comandi:
Lu=nf.getLenUnit()
Fu=nf.getForceUnit()
print("Unità del modello: " + Lu + ", " + Fu)
Lanciando l’applicazione, il risultato che si ottiene fino a questo punto è il seguente:
Si modella a questo punto la pensilina, avente dimensioni 2.0x4.0m. Le coordinate dei nodi possono essere inserite con il metodo addNode, che consente inoltre di specificare le coordinate di due versori e ruotare così il nodo secondo un sistema di riferimento locale. Nel caso in esame i nodi 1 e 4 saranno inclinati a 45° supponendo che la pensilina venga sorretta da piedritti obliqui.
n1=nf.addNode(0,0,0,1,0,-1,0,1,0)
n2=nf.addNode(2,0,0)
n3=nf.addNode(2,4,0)
n4=nf.addNode(0,4,0,1,0,-1,0,1,0)
La documentazione di ciascun metodo implementato nelle NextFEM API è disponibile su nextfem.it/api oppure nella reference in formato Guida di Windows inclusa nell’installazione.
Il metodo setBC viene utilizzato per assegnare i vincoli al nodo indicato, specificando le direzioni da vincolare, come elencate in Designer.
nf.setBC(n1, True, True, True, False, True, True)
nf.setBC(n4, True, True, True, False, False, False)
Ipotizzando quattro traversi in acciaio con profilo IPE 140, materiale e sezione vengono caricati con i metodi addSectFromLib e addMatFromLib, utilizzando l’archivio già presente nel software.
sectID=nf.addSectFromLib("IPE 140")
matID=nf.addMatFromLib("S275")
Per creare gli elementi-trave occorre specificare il nodo iniziale, quello finale, la variabile assegnata al materiale e quella assegnata alla sezione, mediante il metodo addBeam.
beamID1=nf.addBeam(n1, n2, sectID, matID)
beamID2=nf.addBeam(n2, n3, sectID, matID)
beamID3=nf.addBeam(n3, n4, sectID, matID)
beamID4=nf.addBeam(n4, n1, sectID, matID)
Si noti che gli ID di nodi, elementi, materiali e sezioni sono salvati in variabili (sectID, beamID, ecc) che potranno essere riutilizzate in seguito per associare le proprietà dell’elemento.
I carichi sulla pensilina sono ipotizzati pari a 1.8kN/m2, per cui verrà assegnato un carico di piano all’interno del caso di carico G. Nel metodo per il carico di piano devono essere definiti, oltre a denominazione e caso di carico, l’intensità della forza e il verso di applicazione. Per applicare il carico deve essere inoltre definita la modalità, indicata con il numero 2 e rappresentante il carico distribuito su tutti e 4 i lati. Di seguito i comandi:
nf.addLoadCase("G")
nf.setFloorLoad("carico", "G", 1.8, 0, 0, -1)
nf.addFloorLoadPlane("carico", 2, n1, n2, n3, n4)
Si esegue quindi il modello appena creato in background, che in seguito viene aperto in Designer con i risultati disponibili:
s=nf.RunModel(); print(s)
nf.saveModel("pensilina.nxf")
nf.startDesigner("pensilina.nxf")
Forze e reazioni vincolari sono influenzate dai nuovi assi locali assegnati in fase di creazione dei nodi. Come si nota in figura, le reazioni vincolari lungo la direzione Z sono inclinate di 45°.
Si riporta di seguito il codice utilizzato per intero:
import sys
import clr
clr.AddReference("C:\\Program Files\\NextFEM\\NextFEM Designer 64bit\\NextFEMapi.dll")
import NextFEMapi
nf=NextFEMapi.API()
nf.newModel
Lu=nf.getLenUnit()
Fu=nf.getForceUnit()
print("Model units: " + Lu + ", " + Fu)
n1=nf.addNode(0,0,0,1,0,-1,0,1,0)
n2=nf.addNode(2,0,0)
n3=nf.addNode(2,4,0)
n4=nf.addNode(0,4,0,1,0,-1,0,1,0)
nf.setBC(n1, True, True, True, True, True, True)
nf.setBC(n4, True, True, True, True, True, True)
sectID=nf.addSectFromLib("IPE 140")
matID=nf.addMatFromLib("S275")
beamID1=nf.addBeam(n1, n2, sectID, matID)
beamID2=nf.addBeam(n2, n3, sectID, matID)
beamID3=nf.addBeam(n3, n4, sectID, matID)
beamID4=nf.addBeam(n4, n1, sectID, matID)
nf.addLoadCase("G")
nf.setFloorLoad("carico", "G", 1.8, 0, 0, -1)
nf.addFloorLoadPlane("carico", 2, n1, n2, n3, n4)
s=nf.RunModel(); print(s)
nf.saveModel("pensilina.nxf")
nf.startDesigner("pensilina.nxf")
I metodi utilizzabili saranno implementati comprendendo tutte le attuali funzionalità del software e quelle attualmente in sviluppo, con particolare attenzione alle verifiche intelligenti e all’elaborazione dei risultati.