-
.
ma non è che per particolari condizioni si cade nel paradosso di achille e la tartaruga?
e che, per quanti sforzi faccia, achille non raggiungerà mai la tartaruga?
riflettevo su questa riga di codice:CODICEIf Abs(diff) > precisione And delta * diff > 0# Then delta = -delta / 5
basta che essa sia eseguita una sola volta perché delta cambi di segno e l'asse neutro cominci a salire e scendere fino a convergere.
ma se essa non è mai eseguita, delta continua a mantenere lo stesso segno.
immagino quindi un caso in cui diff sia inizialmente negativo, da cui un prodotto delta*diff < 0#. si continua ad aggiungere delta all'asse neutro, ma questo ha sempre lo stesso segno e l'asse neutro si continua a spostare sempre dalla stessa parte.
sbaglio qualcosa?. -
.
Potrebbe accadere che quella istruzione non venga mai eseguita. Ma solamente perchè si è incredibilmente fortunati.
Ovvero nelle prime iterazioni diff sia proprio nulla (o inferiore alla tolleranza) e quindi il ciclo si interrompe, ma, con il valore correttissimo della posizione dell'asse neutro.
Analizziamo cosa indica diff.
Dal listato di Tex essa vale: diff=Nd-Ntd
Ovvero la differenza tra lo sforzo normale effettivamente agente nella sezione e lo sforzo normale che per una certa posizione dell'asse neutro la sezione è effettivamente in grado di 'esplicitare'.
Se diff fosse negativo, vuol dire che Ntd è maggiore di Nd, e che quindi esso deve diminuire.
Come far diminuire Ntd? Semplice, bisogna diminuire la parte compressa della sezione. E questo accade facendo 'salire' l'asse neutro (ordunque valore di delta positivo).
Quindi in definitiva il 'percorso' corretto verso la convergenza prevede sempre un segno di diff e di delta discorde (percorso che potrà proseguire a grandi 'falcate' con il valore attuale di delta=.
Se invece diff e delta avessero lo stesso segno, ecco che qualcosa nella 'direzione' intrapresa dall'algoritmo non va, e che bisogna 'tornare indietro' dal percorso già fatto. Da qui l'inversione di segno di delta, ed il suo raffittimento.. -
.CITAZIONEperchè le due costanti Precisione e MinDelta le definisci all'interno del ciclo Do?
Const precisione As Double = 0.01
Const minDelta As Double = 0.000001
Non sarebbe opportuno spostarle in testa insieme alle altre definizioni di variabili? In questo modo vengono ridefintie ad ogni passo del ciclo Do ... While
In realtà non vengono ridefinite le costanti all'interno dei cicli, per il fatto che le costanti in vba sono gestite come i #define del linguaggio c, ma per la leggibilità del codice adesso le ho spostate fuori.
Ho intrapreso la strada di calcolare il delta iniziale con una funzione apposita "TrovaDelta".
ecco il codice modificato:CODICE'***************************************************************************
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'***************************************************************************
' ASSE NEUTRO
'***************************************************************************
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'***************************************************************************
' --------------------------------------------------------------------------
' Nome Sub :determina_asse_neutro(
' Scopo funzione : Calcola la posizione effettiva dell'asse neutro in modo
' che la somma algebrica delle risultanti di compressio-
' ne e trazione sia proprio Nd (sforzo normale di solle-
' citazione)
' Parametri formali: Struttura dati con tutti i poligoni che costituiscono la
' sezione, struttura dati con tutte le armature della se-
' zione. Nd=sforzo normale di sollecitazione.
' ult_snerv flag per determinare cosa si cerca, se Mr, Ms
' oppure momenti a data curvatura, curv=curvatura
' 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
' traduzione in VBA : Afazio Settembre 2012
' modifica : Tex Dicembre 2012
' --------------------------------------------------------------------------
Private Function asse_neutro_SLU(ByRef polic() As poligono_sezione, armco As armo_sezione, armcp As armp_sezione, nd As Double) As risultante_n_finale
Dim k As Integer
Dim Np As Integer
Dim npm As Integer 'numero del poligono con il vertice di ordinata massima
Dim ymax As Double: ymax = -1000000# 'ordinata massima dei vertici della sezione
Dim yamin As Double: yamin = 1000000# 'ordinata minima delle armature
Dim Ntot As Double 'sforzo normale risultante
Dim cont As Integer 'contatore massimo numero di tentativi
Dim diff As Double 'variabile ausiliaria
Dim yn As Double 'posizione asse neutro
Dim delta As Double 'variazione della posizione dell'asse neutro
Dim deform As deform_sezione 'configurazione deformata della sezione
Dim nc As risultante_n, nt As risultante_n
' Per prima cosa determina ymax della sezione di cls ed yamin della sezione di ferro
For Np = 1 To N_POLI
If polic(Np).traz = 0 Then
For k = 1 To polic(Np).numv
If (polic(Np).Y(k) > ymax) Then
'cls trave
ymax = polic(Np).Y(k)
npm = Np
End If
Next
Else
For k = 1 To polic(Np).numv
If (polic(Np).Y(k) < yamin) Then
'cls resistente a trazione
yamin = polic(Np).Y(k)
End If
Next
End If
Next
' Poi determina yamin tra tutte le armature
For k = 1 To armco.numarm
If armco.Y(k) < yamin Then yamin = armco.Y(k)
Next
For k = 1 To armcp.numarm
If armcp.Y(k) < yamin Then yamin = armcp.Y(k)
Next
' Quindi definisce un primo posizionamento dell'asse neutro
yn = yamin + 0.8 * (ymax - yamin)
'inizializzo contatore massimo numero di tentativi
cont = 0
'inizializzo variazione della posizione dell'asse neutro
'delta = 1250#
delta = TrovaDelta
' Inizia il ciclo iterativo alla ricerca della effettiva posizione dell'asse neutro
' procede con un ciclo a passo variabile, diminuendo il passo di scansione di ricerca
' della posizione dell'asse neutro ogni volta che la differenza tra ncompr ed ntraz cambia di segno
Const precisione As Double = 0.01
Const minDelta As Double = 0.000001
Do
cont = cont + 1
' Calcola le deformazioni ultime della sezione
deform = deform_ultime(polic, ymax, npm, yamin, yn)
' Calcola lo sforzo normale nella parte compressa della sezione
nc = risult_compr(polic, armco, armcp, deform, ymax, yamin, yn)
' Calcola lo sforzo normale della parte tesa della sezione
nt = risult_traz(polic, armco, armcp, deform, ymax, yamin, yn)
' Totale sforzo normale sulla sezione da confrontare con Nd
Ntot = nc.n + nt.n
diff = nd - Ntot
If Abs(diff) > precisione And delta * diff > 0# Then delta = -delta / 5
yn = yn + delta
If cont = 250 Then Exit Do 'max 250 tentativi
Loop While Abs(diff) > precisione And Abs(delta) > minDelta
' Copia nella struttura dati i risultati definitivi con il posizionamento ultimo dell'asse neutro
asse_neutro_SLU.ncf.n = nc.n
asse_neutro_SLU.ncf.X = nc.X
asse_neutro_SLU.ncf.Y = nc.Y
asse_neutro_SLU.ntf.n = nt.n
asse_neutro_SLU.ntf.X = nt.X
asse_neutro_SLU.ntf.Y = nt.Y
asse_neutro_SLU.yn = yn
asse_neutro_SLU.epsc = deform.epsa
asse_neutro_SLU.epss = deform.epsb
asse_neutro_SLU.curv = deform.epsa / (ymax - yn)
End Function
ed ecco lanuova funzione TrovaDeltaCODICE'Calcoliamo delta
Private Function TrovaDelta() As Double
Dim n As Integer
Dim k As Integer
Dim xmin As Double, xmax As Double
Dim ymin As Double, ymax As Double
xmax = -1000000#
xmin = 1000000#
ymax = -1000000#
ymin = 1000000#
For n = 1 To N_POLI
For k = 1 To poli(n).numv
If poli(n).X(k) < xmin Then xmin = poli(n).X(k)
If poli(n).X(k) > xmax Then xmax = poli(n).X(k)
If poli(n).Y(k) < ymin Then ymin = poli(n).Y(k)
If poli(n).Y(k) > xmax Then xmax = poli(n).Y(k)
Next k
Next n
Dim base As Double
Dim altezza As Double
base = xmax - xmin
altezza = ymax - ymin
If base > altezza Then
TrovaDelta = 1.5 * base
Else
TrovaDelta = 1.5 * altezza
End If
End Function. -
.
Tex io trovo un potenziale pericolo nella routine asse_neutro_SLU() che hai appena pubblicato.
Vedo che se il poligono non reagisce a trazione allora determini correttamente ymax (e basta). Viceversa se il poligono reagisce anche a trazione ecco che da quest'ultimo ricavi solamente yamin.
Quest'ultima cosa è corretta. Ho controllato nel mio codice 'primigenio' ed in effetti non avevo previsto questo caso, ovvero l'ascissa più bassa della 'cosa' che all'interno della sezione possa reagire a trazione per me è sempre e soltanto una barra d'armatura.
Però ti chiedo: e se tutti i poligoni reagissero a trazione (come potrebbe essere una trave in c.a.p. isolata)?
Che fine fa la variabile ymax? Chi o cosa la determinerebbe?. -
.
In effetti è giusto quello che dici.
Il fatto è che io nella implementazione più completa in VB6 avevo previsto la definizione anche di poligoni di ferro, sia precompressi che normali oltre a profili di ferro di carpenteria.
In questo foglio ho tolto questa complicazione, perchè superflua e non avendo trovato documentazione in merito a profili di ferro annegati al cls, sul come debbano essere considerati ho optato di lasciare solo l'essenziale.
Sebbene sia importante verificare anche i casi limite, bisogna anche considerare il campo di utilizzo reale del foglio, andare oltre non penso sia utile.. -
.
Per quanto chiedi: §4.3 del DM2008, oltre alla 'classica' casistica della trave in acciaio completata con getto in calcestruzzo, vengono trattati anche i casi di profilo annegato dentro il getto, o al contrario, il caso dello scatolare cavo riempito in calcestruzzo.
D'accordo con te per quanto dici. Ma l'importante è che nel foglio non ci sia la possibilità di dichiarare 'a trazione' alcun poligono (o evitare in qualche modo che tutti i poligoni possano essere 'a trazione'). -
.
OK §4.3 del DM2008.
Far calcolare al programma le travi composte non credo darebbe risultati totalmente affidabili.
Ad esempio una IPE annegata parzialmente in una trave rettangolare di cls, come dovrebbe essere considerata?
Probabilmente per garantire l'aderenza calcestruzzo-ferro toccherà saldare delle staffe all'anima della IPE e forse così funzionerebbe.
Il legame costitutivo dei profili di carpenteria quale dovrebbe essere?
Il limite deformativo dei profili di carpenteria potrei considerarlo pari a quello dell'armatura ordinaria?
Sono tutte questioni che andrebbero approfondite prima di procedere.
Tornando alla realtà travi precompresse con profili di carpenteria annegati non mi risulta che si facciano.. -
.
e questo risolve i problemi?
. -
.Qualcuno può risolvere l'enigma excel, nella ultima versione sperimentale scaricabile la verifica SLU si pianta con questo messaggio di errore di excel:
VerSectZaxCAP_rev9.xls
https://app.box.com/s/u4vpddyq0lmcjyqwipn8
Riscontro anche io il medesimo errore e lo avevo riscontrato anche in altre occasioni (diverse da VerSectZaxCap)
Sono pervenuto a quanto segue:
- la sintassi è corretta
- il metodo è anche presente nell'help on line del VBA
- si trova identica illustrazione nel sito http://msdn.microsoft.com/en-us/library/of...office.15).aspx
- il web è invaso da segnalazioni di errore del metodo
- penso sia un bug della nuova versione di excel.
Riferimenti per sviluppatori Excel
Chart.SeriesCollection, metodo
Restituisce un oggetto che rappresenta una singola serie (un oggetto Series) o un insieme di tutte le serie (un insieme SeriesCollection) nel grafico o nel gruppo grafico.
Sintassi
espressione.SeriesCollection(Indice)
espressione Variabile che rappresenta un oggetto Chart.
Parametri
Nome Obbligatorio/Facoltativo Tipo di dati Descrizione
Indice Facoltativo Variant Specifica il nome o il numero della serie.
Valore restituito
Oggetto. -
.
OK grazie a tutti, con queste informazioni vedrò di risolvere, alla peggio riscrivo in maniera alternativa la procedura. . -
Livio12.
User deleted
nella rev8 l'istruzione "ActiveSheet.ChartObjects(1)" restituisce il "Grafico 1" (che ha 19 serie). nella rev 9 restituisce il "Grafico 9" (che ne ha 3). l'istruzione ActiveChart.SeriesCollection(13 + Np) non è compatibile con la rev9.
usare direttamente il nome: "ActiveSheet.ChartObjects("Grafico 1").activate". -
.nella rev8 l'istruzione "ActiveSheet.ChartObjects(1)" restituisce il "Grafico 1" (che ha 19 serie). nella rev 9 restituisce il "Grafico 9" (che ne ha 3). l'istruzione ActiveChart.SeriesCollection(13 + Np) non è compatibile con la rev9.
usare direttamente il nome: "ActiveSheet.ChartObjects("Grafico 1").activate"
Quindi l'errore consiste nel fatto che l'istruzione si riferisce ad una serie il cui indice è oltre il numero massimo di serie presenti?. -
Livio12.
User deleted
quello è l'errore lato VBA-Excel.
ma il vero errore è il riferimento al grafico sbagliato. -
.quello è l'errore lato VBA-Excel.
ma il vero errore è il riferimento al grafico sbagliato
ok adesso ho capito.
il grafico restituito dalla chiamata non è piu' il "Grafico 1" come era nella versione precedente, bensi il "grafico 9"..