Salut à tout ! j'aimerais résoudre en 1D & 2D l'équation :
dC/dt+VdC/dx=0 C :inconnu & V :vitesse de transport
en servant le shéma centré ,shéma amont,shéma LAX-Wendroff,shéma LAX-Wendroff avec limiteur.
Merci !
Salut à tout ! j'aimerais résoudre en 1D & 2D l'équation :
dC/dt+VdC/dx=0 C :inconnu & V :vitesse de transport
en servant le shéma centré ,shéma amont,shéma LAX-Wendroff,shéma LAX-Wendroff avec limiteur.
Merci !
heu.... sans vouloir te vexé, ta question ne relève pas de fortran....
commence par discrétiser ton équation via les schémas que tu as cité sur papier (c'est des maths pas de la programmation) ensuite tu passe au codage et franchement, l'avantage du fortran c'est que t'as (persque) qu'à recopié tes equations....
Justement ça c'est mon projet en simulation par F77 et que j'ai eu beaucoup de problèmes car le sujet ne te permet pas de comprendre avec exactitude de ton problème !
Par exemple pour le shéma centré on a
C(i,n+1)=C(i,n)-Sigma*V*[C(i+1,n)-C(i-1,n)]
avec Sigma=Deltat/2Deltax
Deltax=XL/(Nx-1)
les données sont : XL :taille du domaine
Nt :nb de pts dépent du temps t
Nx :nb de pts dépent du position x
Deltat=0.01
V(i)=V0 :vitesse de trasport est constant
Condition initiale : f(x)=0.5+0.5*tanh(80*(x-0.1)) <=> C(i,0)=f(x(i))
Pour la CI j'ai fais :
-- cette CI ne dépent pas de temps pour tant C dépent de x et de t
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 do i=1,Nx V(i)=V0 x(i)=[(2*i-1)*Deltax]/2 C(i)=0.5+0.5*tanh(80*(x(i)-00.1)) end do
-- par la suite j'aimerais bien compresser en une seul dimension en faisant
--là j'ai un problème de borne , donc il faut que je fasse
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 do p=1,Nt do q=1,Nx C(q)=C(q)-Sigma*V0*[C(q+1)-C(q-1)] end do end do
--donc ma question est : quelle technique permet-on compresser en 1D ? et comment résoudre le problème de borne ? rapellons que on veut avoir :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 do p=1,Nt C(1)=C(0)-Sigma*V0*[C(2)-C(0)] -> ??? C(Nx)=C(q)-Sigma*V0*[C(q+1)-C(q-1)] ->??? do q=2,Nx-1 C(q)-Sigma*V0*[C(q+1)-C(q-1)] end do end do
Nt
1 C1
.
.
i Ci
.
.
Nx C(Nx)
bon pour commencer, arrete le fortran 77 c'est un peu dinosaure!!! (tu veras le format libre de fortran ça change la vie!!!!) cela dit:
pour résoudre ton truc il te faut des condition des bords, on ne résout pas un problème aux limites sans connaitre les limites....
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 program convection implicit none integer,parameter :: ki=kind(1.d0) !dimension des real comme des double precision integer,parameter :: NT=10000 !dimension des tableaux en temp integer,parameter :: NX=250 !dimension en x real(ki),parameter :: XL=10.d0 !longueur de l'échantillon real(ki),parameter :: DeltaT=1.d-2 !pas de temps real(ki),parameter :: DeltaX=XL/(Nx+1) !pas d'espace real(ki),paramater :: sigma=Deltat/(2.d0*Deltax) real(ki),paramater :: V0=10.d0 !vitesse initiale (que tu peux rentrer après mais pour simplifié je la pose au départ.... real(ki),dimension(0:NX,0:NT) :: C !notre inconnu fonction de l'espace et du temps integer i,nn ! compteurs en espace et en temps !===================================================== ! début du code !===================================================== !initialisation init:do i=0,NX C(i,0)=5.d-1*(1.d0+dtanh(8.d1*(i*DeltaX-1.d-1))) end do init !condition de bords: (ici je prend une condition de diriclet homogène car tu n'a pas renseigné ce que sont les bords....) bord:do nn=0,NT C(0,nn)=0.d0 C(Nx,nn)=0.d0 end do bord ! boucle temporelle (je te fait un schémas d'euler explicit mais tu peut !l'améliauré rapidement en runge-kutta classique d'ordre 4 avec pas de temps !adaptatif si tu veux) Boucletemp:do nn=0,NT-1 bclSpace:do i=1,Nx-1 C(i,nn+1)=C(i,nn)+sigma*V0*(C(i+1,nn)-C(i-1,nn)) end do bclSpace end do Boucletemp !==================================================== ! stockage ! là je te fait un stockage en version matricielle avec les x en horizontal et le t en vertical: open(unit=20,file='C.dat',status='unknown') write(20,*)'C ' !on dit ce qi'il y a dans le fichier write(20,1000)' x=',(i*dx,i=0,Nx) !on écrit l'échelle en x write(20,*)'t=' !décorations bcltempo:do nn=0,NT !ligne par lignes write(20,1001)(nn*DeltaT),(C(i,nn),i=0,Nx) ! les valeur de C end do bcltempo close(20) !jamais oublier de fermé le fichier 1000 format(a3,256d25.16) !les format utilisés.... 1001 format(2500e25.16) END program convection
Merci Genteur Slayer de m'avoir donné des indications pourtant ce n'est pas vraiment ce que tu as compris !
--Pour le constant C,il est plutot conseille de faire un vecteur 1D C(0:Nx) et d'ecraser à chaque pas de temps les valeurs de C(i) ! on sauvegarde les valeurs de C a quelques instants, par exemple toutes les 100 iterations temporelles
--Pour le condition de bords on utilise un schema decentre (on utilise que les points à l'interieur du domaine) et on l'integre a la boucle de temps, ecrive le developpement limite de C(x+dx) et C(x-dx) et tu vas voir.Et
-- Boucle temporelle
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 do nn=0,Nt C(0,nn)=0 ! aucune raison que ce soit 0 C(Nx,nn)=0 ! aucune raison que ce soit 0 end do
--Stockage :Je dois représenter graphiquement les données dans un ficher par itération avec en colonne x, (y en 2D), C(x,y)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 do nn=0,Nt-1 ! ici on fait en i=0, en utilisant les valeurs en i=0 et i=1 ! C(0)= C(0) + 2*sigma*V*(C(1)-C(0)) ! on multiplie sigma par 2 car on est entre i=0 et i+1=1, donc on a Deltax et non pas 2*Deltax au denominateur do i=1,Nx-1 C(i,nn+1)=C(i,nn)+sigma*V*(C(i+1,nn)-C(i-1,nn)) end do ! ici on fait en i=Nx, en utilisant les valeurs en i=Nx-1 et i=Nx ! C(Nx)= C(Nx) + 2*sigma*V*(C(Nx)-C(Nx-1)) ! stockage des valeurs, si nn multiplie de 100 end do
![]()
faire comme tu dis pour C peut parfois être dangereux (dans ce cas précis non) car tu a parfois plusieurs variables interdépendantes et donc tu as besoin à tout moment des prédécésseurs temporels (exemple, méca flotte) cependant dans ton cas c'est pareil, juste tu économise de la mémoire (environ nx*(nt-1)*4 o soit 9.536Mo dans le cas que je t'es donné (à condition que tu compile sur un pc standard)
de plus pour utiliser le shéma avant en début de x et le shémas arrirère en fin de x, tu n'a qu'as le faire en dehors de la boucle central
en virrant la partie juste avant cette boucle dans ce que je t'es donné pour gagner quelques milisecondes de calcul.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 ! boucle temporelle (je te fait un schémas d'euler explicit mais tu peut !l'améliauré rapidement en runge-kutta classique d'ordre 4 avec pas de temps !adaptatif si tu veux) Boucletemp:do nn=0,NT-1 C(0,nn+1)=C(0,nn)+2.d0*sigma*V0*(C(1,nn)-C(0,nn)) !<<< schem av en debut x C(Nx,nn+1)=C(Nx,nn)+2.d0*sigma*V0*(C(Nx,nn)-C(Nx-1,nn)) !<<< schem arr en fin de x bclSpace:do i=1,Nx-1 C(i,nn+1)=C(i,nn)+sigma*V0*(C(i+1,nn)-C(i-1,nn)) end do bclSpace end do Boucletemp
je vois pas où est le soucis
à moins que tu ne cherche pas un schémas explicit en temps
Partager