Está en la página 1de 8

638 15 Fluid Flow Cálculo: incompresible de caja

theFluxes.FLUXC1f (iFaces, 1) = local_FLUXCf1; theFluxes.FLUXC2f (iFaces, 1) = local_FLUXCf2; theFluxes.FLUXVf


(iFaces, 1) = local_FLUXVf; % TheFluxes.FLUXTf (iFaces, 1) = theFluxes.FLUXC1f * pressureC (iFaces) +
theFluxes.FLUXC2f * pressureN (iFaces) + theFluxes.FLUXVf (iFaces)..;
% Mdot_f = theFluxes.FLUXTf (iFaces);
Listado 15.1 (continuación)

15.10.2 OpenFOAM®
Las técnicas numéricas introducidas hasta el momento se utilizan en lo que sigue para desarrollar OpenFOAM® [27]
aplicaciones para la solución de las ecuaciones incompresibles de Navier-Stokes.
15.10.2.1 corrección de presión solucionadores simple
basado en el algoritmo SIMPLE, se construirán una serie de solucionadores. El solucionador de base, simpleFoam,
se presentó por primera vez. Esto es seguido por un número de siones ver-, con cada uno añadiendo más capacidades
para el código base. Estos solucionadores se pueden resumir de la siguiente manera:
1. simpleFoam (no el OpenFOAM® incorporada solucionador) es el código base que
incorpora el algoritmo sencillo en su forma más básica. 2. simpleFoamImproved extiende el código de base para
permitir un mejor tratamiento de
relajación. 3. simpleFoamTransient añade capacidades de transitorios a la simpleFoam de estado estacionario. 4.
simpleFoamBuoyancy añade al código del tratamiento fuerza de cuerpo.
Más versiones estarán cubiertos en los capítulos siguientes, cada una con capacidades extendidas, añadido
mediante la modificación del código de base descrito en este capítulo. Una lista de las versiones que serán cubiertos
en los capítulos siguientes es la siguiente.
5. simpleFoamCompressible es la versión compresible de simpleFoam (Cap. 16) 6. simpleFoamTurbulent incluye
capacidades para el tratamiento de flujos turbulentos
(. Chap 17).
simpleFoam
Antes de revisar el código simpleFoam, se abordan algunas cuestiones básicas de notación. El primer paso es para
definir, como se muestra en el Listado 15.2, los campos geométricos y parámetros que se inicializan y se utilizan en
el código.
15.10 Computacional Punteros 639
# include "fvCFD.H" # include "orthogonalSnGrad.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main (int argc, char * argv [])
{#incluir "setRootCase.H" # incluyen "createTime.H" # incluyen "createMesh.H"
Listado 15,2 Los derivados de macro # include utilizado para definir los tipos de objetos necesarios

en el listado 15.2, se necesitan las directivas macro # include fuera de la función principal de definir los tipos de
objetos que a continuación se declaran y utilizan en la aplica- ción. El #include “fvCFD.H” contiene una lista de
definiciones de clases que son en general necesarios para construir cualquier aplicación en OpenFOAM®. En la
aplicación desarrollada se añadirá una cabecera adicional, no está presente en la cabecera fvCFD.H, necesarias para
la aplicación solucionador SIMPLE.
El uso de las instrucciones # include dentro de la función principal es un procedimiento de compactación, con
cada declaración declarado que representa una parte del código se trasladó al nombre del archivo correspondiente.
Por ejemplo, la declaración #include “createMesh.H” simplemente representa el código del listado 15.3, que es
necesario crear una instancia de la clase de malla.
createMesh.H createMesh.H ~~~~~~~~~~~ ~~~~~~~~~~~ Espuma Espuma :: Información :: Información
<< << "Crear" Crear malla malla de tiempo para el tiempo = = "" << << runTime.timeName () runTime.timeName () << <<
espuma :: espuma nl :: nl << << espuma :: endl; Espuma :: endl;
Espuma :: fvMesh espuma :: fvMesh malla de malla
((espuma:: IOobject espuma :: IOobject
((espuma:: fvMesh :: defaultRegion, Espuma :: fvMesh :: defaultRegion, runTime.timeName (), runTime.timeName (), tiempo de
ejecución, el tiempo de ejecución, espuma :: IOobject :: MUST_READ espuma :: IOobject :: MUST_READ))););
Listing 15.3 El código que representa el archivo createMesh.H # include es necesario crear una instancia de la clasede malla
64015 de flujo de fluidos Cálculo: flujos incompresibles

Una vez que la inicialización necesaria se ha realizado, el siguiente paso es la definición de los campos o
variables adecuadas que necesita el solucionador . Estos se definen en el archivo “createFields.H”. El primer campo
definido, que se muestra en el Listado 15.4, es el campo de presión (p).
Información << "del campo de lectura p \ n" << endl; volScalarField p
(IOobject(
"p", runTime.timeName (), malla, IOobject :: MUST_READ, IOobject :: AUTO_WRITE), de malla);
Añadir 15,4 script utilizado para definir el campo de presión

Dado que la solución se obtiene mediante la resolución de una ecuación de corrección de presión en lugar de una
ecuación de la presión, un campo de corrección de presión (PP) también se define (Listado 15.5).
const volScalarField :: GeometricBoundaryField y PBF = p.boundaryField (); Lista de palabras PBT = pbf.types ();
volScalarField pp
(IOobject(
"pp", runTime.timeName (), malla, IOobject :: NO_READ, IOobject :: AUTO_WRITE), malla, dimensionedScalar ( "cero",
p.dimensions (), 0.0), PBT);
Añadir 15,5 script utilizado para definir el campo de corrección de presión

Vale la pena señalar que en el listado 15.5 un constructor diferente se utiliza para definir el campo de corrección
de presión. Dado que el corrector de presión representa la presión en sí, las mismas condiciones de contorno
definidas para la presión real pueden ser utilizados para el campo de corrección de la presión y sin la necesidad de
definir la misma cantidad dos veces.
La lista de tipos de contorno de presión que se muestran en el Listado 15,6 ahora se copian en virtud de la
variable de PBT en el Listado 15,5 y directamente utilizado en el constructor de pp.
15.10 Computational Punteros 641
// conjunto de contornos pp valora forAll (pp.boundaryField (), Patchi) {
si (isType <fixedValueFvPatchScalarField> (pp.boundaryField () [Patchi]))
{fixedValueFvPatchScalarField
y ppbound =
refCast <fixedValueFvPatchScalarField> (pp.boundaryField () [Patchi]);
ppbound == scalarField (ppbound.size (), 0.0); }}
Listado 15,6 script que muestra la declaración de los diferentes tipos de límites de presión

El corrector debe restablecer a cero el campo de la corrección en cada iteración y también debería aplicarse un
valor de cero en todas las fronteras para los que se utiliza una condición de contorno de Dirichlet para la presión.
La campos de flujo de masa correspondientes velocidad y deben también ser definidos. Como se muestra en el
Listado 15.7, el campo de velocidad se define a través de un archivo de entrada, mientras que el campo de flujo de
masa se puede definir como una cantidad derivada.
Información << "del campo de lectura U \ n" << endl; volVectorField U
(IOobject(
"U", runTime.timeName (), malla, IOobject :: MUST_READ, IOobject :: AUTO_WRITE), de malla); surfaceScalarField Mdot
(IOobject(
"Mdot", runTime.timeName (), malla, IOobject :: READ_IF_PRESENT, IOobject :: AUTO_WRITE), linearInterpolate (U) y
mesh.Sf ());
Añadir 15,7 script utilizado para definir la velocidad y el flujo de masa campos
642 15 Flujo de fluidos computacional: flujos incompresibles

Por último las propiedades termofísicas de fluidos también deben ser definidas. Para laminar incom- prensible
fluye esto implica simplemente la asignación de un valor a la nu viscosidad cinemática, como se muestra en el
Listado 15.8.
Información << "Lectura transportProperties \ n" << endl; IOdictionary transportProperties
(IOobject(
"transportProperties", runTime.constant (), malla, IOobject :: MUST_READ_IF_MODIFIED, IOobject :: NO_WRITE)); nu
dimensionedScalar
(transportProperties.lookup( "nu"));
Añadir 15,8 Código utilizado para definir las propiedades termofísicas de fluidos

Después de definir todas las variables de la aplicación del algoritmo simple puede continuar. Un bucle mientras
que se puede utilizar para los casos en que el criterio de parada es el número de iteraciones simple. Para cada bucle
único, las ecuaciones de movimiento y presión de corrección se resuelven y se llevan a cabo actualizaciones de las
variables. A partir de la ecuación de momento escrito como (la forma resuelto en OpenFOAM®),
rf vv g 1/4 vr2v ð15.217Þ rp
donde la viscosidad cinemática v se define como
v 1/4
lq
ð15.218Þ
y p representa la presión dividida por la densidad, es decir,
p cuarta
presión q estática
ð15.219Þ
su solución se traduce en la secuencia de comandos muestra en el listado 15.9.
15,10 Computational Punteros 643
// Resolver la ecuación Momentum fvVectorMatrix UEqn
(FVM:: div (Mdot, U) - fvm :: laplaciano (nu, U)); UEqn.relax (); resolver
(UEqn== -fvc :: grad (p));
Añadir 15,9 Script para resolver la ecuación de momento

La primera instrucción en el Listado 15,9 define la discretización volumen finito de la ecuación de impulso en forma
de vector con su matriz de almacenamiento (los tres componentes del vector de velocidad se resuelven de una
manera segregada a pesar de su vectorial Implementation ). El sistema es entonces implícitamente se relajó y se
resuelve a través de un solver iterativo. Una vez que se resuelve la ecuación de momento, se obtiene una nueva
suposición para el campo de velocidad. Esta velocidad no satisface la ecuación de continuidad, en general, y el
conjunto de la ecuación de continuidad en la forma de una ecuación de corrección de la presión que se requiere
ahora para corregir el campo de flujo. La ecuación de corrección de presión se escribe como
rD

f

rp0Þ 1/4 r ðvÞ ð15.220Þ


donde un componente de

a un centroide elemento se calcula como
D 1/4
av V
c
pp = escalar (0,0) * pp; pp.correctBoundaryConditions ();
fvScalarMatrix ppEqn
(-fvm :: laplaciano (DUF, pp, "laplaciano (PDIFF, pp)") + FVC :: div (Mdot));
Listado 15,10 comandos para implementar la ecuación de corrección de presión

ð15.221Þ
con valores en las caras obtenidos por interpolación. Su puesta en práctica se traduce en la siguiente sintaxis (Listado
15.10):,donde div (Mdot) es, básicamente,
mientras que PP representa p 'y se pone a cero en cada iteración. Por otra parte,
la variable DUF es el valor de D en la cara celular obtenida, como se muestra en el Listado 15,11, por interpolación
lineal usando los valores en los nodos a caballo entre la cara. Además, .A () representa los términos diagonales de la
matriz de impulso dividido por el volumen.
volScalarField DU = 1,0 / UEqn.A (); surfaceScalarField DUF ( "DUF", linearInterpolate (DU));
Listado 15,11 Script para calcular los valores de DUF

Listado 15,12 calcula la tasa de masa de flujo en las caras de células (Mdot) utilizando la interpolación Rhie-Chow,
donde el cálculo de ∇pf
const surfaceVectorField ed = mesh.delta () () / MAG (malla. delta()()); Espuma :: fv :: orthogonalSnGrad <escalar> faceGradient
(malla); surfaceVectorField gradp_avg_f = linearInterpolate (FVC :: grad (p)); surfaceVectorField gradp_f = gradp_avg_f -
(gradp_avg_f & Ed) * ed + (faceGradient.snGrad (p)) * ed;
surfaceVectorField U_avg_f = linearInterpolate (U);
// Rhie-Chow interplation Mdot = (U_avg_f y mesh.Sf ()) - ((duf * (gradp_f - gradp_avg_f)) y mesh.Sf ());
Listado 15,12 Script para calcular la tasa de flujo de masa en la celda se enfrenta con elRhie-Chow interpolación
ppEqn.solve();
listado 15.13 Declaración utilizado para resolver la ecuación de corrección de

Se muestra claramentepresión.
La ecuación de corrección de presión está completamente establecido y se resuelve ejecutando la sentencia en el
listado 15.13.
Una vez que se resuelve la ecuación de corrección de la presión, la velocidad, la presión, y campos de velocidad
de flujo de masa se actualizan usando el campo de corrección de la presión obtenida. Comenzando con el campo de
flujo de masa (es decir, el flujo Mdot), se actualiza ejecutando el siguiente comunicado (Listado 15.14).
y rp f
644 15 Fluid Flow Cálculo: incompresible Flujos

P
MF
15,10 Computational Punteros 645
Mdot + = ppEqn.flux ();
Añadir 15.14 Declaración utilizado para actualizar el campo de tasa de flujo de masa para satisfacer la continuidad

La función de flujo () en el Listado 15.14 proporciona la multiplicación de la matriz, los coeficientes de matriz
diagonales adicionales, y la solución correspondiente. Recordando la discretización volumen finito del término de
difusión, cada diagonal adicional de coeficientes representa una cara de la malla. Por lo tanto la actualización de los
flujos se puede realizar de una manera más coherente utilizando directamente los coeficientes de la matriz y los
valores de celda. Una versión simplificada de la función de flujo () se muestra en el listado 15.15.
para (cara label = 0; cara <lowerAddr.size (); cara ++)
{mDotPrime[cara] =
upperCoeffs [cara] * pp [upperAddr [cara]] - lowerCoeffs [cara] * pp [lowerAddr [cara]]; }
Return mDotPrime;
Añadir 15.15 Una versión simplificada de la función de flujo () cuando el mDotPrime corrección de flujo se calcula

En el Listado 15.15 el flujo corrección mDotPrime (Ec. 15.101) básicamente se eva- uated mediante la realización
de un bucle sobre las caras utilizando los coeficientes superior e inferior de la matriz y multiplicando estos
coeficientes con los valores de las celdas correspondientes.
Por último, la velocidad y la presión en los centroides de células se actualizan usando el script se muestra en el
Listado 15,16,
escalar URF = mesh.equationRelaxationFactor ( "pp"); p + = URF * pp; p.correctBoundaryConditions (); U - = FVC :: grad (pp)
* DU; U.correctBoundaryConditions ();
15.16 Actualización lista de los campos de velocidad y presión en los centroides de células

donde la variable URF es el factor de relajación explícita para la actualización de presión? P, necesaria para un
solucionador SIMPLE estable.

También podría gustarte