Problemas al implementar el método Lattice Boltzmann

Quiero hacer una implementación 2D básica del método Lattice Boltzmann (en javascript) para simular el flujo de gas/fluido, pero me he encontrado con algunos problemas y parece que no puedo encontrar la causa.

El problema es que cuando ejecuto el paso de colisión (todavía no he implementado completamente la transmisión), la simulación explota y se ejecuta hasta el infinito y revisé mi código minuciosamente en busca de errores.

Comienzo con la inicialización de mis variables:

function Grid(width, height){
        this.width = width;
        this.height = height;
        this.f = [];
        this.e = [
            new vec2(0,0),
            new vec2(0,1),
            new vec2(1,0),
            new vec2(0,-1),
            new vec2(-1,0),
            new vec2(1,1),
            new vec2(1,-1),
            new vec2(-1,-1),
            new vec2(-1,1)
        ];
        this.w  = [4/9, 1/9, 1/9, 1/9, 1/9, 1/36, 1/36, 1/36, 1/36];
        for(var x=0; x<width; x++){
            this.f[x] = [];
            for(var y=0; y<height; y++){
                this.f[x][y] = [];
                for(var i=0; i<9; i++){
                    this.f[x][y][i] = 20+Math.random();
                }
            }
        }
    }

Aquí this.f es la función de distribución con 9 direcciones: 0 para ningún movimiento, 1-4 para movimiento recto y 5-9 para velocidades inclinadas. La función de distribución tiene valores que van desde 20-21. This.e contiene todas las direcciones como vectores (he hecho mi propia clase simple vec2) y this.w contiene los pesos para cada dirección. La primera pregunta que quiero hacer es si inicié la distribución con los valores correctos. No pude encontrar mucha información sobre los valores de inicialización.

En segundo lugar, mi (s) error (es) podría (n) estar en el paso de colisión:

    collide: function(){
        for(var x=0; x<width; x++){
                for(var y=0; y<height; y++){
                    var rho = 0;
                    for(var i=0; i<9; i++){
                        rho += this.f[x][y][i];
                    }

                    var u = new vec2(0,0);
                    for(var i=0; i<9; i++){
                        u  = u.add( this.e[i].scale( this.f[x][y][i] ) );
                    }
                    u = u.scale( 1/rho );
                    for(var i=0; i<9; i++){
                        var eu = u.dot(this.e[i]);
                        var uu = u.dot(u);
                        var fiEq = this.w[i]*rho*(1+3*eu+4.5*eu*eu-1.5*uu);
                        this.f[x][y][i] = this.f[x][y][i] - .005*(this.f[x][y][i]-fiEq);
                    }
                }
            }
        }

Primero calculo la densidad macroscópica rho, luego, con la suma de vectores calculo la velocidad macroscópica u. Los uso en la siguiente fórmula para calcular la distribución de equilibrio: ecuación de equilibrioy luego relajo la distribución hacia el equilibrio. como segunda pregunta me gustaría preguntar si implementé correctamente el paso de colisión.

Un ejemplo en vivo se puede ver aquí

Si necesita más información para ayudar, hágamelo saber y si pudiera ayudarme, ¡realmente lo agradecería!

Como regla, no respondemos preguntas de implementación sobre física computacional , por lo que este puede no ser el lugar adecuado para la pregunta tal como está formulada. Es posible que tenga más suerte en scicomp.stackexchange.com, pero es posible que tampoco les gusten los aspectos de revisión de código.
Sin embargo, algunos consejos generales: ¿qué método de integración de tiempo ha elegido usar y está respetando los límites de estabilidad del mismo? ¿Has comprobado que por cada fuerza sobre un nodo, existe una fuerza igual y opuesta sobre el otro nodo?

Respuestas (1)

Un par de comentarios sobre su implementación:

  1. Inicializas tus funciones de distribución de una manera poco convencional; por lo general, queremos convertir cantidades de 'red' macroscópicas conocidas como ρ y tu en F i . Una manera fácil de hacer esto es usando la distribución de equilibrio que define arriba:

    F i , mi q ( ρ , tu ) = w i ρ [ 1 + mi i tu C s 2 + 1 2 ( mi i mi i C s 2 I ) : tu tu C s 4 ]

    Simplifiquemos nuestra vida y elijamos ρ = 1 y tu = 0 luego inicialice simplemente con:

    F i = F i , mi q ( 1 , 0 ) = w i

    Nota:

    • En el sistema 'lattice', el valor de las cantidades macroscópicas se puede elegir (más o menos) arbitrariamente para satisfacer nuestras necesidades siempre que los números adimensionales relevantes (p. ej., el número de Reynolds) sean equivalentes en el sistema 'dimensional'.
    • Asegúrese de que la velocidad se elija lo suficientemente pequeña para garantizar que el número de Mach METRO a = tu / C s 1 ; por lo general esto se limita a tu 0.1 . Esto se debe a la pequeña METRO a forma de expansión de la distribución de equilibrio que es O ( METRO a 2 ) términos. Supongo que su código diverge porque los valores elegidos para F i en la inicialización corresponden a una velocidad que es demasiado alta.
    • Para flujos inicialmente transitorios, este método de inicialización no es la mejor manera, pero para tu ( X , 0 ) = 0 está bien.
  2. Su implementación del paso de colisión parece correcta pero su 'frecuencia' de relajación ω = 0.005 me parece muy pequeño también (es decir τ = 200 ). Probablemente, esto funciona bien, pero comience con ω = 1 primero porque este es el valor más estable (significa que en un paso de tiempo de 'celosía' nos relajamos hacia la distribución de equilibrio). Una pequeña nota: var uu = u.dot(u);se puede tomar fuera del ciclo ya que no depende de i.

  3. Dudo que el código funcione sin una implementación para el paso de transmisión. Si inicializa con la distribución de equilibrio como se indicó anteriormente, luego del primer paso de tiempo, la distribución se convierte en F i ( X , t + 1 ) = F i ( X , t ) y permanece así para todos los pasos de tiempo subsiguientes. En realidad, esta es una buena verificación para ver si el paso de colisión se implementó correctamente.

  4. Siento que recientemente comenzó a trabajar con LBM, así que déjeme darle algo de literatura que trata los aspectos numéricos:

    • Modelado de Lattice Boltzmann: una introducción para geocientíficos e ingenieros, por MC Sukop y DT Thorne
    • Método Lattice Boltzmann: fundamentos y aplicaciones de ingeniería con códigos informáticos, por AA Mohamad
    • La ecuación de Lattice Boltzmann para la dinámica de fluidos y más allá, por S. Succi

Buena suerte