Excel Forum - Porady, Pomoc,  Excel Help, Excel FAQ Strona Główna
 FAQ  RegulaminRegulamin  Szukaj   Użytkownicy   Grupy   Rejestracja   Profil   Twoje wiadomości   Zaloguj 


Poprzedni temat «» Następny temat
ID tematu: 63534 Skopiuj do schowka Zadanie dot. Transportu Ciepła
Autor Wiadomość
Fareyi 
świeżak


Posty: 6
Wysłany: 17-12-2018, 23:13   Zadanie dot. Transportu Ciepła

Hej
Dostaliśmy na zajęciach takie zadanie dla chętnych, coby przy wykorzystaniu VBA wykonać zadanie dotyczące transportu ciepła w ścianie.

Ogólnie mam problem z zadaniem, gdyż w pętli zagnieżdżonej stosując wartość czasu 36000 iteracja z nieznanego mi powodu wykracza poza zakres.

Znaczy. Jeżeli ustawię pętlę czasową na np. 100 kroków, program liczy.
Ale przy większej ilości (tak mniej więcej od 150) następuje Overflow.
Kod:
Const tempL = 263
Const tempR = 298
Const tempS = 273
Const l = 1
Const lambda = 1
Const tend = 3600
Const n = 20
Const m = 36000
Sub program()
Dim dx As Double
Dim dt As Double
Dim i As Integer
Dim j As Integer
Dim nawias(1 To n) As Double
Dim temp(1 To n) As Double
Dim tempnew(1 To n) As Double


dx = l / (n - 1)
dt = 0.1
dtau = dt * lambda / (dx * dx)

For i = 2 To n - 1
temp(i) = tempS
Next i

temp(n) = tempR
temp(1) = tempL

For j = 0 To m
    For i = 2 To n - 1
        nawias(i) = (temp(i - 1) - 2 * temp(i) + temp(i + 1))
    Next i
    For i = 2 To n - 1
        tempnew(i) = temp(i) + dtau * nawias(i)
    Next i
    For i = 2 To n - 1
        temp(i) = tempnew(i)
    Next i
Next j

For i = 1 To n - 1
Cells(i + 1, 1) = i * dx
Next i
For i = 1 To n - 1
Cells(i, 2) = temp(i)
Next i

End Sub


Nie wiem dlaczego tak się dzieje, bo co analizuję kod, nie widzę nigdzie elementu, który mógłby powodować, by i przyjęło wartość 20.
Wartość temp(i+1) [tablica(20+1)] jest poza zakresem, gdyż tablica temp przyjmuje wartości od 1 do 20. Równocześnie, ze względu na to, że w tej pętli zagnieżdżonej wystąpi wartość temp(21) to i pętla wyżej, przypisująca wartości dla temp(i) wychodzi poza zakres

Dzięki za pomoc ;)

[/code]
ID posta: 358624 Skopiuj do schowka
 
 
ąćęłńóś
ExcelSpec


Pomógł: 161 razy
Posty: 727
Wysłany: 17-12-2018, 23:30   

:?:
1. Const m = 36000
2. Dim j As Integer
3. For j = 0 To m
4. "Integer variables are stored as 16-bit (2-byte) numbers ranging in value from -32,768 to 32,767"
:?:
ID posta: 358628 Skopiuj do schowka
 
 
Fareyi 
świeżak


Posty: 6
Wysłany: 17-12-2018, 23:34   

Zapomniałem dodać.
Wcześniej używałem również dim j as Long, ale i tak wyrzuca błąd Overflow.
ID posta: 358629 Skopiuj do schowka
 
 
ąćęłńóś
ExcelSpec


Pomógł: 161 razy
Posty: 727
Wysłany: 18-12-2018, 00:02   

Nie wyrzuca:
Kod:
Const tempL% = 263
Const tempR% = 298
Const tempS% = 273
Const l As Byte = 1
Const lambda As Byte = 1
Const tend% = 3600
Const dt! = 0.1
Const n As Byte = 20
Const m& = 36000

Sub program_1()
    Dim i As Byte, j&
    Dim dx#, dt#
    Dim nawias#(1 To n), temp#(1 To n), tempnew#(1 To n)
   
    dx = l / (n - 1)
    dtau = dt * lambda / (dx * dx)
   
    temp(1) = tempL
    For i = 2 To n - 1
        temp(i) = tempS
    Next i
    temp(n) = tempR
   
    For j = 0 To m
        For i = 2 To n - 1
            nawias(i) = (temp(i - 1) - 2 * temp(i) + temp(i + 1))
        Next i
        For i = 2 To n - 1
            tempnew(i) = temp(i) + dtau * nawias(i)
        Next i
        For i = 2 To n - 1
            temp(i) = tempnew(i)
        Next i
    Next j
   
    For i = 1 To n - 1
        Cells(i + 1, 1).Value = i * dx
    Next i
    For i = 1 To n - 1
        Cells(i, 2).Value = temp(i)
    Next i
End Sub
ID posta: 358630 Skopiuj do schowka
 
 
Fareyi 
świeżak


Posty: 6
Wysłany: 18-12-2018, 00:06   

U mnie jednak wyrzuca.

Faktycznie, u Ciebie nie wyrzuca błędu.
Przyjrzę się bliżej twojemu rozwiązaniu ;)
ID posta: 358631 Skopiuj do schowka
 
 
Artik 



Pomógł: 2575 razy
Posty: 8487
Wysłany: 18-12-2018, 00:15   

Nie mam pojęcia co to makro ma liczyć, ale wygląda na to, że być może chcesz liczyć na baaaardzo dużych liczbach.
Przy 144. obrocie pętli For j = 0 To m (wartość licznika w tym momencie wynosi 143), w drugiej pętli For i = 2 To n - 1, dla i=2 można odczytać takie wyniki:
temp(i) = -2,09140847229146E+306
dtau = 36,1
nawias(i) = 8,32326928937325E+306.
Przy mnożeniu dtau * nawias(i) dochodzi do przepełnienia dla wartości typu Double (max dla Double to 1,79769313486232+E308).

Obawiam się, że chyba nie o takie wielkości (jak się nie mylę, to temperatur) Ci chodziło.

Artik
_________________
Persistence is a virtue in the world of programming.
ID posta: 358632 Skopiuj do schowka
 
 
Tajan


Pomógł: 4243 razy
Posty: 9445
Wysłany: 18-12-2018, 00:19   

Masz jakiś błąd logiczny w pętlach gdyż otrzymywane wartości znacznie przekraczają dopuszczalne zakresy. Przykładowo, nawet użycie typu Decimal skutkuje błędem przepełnienia w linii:
Kod:
tempnew(i) = temp(i) + dtau * nawias(i)
gdyż już dla j= 13 oraz i=2 wartość tempnew(i) jest równa -1187359104550030705532418704,6 a ty chcesz tę wartość jeszcze pomniejszać.
ID posta: 358633 Skopiuj do schowka
 
 
Fareyi 
świeżak


Posty: 6
Wysłany: 18-12-2018, 00:20   

Dokładnie, temperatury powinny być pomiędzy warunkami brzegowymi (263 i 298). Według wzoru, który rozpisałem na kartce powinno to być w ten sposób zapisane.

Ale z tego co widzę, to mimo przypisania wartości np. w pierwszej pętli temp(i) = 273, to do wzoru skądś bierze wartość np. -88. Mimo, że tego nie ma nigdzie zapisane.
+ w ostatniej iteracji ucieka ostatni człon
ID posta: 358634 Skopiuj do schowka
 
 
ąćęłńóś
ExcelSpec


Pomógł: 161 razy
Posty: 727
Wysłany: 18-12-2018, 00:26   

Ujednolicić wszystkie zmienne, to podstawa, a stałe niech będą stałymi, a nie zmiennymi (dt).

Ps.:
Dlaczego właściwie nawias(i) startuje dopiero od indeksu = 2 a kończy się na 19 i pierwszą i ostatnią pozycje ma zawsze wolne ?
ID posta: 358635 Skopiuj do schowka
 
 
Fareyi 
świeżak


Posty: 6
Wysłany: 18-12-2018, 00:40   

Kod:

Const tempL = 263
Const tempR = 298
Const tempS = 273
Const l = 1
Const lambda = 1
Const tend = 3600
Const dt = 0.1
Const n = 20
Const m = 36000

Sub zadanie()
Dim i As Integer
Dim j As Long
Dim dx, dtau As Double
Dim nawias(1 To n), temp(1 To n), tempnew(1 To n) As Double

dx = 1 / (n - 1)
dtau = dt * lambda / (dx * dx)

temp(1) = tempL
For i = 2 To n - 1
temp(i) = tempS
Next i
temp(n) = tempR

For j = 0 To m
    For i = 2 To n - 1
        nawias(i) = (temp(i - 1) - 2 * temp(i) + temp(i + 1))
    Next i
    For i = 2 To n - 1
        tempnew(i) = temp(i) + dtau * nawias(i)
    Next i
    For i = 2 To n - 1
        temp(i) = tempnew(i)
    Next i
    For i = 1 To n
        Cells(i, 1) = temp(i)
    Next i
Next j
For i = 1 To n - 1
    Cells(i, 2) = i * dx
Next i

End Sub


O to chodziło z ujednoliceniem?
Gdyby nawias był od indeksu 1, to wtedy w równaniu byłoby temp(1 - 1), czyli program szukałby wartości od temp(0) - a takiej wartości nie ma.
Kończy się również na pozycji 19, gdyż gdyby przyjął wartość 20, to wtedy w równaniu byłoby temp (21), które też jest poza zakresem.
A takie równanie powstało aproksymując równanie d/dx(Lambda(x)dT/dx)
ID posta: 358636 Skopiuj do schowka
 
 
ąćęłńóś
ExcelSpec


Pomógł: 161 razy
Posty: 727
Wysłany: 18-12-2018, 02:09   

ąćęłńóś napisał/a:
Ujednolicić wszystkie zmienne, to podstawa, a stałe niech będą stałymi, a nie zmiennymi (dt)

Const dt! = 0.1
Dim dx#, dt#

:-) ... no to żem se ujednolicił ... :-) ... niech to pryszczata jadźka ... :->

Ciekawe, że w takiej sytuacji kompilator głupieje i przechodzi swobodnie przez kod, cały czas wyliczając przy tym dla: "nawias(i)/tempnew(i)/temp(i)" te same wartości: "25/273/273".
Jak wywalić to "dt#", to jest, jak Artik i Tajan pisali, przepełnienie - wsadź w poszcególne pętle:
a) Cells(j + 1, 4).Value = nawias(i)
b) Cells(j + 1, 5).Value = tempnew(i)
c) Cells(j + 1, 6).Value = temp(i)
i zobacz jakie masz ciekawe wartości.
ID posta: 358638 Skopiuj do schowka
 
 
Fareyi 
świeżak


Posty: 6
Wysłany: 18-12-2018, 19:29   

Hej.
Postanowiłem poprosić prowadzącego przedmiot, by zajrzał do kodu i sprawdził, dlaczego program wylicza takie liczby.

Okazało się, że wszystkiemu winne są dane w zadaniu :)
Znaczy, krok czasowy był zbyt duży i równania, które zostały przeze mnie wyprowadzone nie odpowiadały tej sytuacji.
Zmniejszenie dt do 0.0001 (i równoczesne wyrzucenie m ze stałych i przypisanie mu wartości
m = tend/dt) sprawiło, że program zaczął poprawnie liczyć.

A co do wartości wychodzących poza zakres (np. pojawiające się temp(20+1))
Prowadzący wytłumaczył, że to nie jest błąd, tylko tak widać w trybie debugowania.


Dzięki za pomoc :)
ID posta: 358691 Skopiuj do schowka
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Theme xandgreen created by spleen& Programosy modified v0.3 by warna
Opieka techniczna www.marketingNET.pl

Archiwum

Strona używa plików cookies.

Kliknij tutaj, żeby dowiedzieć się jaki jest cel używania cookies oraz jak zmienić ustawienia cookie w przeglądarce.
Korzystając ze strony użytkownik wyraża zgodę na używanie plików cookies, zgodnie z bieżącymi ustawieniami przeglądarki.
Sprawdź, w jaki sposób przetwarzamy dane osobowe