Il Bar dell'Ingegneria

Ci A Pi

« Older   Newer »
 
  Share  
.
  1. texitaliano64
        +1   -1
     
    .
    Avatar

    Member

    Group
    Member
    Posts
    766
    Reputation
    +23

    Status
    Offline
    Ho modificato il foglio dando la possibilità all'utente di modificare sia lo spessore minimo delle fibre che il numero massimo di fibre da utilizzare nella integrazione, inoltre grazie a quanto detto a proposito di modifica della ampiezza dati di origine dei grafici (topic Gestione grafici excel via VBA) ho reso possibile la scelta da parte dell'utente del numero di punti utili per tracciare il grafico del dominio di rottura.
    Implementata la tecnica di infittimento punti del dominio di rottura qualora non vada a convergenza col numero punti scelto dall'utente, di cui se ne era parlato circa un anno fa nel topic "Verifica di sezioni complesse in ca. agli SLE ed agli SLU", tecnica utile per ridurre i tempi di elaborazione.

    CODICE
    Ricalcola:

    Dim flag_convergenza As Boolean
    Dim flag_circa As Boolean
    Dim index As Integer
    Call calcola_MomentiRottura(dominio_slu, soll(25 + n_c), MomentiRottura, flag_convergenza, flag_circa, index)

       'Controlliamo la convergenza
       If Not flag_convergenza Then
           'se non converge infittiamo i punti del contorno del dominio localmente e ricalcoliamo
           'npt  --> punti del dominio iniziali
           'ninf --> numero massimo di infittimenti locali consentiti
           'pfis --> numero di punti fisici effettivamente calcolati
           'pvt  --> numero punti virtuali corrispondenti ad un infittimento globale equivalente
           'pfis=(npt*2^ninf)
           'pvt=(pfis-npt)*npt
           
           'esempi:
           
           'caso npt=4 ninf=6 corrisponde a 256 punti fisici ed almeno 1008 punti virtuali
           'caso npt=8 ninf=5 corrisponde a 256 punti fisici ed almeno 1984 punti virtuali
           'caso npt=16 ninf=4 corrisponde a 256 punti fisici ed almeno 3840 punti virtuali
           'caso npt=32 ninf=3 corrisponde a 256 punti fisici ed almeno 7168 punti virtuali
           'caso npt=64 ninf=2 corrisponde a 256 punti fisici ed almeno 12288 punti virtuali
           'caso npt=128 ninf=1 corrisponde a 256 punti fisici ed almeno 16384 punti virtuali
           'caso npt=256 ninf=0 corrisponde a 256 punti fisici ed 0 punti virtuali
           
           'caso npt=4 ninf=5 corrisponde a 128 punti fisici ed almeno 496 punti virtuali
           'caso npt=8 ninf=4 corrisponde a 128 punti fisici ed almeno 960 punti virtuali
           'caso npt=16 ninf=3 corrisponde a 128 punti fisici ed almeno 1792 punti virtuali
           'caso npt=32 ninf=2 corrisponde a 128 punti fisici ed almeno 3072 punti virtuali
           'caso npt=64 ninf=1 corrisponde a 128 punti fisici ed almeno 4096 punti virtuali
           'caso npt=128 ninf=0 corrisponde a 128 punti fisici ed 0 punti virtuali
           
           'caso npt=4 ninf=4 corrisponde a 64 punti fisici ed almeno 240 punti virtuali
           'caso npt=8 ninf=3 corrisponde a 64 punti fisici ed almeno 448 punti virtuali
           'caso npt=16 ninf=2 corrisponde a 64 punti fisici ed almeno 768 punti virtuali
           'caso npt=32 ninf=1 corrisponde a 64 punti fisici ed almeno 1024 punti virtuali
           'caso npt=64 ninf=0 corrisponde a 64 punti fisici ed 0 punti virtuali
           
           'caso npt=4 ninf=3 corrisponde a 32 punti fisici ed almeno 112 punti virtuali
           'caso npt=8 ninf=2 corrisponde a 32 punti fisici ed almeno 192 punti virtuali
           'caso npt=16 ninf=1 corrisponde a 32 punti fisici ed almeno 256 punti virtuali
           'caso npt=32 ninf=0 corrisponde a 32 punti fisici ed 0 punti virtuali
           
           'caso npt=4 ninf=2 corrisponde a 16 punti fisici ed almeno 32 punti virtuali
           'caso npt=8 ninf=1 corrisponde a 16 punti fisici ed almeno 64 punti virtuali
           'caso npt=16 ninf=0 corrisponde a 16 punti fisici ed 0 punti virtuali
           
           'caso npt=4 ninf=1 corrisponde a 8 punti fisici ed almeno 16 punti virtuali
           'caso npt=8 ninf=0 corrisponde a 8 punti fisici ed 0 punti virtuali
           
           'caso npt=4 ninf=0 corrisponde a 4 punti fisici ed 0 punti virtuali
           
           If NMaxDom < pfis Then '32
               If flag_circa Then
                   Call Infittimento_Dominio_locale(dominio_slu, NMaxDom, index)
                   GoTo Ricalcola
               Else
                   'fallimento totale niente soluzione infittimento locale impossibile
                   'tentiamo con infittimento globale
                   Call Infittimento_Dominio_globale(dominio_slu, NMaxDom)
                   GoTo Ricalcola
               End If
           Else
               If Not flag_circa Then
                   'fallimento totale niente soluzione
                   Sheets(3).Range("Mrxd") = 0#
                   Sheets(3).Range("Mryd") = 0#
               End If
           End If
       End If

    '-----------------------------------------------------------------
    '               Infittimento_Dominio_locale
    '
    ' Infittimento punti del dominio solo dove serve
    ' accorgimento che consente a partà di precisione di velocizzare
    ' il calcolo consumando meno memoria
    '-----------------------------------------------------------------
    Private Sub Infittimento_Dominio_locale(ByRef dominio_slu As Dominio_Rottura, NMaxDom As Integer, index As Integer)
       
       Dim i As Integer
       Dim k As Integer
           
       ' infittiamo i punti del dominio localmente
       NMaxDom = NMaxDom + NMaxDom
           
       ' ingrandisco campo dati mantenendo i vecchi valori calcolati
       ReDim Preserve dominio_slu.mrx(1 To NMaxDom)
       ReDim Preserve dominio_slu.mry(1 To NMaxDom)
       ReDim Preserve dominio_slu.ang(1 To NMaxDom)
       ReDim Preserve dominio_slu.nrc(1 To NMaxDom)
       ReDim Preserve dominio_slu.nrt(1 To NMaxDom)
       ReDim Preserve dominio_slu.xrc(1 To NMaxDom)
       ReDim Preserve dominio_slu.yrc(1 To NMaxDom)
       ReDim Preserve dominio_slu.xrt(1 To NMaxDom)
       ReDim Preserve dominio_slu.yrt(1 To NMaxDom)
       ReDim Preserve dominio_slu.epsc(1 To NMaxDom)
       ReDim Preserve dominio_slu.epss(1 To NMaxDom)
       ReDim Preserve dominio_slu.yn(1 To NMaxDom)
       ReDim Preserve dominio_slu.curv(1 To NMaxDom)
       
       ' sposto i valori da index+1 in avanti in modo da lasciare lo spazio per
       ' l'inserimento dei nuovi valori di infittimento
       k = NMaxDom \ 2
       For i = index + 1 To k
           dominio_slu.mrx(i + k) = dominio_slu.mrx(i)
           dominio_slu.mry(i + k) = dominio_slu.mry(i)
           dominio_slu.ang(i + k) = dominio_slu.ang(i)
           dominio_slu.nrc(i + k) = dominio_slu.nrc(i)
           dominio_slu.nrt(i + k) = dominio_slu.nrt(i)
           dominio_slu.xrc(i + k) = dominio_slu.xrc(i)
           dominio_slu.yrc(i + k) = dominio_slu.yrc(i)
           dominio_slu.xrt(i + k) = dominio_slu.xrt(i)
           dominio_slu.yrt(i + k) = dominio_slu.yrt(i)
           dominio_slu.epsc(i + k) = dominio_slu.epsc(i)
           dominio_slu.epss(i + k) = dominio_slu.epss(i)
           dominio_slu.yn(i + k) = dominio_slu.yn(i)
           dominio_slu.curv(i + k) = dominio_slu.curv(i)
       Next i

       'PiGreco
       PiGreco = 4# * Atn(1#)

       'prelevo gli angoli dei due punti estremi del segmento di dominio da considerare
       Dim ang1 As Double, ang2 As Double
       ang1 = dominio_slu.ang(index)
       If index = NMaxDom Then
           ang2 = dominio_slu.ang(1)
       Else
           ang2 = dominio_slu.ang(index + 1)
       End If

       'arco individuato dai due angoli di cui sopra
       Dim arco As Double
       arco = ang2 - ang1
       If arco < 0# Then arco = arco + 2# * PiGreco
       Delta_alfa = arco / (k + 1) ' divido per k+1 per tener conto che i punti estremi sono già calcolati
       
       Dim alfa As Double
       alfa = ang1 + Delta_alfa
       'calcolo i valori di infittimento
       For i = index + 1 To index + k
           If alfa >= 2# * PiGreco Then alfa = alfa - 2# * PiGreco
           Call calcola_dominio_alfa(dominio_slu, alfa, i)
           alfa = alfa + Delta_alfa
       Next i
       
    End Sub


    '-----------------------------------------------------------------
    '                  Infittimento_Dominio_globale
    '
    ' Infittimento punti del dominio con calcolo solo punti mancanti
    '-----------------------------------------------------------------
    Private Sub Infittimento_Dominio_globale(ByRef dominio_slu As Dominio_Rottura, ByRef NMaxDom As Integer)
       
       Dim i As Integer
       Dim k As Integer
       
       ' infittiamo i punti del dominio
       NMaxDom = NMaxDom + NMaxDom
       
       ' ingrandisco campo dati mantenendo i vecchi valori calcolati
       ReDim Preserve dominio_slu.mrx(1 To NMaxDom)
       ReDim Preserve dominio_slu.mry(1 To NMaxDom)
       ReDim Preserve dominio_slu.ang(1 To NMaxDom)
       ReDim Preserve dominio_slu.nrc(1 To NMaxDom)
       ReDim Preserve dominio_slu.nrt(1 To NMaxDom)
       ReDim Preserve dominio_slu.xrc(1 To NMaxDom)
       ReDim Preserve dominio_slu.yrc(1 To NMaxDom)
       ReDim Preserve dominio_slu.xrt(1 To NMaxDom)
       ReDim Preserve dominio_slu.yrt(1 To NMaxDom)
       ReDim Preserve dominio_slu.epsc(1 To NMaxDom)
       ReDim Preserve dominio_slu.epss(1 To NMaxDom)
       ReDim Preserve dominio_slu.yn(1 To NMaxDom)
       ReDim Preserve dominio_slu.curv(1 To NMaxDom)
       
       ' sposto i valori opportunamente in modo da lasciare lo spazio per
       ' l'inserimento dei nuovi valori di infittimento
       ' il primo valore rimane sul posto poi spazio poi secondo valore
       ' poi spazio poi terzo valore poi spazio poi quarto valore ecc...
       k = NMaxDom \ 2 - 1
       For i = NMaxDom - 1 To 3 Step -2
           dominio_slu.mrx(i) = dominio_slu.mrx(i - k)
           dominio_slu.mry(i) = dominio_slu.mry(i - k)
           dominio_slu.ang(i) = dominio_slu.ang(i - k)
           dominio_slu.nrc(i) = dominio_slu.nrc(i - k)
           dominio_slu.nrt(i) = dominio_slu.nrt(i - k)
           dominio_slu.xrc(i) = dominio_slu.xrc(i - k)
           dominio_slu.yrc(i) = dominio_slu.yrc(i - k)
           dominio_slu.xrt(i) = dominio_slu.xrt(i - k)
           dominio_slu.yrt(i) = dominio_slu.yrt(i - k)
           dominio_slu.epsc(i) = dominio_slu.epsc(i - k)
           dominio_slu.epss(i) = dominio_slu.epss(i - k)
           dominio_slu.yn(i) = dominio_slu.yn(i - k)
           dominio_slu.curv(i) = dominio_slu.curv(i - k)
           k = k - 1
       Next i
       
       PiGreco = 4# * Atn(1#)
       Delta_alfa = 2# * PiGreco / NMaxDom
       
       Dim alfa As Double
       alfa = Delta_alfa
       'calcolo solo i valori di infittimento
       For i = 2 To NMaxDom Step 2
           Call calcola_dominio_alfa(dominio_slu, alfa, i)
           alfa = alfa + Delta_alfa + Delta_alfa
       Next i
       
    End Sub

    ' --------------------------------------------------------------------------
    ' Nome sub           calcola_dominio_alfa(
    ' Scopo funzione   : Facendo ruotare di alfa la sezione determina le
    '                    coppie di punti mrx,mry di rottura per dato valore
    '                    di sforzo normale.
    ' Parametri formali: Nd=sforzo normale di sollecitazione.
    ' Valore restituito: Struttura dati con varie informazioni: risultanti di
    '                    compressione e trazione, posizioni risultanti, posizio-
    '                    ne asse neutro, deformazioni limite a rottura sezione
    ' Implementazione  : Luglio 2011
    ' Autore           : Zax2010
    ' --------------------------------------------------------------------------
    Public Sub calcola_dominio_alfa(ByRef dom As Dominio_Rottura, alfa As Double, index As Integer)
    Dim k As Integer
    Dim Np As Integer
    Dim polic() As poligono_sezione
    ReDim polic(N_POLI)
    Dim armco As armo_sezione
    Dim armcp As armp_sezione
    Dim Nfin As risultante_n_finale
    Dim Xc As Double
    Dim Yc As Double
    Dim xt As Double
    Dim yt As Double

    Dim c As Double
    Dim s As Double

    '---------------------------------------------------------------------------------
    PiGreco = 4# * Atn(1#)
    'hack per risolvere problema di stallo a 90° con poligoni rettangolari sovrapposti
    If alfa = PiGreco / 2# Then alfa = alfa + 0.000001
    '---------------------------------------------------------------------------------

    ' Calcola una sola volta cos(alfa) e sin(alfa) per evitare elaborazione ogni volta
    c = Cos(alfa)
    s = Sin(alfa)
    ' Prima copia la sezione in altra struttura dati e poi la ruota di alfa
    For Np = 1 To N_POLI
       polic(Np) = poli(Np)
       For k = 1 To polic(Np).numv
           polic(Np).X(k) = poli(Np).X(k) * c + poli(Np).Y(k) * s
           polic(Np).Y(k) = -poli(Np).X(k) * s + poli(Np).Y(k) * c
       Next
    Next
    ' Copia le armature in altra struttura dati e poi le ruota di alfa
    armco = arm
    For k = 1 To arm.numarm
       armco.X(k) = arm.X(k) * c + arm.Y(k) * s
       armco.Y(k) = -arm.X(k) * s + arm.Y(k) * c
    Next
    armcp = armp
    For k = 1 To armp.numarm
       armcp.X(k) = armp.X(k) * c + armp.Y(k) * s
       armcp.Y(k) = -armp.X(k) * s + armp.Y(k) * c
    Next
       ' Chiama la funzione per definire l'asse neutro della sezione (ruotata di alfa)
       Nfin = asse_neutro_SLU(polic, armco, armcp, dom.nd)
       ' Ripristina il sistema di riferimento delle risultanti
       Xc = Nfin.ncf.X * c - Nfin.ncf.Y * s
       Yc = Nfin.ncf.X * s + Nfin.ncf.Y * c
       xt = Nfin.ntf.X * c - Nfin.ntf.Y * s
       yt = Nfin.ntf.X * s + Nfin.ntf.Y * c
       ' Calcola i momenti resistenti per ciascuna configurazione ruotata
       dom.mrx(index) = Nfin.ncf.n * (Yc - ygO) + Nfin.ntf.n * (yt - ygO)
       dom.mry(index) = Nfin.ncf.n * (Xc - xgO) + Nfin.ntf.n * (xt - xgO)
       dom.ang(index) = alfa
       dom.nrc(index) = Nfin.ncf.n
       dom.nrt(index) = Nfin.ntf.n
       dom.xrc(index) = Xc
       dom.yrc(index) = Yc
       dom.xrt(index) = xt
       dom.yrt(index) = yt
       dom.epsc(index) = Nfin.epsc
       dom.epss(index) = Nfin.epss
       dom.yn(index) = Nfin.yn
       dom.curv(index) = Nfin.curv
    End Sub
     
    Top
    .
283 replies since 18/1/2014, 10:24   14202 views
  Share  
.