/* @pjs pauseOnBlur=true; */ //============================================================================= // simulation montrant des particules de fluides en mouvement dans un écoulement stationnaire. Plusieurs champs de vitesse sont proposés. // Les vitesses sont exprimés en pixel par frame. // ATTENTION : les vitesses sont exprimées en cartésiens : x=xx-OX et y=yy-OY // ©J.Roussel -- // 20 Janv. 2013 : création // 21 Janv. 2013 : ajout de couette cylindrique. Modification de paquets de traceurs produit après un clic // MAJ : Avril 2016 (fonction changeVitesse et setG) //========== IDEES ================== // la méthode d'Euler n'est pas très précise. Pour remédier au pb il faudrait calculer la position des particules avec une méthode plus précise (Runge Kutta, Verlet...) int OX, OY;//Origine du repère int R=50;//rayon du cylindre en pixels int R2=150;//rayon du cylindre extérieur pour l'écoulement de Couette-cylindrique int V0=4;// vitesse du fluide loin ArrayList particules; int label=6; void setup() { size(600, 300); frameRate(20); smooth(); particules = new ArrayList(); } void draw() { background(255); //*** ecoulement uniforme *** if(label==1){ OX=0; OY=0; drawVitesse1(); for (int i = particules.size()-1; i >= 0; i--) { ParticuleFluide PF = (ParticuleFluide) particules.get(i); PF.velocity=vitesse1(PF.location.x, PF.location.y); PF.update(); PF.display(); if (PF.finished()) {particules.remove(i);} }} //*** ecoulement de Couette-Plan if(label==2){ OX=width/2; OY=0; drawVitesse2(); for (int i = particules.size()-1; i >= 0; i--) { ParticuleFluide PF = (ParticuleFluide) particules.get(i); PF.velocity=vitesse2(PF.location.x, PF.location.y); PF.update(); PF.display(); if (PF.finished()) {particules.remove(i);} }} // ecoulement Couette-Cylindrique if(label==3){ OX=width/2; OY=height/2; drawVitesse3(); for (int i = particules.size()-1; i >= 0; i--) { ParticuleFluide PF = (ParticuleFluide) particules.get(i); PF.velocity=vitesse3(PF.location.x, PF.location.y); if(PF.velocity.mag()==0){particules.remove(i);} PF.update(); PF.display(); if (PF.finished()) {particules.remove(i);} }} // ecoulement maelstrom if(label==4){OX=width/2; OY=height/2; drawVitesse4(); for (int i = particules.size()-1; i >= 0; i--) { ParticuleFluide PF = (ParticuleFluide) particules.get(i); PF.velocity=vitesse4(PF.location.x, PF.location.y); PF.update(); PF.display(); if (PF.finished()) {particules.remove(i);} }} // ecoulement maelstrom if(label==5){OX=width/2; OY=height/2; drawVitesse5(); for (int i = particules.size()-1; i >= 0; i--) { ParticuleFluide PF = (ParticuleFluide) particules.get(i); PF.velocity=vitesse5(PF.location.x, PF.location.y); PF.update(); PF.display(); if (PF.finished()) {particules.remove(i);} }} if(label==6){ OX=width/2; OY=height/2;//Repère centré au milieu drawVitesse6(); for (int i = particules.size()-1; i >= 0; i--) { ParticuleFluide PF = (ParticuleFluide) particules.get(i); PF.velocity=vitesse6(PF.location.x, PF.location.y); PF.update();PF.display(); if (PF.finished()) {particules.remove(i);} }} } //****** champs de vitesse ******** PVector vitesse1(float xx, float yy) { return new PVector(V0,0); } PVector vitesse2(float xx, float yy) {return new PVector(V0*(yy-OY)/height,0); } PVector vitesse3(float xx, float yy) { if (sq(xx-OX)+sq(yy-OY)>=sq(R) && sq(xx-OX)+sq(yy-OY)<=sq(R2)) return new PVector(0.0075*V0*(sq(R)*(yy-OY) / (sq(xx-OX)+sq(yy-OY))-yy+OY),0.0075*V0*(xx-OX-sq(R)*(xx-OX) / (sq(xx-OX)+sq(yy-OY)))); else {return new PVector(0, 0);} } PVector vitesse4(float xx, float yy) { if (sq(xx-OX)+sq(yy-OY)>=100) return new PVector(V0*50*(-xx-yy+OY+OX) / (sq(xx-OX)+sq(yy-OY)),V0*50*(xx-yy+OY-OX) / (sq(xx-OX)+sq(yy-OY))); else {return new PVector(0, 0);} } PVector vitesse5(float xx, float yy) { if (sq(xx-OX)+sq(yy-OY)>=100) return new PVector(V0*(-xx-yy+OY+OX) / sqrt(sq(xx-OX)+sq(yy-OY)),V0*(xx-yy+OY-OX) / sqrt(sq(xx-OX)+sq(yy-OY))); else {return new PVector(0, 0);} } PVector vitesse6(float xx, float yy) { if (sq(xx-OX)+sq(yy-OY)>sq(R)) return new PVector(V0+V0*(sq(yy-OY)-sq(xx-OX))*sq(R)/sq(sq(yy-OY)+sq(xx-OX)), -2*V0*(xx-OX)*(yy-OY)*sq(R)/sq(sq(xx-OX)+sq(yy-OY)));// ecoulement en selle de cheval(-x,y) else {return new PVector(0, 0);} } //****** tracé des vecteurs vitesses ************ void drawVitesse1() { float len; strokeWeight(1); stroke(153); float arrowsize = 4; for (int i=0;i