Documentos de Académico
Documentos de Profesional
Documentos de Cultura
FACULTAD DE INGENIER
IAS FISICOMECANICAS
MODELADO Y SIMULACION DEL FLUJO DE UN FLUIDO SOBRE UNA PLACA
Presentado por:
MANUEL FERNANDO JEREZ CARRIZALES
Director:
Ph.D. DAVID ALFREDO FUENTES
FACULTAD DE INGENIER
IAS FISICOMECANICAS
MECANICA
ESCUELA DE INGENIERIA
BUCARAMANGA
2012
DEDICATORIA
AGRADECIMIENTOS
a
desarrollo de este proyecto que genera un escal n m s hacia el conocimiento de la CFD.
o
a
A David Fuentes por la asesora brindada y el tiempo dedicado.
CONTENIDO
p g.
a
INTRODUCCION
1
20
DINAMICA DE FLUIDOS
21
1.1
CARACTER
ISTICAS DEL FLUJO Y DE LOS FLUIDOS . . . . . . . . . . 21
1.2
1.2.2
1.2.3
1.3
1.4
1.5
FLUJO EN LA CAPA L
IMITE . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.5.1
1.5.2
1.5.3
1.5.4
2
36
2.1
2.2
2.3
MALLA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.3.1
Malla estructurada . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.3.2
Malla no estructurada . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.3.3
2.4
2.4.2
2.4.3
2.5
CONDICIONES DE FRONTERA . . . . . . . . . . . . . . . . . . . . . . . 46
2.6
Ecuaciones lineales . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.6.2
Ecuaciones no lineales . . . . . . . . . . . . . . . . . . . . . . . . . 49
2.7
2.8
CARACTER
ISTICAS A EVALUAR EN LA CFD . . . . . . . . . . . . . . 50
2.9
3
POST-PROCESAMIENTO . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
METODOLOG DE TRABAJO . . . . . . . . . . . . . . . . . . . . . . . 51
IA
53
IMPLEMENTACION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.1.1
3.1.2
3.2
4
M todo intuitivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
e
Desarrollo mediante el uso de las libreras . . . . . . . . . . . . . . . 75
RESULTADOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
FLUJO DIFUSIVO-CONVECTIVO
4.1
88
ESQUEMA DE APROXIMACION . . . . . . . . . . . . . . . . . . . . . . 89
4.1.1
Interpolaci n aguas-arriba . . . . . . . . . . . . . . . . . . . . . . . 89
o
4.1.2
4.2
4.3
5
IMPLEMENTACION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
RESULTADOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
105
Implementaci n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
o
5.1.2
5.2
Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Implementaci n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
o
Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
127
6.2
6.3
6.4
6.5
6.6
IMPLEMENTACION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
6.7
6.7.2
6.7.3
6.8
7
CONCLUSIONES
216
9
RECOMENDACIONES Y OBSERVACIONES
217
BIBLIOGRAFIA
218
ANEXOS
221
10
LISTA DE TABLAS
p g.
a
Tabla 1
Tabla 2
ciones lineales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Tabla 3
Tabla 4
Tabla 5
Tabla 6
Tabla 7
Tabla 8
Tabla 9
75
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
a
del caso NSCL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Tabla 15 Comparaci n de resultados para el grosor de la capa lmite t rmica del
o
e
caso NSCL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Tabla 16 Comparaci n de resultados para fy=0 en el caso NSCL. . . . . . . . . . 186
o
Tabla 17 Comparaci n de resultados para C f ,x en el caso NSCL. . . . . . . . . . 187
o
Tabla 18 Comparaci n de resultados para el coeciente adimensional de transfeo
rencia de calor en el caso NSCL. . . . . . . . . . . . . . . . . . . . . . 188
Tabla 19 Comparaci n de resultados para el grosor de la capa lmite hidr ulica
o
a
del caso Blasius1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Tabla 20 Comparaci n de resultados para el grosor de la capa lmite t rmica del
o
e
caso Blasius1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Tabla 21 Comparaci n de resultados para el coeciente de fricci n local C f ,x del
o
o
caso Blasius1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Tabla 22 Comparaci n de resultados para vmax del caso Blasius1. . . . . . . . . . 205
o
Tabla 23 Comparaci n de resultados para el coeciente adimensional de transfeo
rencia de calor del caso Blasius1. . . . . . . . . . . . . . . . . . . . . . 207
Tabla 24 Comparaci n de resultados para el espesor de la capa hidr ulica del caso
o
a
Falkner1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
12
LISTA DE FIGURAS
p g.
a
Figura 1
Figura 2
Figura 3
Figura 4
Figura 5
Figura 6
Figura 7
Figura 8
Figura 9
Malla no estructurada. . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
e
o
Figura 23 Temperatura a trav s de una trayectoria especca. . . . . . . . . . . . . 87
e
a
Figura 34 Capa lmite t rmica ter del caso NSCL. . . . . . . . . . . . . . . . . . 182
e
Figura 35 Perl de velocidad u y temperatura T para x = 4[m] . . . . . . . . . . . 184
Figura 36 Velocidad v para NSCL . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Figura 37 Valor f en la supercie para NSCL. . . . . . . . . . . . . . . . . . . . 185
Figura 38 Coeciente local de fricci n para NSCL. . . . . . . . . . . . . . . . . . 186
o
Figura 39 T rmino fuente para la ecuaci n de la cantidad de movimiento en die
o
recci n x. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
o
Figura 40 Coeciente adimensional de transferencia de calor para NSCL. . . . . . 188
Figura 41 Presi n a lo largo de la placa. . . . . . . . . . . . . . . . . . . . . . . . 189
o
Figura 42 Norma del residuo m sico . . . . . . . . . . . . . . . . . . . . . . . . . 190
a
Figura 43 Norma del residuo m sico sin tener en cuenta el volumen de control de
a
referencia para la ecuaci n de correcci n de presi n . . . . . . . . . . . 190
o
o
o
14
e
Figura 50 Perl de velocidad del caso Blasius1. . . . . . . . . . . . . . . . . . . . 203
Figura 51 Comparaci n del valor de f |y=0 . . . . . . . . . . . . . . . . . . . . . . 204
o
Figura 52 Comparaci n del valor del coeciente de fricci n local C f ,x . . . . . . . . 205
o
o
Figura 53 Comparaci n de la velocidad v m xima. . . . . . . . . . . . . . . . . . 206
o
a
Figura 54 Comparaci n del coeciente adimensional de transferencia de calor. . . 206
o
Figura 55 Convergencia del residuo m sico para Blasius1. . . . . . . . . . . . . . 208
a
Figura 56 Convergencia de la velocidad para Blasius1. . . . . . . . . . . . . . . . 208
Figura 57 Espesor de la capa lmite t rmica e hidr ulica para 300x30 nodos.
e
a
. . . 209
a
Figura 58 Espesor de la capa lmite t rmica e hidr ulica para 600x40 nodos.
e
a
. . . 210
Figura 60 Espesor de la capa lmite hidr ulica del caso Falkner1. . . . . . . . . . . 212
a
Figura 61 Lneas de ujo para el caso Falkner1. . . . . . . . . . . . . . . . . . . . 213
15
LISTA DE ANEXOS
p g.
a
Anexo A. CLASES EN C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
LA CLASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
16
DE LA CAPA L
IMITE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
DE LA CAPA L
IMITE: ENCABEZADO DE LA CLASE . . . . . . . . . . . . . . . . 339
DE LA CAPA L
IMITE: ARCHIVO DE CODIGO FUENTE . . . . . . . . . . . . . . 341
17
RESUMEN
.
MEDIANTE VOLUMENES FINITOS1
MANUEL FERNANDO JEREZ CARRIZALES2 .
AUTOR:
PALABRAS CLAVE:
FVM, CAPA L
IMITE, SIMPLE, PLACA PLANA.
Se presentan dos m todos para resolver el problema del ujo en la capa lmite sobre una placa plana.
e
e
u
se program en C++ el m todo de soluci n para las ecuaciones planteadas. Se explica el c digo
o
e
o
o
desarrollado y adicionalmente se ense a el modo de usar algunas libreras.
n
Las ecuaciones de la din mica de uidos se dividieron en dos grupos: ecuaci n de convecci n dia
o
o
fusi n y ecuaci n de difusi n. Cada grupo de ecuaciones se calcul y resolvi de una forma diferente
o
o
o
o
o
teniendo en cuenta el estado transitorio. Con el n de vericar la funcionalidad de las dos clases se
presenta para cada clase un ejemplo resuelto.
Una vez se explica c mo resolver los dos tipos b sicos de ecuaciones, se une el trabajo realizado en
o
a
una clase general llamada NavierStokes. La clase NavierStokes permite resolver mediante dos formas
las ecuaciones no lineales de la mec nica de uidos como un proceso iterativo de varias ecuaciones
a
lineales. Los dos m todos de soluci n se implementaron para resolver una gran variedad de problemas
e
o
de ujo laminar. Los resultados obtenidos de la simulaci n del ujo en la capa lmite sobre una
o
supercie plana en regimen laminar se comparan con la teora desarrollada por Blasius.
1 Trabajo
de grado.
de Ingenieras Fisicomec ncias, Escuela de Ingeniera Mec nica, Director Ph.D. David Fuentes.
2 Facultad
18
ABSTRACT
AUTHOR:
KEY WORDS:
Two methods for solving boundary layer problem over a at plate have been implemented. The rst
method is based on the full Navier-Stokes equations by assuming an unknown gradient pressure, which
is calculated by SIMPLE method. On the other hand, the second method is based on the simplied
equation by Blasius and it is solved by using a velocitys correction method.
A nite volume method is used as approach. The FVM is programmed in C++ with Ph.D. Fuentes
libraries. The created code is explained in each instruction and it is taught how to use some libraries.
Equations in the FVM are classied into two groups: diffusions equations and diffusion convections
equations. Each group is calculated and solved in a different class, where unsteady state is taking into
account. Intermediate results are shown to check functionality in each group.
Once it is explained how to solve the two types of basics equations, created classes are modied to be
part of a more general class called NavierStokes.
NavierStokes allows solving non-linear equations in an iterative process made by linear equations.
Both semi-implicit method for pressure-linked equations and velocitys correction method are implemented to solve a great variety of laminar ow problems.
Results from the simulation of boundary layer over a at plate are compared with theory made by
Blasius.
1 Work
degree.
2 Physical-Mechanical
19
INTRODUCCION
El problema del ujo en la capa lmite es un tema fundamental para el estudio de la trans
ferencia de calor. Para el caso del ujo sobre una supercie plana se han descrito varias
soluciones analticas de acuerdo a una serie de par metros. Son estas soluciones junto a la
a
simplicidad del problema las que hacen del ujo en la capa lmite un excelente candidato a
ser simulado por medio del m todo de los vol menes nitos.
e
u
La forma de operar del m todo de los vol menes nitos puede ser vista como el balance
e
u
de una propiedad a trav s de un volumen de control. El MVF no requiere del uso de variae
bles de transformaci n, estas variables por lo general, convierten el problema de din mica
o
a
de uidos computacional en un conjunto de ecuaciones diferenciales que posteriormente son
discretizadas.
Para cumplir con los objetivos planteados se realiza la siguiente dristibuci n de los captulos
o
en el libro:
En el captulo 1 se introduce el marco te rico y se desarrolla un modelo matem tico de
o
a
las ecuaciones simplicadas del ujo en la capa lmite a partir de las ecuaciones completas
marco te rico pero en este caso se enfatiza en el m todo de los vol menes nitos.
o
e
u
En los captulos 3, 4 y 5 se presenta la discretizaci n de dos tipos de ecuaciones, la ecuaci n
o
o
de difusi n y la ecuaci n de convecci n-difusi n. El modelado a partir de estos dos tipos de
o
o
o
o
ecuaciones permite desarrollar una gran cantidad de problemas de la din mica de uidos.
a
Finalmente, en el captulo 6 se realiza la simulaci n del ujo en la capa lmite a partir de
dos modelos, el primer modelo tiene en cuenta las ecuaciones completas de Navier-Stokes y
el segundo modelo resuelve las ecuaciones de Blasius.
El c digo desarrollado para cada una de las libreras creadas se explica en cada captulo y
o
se incluye de forma completa en los anexos del presente trabajo, incluyendo comentarios
adicionales.
20
1. DINAMICA DE FLUIDOS
La din mica de uidos es la ciencia que trata del comportamiento de los uidos en reposo o
a
en movimiento y de su interacci n con s lidos o con otros uidos en las fronteras.
o
o
El an lisis de la din mica de uidos vara sustancialmente del nivel macrosc pico al nivel
a
a
o
microsc pico. El estudio a nivel macrosc pico est basado en la teora del continuo. La
o
o
a
teora del continuo asume que no existen discontinuidades en la materia, por lo tanto, se
pueden denir las propiedades del uido como la densidad o la presi n como funciones cono
tinuas para todo el espacio. La teora del continuo no es v lida para an lisis microsc picos,
a
a
o
regi n en la que debe ser considerado las interacciones entre las mol culas y los espacios
o
e
vacos existentes entre ellas. Para el desarrollo del presente trabajo de grado se asumir la
a
teora del continuo ya que todos los an lisis que se realizan son a nivel macrosc pico.
a
o
1.1
Un uido se caracteriza por no resistir esfuerzos de corte. Los uidos pueden ser lquidos
o
muy peque a y de una manera similar pasa con la temperatura, por lo que en la
n
mayora de los casos se considera que los lquidos son incompresibles. Un gas
e
energa de presi n, si la velocidad del uido es menor a un valor caracterstico de
21
1(a) se muestra la variaci n del esfuerzo de corte con el aumento de la rapidez de deforo
maci n y en la gura 1(b) se muestra la variaci n del esfuerzo de corte con el tiempo.
o
o
El presente trabajo ser basado en uidos newtonianos independientes del tiempo.
a
Figura 1: Clasicaci n de los uidos de acuerdo al comportamiento reol gico.
o
o
Esfuerzo
tangencial
Esfuerzo
tangencial
Plastico de Bingham
Reopctico
Pseudoplstico
Tiempo
Rapidez de deformacin
Seg n la variaci n de las propiedades: en algunos casos, los cambios en las propiedades
u
o
como la densidad y el Prandtl son lo sucientemente peque os que se pueden despren
ciar, al despreciar estos cambios, el an lisis de un problema suele ser m s sencillo.
a
a
Fluido de propiedades constantes: las propiedades de un uido no dependen de
la posici n, del tiempo u otros factores como campos magn ticos. Para que el
o
e
uido tenga propiedades constantes debe ser un elemento puro o una mezcla homog nea. Esta es una suposici n v lida para simplicar los problemas de ingee
o a
niera.
22
1.2
Las ecuaciones de la din mica de uidos se pueden construir usando el enfoque de Euler o el
a
enfoque de Lagrange, cada uno de estos enfoques produce una ecuaci n para cada principio
o
de conservaci n que, aunque parece diferente, puede ser transformada de tal manera que se
o
llega al mismo resultado presentado por el otro enfoque. En el presente trabajo se usar el
a
enfoque de Euler que determina las propiedades como la velocidad en un punto jo en el
espacio; las ecuaciones generadas al utilizar el enfoque de Euler se llaman ecuaciones conservativas.
La formulaci n matem tica que se presenta a continuaci n est basada en tres principios
o
a
o
a
1.
de conservaci n
o
1.2.1
de masa requerida para proporcionar una energa igual en magnitud a la energa cin tica, el
e
valor de la masa sera tan peque o que se requeriran procesos especiales para realizar su
2.
medici n
o
En el presente trabajo, en el cual se realiza un an lisis macrosc pico y no se tienen en cuenta
a
o
reacciones nucleares ni qumicas, es v lido utilizar el principio de conservaci n de la masa
a
o
1 Aunque
existen otros principios, como la ley de especies qumicas, no ser n comentados dado que est n
a
a
fuera del alcance del presente proyecto.
2 CENGEL, Y.A. Y BOLES, M. Termodin mica: un enfoque pr ctico, 5 ed. M xico: McGraw Hill, 2007.
a
a
e
p.71.
23
+
t
1.2.2
(V ) = 0
(Ec 1.1)
A partir de la segunda ley de Newton, se deduce que la sumatoria de las fuerzas aplicadas
a un elemento innitesimal de uido es igual a la variaci n en el tiempo de la cantidad de
o
movimiento (Ec 1.2).
(u)
+
t
(u V ) = ( p) i + f i + ( ) i
(Ec 1.2a)
(v)
+ (v V ) = ( p) j + f j + ( ) j
t
(w)
+ (w V ) = ( p) k + f k + ( ) k
t
Para uidos newtonianos, es
xx = ( V ) + 2 u
x
zz = ( V ) + 2 w
z
v
xy = yx = ( u + x )
y
xx xy xz
= yx yy yz
zx zy zz
En donde
1.2.3
(Ec 1.2b)
(Ec 1.2c)
yy = ( V ) + 2 v
y
yz = zy = ( v + w )
z
y
xz = zx = ( w + u )
x
z
a
energa no puede crearse ni destruirse, solo se transforma. La primera ley de la termodin mica
a
puede expresarse en funci n de la energa interna como (Ec 1.3) o en funci n de la entalpa
o
V2
e+
t
2
V2
e+
2
+
2
((h + V2 ))
+
t
T ) + q
(k
V2
(h + )V =
2
(k
T ) + q + + f V
(Ec 1.4)
para
= 2
+
u
x
u
x
+2
+ v + w
y
z
v
y
2
+2
w
z
( V )
24
v
x
+ u
y
w
y
+ v
z
u
z
+ w
x
ECUACION DIFERENCIAL GENERAL EN LA DI
NAMICA DE FLUIDOS
1.3
La conservaci n de la masa, cantidad de movimiento y energa pueden ser escritas de una mao
nera general como se muestra en la (Ec 1.5) utilizando cuatro t rminos: el t rmino transitorio,
e
e
el t rmino convectivo, el t rmino difusivo y el t rmino fuente.
e
e
e
( )
t
( V ) =
t ermino transitorio
t ermino convectivo
) +
t ermino di f usivo
t ermino f uente
(Ec 1.5)
Donde
Ec. de continuidad = 1 = 0
S= 0
p
Ec. cant. mvto.
= ui =
S = xi + Bi + Su,i
1
1
1
Ec. de energa
= h = k/C p S = Cp q + Cp ( V ) + Cp f V
En el presente trabajo se usar una versi n simplicada de la ecuaci n de la energa en
a
o
o
t rminos de la temperatura (Ec 1.6) puesto que en la ingeniera mec nica es bastante famie
a
liar el concepto del gradiente de la temperatura que est relacionado con el ujo de calor. La
a
(Ec 1.6) fue obtenida al asumir que C p = constante, y h = C p (T Tre f ).
( T )
+
t
= T
( T V ) =
=
k
Cp
k
Cp
q
Cp
(Ec 1.6a)
q
Cp
(Ec 1.6b)
T)+
S =
1.4
2
+ 2 + + = f
2
x
y
x
y
25
<0
(Ec 1.7)
2.
Ecuaciones parab licas (Ec 1.8): la propagaci n de la informaci n se realiza aguaso
o
o
abajo y por esta raz n, solo se necesita una condici n en la frontera aguas-arriba para
o
o
resolver las ecuaciones. Los dos ejemplos m s comunes de este tipo de ecuaci n son el
a
o
ujo en la capa lmite y cualquier ecuaci n dependiente del tiempo.
2
+ + = f
x2
x
y
=0
(Ec 1.8)
3.
Ecuaciones elpticas (Ec 1.9): en este tipo de ecuaci n la informaci n de un punto se
o
o
propaga en todas las direcciones, es necesario denir una condici n en cada frontera. La
o
ecuaci n de Poisson es el ejemplo m s com n de este tipo.
o
a
u
2
2
+ 2 + + = f
2
x
y
x
y
1.5
>0
(Ec 1.9)
o
coeciente de transferencia de calor por convecci n (locales y promedios) as como tambi n
o
e
el grosor de la capa hidr ulica, el ujo de calor o denir la zona en la cual el uido no se ha
a
visto afectado por la supercie, ya sea hidr ulica o t rmicamente. En la gura 2 se presenta
a
e
un perl tpico de la velocidad y el ancho de la capa lmite para el ujo sobre una placa plana.
El c lculo de la capa lmite no se limita al ujo sobre una placa plana, es com n el an lisis
a
u
a
del ujo a trav s de un cilindro (gura 3) o de perles de ala de avi n; en ujos internos,
e
o
26
se analizan ductos de aire e incluso se puede tener en cuenta la mezcla de dos ujos y su
evoluci n a trav s de la tubera. El ujo en la capa lmite tampoco est limitado al ujo sobre
o
e
a
una supercie, m s all del borde de salida del ala de un avi n se puede producir el fen meno
a
a
o
o
de la capa lmite en donde la supercie (una lnea imaginaria que no es atravesada por el
o
regi n, el gradiente de presi n produce la inversi n de la velocidad del uido, se puede eno
o
o
contrar este fen meno en geometras con cambios dr sticos como cilindros o difusores que
o
a
provocan un aumento en el gradiente de presi n.
o
Figura 3: Capa lmite a trav s de un cilindro.
Fuente:
http://www.see.ed.ac.uk/ johnc/teaching/uidmechanics4/2003-04/uids14/image41.gif
La teora del ujo en la capa lmite se basa en la condici n de no deslizamiento, es decir,
o
que el uido que est en contacto con la supercie tiene la velocidad de esta. La condici n
a
o
de no deslizamiento es v lida para an lisis macrosc picos pero a nivel miscrosc pico se debe
a
a
o
o
realizar otro planteamiento.
El grosor de la capa lmite hidr ulica es la distancia a la supercie en donde el uido
a
tiene el 99% de la velocidad de entrada. Si se dene y como la distancia de un punto a la supercie y u o V como la velocidad del uido lejos de la supercie, el grosor de la capa lmite
hidr ulica se puede denir como (Ec 1.10). La lnea generada por h divide el an lisis en dos
a
a
27
zonas, la zona de ujos viscosos, tambi n llamada capa lmite hidr ulica, es la zona m s cere
a
a
cana a la supercie; m s alla de esta zona, se encuentra la zona de ujo no viscoso en donde
a
los efectos de la fricci n son despreciables, esta zona se puede modelar matem ticamente
o
a
con la ecuaci n de Euler.
o
h = y|u=0.99 u = y|u=0.99 V
[m]
(Ec 1.10)
e
o
corresponde a un solo punto de la supercie o global si es un promedio para una regi n en la
o
supercie.
Cf =
2
u
s
=
|y=0
V 2 /2 V 2 y
[adimensional]
(Ec 1.11a)
s, prom
(Ec 1.11b)
V 2 /2
En los casos en donde se debe tener en cuenta la transferencia de calor, resulta conveniente
denir el grosor de la capa lmite t rmica (Ec 1.12) de forma an loga al grosor de la capa
e
a
lmite hidr ulica.
a
[m]
(Ec 1.12)
t = y|T Tsup =0.99 (T Tsup )
C f , prom =
T
|y=0
y
[W /m2 ]
(Ec 1.13)
El coeciente de transferencia de calor por convecci n (Ec 1.14) se dene con base en el
o
ujo de calor en la supercie y la diferencia de temperatura existente. El valor de h puede ser
expresado indirectamente de una forma m s general a partir del coeciente adimensional de
a
transferencia de calor o n mero de Nusselt (Ec 1.15).
u
qs
[W /(m2 C)]
(Ec 1.14)
h=
Ts T
Nu =
1.5.1
h Lc
k
[adimensional]
(Ec 1.15)
placa plana
Para poder analizar el ujo en la capa lmite sobre una placa plana se deben tener en cuenta
las siguientes simplicaciones al modelo matem tico com nmente conocidas como aproxia
u
maciones de la capa lmite (Ec 1.16).
u
28
(Ec 1.16a)
v
0
x
v
0
y
(Ec 1.16b)
(Ec 1.16c)
u
x
u
y
(Ec 1.16d)
T
x
T
y
(Ec 1.16e)
La velocidad del uido en la zona de entrada tiene unicamente componente en u, la velocidad v es generada por la ecuaci n de continuidad al disminuir gradualmente el valor de u,
o
por esta raz n, v es mucho menor que u (Ec 1.16a). Las aproximaciones de (Ec 1.16b) y (Ec
o
1.16c) se tienen en cuenta solamente al analizar la cantidad de movimiento en y, en general
estos valores son muy peque os. La variaci n de la velocidad u (Ec 1.16d) es mucho m s
n
o
a
signicativa en el eje y que en la direcci n del ujo de entrada y sucede de igual forma con
o
la variaci n de la temperatura (Ec 1.16e).
o
En esta secci n se utilizar n dos n meros adimensionales, el Reynolds (Re) y el Prandtl
o
a
u
(Pr). El n mero de Reynolds (Ec 1.17) depende del ujo y de las propiedades del uido, en
u
cambio, el n mero de Prandtl (Ec 1.18) depende solamente de las propiedades del uido.
u
Re =
Pr =
Fuerzas de inercia V Lc
=
Fuerzas viscosas
Difusividad molecular
de la cantidad de movimiento
(Ec 1.17)
(Ec 1.18)
valor mnimo de Re para que el modelo matem tico sea coherente con la realidad.
a
Re > 1000
29
+
t
(V )
u v
+ =0
x y
(Ec 1.19)
Ecuaci n de cantidad de movimiento: para el caso del ujo en la capa lmite sobre una
o
p
+ ( ) i
x
B
0
(uu) (uv)
u
v
u
u v
u
u
(u V ) =
+
= 2u + u + v = u
+
+ u + v
x
y
x
y
y
x y
x
y
u v
B
0
2
+
( + ) =
(V ) +
x
x
x
y
y x
0
b
&
&
2 u
u &v
2 u
2 u
2 u
2 u
= 2 + &
+
+ 2 = 2 + 2 2
x
x &
x y
y
x
y
y
( ) i =
u
u
dp
2 u
(Ec 1.20)
+ v = + 2
x
y
dx
y
En (Ec 1.20) se utiliza la notaci n de derivada exacta de la presi n porque esta no depende
o
o
del eje y ni del tiempo. Normalmente, el valor de la derivada de la presi n es dado como un
o
5 . Para determinar el valor de d p es suciente con hacer el c lculo fuera de la
dato de entrada
a
dx
regi n de la capa lmite en donde es posible usar la ecuaci n de Euler para ujo no viscoso.
o
o
u
3 No
del eje y, esto es posible utilizando las simplicaciones de (Ec 1.16) y sin tener en cuenta la fuerza gravitatoria.
5 Si la presi n o la derivada no se da como un valor de entrada, se debera denir la velocidad de salida para
o
calcular la presi n.
o
30
Ecuaci n de conservaci n de la energa: los primeros t rminos a eliminar son los t rminos
o
o
e
e
transitorios, la generaci n de calor, la energa cin tica y . Para ujos a bajas velocidades
o
e
se pueden despreciar la transformaci n de la energa cin tica y el t rmino , la entalpa y la
o
e
e
conductividad t rmica son los dos efectos a considerar en el balance de la energa. Teniendo
e
0
B
0
2
!
((h
+ V2 ))
V 2
0 0
b
&
+ (h + )V = (k T ) + & +
q
t
2
T
T
u
+v
x
y
b
&
&
u &v
+ T ( &
+ )
x y
&
U
k 2 T 2 T
=
2 + 2
Cp
x
y
T
k 2 T
T
+v
=
u
x
y
C p y2
1.5.2
(Ec 1.21)
El ujo fuera de la zona de la capa lmite se analiza como un ujo no viscoso por lo que, solo
es:
dp
u
(Ec 1.22)
u =
x
dx
La (Ec 1.22) es particularmente util para determinar el gradiente de presi n para un perl
o
externo de velocidad dado.
1.5.3
Las ecuaciones de continuidad (Ec 1.19) , cantidad de movimiento (Ec 1.20) y conservaci n
o
de la energa (Ec 1.21) del ujo en la capa lmite han sido resueltas analticamente mediante
v=
=y
31
U
x
(Ec 1.23)
(Ec 1.24a)
f () =
(Ec 1.24b)
x
U
Una vez se ha realizado una serie de operaciones se transforma las dos ecuaciones parciales
en una ecuaci n diferencial no lineal ordinaria (Ec 1.25) que puede ser resuelta por m todos
o
e
num ricos. Algunos de los valores de , f , f , f que satisfacen (Ec 1.25) se muestran en la
e
tabla 1 tomada de Schlichting6 .
d2 f
d3 f
=0
(Ec 1.25)
2 3+f
d
d2
Tabla 1: Valores de , f , f y f para la ecuaci n de Blasius.
o
df
d
d2 f
d2
df
d
d2 f
d2
0
0
0
0.4
0.02656
0.13277
1.0
0.16557
0.32979
1.4
0.32298
0.45627
2.0
0.65003
0.62977
2.4
0.92230
0.72899
3.0
1.39682
0.846
3.4
1.74696
0.90177
0.33206
0.33147
0.32301
0.30787
0.26675
0.22809
0.16136
0.11788
4.4
2.69238
0.97587
4.6
2.88826
0.98269
4.8
3.08534
0.98779
5.0
3.28329
0.99155
6.0
4.27964
0.99898
7.6
5.87924
0.99999
8.0
6.27923
1.00000
1.0
0.03897
0.02948
0.02187
0.01591
0.00240
0.00004
0.00001
En (Ec 1.26a) se muestra el grosor de la capa lmite hidr ulica, en (Ec 1.26b) el coeciente
a
local de fricci n. Adicionalmente, para una supercie isot rmica y 10 > Pr > 0.6 se muestran
o
e
el valor del grosor de la capa lmite t rmica7 (Ec 1.26c), el ujo de calor (Ec 1.26d) y el
e
coeciente adimensional de transferencia de calor (Ec 1.26e).
5.0 x
h =
Rex
(Ec 1.26a)
1/2
C f , x = 0.664 Rex
t =
5.0x
Rex
(Ec 1.26c)
Pr1/3
qs = 0.332 Pr1/3 k
V
(Ts T )
x
1/2
(Ec 1.26b)
(Ec 1.26d)
(Ec 1.26e)
soluci n de la ecuaci n diferencial para la capa lmite t rmica fue realizada por primera vez por
o
o
e
Pohlhausen en 1921.
7 La
32
El coeciente del grosor de la capa lmite hidr ulica es aproximado por Schlichting [26],
a
Schetz [25], Mills [21] y White [30] a 5.0 pero se pueden encontrar otros valores en la literatura, por ejemplo, Cengel [7] utiliza el valor de 4.91.
Adicional a (Ec 1.26) se presentan otras relaciones en (Ec 1.27) que ser n utilizadas posa
teriormente.
df
(Ec 1.27a)
u=U
d
1 U
df
v=
( f )
(Ec 1.27b)
2 Rex d
v(x,) =
U2
w = 0.332
Rex
1.5.4
0.8604 U
Rex
Rex u
( )|y=0 = 0.332 = cte
U 2 y
(Ec 1.27c)
(Ec 1.27d)
La variable de semejanza presentada por Blasius asume que la velocidad del uido es constante m s all de la capa lmite, es decir, no se produce una variaci n con respecto a la coora
a
o
denada x, por esta raz n, se presentan otras variables de semejanza y transformaciones en las
o
coordenadas8 para permitir un an lisis general. Sin duda alguna, la geometra del problema
a
afecta la soluci n de la ecuaci n pero si se emplean m todos num ricos para solucionar la
o
o
e
e
ecuaci n diferencial, se pueden utilizar las variables de semejanza para una gran cantidad de
o
geometras modicando las condiciones de frontera.
En 1931 Falkner-Skan denieron una ecuaci n (Ec 1.28d) un poco m s exible que tiene
o
a
en cuenta la variaci n de la velocidad u con respecto a la coordenada x. En este m todo se
o
e
usa una denici n similar para la variable adimensional (Ec 1.28a) y se dene una funci n
o
o
corriente (x, y) adimensional (Ec 1.28b). C es una constante al igual que m con las cuales
se dene la velocidad del uido (Ec 1.28c) en la regi n lejos de la supercie. La (Ec 1.28d)
o
es una ecuaci n diferencial ordinaria no lineal que puede ser resuelta por m todos n mericos
o
e
u
teniendo en cuenta las condiciones de frontera.
ue m + 1
x
2
(x, y) = ue x f (x, )
=y
ue = C xm
0.0904 m
8 Estos
(Ec 1.28a)
(Ec 1.28b)
(Ec 1.28c)
m todos se presentan de manera informativa pues la utilizaci n de ellos est fuera del alcance del
e
o
a
presente proyecto.
33
m+1
f f + m[1 ( f )2 ] = 0
(Ec 1.28d)
2
2m
=
(Ec 1.28e)
m+1
Falkner-Skan denieron el angulo bajo el cual se modela el ujo del uido sobre una cu a.
n
Algunos de los valores m s comunes son:
a
f +
1.
2.
= 1 m = 1 punto de estancamiento.
3.
y(x, u) =
0
(h) du
(x, u)
(Ec 1.29)
(Ec 1.30a)
dy
e
(Ec 1.30b)
e Ue e r0 dx
0
y
e Ue r
0
2s
34
En el a o 2011 S. J. Karabelas [17] deni una nueva variable de semejanza (Ec 1.31a) que
n
o
puede ser aplicada al ujo con un perl de velocidad externo potencial o exponencial (Ec
1.31b).
ue (x) y2 n
= ln(
)
(Ec 1.31a)
x
u (x)C xm
e
u e
(x)C em x
=e
(x, y) = f () g(x, y)
35
(Ec 1.31b)
(Ec 1.31c)
mediante el uso del computador. El t rmino CFD fue utilizado en los a os 70 como una
e
n
combinaci n de fundamentos fsicos, m todos num ricos y computaci n para simular uo
e
e
o
jos. En los a os 80 se resolvieron las ecuaciones de Euler en CFD en dos y tres dimenn
siones. Adem s, en esta d cada se simul el ujo viscoso de las ecuaciones de Naviera
e
o
Stokes. La mec nica de uidos computacional se ha empleado en aeron utica, autom viles,
a
a
o
turbomaquinaria, c maras de combusti n, metereologa, oceanografa, dise o de edicios,
a
o
n
medicina, entre otros; la CFD es una ayuda en el dise o y optimizaci n de equipos.
n
o
Una parte necesaria para la CFD, los m todos num ricos, fueron desarrollados a partir del
e
e
siglo XVIII pero su uso en la CFD s lo fue posible d cadas despu s. Otra parte necesaria, el
o
e
e
mallado, ha tenido grandes avances entre los que se destaca el mallado no estructurado.
Existen varios m todos en la CFD, los m s com nes son el m todo de vol menes nitos,
e
a
u
e
u
el m todo de diferencias nitas, FDM, y el m todo de elementos nitos, FEM. El m todo
e
e
e
de volumenes nitos (FVM) fue desarrollado en 1980 por Imperial College para resolver
problemas de din mica de uidos. En la simulaci n del ujo turbulento se han desarrollado
a
o
los m todos DNS (Direct Numerical Simulation) y LES (Large Eddy Simulation) y se sigue
e
investigando para lograr una mayor aproximaci n a la realidad y ser aplicado en la ingeo
niera cotidiana. En el presente trabajo se resuelve el problema del ujo en la capa lmite
mediante el m todo de los vol menes nitos, por esta raz n, se explicar las decisiones m s
e
u
o
a
a
importantes a tomar para el m todo.
e
2.1
Aunque los m todos FVM, FDM y FEM tienen fundamentos diferentes, en algunos casos es
e
posible llegar a una misma soluci n para todos los m todos. El FVM usa las ecuaciones ino
e
tegrales de la din mica de uidos en vez de las ecuaciones diferenciales parciales del FDM.
a
Esta caracterstica le permite al FVM ser aplicado a cualquier tipo de malla logrando una
En el FVM es f cil recordar que las ecuaciones utilizadas cumplen los principios de cona
servaci n ya que la discretizaci n se realiza directamente de estos principios, los t rminos
o
o
e
evaluados en las fronteras son los ujos de entrada de la propiedad evaluada y los t rminos
e
evaluados en el volumen representan la generaci n en el volumen de control.
o
36
El FVM puede no producir resultados correctos cuando se trabaja con ujo turbulento, en
estos casos puede resultar m s conveniente usar otros m todos como DNS o LES. En el
a
e
FVM com nmente se modica la viscosidad para incluir el efecto de la turbulencia y por
u
lo tanto, no se pueden ver los remolinos generados. Otro problema encontrado en el FVM
de primer orden es la falsa difusi n que se presenta en la ecuaci n de difusi n-convecci n
o
o
o
o
cuando el ujo no est alineado con la malla.
a
2.2
En la gura 5 se muestran los pasos para resolver un problema en el FVM, se explicar n cada
a
uno de los pasos a continuaci n.
o
Primero se debe denir el modelo matem tico y los principios de conservaci n que se van
a
o
Figura 5: Pasos generales para resolver un problema en el FVM.
37
F es un campo vectorial que tiene derivadas parciales continuas en una regi n del
o
3 en donde S esta denida.
espacio R
C es una curva cerrada simple, diferenciable por trozos con orientaci n positiva que
o
limita a la supercie S.
C+
F dr =
Fd S
(Ec 2.1)
2.
Teorema de green (Ec 2.2): en el caso de 2D (2 dimensiones: x e y) es conveniente
transformar una integral de area en una integral de lnea; al realizar este proceso, se eval a
u
el ujo de una propiedad en la supercie del volumen de control evitando la dicultad de
integrales dobles. La correcta aplicaci n del teorema implica que la integral de lnea debe
o
L y M son funciones que tienen derivadas parciales continuas en una regi n abierta
o
que contiene a D.
C
Pdx + Qdy =
Q P
dA
x y
(Ec 2.2)
3.
Teorema de la divergencia (Ec 2.4): Son necesarias las siguientes condiciones para
denir el teorema de la divergencia:
F es un campo vectorial con derivadas parciales continuas en una regi n abierta que
o
contiene E.
S
F dS =
38
FdV
(Ec 2.4)
El siguiente paso a realizar es el mallado, existen diferentes tipos de mallado que permiten
adaptarse a una gran variedad de geometras, algunos de estos se presentar n en la secci n
a
o
2.3. Posteriormente, se discretizan (ver la secci n 2.4) las ecuaciones obtenidas aproximando
o
las integrales y las derivadas, este proceso produce un conjunto de coecientes que denen
las ecuaciones a resolver. Las ecuaciones se resuelven conm nmente por m todos iterativos
u
e
como se explica en la secci n 2.6. Finalmente, se realiza un post-procesamiento de los resulo
tados (ver secci n 2.7) que incluye la gracaci n, generaci n de tablas, informes, etc.
o
o
o
2.3
MALLA
El MVF se puede aplicar a varios tipos de malla que pueden adaptarse mejor a ciertas geometras o simplicar el proceso de soluci n. En esta secci n se presentan algunos tipos de
o
o
mallas explicando su caracterstica principal en dos dimensiones.
2.3.1
Malla estructurada
Este tipo de malla est compuesta por dos conjuntos de lneas en los cuales las lneas que
a
Malla ortogonal: la malla ortogonal es un tipo especial de malla estructurada en la que los
vol menes de control est n formados por lados rectos y perpendiculares. Este tipo de malla
u
a
puede tener vol menes de igual tama o, gura 6, o vol menes de tama o variable, gura 7.
u
n
u
n
39
Aunque las mallas de tama o de celda variable pueden generarse aleatoriamente es com n
n
u
usar un factor de proporci n constante entre el tama o de la celda actual y la celda siguiente.
o
n
Malla no ortogonal: los dos conjuntos de lneas que conforman una malla estructurada no
tienen que ser necesariamente lneas rectas que formen angulos de 90o con las lneas del otro
40
2.3.2
Malla no estructurada
En este tipo de malla se usan vol menes de control con la forma de polgonos o guras en
u
general para lograr la adaptaci n de la malla a cualquier geometra sin la necesidad de una
o
Fuente: http://machinedesign.com/article/cfd-helps-cure-separation-anxiety-0414
Doble mallado de bloques estructurados (composite grid or chimera grid): es particu
larmente util cuando se tienen cuerpos en movimiento inmersos en un uido en donde se usa
una malla ja y una malla que sigue el movimiento del cuerpo o, cuando se tienen geometras
complejas. Las condiciones de frontera de la segunda malla son obtenidas por interpolaci n
o
de los valores obtenidos en la primera malla. Se muestra un ejemplo de este tipo de malla en
la gura 10.
Figura 10: Doble mallado.
41
2.3.3
Nodo en los v rtices de la malla (cell vertex scheme): existen dos tipos, con traslape
e
(overlaping) el cual mantiene la denici n del volumen de control de la malla pero el
o
valor de las propiedades se ubica en cada una de las esquinas del volumen de control.
Por otro lado se encuentra el doble volumen de control (dual control volumes) en el cual
se dene un volumen de control que contiene una secci n de cada una de las celdas que
o
tienen el nodo como v rtice, se muestra un ejemplo de este tipo de malla en la gura
e
12.
En el presente trabajo no se requiere condiciones especiales de mallado que ameriten una
mayor complejidad en la denici n del m todo por lo que se ubicar el nodo en el centro de
o
e
a
la celda . Adicionalmente, al usar una unica malla cuyas celdas coinciden con los vol menes
u
de control se disminuye el espacio requerido para almacenar la informaci n de otras mallas.
o
En el captulo 6 se mostrar la correcci n de la velocidad por la presi n cuando se asume el
a
o
o
esquema nodo en el centro de la celda para la presi n y la velocidad, tambi n llamado mallas
o
e
colocadas.
42
Figura 12: Nodo en el v rtice de la malla o cell-vertex scheme.
e
2.4
aparecer en la literatura, esta nomenclatura implica que el an lisis actual se hace a un volua
men de control P, el cual limita a la derecha por el volumen E o este , a la izquierda por
el volumen W o west , al norte por el volumen N y al sur por el volumen S. Si el subndice
aparece en min scula signica que la propiedad se eval a en la frontera1 o en otro punto
u
u
diferente al centro del volumen de control. A veces se usan dos subndices, por ejemplo,
NN , este caso signica que se toma el valor de del segundo volumen de control al norte
del volumen actual. En la gura 13 se muestra el uso de los subndices para un volumen de
control, los subndices necesarios permiten denir el tama o de la mol cula computacional
n
e
del esquema usado.
2.4.1
Este m todo considera que el valor de una propiedad dentro del volumen de control es conse
tante e igual a P . Para evaluar las propiedades en la frontera se tiene en cuenta la direcci n
o
del ujo; en la (Ec 2.5) se muestra la forma de evaluar una propiedad en la frontera para una
1 En
el presente documento se usa adicionalmente sc para indicar que la propiedad se eval a en la supercie
u
de control
43
NN
4
NW
NE
n(sc)
WW
EE
w(sc)
e(sc)
SW
s(sc)
SE
sc: supercie
de control
SS
0
0
v n)
v n)
E ssi (v n e(sc) < 0
N ssi (v n n(sc) < 0
e(sc) =
n(sc) =
v n)
v n)
P ssi (v n e(sc) > 0
P ssi (v n n(sc) > 0
w(sc) =
v n)
W ssi (v n w(sc) < 0
v n)
P ssi (v n w(sc) > 0
s(sc) =
v n)
S ssi (v n s(sc) < 0
(Ec 2.5)
v n)
P ssi (v n s(sc) > 0
La denici n utilizada en (Ec 2.5) puede tratarse de una forma m s general como en (Ec 2.6)
o
a
que permite su aplicaci n a cualquier tipo de malla en donde v es el vector de la velocidad del
o
uido y n es un vector normal a la supercie que apunta hacia afuera del volumen de control.
sc =
p
ssi v n 0
vecino ssi v n < 0
(Ec 2.6)
El uso de este procedimiento conlleva a un error proporcional a la longitud del lado xi del
volumen de control, algunas veces se usa O (x) para designar que este m todo de aproxie
maci n es de primer orden.
o
2.4.2
El m todo recibe tambi n el nombre de CDS (siglas en ingl s de central difference scheme)
e
e
e
debido a su similitud con el m todo de diferencias centradas del FDM. Se asume una dise
tribuci n lineal de una propiedad entre dos nodos adyacentes por lo que el error producido
o
por su uso es de segundo orden, O (x2 ). La desventaja de este m todo y otros m todos de
e
e
44
Figura 14: Interpolaci n aguas-arriba o upwind interpolation.
o
orden superior es que no son incondicionalmente estables por lo que se limita el tama o de
n
los vol menes de control o el avance en el tiempo.
u
En el caso de una malla ortogonal de dos dimensiones se tienen 4 vol menes de control
u
colindando con el VC actual por lo que la denici n de una propiedad en la supercie se
o
hace a partir de la ecuaci n (Ec 2.7) en donde xI y yI representan la posici n del centro del
o
o
volumen de control I en el eje x y el eje y.
e(sc) = E
xe(sc) xP
xE xP
+ P
x
xP
w(sc) = W w(sc) P
xW x
xE xe(sc)
xE xP
n(sc) = N
xW xw(sc)
+ P xW xP
yn(sc) yP
yN yP
y
yP
s(sc) = S s(sc) P
yS y
+ P
yN yn(sc)
yN yP
yS ys(sc)
+ P yS yP
(Ec 2.7)
Si la malla posee un tama o de celda jo la (Ec 2.7) se puede simplicar en (Ec 2.8)
n
e(sc) =
E +P
2
w(sc) =
n(sc) =
W +P
2
s(sc) =
45
N +P
2
S +P
2
(Ec 2.8)
2.4.3
Por sus siglas en ingl s, quadratic upwind interpolation for convective kinematics, el m todo
e
e
utiliza tres puntos para denir el valor de una propiedad en la frontera. Para una malla ortogonal la denici n del ujo en las cuatro fronteras se muestra en (Ec 2.9). Este m todo tiene
o
e
un error de O (x4 ).
e(sc) = P +
n(sc) = P +
w(sc) = w +
s(sc) = S +
2.5
(xe(sc) xP )(xe(sc) xW )
(xe(sc) xP )(xE xe(sc) )
(xE xP )(xE xW ) (E P ) +
(xP xW )(xE xW ) (P W )
(yn(sc) yP )(yn(sc) yS )
(yn(sc) yP )(yN yn(sc) )
(yN yP )(yN yS ) (N P ) +
(yP yS )(yN yS ) (P S )
(xw(sc) xw )(xP xw(sc) )
(xw(sc) xw )(xw(sc) xww )
(xP xw )(xP xww ) (P w ) + (xw xww )(xP xww ) (w ww )
(ys(sc) yS )(ys(sc) ySS )
(ys(sc) yS )(yP ys(sc) )
(yP yS )(yP ySS ) (P S ) +
(yS ySS )(yP ySS ) (S SS )
(Ec 2.9)
CONDICIONES DE FRONTERA
Existen tres tipos de condiciones de frontera que fueron denidas por Dirichlet, Neumann y
Cauchy/Robin
Condici n de frontera de Dirichlet: se dene el valor de una propiedad en un punto
o
determinado, por ejemplo, el valor de la velocidad, de la temperatura, de la funci n
o
corriente, etc. Se expresa como (Ec 2.10).
=
(Ec 2.10)
=
xi
(Ec 2.11)
= para = 0 y = 0
xi
46
(Ec 2.12)
2.6
2.6.1
Ecuaciones lineales
u
o
lineales se representa como (Ec 2.13) en donde A es la matriz de coecientes, b es el vector
de t rminos independientes y x es el vector soluci n.
e
o
Ax =b
(Ec 2.13)
Los sistemas de ecuaciones lineales pueden ser resueltos por m todos directos y m todos ine
e
directos. Los m todos directos no son ecientes respecto al tiempo requerido para la soluci n
e
o
aunque se pueden obtener en algunos casos, resultados m s exactos. Por otro lado, los
a
m todos indirectos no siempre convergen. En la tabla 2 se nombran los m todos disponibles
e
e
en las libreras para resolver los sistemas de ecuaciones lineales y posteriormente se comen
tan algunos de los m todos m s com nmente usados.
e
a
u
C lculo de la matriz inversa: es un m todo directo que consiste en encontrar la matriz
a
e
1 y multiplicarla por el vector de t rminos independientes, este proceso requiere
inversa A
e
O (n3 ) operaciones.
x = A1 b
(Ec 2.14)
47
Tabla 2: M todos existentes en las libreras pdelib para resolver sistemas de ecuaciones lie
neales.
C lculo de la matriz ina
versa
Jacobi
M todos directos
e
Factorizaci n LU
o
Factorizaci n Cholesky
o
M todos iterativos
e
Relajaciones sucesivas (SOR)
Relajaciones
sucesivas para sistemas
sim tricos (SSOR)
e
M todo del gradiente M todo generalizado del Gradiente conjugado
e
e
conjugado (GradConj) mnimo residuo para sistemas cuadrado para sistemas
e
Factorizaci n LU: la matriz A se factoriza en dos matrices (Ec 2.15a), L y U , L es una matriz
o
triangular inferior con 1 en los elementos de la diagonal y U es una matriz triangular superior,
de esta forma, el sistema de ecuaciones se transforma a (Ec 2.15b). Se procede a hallar Y en
(Ec 2.15c) y nalmente se halla x en (Ec 2.15d). Este m todo directo requiere un n mero de
e
u
operaciones del orden de O (2n3 /3) operaciones y es particularmente util cuando se desea resolver varios sistema de ecuaciones con la misma matriz de coecientes y diferentes vectores
de t rminos independientes ya que el proceso de factorizaci n es independiente del vector de
e
o
t rminos independientes.
e
A =LU
(Ec 2.15a)
LU x =b
(Ec 2.15b)
Y =U x
(Ec 2.15c)
U x =Y
(Ec 2.15d)
(Ec 2.16)
M todo iterativo Jacobi: la matriz A se dene como la suma de tres matrices (Ec 2.17a),
e
una matriz diagonal D, una matriz estrictamente triangular superior L y una matriz estrictamente triangular inferior U. Al realizar este proceso el sistema a resolver es (Ec 2.17b)
48
del cual se puede denir la regla para el m todo iterativo de forma vectorial (Ec 2.17c) en
e
k+1
donde k representa el contador de iteraciones, el valor de xi para i = 1, 2, 3, .., n se halla mediante (Ec 2.17d). El m todo Jacobi converge cuando A es una matriz estrictamente diagonal
e
dominante.
L U
A = D +L +U
(Ec 2.17a)
L U
D x + (L +U )x = b
(Ec 2.17b)
L U
x(k+1) = D1 [b (L +U )x(k) ]
(Ec 2.17c)
k+1
xi
1
=
bi
aii
(k)
ai j x j
j=1
(Ec 2.17d)
j=i
(k)
= (1 ) xi +
aii
bi
i1
(k)
(k+1)
[ai j x j ] [ai j x j
]
j=i+1
j=1
(Ec 2.18a)
(Ec 2.18b)
2.6.2
Ecuaciones no lineales
Los m todos disponibles para resolver un sistema de ecuaciones no lineales son el m todo
e
e
de NewtonRaphson, el m todo de gradiente conjugado y el m todo de substituci n sucee
e
o
siva.
Una forma opcional de resolver las ecuaciones no lineales es reordenar la ecuaci n para
o
poder tratarla como una ecuaci n lineal que se resuelve por m todos iterativos, un ejemplo
o
e
49
de este tipo es el m todo SIMPLE para resolver el sistema de ecuaciones diferenciales pare
ciales no lineales compuesto por las ecuaciones de Navier-Stokes, este m todo se explicar
e
a
posteriormente.
2.7
POST-PROCESAMIENTO
o
y gr cas. En el presente trabajo, este proceso se realizar en Paraview.
a
a
La generaci n de gr cas presenta un sinn mero de opciones, se pueden generar gr cas en
o
a
u
a
2D y 3D, isocontornos, campos vectoriales, mostrar la malla para el an lisis usado y gracar
a
varias propiedades en una misma gr ca, entre otros.
a
2.8
el uso de m todos num ricos conduce a una soluci n estable si la soluci n encontrada es
e
e
o
o
tambi n acotada. Existen algunos m todos que son estables bajo ciertas condiciones como
e
e
suele ser el caso para aproximaciones de alto orden, por otro lado, existen m todos que son
e
incondicionalmente estables como es el caso del esquema UDS para la ecuaci n de cono
vecci n-difusi n en estado estable.
o
o
Se han desarrollado algunos m todos para vericar la condici n de estabilidad, los dos
e
o
m todos m s usados para vericar la estabilidad en problemas lineales son el m todo de
e
a
e
Von Neumann y el m todo de la matriz. Cabe destacar para el tema del presente trabajo, el
e
uso del m todo de la analoga de circuitos de Karplus por parte de Schetz [25] para verie
car la estabilidad de un m todo explcito para resolver las ecuaciones de la capa lmite en
e
a
valores encontrados; los lmites a la soluci n pueden ser dados por las condiciones de fron
o
tera o valores sicamente imposibles como presiones absolutas negativas o temperaturas
inferiores a 0 [K].
2.9
METODOLOGIA DE TRABAJO
Antes de desarrollar el c digo para resolver el problema del ujo en la capa lmite mediante
o
FVM, se mostrar el proceso a seguir para tres problemas m s sencillos, los cuales son:
a
a
Ecuaci n de difusi n.
o
o
Ecuaci n de difusi n y convecci n.
o
o
o
Ecuaciones transitorias de la difusi n y la convecci n-difusi n.
o
o
o
51
Con el primer ejemplo se introduce2 el uso de las libreras desarrolladas por Ph.D. David
Fuentes y se van dando m s detalles con los dem s ejemplos. La raz n para resolver estos
a
a
o
problemas m s sencillos es familiarizar al lector con el m todo de operar de cada problema
a
e
para, posteriormente integrar los dos procesos para la soluci n de las ecuaciones de la capa
o
lmite que involucra un problema de difusi n para la correci n de presi n y un problema de
o
o
o
convecci n difusi n para las ecuaciones de la cantidad de movimiento.
o
o
2 En
el presente trabajo no se pretende realizar un manual de referencia de todas las funciones, en cambio, se
presenta el c digo necesario para desarrollar los problemas planteados.
o
52
o
o
o
desde dos puntos de vista diferentes.
Para obtener la soluci n de la ecuaci n de difusi n se debe partir de la ecuaci n difereno
o
o
o
cial general de la mec nica de uidos (Ec 1.5).
a
( )
t
( V ) =
t ermino convectivo
t ermino transitorio
) +
t ermino di f usivo
t ermino f uente
) + S = 0
(Ec 3.1)
En este captulo se tomar = T ya que se tiene una mejor percepci n del valor de la tempe
a
o
ratura y su derivada (proporcional al ujo de calor) pero el procedimiento se puede realizar
para una propiedad cualquiera que cumpla un principio de conservaci n; es por esta raz n
o
o
que se tomar como la conductividad t rmica k y S como la generaci n de calor por unidad
a
e
o
de volumen q. Se vuelve a escribir (Ec 3.1) en t rminos de T , k y q en (Ec 3.2):
e
(k
T)+ q = 0
(Ec 3.2)
T ) dV +
q dV = 0
(Ec 3.3)
Al aplicar el teorema de la divergencia (Ec 2.4) a la primera integral de volumen de (Ec 3.3)
se obtiene (Ec 3.4) en donde S es la supercie que rodea al volumen de control.
(k
T ) dA +
q dV = 0
(Ec 3.4)
hacia afuera del volumen de control y el diferencial de area dA como se muestra en (Ec 3.5).
k( T n) dA +
q dV = 0
53
(Ec 3.5)
La (Ec 3.5) debe ser discretizada y para ello, se debe analizar de una forma diferente cada
una de las dos integrales.
La soluci n de la integral de volumen del t rmino fuente depender del valor de q. Si
o
e
a
q es una funci n se debe aplicar m todos num ricos para hallar el valor de la integral en el
o
e
e
volumen de control. En este captulo se asumir un valor constante para q de manera que se
a
cumple la siguiente igualdad:
q dV = q
(Ec 3.6)
Por otro lado, la integral del t rmino difusivo se aproxima a una sumatoria de n ujos de
e
calor para cada uno de los n lados del volumen de control. Se presenta esta sumatoria en (Ec
3.7):
n
k( T n) dA [ki (( T )i ni ) Ai ]
(Ec 3.7)
i=1
En (Ec 3.7) el t rmino [ki (( T )i ni ) Ai ] representa el ujo de calor a trav s del area Ai . Se
e
e
debe discretizar dicho t rmino, como se muestra en (Ec 3.8), donde Tp denota la temperatura
e
en el nodo actual, Ti representa la temperatura del nodo vecino a la supercie considerada y
Ui representa la conductancia entre los dos nodos en consideraci n.
o
Flu jo
calor
[ki (( T )i ni ) Ai ] = Ui Ai (Ti Tp ) =
(Ec 3.8)
i
k
i
para k = constante
(Ec 3.9)
1
1
=
=
Rei + R pi
RT
Ui =
1
Uei
1
=
+ U1pi
1
ei
ki
1
ei
ki
pi
kp
(Ec 3.10)
pi
kp
Se reemplazan (Ec 3.6), (Ec 3.7) y (Ec 3.8) en (Ec 3.5) y se obtiene la ecuaci n discretizada
o
de la difusi n para un volumen de control (Ec 3.11):
o
n
i=1
54
p = 0
(Ec 3.11)
3.1
IMPLEMENTACION
La (Ec 3.11) se aplicar de dos formas para dar fundamento al c digo de computador prea
o
sentado. Se presenta una manera intuitiva de tratar el problema de la difusi n y una forma
o
m s general que permite mayor exibilidad y requiere la escritura de menos lneas de c digo.
a
o
Para mostrar el proceso de difusi n se escoge un ejemplo sencillo, una placa rectangular
o
con las condiciones de frontera mostradas en la gura 15.
Figura 15: Denici n del problema de difusi n en una placa plana.
o
o
q=10000 [W/m]
T=100 [C]
1 [m]
T=200 [C]
q=0 [W/m]
0
0
2 [m]
Otros datos:
k = 50 [W/m]
q = 5000 [W/m]
El dibujo no est a escala
difusivo utilizando una malla ortogonal, de una manera rgida y posteriormente, se presenta
se usar un tama o de celda jo y, en los dos c digos que se presentan, se asume que el valor
a
n
o
de las propiedades est ubicado en el centro de la celda de la malla.
a
3.1.1
M todo intuitivo
e
En este m todo se asume que cada volumen de control es rectangular, tiene el mismo tama o
e
n
y est alineado con los ejes coordenados como se muestra en la gura 16. Se desarrolla la
a
sumatoria de (Ec 3.11) y se obtiene (Ec 3.12):
Unorte Anorte =
k
x
y
Ueste Aeste =
k
y
x
Usur Asur =
k
x
y
Uoeste Aoeste =
kx
kx
ky
ky
(TN TP ) +
(TS TP ) +
(TE TP ) +
(TW TP ) + xy q = 0
y
y
x
x
55
k
y
x
(Ec 3.12)
aw
an
as
ap
ky
x
ky
x
kx
y
kx
y
(ae + an + aw + as ) = ai
b
xy q = bgen
Cuando se presenta una condici n de frontera en el volumen de control se debe modicar los
o
coecientes de la tabla 3 de acuerdo al tipo de frontera que puede ser:
Frontera tipo Dirichlet: en este tipo de frontera se dene el valor de la temperatura en
la frontera. Los coecientes a aplicar para una frontera tipo Dirichlet se muestran en la tabla
4.
56
Se calcula
Te(wall)
adir,e =
T rminos a modicar
e
ky
x/2
aP = (adir,e + an + aw + as )
adir,n =
kx
y/2
adir,w =
ky
x/2
adir,s =
an =
b = bgen + bdir,n
aP = (ae + an + adir,w + as )
b = bgen + bdir,e
aP = (ae + adir,n + aw + as )
ae =
kx
y/2
aw =
b = bgen + bdir,w
aP = (ae + an + aw + adir,s )
as =
b = bgen + bdir,s
ujo de calor por unidad de area. El ujo de calor est relacionado con el gradiente de la
a
T
o
temperatura mediante qwall = k( xi )wall . Los coecientes para una condici n de frontera
tipo Neumann se dan en la tabla 5.
Tabla 5: Modicaci n de los coecientes debido a la condici n Neumann en la frontera.
o
o
Valor dado
T
x
T
y
T
x
T
y
e(wall)
n(wall)
w(wall)
s(wall)
Se calcula
bneu,e = k y
bneu,n = k x
bneu,w = k y
bneu,s = k x
T
x
T
y
T
x
T
y
T rminos a modicar
e
e(wall)
n(wall)
w(wall)
s(wall)
aP = (an + aw + as )
ae =
b = bgen + bneu,e
aP = (ae + aw + as )
an =
b = bgen + bneu,n
aP = (ae + an + as )
aw =
b = bgen + bneu,w
aP = (ae + an + aw )
as =
b = bgen + bneu,s
57
Por otro lado y antes de entrar en detalle en la programaci n, se debe asignar un n mero a
o
u
cada volumen de control, para realizar este trabajo se utiliza la denici n presentada en la
o
Figura 17.
(1,ny)
(nx,ny)
La posicin del punto P
se puede denir como:
(i,j+1)
3
(i-1,j)
longy
(i,j) (i+1,j)
P
(i,j-1)
(i,j)
Posicin en una matriz
como se muestra en la grca
(1,1)
(nx,1)
0
0
longx
De manera general, se necesitan los siguientes pasos para desarrollar el c digo de computao
dor:
1.
2.
3.
4.
A continuaci n se explica cada uno de los pasos necesarios para desarrollar la clase.
o
Paso 1. Declarar la clase diftemp. Al crear una clase en Visual Studio se crean por defecto dos archivos, el archivo de encabezado con el nombre de la clase de extensi n .h,
o
diftemp.h, y el archivo de c digo fuente con el nombre de la clase de extensi n .cpp,
o
o
diftemp.cpp. En el archivo de encabezado se encuentra la siguiente informaci n:
o
#pragma once
class diftemp
{
public:
diftemp(void);
58
diftemp(void);
};
1.
Crear la clase: la instrucci n #pragma once permite la optimizaci n del tiempo
o
o
59
int nx,
real dx,
real k;
public:
...
};
ny
dy
;
;
Las variables creadas son: longitud de la placa en direcci n x longx, longitud de la placa en
o
direcci n y longy, n mero de vol menes de control en direcci n x nx y en direcci n y ny,
o
u
u
o
o
espacio de memoria, o datos de tipo double, para una mayor precisi n en las operaciones.
o
2.
Agregar objetos Matriz y Vector: este tipo de objetos presenta m ltiples ventajas
u
con respecto a los vectores o matrices tradicionales en C++; para la clase Matriz, se tienen
las operaciones de suma y multiplicaci n, el determinante de la matriz, varios tipos de
o
factorizaci n, un f cil dimensionamiento del objeto, m todos de escritura y lectura, entre
o
a
e
otras funciones. Para la clase Vector se tienen, entre otras caractersticas, las operaciones
Adem s de la clase Matriz existen otros tipos de matrices, entre las que se encuentran: la
a
clase Matriz_basico que permite manejar datos que no necesiten operaciones matem ticas,
a
matrices ecientes en el uso del espacio de memoria como, matriz diagonal Matriz_Diag,
matriz bandeada Matriz_Band, matriz tridiagonal Matriz_Tri y matriz dispersa
Matriz_Dispersa.
Para usar las matrices y los vectores se debe agregar un argumento a la plantilla para denir
el tipo de datos a utilizar, por esta raz n, la declaraci n de un objeto tipo Matriz se realiza
o
o
mediante la instrucci n Matriz<tipo_dato> objeto;.
o
...
#include <Matriz.h>
#include <Vector.h>
class diftemp
{
2 Todos
60
private:
...
Matriz<real>
matriz_a;
Vector<real>
b;
Vector<real>
x;
Matriz<real>
temp;
prm_Matriz <real> pm;
public:
...
};
Se debe almacenar la informaci n para el sistema de ecuaciones lineales, por tal motivo,
o
se crea la matriz de coecientes matriz_a, el vector de t rminos independientes b y el
e
vector soluci n x. Se crea la matriz temp para un m todo alternativo3 de almacenamiento
o
e
y acceso de la informaci n del campo de temperatura en el problema. Adicionalmente
o
se crea un objeto de tipo prm_Matriz<real> para almacenar la informaci n del tipo de
o
matriz a usar, si bien es cierto que en este caso no es necesario, se recomienda su creaci n,
o
la importancia de su uso se explicar posteriormente.
a
3.
Condiciones de frontera: la informaci n del tipo de condici n de frontera en cada
o
o
lado se guarda en una cadena de caracteres de la clase Cadena, para acceder a esta clase
es necesario agregar la librera correspondiente, #include <Cadena.h>; la clase Cadena
dene operaciones de recorte trim, antes, despues, subcadena, uni n juntar, b squeda
o
u
de caracteres contiene, primercar, ultimocar, entre otras; el uso de la clase Cadena
permite un acceso m s sencillo a las operaciones con caracteres.
a
...
#include <Cadena.h>
class diftemp
{
private:
...
Cadena x0tipo,y0tipo,xfinaltipo,yfinaltipo;
public:
...
};
Se denen cuatro objetos tipo Cadena: condici n de frontera para x = 0 o el lado sur
o
x0tipo, para y = 0 o el lado oeste y0tipo, para x = longx o el lado este xfinaltipo
y para x = longy o el lado norte yfinaltipo. En cada cadena se almacenar la palabra
a
dirichlet o la palabra neumann.
3 Ver
la Figura 17.
61
4.
Administrador de ecuaciones lineales: antes de hablar acerca del administrador de
ecuaciones lineales se presenta la clase Puntero. La clase Puntero permite administrar inteligentemente el manejo de memoria din mica. Para declarar un objeto de tipo Puntero se
a
debe dar un argumento a la plantilla, Puntero<argumento_plantilla> objeto;. Por otro
lado, la clase AdmonEcLin contiene las instrucciones necesarias para resolver, por diferentes
m todos, un sistema de ecuaciones lineales ya sea directa o iterativamente. Para acceder a
e
la clase AdmonEcLin se debe agregar al encabezado #include <AdmonEcLin.h>.
...
#include <AdmonEcLin.h>
class diftemp
{
private:
...
Puntero<AdmonEcLin> admlin;
public:
...
};
Se crea un puntero inteligente admlin a un objeto AdmonEcLin para posteriormente realizar
una correcta inicializaci n.
o
5.
Par metros de control: se deben crear dos variables que permitan vericar que el
a
programa se ejecute en el orden correcto, por ejemplo, no se puede resolver un sistema de
ecuaciones que aun no ha sido denido, posteriormente se mostrar detenidamente el uso
a
de estas dos variables.
...
class diftemp
{
private:
...
bool calculado;
bool leido;
public:
...
};
En este caso, los par metros de control son variables de tipo bool, las cuales son calculado
a
y leido; el valor de las variables debe ser iniciado en false, proceso que se realiza en el
constructor mediante leido=false;calculado=false;.
Paso 3. Agregar funciones a la clase. Todas las funciones se declaran public de manera
que se puede acceder a ellas fuera de la clase; sin embargo, en algunos casos es conveniente
62
denir los m todos como private para evitar errores en la ejecuci n del programa. Se deben
e
o
agregar los siguientes m todos a la clase:
e
1.
Lectura de la informaci n: se agrega el m todo Leer el cual toma la informaci n de
o
e
o
la geometra, las particiones y el solucionador de ecuaciones para realizar la inicializaci n
o
de las variables de la clase. La funci n Leer presenta una sobrecarga la cual se dene para
o
dar un ejemplo del valor de los argumentos.
...
class diftemp
{
private:
...
public:
...
void Leer (real ancho, real alto, real divx,real divy);
void Leer (void) {Leer(1.0,1.0,20,20);}
};
Los argumentos a introducir son el ancho de la placa ancho, la altura de la placa alto , el
n mero de divisiones en el eje x divx y en el eje y divy . La versi n sobrecargada tiene
u
o
como par metros por defecto una placa cuadrada de 1x1 metro y 20 divisiones en cada
a
direcci n. El m todo se dene como void pues no es necesario entregar un valor como
o
e
resultado.
2.
Condiciones de frontera y generaci n de calor: se denen 5 funciones para las condio
ciones de frontera y la generaci n de calor dentro de la placa, est s funciones de tipo real
o
a
presentan la ventaja de poder denir el valor de acuerdo a la posici n. En el caso de las
o
unidad de longitud. Por otro lado, se encuentra la funci n q la cual devuelve el valor de la
o
generaci n de calor por unidad de volumen dependiendo de la posici n en x e y.
o
o
...
class diftemp
{
private:
...
public:
...
real condx0 (real
real condy0 (real
real condxf (real
real condyf (real
y);
x);
y);
x);
63
a
general, de manera que se pueden denir varias combinaciones de fronteras y generaci n
o
de calor.
3.
Funciones de procesamiento: se agrega una funci n que calcula los coecientes
o
del sistema de ecuaciones lineales, dicha funci n se llama calcular y no requiere de
o
par metros de funcionamiento ni devolver un valor. Despu s de realizar el llenado del sisa
e
tema de ecuaciones se debe resolver el sistema mediante la llamada a la funci n resolver
o
que no necesita par metros pero devuelve un valor booleano que indica si se logr obtener
a
o
la soluci n al sistema de ecuaciones.
o
...
class diftemp
{
private:
...
public:
...
void calcular();
bool resolver();
};
4.
Postprocesamiento: para llevar acabo esta etapa se agrega la funci n exportar que
o
se encarga de tomar los resultados del vector soluci n y generar un archivo que puede ser
o
ledo en Matlab. La funci n exportar tiene un unico argumento con el nombre del archivo
o
a crear.
...
class diftemp
{
private:
...
public:
...
void exportar(Cadena archivo);
};
La forma nal de la declaraci n de la clase se encuentra en el Anexo B.
o
64
"diftemp.h"
No es necesario incluir otras libreras en el archivo de c digo fuente debido a que la inclusi n
o
o
se realiza en el archivo diftemp.h. A continuaci n se especican algunos de los m todos
o
e
agregados a la clase.
1.
M todo Leer: la versi n de la funci n Leer con 4 argumentos est compuesta de las
e
o
o
a
siguientes etapas.
I.
Inicializaci n de la geometra: se toman los par metros de la funci n y se almaceo
a
o
nan en las variables correspondientes de la clase. De esta manera, se modica el tama o
n
de la placa longx y longy, el n mero de divisiones en cada direcci n nx y ny y el tama o
u
o
n
de un volumen de control en la direcci n x dx e y dy.
o
void diftemp::Leer (real ancho, real alto, real divx,real divy)
{
longx = ancho ; longy = alto ;
nx
= divx ; ny
= divy ;
dx
=longx/nx ; dy
= longy/ny;
...
II. Dimensionamiento y llenado de las matrices y los vectores: las variables a dimensionar son en orden respectivo: la matriz de coecientes, el vector de t rminos indepene
dientes, el vector soluci n y la matriz que almacena el valor de la temperatura. Se sugiere
o
realizar el llenado inicial de todos los vectores y las matrices pero solo es estrictamente
necesario en la matriz de coecientes matriz_a, el vector de t rminos independientes b
e
y el vector soluci n x el cual se inicia con el valor de 190.0 para disminuir el n mero de
o
u
iteraciones necesarias en el m todo de soluci n.
e
o
...
matriz_a.chaSize(nx*ny);
matriz_a.llenar(0.0);
b.chaSize(nx*ny);
b.llenar(0.0);
x.chaSize(nx*ny);
x.llenar(190.0);
temp.chaSize(nx,ny);
temp.llenar(0.0);
...
III. Selecci n del tipo de frontera: se escribe una cadena de texto con los dos tipos de
o
frontera m s comunes. Para el tipo de frontera dirichlet se da el valor de la propiedad
a
en la supercie; en cambio, para la frontera neumann se da el gradiente de la propiedad
en direcci n normal a la supercie, en el caso que la propiedad es la temperatura, dicho
o
gradiente es proporcional al ujo de calor.
65
...
x0tipo = "dirichlet";
y0tipo = "neumann";
...
xfinaltipo = "dirichlet";
yfinaltipo = "neumann";
IV. Denir las propiedades del material: solo es necesario denir la conductividad
t rmica del material.
e
...
k = 50;
...
V.
Inicializar el administrador de ecuaciones lineales: para que el proceso sea general,
es conveniente leer la informaci n del m todo de soluci n en un archivo de texto llao
e
o
4 contiene tres partes, la informaci n de la matriz, la
mado solve_datos.txt. El archivo
o
informaci n del m todo de soluci n y la informaci n de los precondicionadores.
o
e
o
o
Parametros de la matriz (clase prmMatriz);
>guarda = Matriz;
>guarda_sim = FALSE
>pivoteo = FALSE
>umbral =0.0
prm_solucionEcLin parametros:
>solver_classname=Orthomin
>metodo=R-OM(7)
>cambiar=0.0
>pivoteo=NO_PIVOT
>relajacion=1.2
>startvector=USER_START
>criterio_def=TRUE
>nextern_crit=0
>maxit=1000
>estimate_eigvals=FALSE
Parametros del precondiciondor:
>precondicionador=PrecIdentidad
>left_prec=TRUE
>auto_iniciar=TRUE
>nivel_llenado=0
>prec_RILU=1
>prec_SSOR=1
>pasos_int=1
4 La
informaci n que debe contener el archivo mostrado hace parte del uso de las libreras, no se har un
o
a
an lisis detallado de esa informaci n en este proyecto.
a
o
66
Para leer el archivo de texto es necesario crear un objeto de tipo Is. Seguidamente, se
leen los par metros de la matriz con el objeto de tipo prm_Matriz, se inicia el puntero
a
inteligente admlin con un nuevo objeto de la clase AdmonEcLin y se leen los par metros
a
correspondientes al m todo de soluci n y al precondicionador.
e
o
...
Is is("ARCH=solve_datos.txt");
pm.Leer ( is );
admlin.vincular(new AdmonEcLin(EXTERNAL_STORAGE));
admlin().Leer(is);
...
VI. Asignar el valor a la bandera: nalmente se debe asignar true para reconocer que
el programa ya ejecut este procedimiento y por lo tanto puede seguir con el siguiente
o
paso.
..
leido=true;//bandera
}
2.
Condiciones de frontera y generaci n de calor: la denici n de las funciones es relao
o
tivamente sencilla por lo que no se hace una explicaci n adicional de estas funciones:
o
real
real
real
real
real
3.
M todo Calcular: para calcular los coecientes del sistema de ecuaciones lineales
e
se requieren los siguientes pasos.
I.
Vericaci n del par metro de control: antes de realizar cualquier proceso, se debe
o
a
vericar que el c digo ha sido ejecutado de la manera correcta, es por esto que se debe
o
vericar el valor de la bandera leido.
void diftemp::calcular()
{
if (leido==false)
{ Leer( ); std_o<<"Advertencia: posible error en la ejecucion"; }
if (calculado== true)
{std_o<<"Ya se habia calculado los coeficientes\n"<<
"POSIBLES ERRORES EN LOS RESULTADOS\n";}
...
67
IV. Asignaci n del efecto este-oeste en la frontera oeste: lo primero que se debe hacer
o
es vericar el tipo de frontera, en este caso, si no corresponde al tipo de frontera dirichlet
corresponder a la frontera tipo neumann. Los subndices usados en la matriz de coea
B.
...
for(j=1;j<=ny;j++)
{
if(x0tipo.contiene("diri") || x0tipo.contiene("Diri"))
{
matriz_a( (j-1)*nx+1, (j-1)*nx+1) -= 3.0*k/dxsy;
matriz_a( (j-1)*nx+1, (j-1)*nx+2)
= 1.0*k/dxsy;
b( (j-1)*nx+1 ) += - condx0( (j-0.5)*dy ) * 2.0*k/dxsy;
}
...
Para la condici n de frontera neumann: se tienen en cuenta los valores presentados
o
en la tabla 5. Se asigna el valor correspondiente al volumen actual, el volumen este
V.
Asignaci n del efecto este-oeste en la zona central: en este caso no se tiene en
o
cuenta las condiciones de frontera y el valor de los coecientes se extrae de la tabla 3.
...
for(i=2;i<=nx-1;i++)
{
for(j=1;j<=ny;j++)
{
matriz_a((j-1)*nx+i , (j-1)*nx+i )
matriz_a((j-1)*nx+i, (j-1)*nx+i+1)
matriz_a((j-1)*nx+i, (j-1)*nx+i-1)
}
}
...
-= 2.0*k/dxsy;//nodo actual
= 1.0*k/dxsy;//nodo east
= 1.0*k/dxsy;//nodo west
VI. Asignaci n del efecto este-oeste en la frontera este: los coecientes se toman de las
o
tablas 4 y 5.
...
for(j=1;j<=ny;j++)
{
if(xfinaltipo.contiene("diri") || xfinaltipo.contiene("Diri"))
{
69
matriz_a(
matriz_a(
b
(
}
else
{
matriz_a(
matriz_a(
b( j*nx
}
}
...
j*nx, j*nx
)
j*nx, j*nx-1 )
j*nx )
-= 3.0*k/dxsy;
= 1.0*k/dxsy;
-= condxf( (j-0.5)*dy )*2.0*k/dxsy;
j*nx , j*nx
) -= k/dxsy;
j*nx , j*nx-1 ) = k/dxsy;
) -= k*dy*condxf ( (j-0.5)*dy ) ;
VII. Asignaci n del efecto norte-sur: se procede de una forma similar al paso anterior.
o
...
for(i=1;i<=nx;i++)
{
if(y0tipo.contiene("Diri") ||y0tipo.contiene("diri"))
{
matriz_a( i, i
) -= 3.0*k*dxsy;
matriz_a( i, i+nx ) = 1.0*k*dxsy;
b( i ) -= condy0( (i-0.5)*dx ) * 2.0*k*dxsy;
}
else
{
matriz_a(i,
i) -= k*dxsy ;
matriz_a(i, i+nx)
= k*dxsy;
b ( i )
-= k*dx*condy0 ( (i-0.5)*dx ) ;
}
}
for(i=1;i<=nx;i++)
{
for(j=2;j<=ny-1;j++)
{
matriz_a((j-1)*nx+i , (j-1)*nx+i) -= 2.0*k*dxsy;
matriz_a((j-1)*nx+i , (j-0)*nx+i) = 1.0*k*dxsy;
matriz_a((j-1)*nx+i , (j-2)*nx+i) = 1.0*k*dxsy;
}
}
for(i=1;i<=nx;i++)
{
if(yfinaltipo.contiene("Diri") ||yfinaltipo.contiene("diri"))
{
70
calcular( ); }
II. Soluci n de las ecuaciones: para resolver el sistema de ecuaciones se debe indicar
o
al administrador de ecuaciones lineales admlin() cu l es la matriz de coecientes, el
a
vector soluci n y el vector de t rminos independientes. Una vez realizado esto, se llama
o
e
a la funci n solve()de admlin() que devuelve un valor de tipo bool el cual es true si
o
fue encontrada la soluci n o false si el sistema no pudo llegar a la soluci n.
o
o
...
admlin().adjuntar(matriz_a,x,b);
bool solucion=admlin().solve();
...
71
...
for( int i=1 ; i<=nx ; i++)
for( int j=1 ; j<=ny ; j++)
temp(i,j)=x( (j-1)*nx + i );
...
IV. Finalmente se devuelve el valor booleano que permite conocer si se ha encontrado
la soluci n al problema o no.
o
...
return solucion;
}
5.
Etapa de post-procesamiento, exportar: los resultados ser n guardados en un archivo
a
.m el cual puede ser ledo por Matlab. De manera general, se crean dos vectores que con
tienen la posici n del centro de los volumenes de control en cada direcci n, se genera una
o
o
matriz con el campo de temperaturas, se genera una gr ca y se guarda la informaci n en
a
o
el archivo.
void diftemp::exportar ( Cadena archivo) //public
{
int i,j;
Os exportar(archivo);
exportar << "%Difusion con termino fuente\n" ;
exportar << "clear";
exportar << "\n%Mallado: " << aform(
"d=2 dominio = [0,%10g]x[0,%10g] indices= [1: %5d]x[1:%5d]",
longx , longy , nx , ny )<<"\n\n";
exportar << "Posicion x,Px=zeros(1,"<<nx<<");\n" ;
exportar << "Px=["<< 0.5*dx;
for(i=2;i<=nx;i++)
exportar << "," << (i-0.5)*dx;
exportar << "];\n";
exportar << "Posicion y,Py=zeros(1,"<< ny<<");\n";
exportar <<"Py=["<< 0.5*dy;
for(j=2;j<=ny;j++)
exportar << "," << (j-0.5)*dy;
exportar << "];\n";
exportar << "\nTemperatura,temp=zeros(" << ny << "," << nx <<");\n" ;
for(j=1;j<=ny;j++)
{
exportar << "temp("<<j<<",:)=[" << temp(1,j);
for(i=2;i<=nx;i++) exportar << "," << temp(i,j);
exportar << "];\n";
72
}
exportar<< "\nfigure(1); surf(Px,Py,temp);%hold on;\n"<<
"title(Temperatura)\n"
<<"xlabel(Eje x[m]);ylabel(Eje y [m]);\n";
exportar->actualizar(); exportar->cerrar();
}
Paso 5. Creaci n de un objeto de la clase diftemp. Es necesario incluir la librera creada
o
mediante comillas porque se encuentra en el directorio del proyecto. Dentro del cuerpo
principal del programa, se encuentra la funci n main(). Inicialmente, dentro de la funci n
o
o
main() debe llamarse a la funci n iniciarLIB para una correcta inicializaci n del sistema.
o
o
Despu s, se crea un objeto de la clase diftemp, se ejecuta la funci n Leer(2.0,1.0,6,10)
e
o
en donde los valores dados son el tama o de la placa y el n mero de particiones en cada
n
u
direcci n. Posteriormente, se llama a la funci n calcular() y luego resolver(). Fio
o
nalmente, se llama a la funci n exportar con el argumento ARCH=difusion_6_10.m
o
en donde difusion_6_10.m es el nombre del archivo a crear. En algunos casos puede ser
recomendable imprimir un valor en la pantalla para conocer el estado de ejecuci n del proo
grama adem s de introducir una funci n que permita mantener en pantalla la informaci n por
a
o
o
un tiempo determinado o hasta realizar una acci n determinada, por tal motivo, se realiza una
o
salida en pantalla mediante el std_o y se utiliza system("pause") (denido en stdlib.h)
bloqueando la pantalla hasta que se oprima cualquier tecla. El c digo nal se muestra a
o
continuaci n:
o
#include "stdafx.h"
#include <stdlib.h>
#include "diftemp.h"
int main(int argc,const char ** argv)
{
iniciarLIB(argc,argv);
diftemp difusivo;
difusivo.Leer(2.0,1.0,6,10);
difusivo.calcular();
difusivo.resolver();
difusivo.exportar("ARCH=difusion_6_10.m");
std_o<<"Hecho";
system("pause");
}
Al abrir y ejecutar el archivo difusion_6_10.m en Matlab se obtiene la gura 19 con el
comando surf que muestra el valor de la temperatura en el centro de cada volumen de control
adem s de mostrar el tama o de la placa.
a
n
73
0.8
280
0.7
260
Eje y [m]
0.6
0.5
240
0.4
220
0.3
200
0.2
180
0.1
160
0.5
1
Eje x[m]
1.5
Tabla 6: Valor del campo de temperatura para el problema propuesto al usar la clase diftemp.
Nodo
1
2
3
4
5
6
7
8
9
10
1
182,160
182,733
183,915
185,783
188,468
192,181
197,256
204,218
213,902
227,650
2
229,001
230,327
233,018
237,153
242,856
250,296
259,690
271,302
285,430
302,379
3
250,005
251,647
254,958
259,995
266,839
275,593
286,375
299,310
314,516
332,091
4
241,672
243,313
246,625
251,662
258,506
267,260
278,042
290,976
306,182
323,757
5
204,001
205,327
208,018
212,153
217,856
225,296
234,690
246,302
260,430
277,379
6
140,494
141,067
142,249
144,116
146,801
150,514
155,590
162,552
172,235
185,984
3.1.2
aP
Ui Ai
ae
q p = bgen
i=1
Se calcula
Dirichlet
adir,i =
Neumann
aneu,i = 0
ki
i
Sumar a
aP
Ai
Sumar a
b
adir,i
bdir,i
bneu,i
T
ni (wall)
nbc
i=1
ai +
bc
ab,i
(Ec 3.13)
i=1
bn
bc
i=1
i=1
i=1
75
(Ec 3.14)
Para obtener los valores de (Ec 3.13) y (Ec 3.14) se debe remitir a diferentes tablas y ecuaciones como se resume en la tabla 9.
Tabla 9: Resumen de los coecientes necesarios para aplicar la ecuaci n de difusi n (Ec
o
o
3.11) a cada volumen de control.
Variable a calcular
Ui
ae , bgen
adir,i , bdir,i
aneu,i , bneu,i
ab,i bb,i
Ecuaci n o tabla
o
(Ec 3.10)
Tabla 7
Tabla 8
Para desarrollar el c digo a partir del m todo presentado en esta secci n se hace uso de las
o
e
o
libreras de mallado, soluci n de ecuaciones, exportaci n de resultados a Paraview, entre
o
o
otras. Para la creaci n de la clase se tiene en cuenta los siguientes pasos:
o
1.
2.
3.
4.
5.
Los pasos generales son los mismos pero, la implementaci n de algunas secciones del c digo
o
o
son bastantes diferentes.
Paso 1. Declarar la clase diffgeneral. Se crea una clase llamada diffgeneral que
contiene inicialmente la siguiente informaci n en el archivo de encabezado.
o
#pragma once
class diffgeneral
{
public:
diffgeneral(void);
diffgeneral(void);
};
Se realizar n modicaciones al archivo de encabezado (diffgeneral.h) hasta denir todos
a
los elementos necesarios. En un primer paso es necesario denir la clase como una clase
derivada de GuardarEnsight para hacer uso de las funciones que permitir n realizar el rea
porte de los resultados de una forma muy sencilla.
76
...
#include <GuardarEnsight.h>
class diffgeneral:public GuardarEnsight
{
public:
diffgeneral(void);
diffgeneral(void);
};
Paso 2. Agregar las variables a la clase diffgeneral. Las variables necesarias se dividen
en dos grupos:
1.
Variables correspondients a la malla, c lculo de la geometra, conectividad y campo
a
tipo VecinoFVM el cual ayuda a calcular los elementos que rodean a cada volumen de control en la malla. Finalmente se declara el campo de temperatura llamado Temperatura del
tipo Puntero<CampoFVM> en el cual se asignar los valores obtenidos del vector soluci n;
a
o
para realizar este proceso es necesario declarar Puntero<GradoLibertadFV> gdl como
ayuda para realizar una correcta conversi n de la informaci n.
o
o
Es necesario declarar varias libreras para acceder a las clases como se muestra en el si
guiente c digo:
o
//Archivo diffgeneral.h
...
#include <MallaFV.h>
#include <ConstOLeemalla.h>
#include <GradoLibertadFV.h>
class diffgeneral:public GuardarEnsight
{
private:
Puntero<MallaFV> malla;
Vector_basico <PunteroElmDefs> elems;
VecinoFVM vecino;
Puntero<CampoFVM>
Temperatura;
Puntero<GradoLibertadFV> gdl;
public:
...
};
2.
Variables correspondientes al sistema de ecuaciones, su soluci n y los par metros de
o
a
control, se muestran en el siguiente fragmento de c digo:
o
77
...
#include <AdmonEcLin.h>
class diffgeneral:public GuardarEnsight
{
private:
...
int nelementos ;
Vector<real>
k;
Matriz<real>
matriz_a;
prm_Matriz <real> pm;
Vector<real>
b;
Vector<real>
x;
Puntero<AdmonEcLin> admlin;
bool calculado;
bool leido;
bool solucionado;
public:
...
};
Las variables creadas son: el n mero de vol menes de control, nelementos, la conducu
u
tividad t rmica denida como un vector, k, la matriz de coecientes, matriz_a, el vector
e
de t rminos independientes, b, el vector soluci n, x, el puntero del administrador de ecuae
o
ciones lineales (es necesario incluir AdmonEcLin.h para acceder a la clase del administrador de ecuaciones lineales) y nalmente tres par metros de control: calculado, leido y
a
solucionado.
Paso 3. Agregar los m todos a la clase. Ya no es necesario denir las condiciones de
e
frontera como funciones porque la informaci n de estas se escribir en un archivo de texto.
o
a
Las funciones a agregar son:
...
class diffgeneral:public GuardarEnsight
{
private:
...
public:
...
int Leer (Cadena archivo);
int calcular();
bool resolver();
virtual void Reportarresultados();
real q (real x, real y);
};
78
Para Leer, los argumentos son dos cadenas de texto que contienen las direcciones de dos
archivos, como posteriormente se explicar . Se crea la funci n calcular que no toma par a
o
a
metros y devuelve un valor entero. Por otro lado, se encuentra la funci n resolver que
o
devuelve un valor bool indicando si se encontr la soluci n para el sistema de ecuacioo
o
nes. El m todo encargado de exportar los resultados para ser visualizados en Paraview es
e
Reportarresultados() el cual se declara como virtual para permitir que sea redenida
en clases derivadas. La generaci n de calor se dene como una funci n dependiente de la
o
o
posici n.
o
La declaraci n completa de la clase diffgeneral se encuentra en el anexo D.
o
Paso 4. Implementaci n de las funciones. A continuaci n se presenta la denici n de cada
o
o
o
una de las funciones y algunos comentarios del proceso realizado en el archivo de c digo
o
fuente diffgeneral.cpp.
1.
Constructor y destructor: no es necesario denir el constructor y el destructor en el
archivo de encabezado. Para el constructor se asigna el valor de false a los tres par metros
a
de control. No se realizan procesos adicionales a la liberaci n de memoria al llamar al
o
destructor de la clase diffgeneral.
#include "diffgeneral.h"
diffgeneral::diffgeneral(void)
{
calculado = leido = solucionado = false;
}
diffgeneral::diffgeneral(void) { }
...
2.
Funci n Leer: solo se dene la funci n diffgeneral::Leer(Cadena archivo,
o
o
Cadena solucionador) en donde archivo y solucionador contienen cada uno un nombre de un archivo.
I.
Denici n y declaraci n de variables: es necesario crear una variable de tipo static
o
o
const char que contiene dos cadenas indispensables para obtener el comando correcto
para crear la malla. Se crea una Cadena para obtener el argumento y se crea un objeto de
tipo Is para leer un archivo.
...
static const char *mallador_tb[] = {"mallador", NULL};
Cadena cadmalla;
Is is(archivo);
...
Un ejemplo del contenido del archivo a leer es el siguiente:
79
> nsd = 2;
> subdominios = 1;
> no_de_superels = 1;
>nbind = 4
>bname T=100 T=150 Q=10000 Q=0
>SupEl;
>subdominio_no = 1;
>tipoelemento = ElmB4n2D;
>fronteras = [1(1)] [3 (2)] [2 (3)] [4(4)];
>nodos = [1(0 0)]+[2(2 0)]+[3(0 1)]+[4(2 1)];
>lados=;
En cambio, el archivo datos_difusion.parts contiene el n mero de particiones a reu
alizar en cada superelemento y el tipo de partici n.
o
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[6,10];>grad=[1,1];
Las estructuras que forman estos archivos hacen parte de las libreras, y por lo tanto, en
IV. Creaci n del campo de temperaturas: debido a que Temperatura y gdl fueron
o
declaradas como instancias de la clase Puntero se realizan las siguientes dos inicializaciones.
...
Temperatura.vincular(new CampoFVM(malla(),"Temperatura"));
gdl.vincular(new GradoLibertadFV(malla(),1));
...
El valor 1 en GradoLibertadFV(malla(),1) implica que en cada volumen de control
existe un solo grado de libertad o inc gnita.
o
V.
Dimensionalizaci n de los vectores y las matrices: se obtiene el n mero de vol menes
o
u
u
de control, se dimensionan e inicializan los siguientes elementos.
...
nelementos=malla->obtNoElem();
matriz_a.chaSize(nelementos, nelementos); matriz_a.llenar(0.0);
b.chaSize(nelementos); b.llenar(0.0);
x.chaSize(nelementos); x.llenar(90.0);
k.chaSize(nelementos); k.llenar(50);
elems.chaSize(nelementos);
for (int i=1; i<=nelementos;i++)
{
elems(i).refill( malla->obtTipoElem(i), malla->obtNoDimEspacio() );
elems(i)->CalcGeomParameters( malla->obtCoorElem(i) );
}
...
VI. Inicializaci n del administrador de ecuaciones lineales: el proceso se realiza de la
o
misma forma como se haba mostrado en la p gina 67.
a
...
Is solucionador("ARCH=Solve_datos.txt");
pm.Leer ( solucionador );
admlin.vincular(new AdmonEcLin(EXTERNAL_STORAGE));
admlin().Leer(solucionador);
...
VII. Actualizaci n del par metro de control y valor de retorno: se actualiza el valor de
o
a
leido indicando que el proceso ha sido realizado. Se devuelve el valor 1 para dar a
conocer que la funci n se ejecut exitosamente.
o
o
...
leido=true;
return 1;
}
81
3.
Funci n calcular: para calcular los coecientes del sistema de ecuaciones se reo
quiere, de forma general, los siguientes pasos.
I.
Vericaci n de los par metros de control: si no se ha cargado los datos de entrada
o
a
mediante Leer no se ejecuta la asignaci n de coecientes, por otro lado, si ya se haba
o
{
conxvec=elems(veci)->GetNumOfConex();
for ( l=1 ; l<=conxvec ; l++ )
{
if(malla->getConx(veci,l)==i)
break;
}
u1=k(i)/elems(i)->getDelta(j);
u2=k(veci)/elems(veci)->getDelta(l);
ut=1.0 / ( (1.0/u1)+ (1.0/u2) );
matriz_a( i, i ) -= ut* elems(i)->getArea(j);
matriz_a( i,veci) = ut* elems(i)->getArea(j);
}
else //lado frontera
{
for (h=1; h<=nbi; h++)
{
if (malla->LadoFront(i,j,h,elems(i)()))
{
boname=malla->obtNombreIndFront(h);
bovalue=boname.despues(=);
valor=atof(bovalue.carts());
if ( boname.contiene("T") ||
boname.contiene("Dirichlet")||
boname.contiene("dirichlet")
)
{
ut = k(i)/elems(i)->getDelta(j);
matriz_a(i,i)
-= ut * elems(i)->getArea(j);
b(i) -= ut * elems(i)->getArea(j)*valor;
}
else
{
if (boname.contiene("Neumann")||
boname.contiene("neumann") )
{
b(i)
-= valor * k(i) * elems(i)->getArea(j);
}
if (boname.contiene("Q"))
{
b(i)
-= valor * elems(i)->getArea(j);
}
}
}
83
}
}
}
};
...
IV. Se modica el valor de la bandera y se entrega un valor de retorno: se modica
el valor de calculado para poder continuar correctamente con el siguiente proceso.
Tambi n se devuelve el valor 1 para indicar que el proceso se ejecut correctamente.
e
o
...
calculado=true;
return 1;
}
4.
Funci n resolver: adem s de resolver el sistema de ecuaciones, se presenta la ino
a
formaci n del n mero de iteraciones y tiempo de soluci n en pantalla y, se entrega un
o
u
o
booleano como resultado; es necesario pasar la informaci n contenida en el vector soluci n
o
o
x al campo de temperatura Temperatura(), este trabajo es realizado mediante una funci n
o
de la clase GradoLibertadFV llamada vector2campo.
bool diffgeneral::resolver()
{
if(calculado==false) calcular();
admlin().adjuntar(matriz_a,x,b);
bool solucion=admlin().solve();
int itera; bool conv;
admlin().obtEstadisticas(itera, conv);
std_o<<"iteraciones="<<itera<<"\nTiempo"<<
admlin().obttiempoCPUsolve() ;
if (conv==1) std_o<<"\nEl sistema si convergio";
gdl->vector2campo(x,Temperatura());
solucionado=true;
return solucion;
}
5.
Funci n Reportarresultados: se verica el par metro de control y se llama a la
o
a
funci n volcar la cual se dene en la clase base GuardarEnsight.
o
void diffgeneral::Reportarresultados()
{
if(solucionado == false) resolver();
volcar(Temperatura(),0);
}
84
1
182.156
7
182.729
13
183.911
19
185.778
25
188.463
31
192.176
37
197.251
43
204.213
49
213.897
55
227.645
2
228.99
8
230.315
14
233.006
20
237.141
26
242.844
32
250.284
38
259.677
44
271.289
50
285.417
56
302.366
3
249.991
9
251.632
15
254.943
21
259.981
27
266.825
33
275.578
39
286.36
45
299.294
51
314.5
57
332.075
85
4
241.658
10
243.299
16
246.61
22
251.647
28
258.492
34
267.245
40
278.027
46
290.961
52
306.167
58
323.742
5
203.99
11
205.315
17
208.006
23
212.141
29
217.844
35
225.284
41
234.677
47
246.289
53
260.417
59
277.366
6
140.488
12
141.061
18
142.243
24
144.11
30
146.795
36
150.508
42
155.584
48
162.545
54
172.229
60
185.977
3.2
RESULTADOS
Figura 21: Variaci n del n mero de vol menes de control para diffgeneral.
o
u
u
En la gura 21 se muestran los resultados del problema planteado utilizando una instancia
de diffgeneral para varios n meros de vol menes de control. Como ejemplo, para obtener
u
u
la gr ca de 3600 vol menes de control es necesario modicar las divisiones en el archivo
a
u
datos_difusion.parts:
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[60,60];>grad=[1,1];
86
Paraview ofrece varios ltros que pueden ser muy utiles para analizar los datos encontrados.
Para el problema resuelto, se muestran las lneas isot rmicas (Figura 22) junto con la tempe
e
ratura m xima en la placa. Para lograr esto, se convirtieron los datos de celda a datos de punto
a
con Cell Data to Point Data y se aplic Contour,para visualizar el punto de m xima temo
a
peratura se reordenaron los datos de mayor a menor temperatura en Spreadsheet View.
Figura 22: Lneas isot rmicas para el problema de la difusi n.
e
o
87
4. FLUJO DIFUSIVO-CONVECTIVO
En este captulo se tratar el problema del ujo difusivo-convectivo que se muestra en (Ec 4.1)
a
asumiendo la condici n de estado estable en la ecuaci n diferencial general de la mec nica
o
o
a
de uidos (Ec 1.5).
( V ) = (
) + S
(Ec 4.1)
En esta ecuaci n se tiene en cuenta el movimiento del uido, adem s, se asumir que se
o
a
a
conoce el perl de velocidad del uido por lo que se debe hallar solamente el valor de la
propiedad en cada volumen de control. De nuevo, por la familiaridad en el concepto de
la temperatura, se tomar = T pero el proceso que se muestra puede ser generalizado a
a
cualquier variable que cumpla la (Ec 4.1).
Se reescribe la (Ec 4.1) en t rminos de la temperatura (Ec 4.2).
e
( V T ) =
k
Cp
T)+
q
Cp
(Ec 4.2)
k
Cp
q
dV
Cp
T ) dV +
k
( T n) dA +
Cp
q
dV
Cp
(Ec 4.3)
La (Ec 4.3) debe ser discretizada para cada volumen de control. Ya se ha presentado la
discretizaci n del t rmino difusivo (Ec 3.7) y del t rmino fuente (Ec 3.6). Ahora se muestra
o
e
e
la discretizaci n del t rmino convectivo, el cual se transforma en la sumatoria mostrada en
o
e
(Ec 4.4) en donde Vnl es la velocidad normal al lado l.
T (V n) dA
[l Tl Vnl Sl ]
(Ec 4.4)
l=1
Se reemplaza en la (Ec 4.3) las ecuaciones (Ec 3.6), (Ec 3.7) y (Ec 4.4) obteniendo la ecuaci n
o
discretizada de la convecci n-difusi n en estado estable (Ec 4.5).
o
o
n
l=1
l=1
[l Tl Vnl Sl ] =
Tvecino Tp
kl
q
Sl
+
p
Cp
l
Cp
88
(Ec 4.5)
4.1
ESQUEMA DE APROXIMACION
Se denen dos variables que permiten ver m s claramente el efecto convectivo y el efecto
a
difusivo en la (Ec 4.5).
S (k/C p ) S
(Ec 4.6)
=
Se debe tener en cuenta en (Ec 4.6) que Vn ser positiva o negativa si el ujo est respectia
a
vamente entrando o saliendo del volumen de control, por tal motivo, F puede ser positivo o
negativo. Por otro lado, D siempre ser positivo. Se reemplazan las deniciones de (Ec 4.6)
a
en (Ec 4.5) y se obtiene (Ec 4.7):
F = Vn S
[Fl Tl ] =
l=1
D=
(Ec 4.7)
l=1
Dependiendo del esquema que se use, el valor de Tl cambiar . Para determinar la dependencia
a
del nodo actual o el nodo vecino se debe denir el n mero adimensional de Peclet (Ec 4.8)
u
que relaciona el efecto de la convecci n con el efecto de la difusi n.
o
o
Pe =
4.1.1
F
D
(Ec 4.8)
Interpolaci n aguas-arriba
o
Para asignar el valor de Tl se debe tener en cuenta la denici n general del esquema UDS (Ec
o
2.6) que, se reescribe en t rminos de F:
e
Tl =
TP
si F 0
Tvecino si F < 0
(Ec 4.9)
Para cumplir la (Ec 4.9) se hace uso de la funci n m ximo como se muestra en (Ec 4.10).
o
a
Fl Tl = max( 0, Fl )TP max( 0, Fl )Tvecino
(Ec 4.10)
La siguiente ecuaci n es el resultado de aplicar (Ec 4.10) y reordenar los t rminos en funci n
o
e
o
de TP y Tvecino :
n
l=1
l=1
l=1
l=1
1.
Para la condici n de frontera tipo Dirichlet (se conoce la temperatura en la frontera)
o
se aplica (Ec 4.12) en donde el t rmino bd es el n mero de condiciones de frontera tipo
e
u
Dirichlet existentes.
nbd
l=1
l=1
bd
(Ec 4.12)
2.
Para la condici n de frontera tipo Neumann (se conoce la derivada parcial en la suo
percie) se debe reemplazar el valor directamente en (Ec 4.3), nalmente se obtiene (Ec
4.13) en donde bn es el n mero de fronteras tipo Neumann existentes:
u
nbn
bn
l=1
l=1
nbn
bn
4.1.2
h=1
(Ec 4.13)
Se hace uso de la funci n A(Pe, metodo ) para adaptar f cilmente el m todo de an lisis
o
a
e
a
a diferentes tipos de esquemas, el valor de A(Pe, metodo ) se muestra en la tabla 11 y se
reemplaza en la (Ec 4.11), (Ec 4.12) y (Ec 4.13).
Tabla 11: Funci n A(Pe)
o
Equema
Upwind (UDS)
Diferencia centrada (CDS)
Hibrido
Power law
Funcion A(Pe)
1
1 0.5|Pe|
max(0, 1 0.5|Pe|)
max(0, (1 0.1|Pe|5 ))
|Pe|
|Pe| 1
e
Exponencial
El esquema UDS de primer orden presenta la desventaja de generar una falsa difusi n, es
o
decir, el m todo suaviza el gradiente del campo de temperatura calculado, este proceso se
e
evidencia m s cuando el ujo no es paralelo a la malla. El m todo CDS de O (x2 ) es inesa
e
table para |Pe| > 2 pero para menores valores de Peclet el error de la soluci n es menor que
o
el m todo UDS. El esquema hbrido aprovecha la ventaja de la estabilidad del m todo UDS
e
e
para altos valores de Peclet y la precisi n del m todo CDS para peque os valores de Peclet.
o
e
n
Los esquemas power law y exponencial proporcionan soluciones m s precisas para el caso
a
90
unidimensional pero, para situaciones de 2D y 3D no son tan exactos adem s de su alto costo
a
computacional para calcular los coecientes.
4.2
IMPLEMENTACION
Para desarrollar el c digo de computador del problema propuesto, se debe denir una ecuaci n
o
o
que tenga en cuenta los dos tipos de condiciones de frontera de forma general. La ecuaci n
o
de difusi n-convecci n se puede denir como:
o
o
a p Tp
En donde
ap =
nnb
[ae Te] = b
nnb
nb
e=1
j=1
1 FERZIGER,
p. 83.
(Ec 4.14)
e=1
(Ec 4.15a)
(Ec 4.15b)
J.H y PERIC, M. Computational Methods for Fluids Dynamics, 3 ed. Berln: Springer,2002.
91
ab, j =
Fj
nb
b = bgen + [bb, j ]
(Ec 4.15d)
j=1
bgen = (
bb, j =
q
) p
Cp
(Ec 4.15e)
( T )wall S j k
n
2.
3.
4.
Paso 1. Declarar la clase convdiff y agregar las variables: la clase convdiff es una clase
derivada de GuardarEnsight por lo que se declara de la siguiente forma:
#pragma once
#include <MallaFV.h>
#include <ConstOLeemalla.h>
#include <AdmonEcLin.h>
#include <GuardarEnsight.h>
#include <GradoLibertadFV.h>
class convdiff:public GuardarEnsight
{
real longx,longy ;
int nelementos ;
Puntero<MallaFV> malla;
Vector_basico <PunteroElmDefs> elems;
VecinoFVM vecino;
Puntero<CamposFVM> campo_vel;
Puntero<CampoFVM>
Temperatura;
92
Puntero<GradoLibertadFV> gdl;
Matriz<real>
matriz_a;
Vector<real>
b;
Vector<real>
x;
Vector<real>
u;
Vector<real>
v;
Vector<real>
k;
Vector<real>
rho;
Vector<real>
C_p;
real pe_min ;
real pe_max ;
Puntero<AdmonEcLin> admlin;
prm_Matriz <real> pm;
bool calculado;
bool leido;
bool solucionado;
bool primer_peclet;
...
Se destaca, entre otras variables, la creaci n de campo_vel de tipo Puntero<CamposFVM>
o
en la cual se almacena la informaci n a ser exportada del campo vectorial de la velocidad.
o
Se dene la densidad del material rho, la velocidad u en direcci n x y la velocidad v en
o
direcci n y. Adem s se denen pe_min y pe_max de tipo real para almacenar el valor del
o
a
peclet mnimo y el peclet m ximo, el par metro adimensional peclet es muy importante en
a
a
el an lisis de la convecci n-difusi n. Se dene el par metro de control primer_peclet para
a
o
o
a
ayudar en el c lculo del peclet mnimo y m ximo.
a
a
Paso 2. Agregar los m todos a la clase. Adem s de denir el constructor convdiff(void),
e
a
el destructor convdiff(void), el m todo de lectura de datos Leer (Cadena problema,
e
Cadena solucionador), el m todo de c lculo de coecientes Calcular(), el m todo
e
a
e
para resolver las ecuaciones Resolver() y el reporte de resultados a Paraview
Reportarresultados(), se denen las funciones difusion(...), conveccion(...),
peclet(...), peclet_min(), peclet_max() y funcion_a(...).
...
public:
convdiff(void) {primer_peclet=true; calculado=false; leido=false;}
convdiff(void);
int Leer (Cadena problema, Cadena solucionador);
int Calcular();
bool Resolver();
real funcion_a ( real pe, Cadena modo);
real difusion(int vol1, int dir1, int vol2, int dir2, real area);
real difusion(int vol1, int dir1, real area);
93
a
peclet_max() para tener acceso al valor del peclet fuera del objeto.
Paso 3. Denici n de las funciones. Para resolver el problema de la difusi n-convecci n
o
o
o
propuesto se especic el siguiente procedimiento en cada una de las funciones:
o
1.
Funci n Leer: esta funci n toma como argumentos dos cadenas de caracteres que
o
o
contienen las direcciones de archivo de los par metros del problema y los par metros del
a
a
m todo de soluci n:
e
o
int convdiff::Leer(Cadena problema, Cadena solucionador)
{
...
Se leen los par metros de la malla y se calcula la conectividad entre los vol menes de la
a
u
2
misma forma como se explic en el captulo anterior.
o
...
static const char *mallador_tb[] = {"mallador", NULL};
Cadena cadmalla;
Is is(problema);
is->obtComando(cadmalla,mallador_tb);
malla.vincular(new MallaFV());
ConstOLeeMalla(malla(),cadmalla);
vecino.iniciar(malla());
malla->CalcConectividad(vecino);
...
Para asignar el valor de la temperatura en la frontera oeste, que es una funci n de la
o
posici n, se debe calcular el tama o de la regi n a trabajar para realizar un correcto eso
n
o
calado del valor de la temperatura.
2 Ver
secci n 3.1.2
o
94
...
nelementos=malla->obtNoElem();
Vector_xyz <real> min,max;
malla->obtCoorMinMax(min,max);
longx=max(1)-min(1);
longy=max(2)-min(2);
...
Se dimensionan y asignan valores a los vectores y las matrices a usar.
...
matriz_a.chaSize(nelementos, nelementos); matriz_a.llenar(0.0);
b.chaSize(nelementos); b.llenar(0.0);
x.chaSize(nelementos); x.llenar(1.0);
u.chaSize (nelementos);
v.chaSize (nelementos);
k.chaSize(nelementos); k.llenar(0.01);
rho.chaSize(nelementos); rho.llenar(1.0);
C_p.chaSize(nelementos); C_p.llenar(1.0);
...
Adem s, se asigna la memoria a los punteros de CampoFVM y CamposFVM.
a
...
Temperatura.vincular(new CampoFVM(malla(),"Temperatura"));
campo_vel.vincular(new CamposFVM(malla(),"Velocidad"));
gdl.vincular(new GradoLibertadFV(malla(),1));
...
Se calculan los par metros geom tricos y se utiliza el bucle repetitivo para asignar la vea
e
locidad a cada volumen de control.
...
elems.chaSize(nelementos);
for (int i=1; i<=nelementos;i++)
{
elems(i).refill( malla->obtTipoElem(i), malla->obtNoDimEspacio() );
elems(i)->CalcGeomParameters( malla->obtCoorElem(i) );
u(i) = elems(i)->centroid(malla->obtCoorElem(i))(1);
v(i) = -elems(i)->centroid(malla->obtCoorElem(i))(2);
}
...
95
o
3.1.2.
...
Is solucion(solucionador);
pm.Leer ( solucion );
admlin.vincular(new AdmonEcLin(EXTERNAL_STORAGE));
admlin().Leer(solucion);
leido=true;
return 1;
}
2.
I.
Difusi n entre dos vol menes de control: se toman como par metros los n meros
o
u
a
u
que identican a los dos vol menes de control y la direcci n en la cual se encuentra la
u
o
supercie en com n. Se realiza el c lculo de D asumiendo que cada volumen de control
u
a
tiene una conductividad t rmica constante.
e
real convdiff::difusion(int vol1,int dir1,int vol2,int dir2,real area)
{
real D1, D2, Dt, gamma;
gamma = k(vol1)/C_p(vol1); D1= gamma / elems(vol1)->getDelta(dir1);
gamma = k(vol2)/C_p(vol2); D2= gamma / elems(vol2)->getDelta(dir2);
Dt
= area / (1.0/D1 + 1.0/D2);
return Dt;
}
II. Difusi n en un lado de un volumen de control que limita con una frontera tipo
o
Dirichlet: se calcula el valor de D existente entre el nodo del volumen de control y la
supercie denida con la condici n de frontera tipo Dirichlet.
o
real convdiff::difusion(int vol1, int dir1, real area)
{
real Dt, gamma ;
gamma = k(vol1)/C_p(vol1) ;
Dt = gamma / elems( vol1 )->getDelta(dir1);
Dt = area *Dt;
return Dt;
}
III. Difusi n en un lado de un volumen de control que limita con una frontera en la cual
o
se dene la convecci n del uido y la temperatura del uido3 : en este caso se presenta la
o
3 Este
caso solo se presenta cuando la variable de la ecuaci n general de la mec nica de uidos se aplica a
o
a
la temperatura.
96
if ( modo.contiene("power") || modo.contiene("law") )
{ return max(0.0,pow(1-0.1*fabs(pe),5)); }
if ( modo.contiene("exp") || modo.contiene("Exp") )
{ return fabs(pe)/(exp(fabs(pe))-1.0); }
return 0;
}
6.
Funci n peclet_min y peclet_max: debido a que las variables pe_min y pe_max
o
no son declaradas como p blicas, se debe crear una funci n de acceso a su valor.
u
o
real convdiff::peclet_min(void) {return pe_min;}
real convdiff::peclet_max(void) {return pe_max;}
7.
Funci n Calcular: se realiza la asignaci n a los coecientes de la matriz matriz_a
o
o
y al vector de t rminos independientes b. Para realizar este proceso, se requieren los sie
guientes pasos.
I.
Vericaci n del par metro de control: solo se deben calcular los coecientes deso
a
pu s de haber establecido las condiciones del problema a desarrollar. Tambi n se debe
e
e
vericar que el proceso no sea ejecutado m ltiples veces y de esta forma evitar posibles
u
errores durante la ejecuci n del m todo.
o
e
int convdiff::Calcular(void)
{
if (leido==false)
{std_o<<"ERROR: Calcular NO SE EJECUTO EL PROCESO CORRECTAMENTE";
return 0;
}
if (calculado)
{
std_o<<"Ya se habia ejecutado la funcion Calcular: "
<<"No se realizan los calculos\n"; return 0;
}
...
8.
Declaraci n de las variables del m todo: se denen todas las variables necesarias
o
e
para realizar los c lculos.
a
...
int e, h, l;
int veci; int conx;
Cadena boname, bovalue;
int nbi = malla->obtNoIndFront ();
98
double valor;
real F, D, Pe, a_e, a_b, b_b,
real area, y, volumen;
Vector_xyz<real> vel(2), pos;
...
9.
A;
I.
Para cada volumen de control, se calcula la generaci n de calor y se obtiene el
o
n mero de lados.
u
...
for(e=1;e<=nelementos;e++)
{
pos=elems(e)->centroid(malla->obtCoorElem(e));
volumen=elems(e)->getVolume();
b(e) = q (pos(1), pos(2)) * volumen;
conx = elems(e)->GetNumOfConex();
...
II. Para cada lado se verica si el elemento lateral es una condici n de frontera o un
o
volumen de control.
...
for( l=1 ; l<=conx ; l++ )
{
veci = malla->getConx(e,l);
area = elems(e)->getArea(l);
...
III. Si no es una condici n de frontera, se calcula la velocidad, F, D, Pe y se asignan
o
los coecientes.
...
if (veci!=0)
{
for ( h=1 ; h<=conx ; h++ )
{ if(malla->getConx(veci,h)==e)
break; }
vel(1) = ( u(e) + u(veci) )/2.0;
vel(2) = ( v(e) + v(veci) )/2.0;
F = conveccion(e,l,area,vel);
D = difusion( e, l, veci, h, area);
Pe = peclet( F,D );
A = funcion_a(Pe, "upwind");
a_e = D * A + std::max( 0.0 , -F );
matriz_a(e,e
) +=
a_e + F;
matriz_a(e,veci) = -a_e;
99
}
...
IV. Si es una condici n de frontera, se realiza el proceso de asignaci n dependiendo del
o
o
tipo de frontera.
...
else {
for (h=1; h<=nbi; h++) {
if ( malla->LadoFront(e,l,h,elems(e)())
) {
vel(1) = elems(e)->centroArea(malla->obtCoorElem(e),l)(1) ;
vel(2) = -elems(e)->centroArea(malla->obtCoorElem(e),l)(2) ;
F
= conveccion(e,l,area,vel) ;
boname = malla->obtNombreIndFront(h);
bovalue = boname.despues(=);
valor
= atof(bovalue.carts());
D
= difusion(e,l,area);
if ( boname.contiene("T") || boname.contiene("dirichlet")
|| boname.contiene("Dirichlet") )
{
if( boname.contiene("L") ) {
y
= elems(e)->centroArea(malla->obtCoorElem(e),l)(2);
valor = valor * ( 2.0 - y/longy ); }
Pe = peclet( F,D );
A = funcion_a(Pe, "upwind");
a_b = D*A + std::max(F,0.0);
b_b = (D*A + std::max(-F,0.0))*valor;
}
if ( boname.contiene("Q") ) {
a_b = F;
b_b = valor * area/C_p(e); }
if ( boname.contiene("Neumann")||boname.contiene("neumann") ) {
a_b = F;
b_b = valor * area * k(e)/C_p(e); }
matriz_a (e,e) += a_b;
b (e) += b_b;
}}}}}
V.
Actualizaci n del par metro de control: se actualiza el valor del par metro de cono
a
a
trol y se devuelve el valor 1 que indica que el proceso fue realizado satisfactoriamente.
...
calculado=true;
return 1;
}
100
101
> nsd = 2;
> subdominios = 1;
> no_de_superels = 1;
>nbind = 3
>bname T=1 Q=0 TL=1
>SupEl;
>subdominio_no = 1;
>tipoelemento = ElmB4n2D;
>fronteras = [2(1)] [1 (2)] [3 (3)] [2(4)];
>nodos = [1(0 0)]+[2(1 0)]+[3(0 1)]+[4(1 1)];
>lados=;
El archivo de las particiones datos_conv_dif.parts es:
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[6,10];>grad=[1,1];
El contenido del archivo Solve_datos.txt es:
Parametros de la matriz (clase prmMatriz);
>guarda = Matriz;
>guarda_sim = FALSE
>pivoteo = FALSE
>umbral =0.0
prm_solucionEcLin parametros:
>solver_classname=Orthomin
>metodo=R-OM(7)
>cambiar=0.0
>pivoteo=NO_PIVOT
>relajacion=1.9
>startvector=USER_START
>criterio_def=TRUE
>nextern_crit=0
>maxit=3000
>estimate_eigvals=FALSE
Parametros del precondiciondor:
>precondicionador=PrecIdentidad
>left_prec=TRUE
>auto_iniciar=TRUE
>nivel_llenado=0
102
Tabla 12: Distribuci n del campo de temperatura para el problema propuesto al usar la clase
o
convdiff.
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
Volumen
Valor
1
1.54995
7
1.43724
13
1.32028
19
1.22687
25
1.15607
31
1.10274
37
1.06297
43
1.03424
49
1.01485
55
1.00362
2
1.37608
8
1.27334
14
1.17380
20
1.10449
26
1.06051
32
1.03331
38
1.01690
44
1.00749
50
1.00260
56
1.00051
3
1.29020
9
1.19841
15
1.11406
21
1.06055
27
1.03061
33
1.01463
39
1.00640
45
1.00243
51
1.00072
57
1.00012
4
1.23736
10
1.15511
16
1.08258
22
1.03971
28
1.01796
34
1.00763
40
1.00296
46
1.00100
52
1.00026
58
1.00004
5
1.20121
11
1.12698
17
1.06364
23
1.02824
29
1.01164
35
1.00448
41
1.00157
47
1.00048
53
1.00012
59
1.00002
6
1.17589
12
1.10806
18
1.05165
24
1.02147
30
1.00819
36
1.00290
42
1.00093
48
1.00026
54
1.00006
60
1.00001
>prec_RILU=1
>prec_SSOR=1
>pasos_int=1
El vector soluci n para 60 vol menes de control se encuentra en la tabla 12.
o
u
4.3
RESULTADOS
e
la velocidad (ltro StreamTracer y Glyph) para 8100 vol menes de control.
u
103
104
5. ECUACION TRANSITORIA DE LA
DIFUSION Y LA CONVECCION-DIFUSION
Ya se han presentado las ecuaciones de difusi n y convecci n-difusi n en estado estable,
o
o
o
ahora se complementar la discretizaci n de las dos ecuaciones en estado transitorio.
a
o
5.1
En la (Ec 5.1) se muestra la ecuaci n a discretizar. Esta ecuaci n se debe integrar a trav s de
o
o
e
un volumen de control, como se muestra en (Ec 5.2):
( T )
=
t
( T )
dV =
t
k
Cp
T)+
k
Cp
T )] dV +
q
Cp
(Ec 5.1)
q
dV
Cp
(Ec 5.2)
(Ec 5.3)
La integral del t rmino difusivo se puede evaluar en el tiempo futuro, el tiempo actual o como
e
una dependencia de ambos valores. Para denir esta dependencia se introduce la variable
en (Ec 5.5) y el n mero discreto de Fourier (Fo) en (Ec 5.4).
u
Fo =
t
2
(Ec 5.4)
T = T t+t + (1 ) T t
0
(Ec 5.5)
Depende del
tiempo futuro
Depende del
tiempo actual
El caso = 0 se conoce com nmente como esquema explcito porque solo se utiliza el valor
u
t+t
[ t + (Ui Ai )] Tp [Ui Ai Tit+t ] =
i=1
5.1.1
t
(Tp ) +
i=1
n
q
t
{Ui Ai [(1 ) (Tit Tp )]} + Cp p
(Ec 5.6)
i=1
Implementaci n
o
nnb
[ ai Tit+t ] = b
i=1
En donde
a p = atr +
nnb
i=1
nb
ai + ab,h
p
t
ai = Ui Ai
Ui =
k
C p i
si
(Ec 5.8b)
k Ah
C p h
ab,h =
(Ec 5.8c)
k
Cp
si
C p ei C p pi
ki + k p
si es
(Ec 5.8d)
nb
nnb
h=1
i=1
t
b = bgen + bb,h + atr Tp + (1 )
1 Se
(Ec 5.8a)
h=1
atr =
(Ec 5.7)
106
(Ec 5.8f)
bgen =
k Ah
t
C p h [(1 )Tp
bb,h =
k
Cp
Cp
(Ec 5.8g)
Ah ( T )wall
n
(Ec 5.8h)
si es Frontera tipo Neumann
Para poner a prueba el c digo de computador que resuelve la ecuaci n de difusi n en estado
o
o
o
transitorio se analizar el mismo ejemplo propuesto en la secci n 3.1 pero partiendo de una
a
o
temperatura inicial Tinicial = 100 [C] con = 500 [Kg/m3 ] y C p = 1 [J/(Kg C)]. Se realizan
los siguientes pasos para desarrollar el problema planteado:
1.
2.
3.
4.
A continuaci n se explican cada uno de los pasos realizados omitiendo los detalles que han
o
sido aclarados en captulos anteriores:
Matriz<real> matriz;
prm_Matriz <real> pm;
Vector<real>b;
Vector<real>x;
Vector<real>x_futuro;
Puntero<AdmonEcLin> admlin;
real theta;
Puntero<prmTiempo> tiempo_p;
bool calculado;
bool leido;
bool solucionado;
bool primera_solucion;
bool primer_fourier;
real phi_inicial;
real Fo_min;
real Fo_max;
...
}
Adem s de las variables utilizadas en la clase diffgeneral,se denen:
a
1.
Otras propiedades del material como la densidad rho, el calor especco cp, la difu
sividad t rmica alph.
e
2.
3.
4.
Se denen los par metros de control primera_solucion y primer_fourier que
a
ayudan en procesos especcos como se explicar posteriormente.
a
5.
Como se coment anteriormente, para el esquema explcito es muy importante conoo
cer el valor del n mero discreto de fourier, raz n por la cual se almacena el valor absoluto
u
o
mnimo Fo_min y m ximo Fo_max.
a
Paso 2. Agregar los m todos a la clase. Se requiere las siguientes funciones para resolver
e
el problema a trabajar.
...
class DifusionTransitoria : public GuardarEnsight
{
...
real Fourier(real alpha, real dt, real dx);
protected:
virtual int CalculoUnTiempo();
108
DifusionTransitoria::DifusionTransitoria(void)
{
primera_solucion=primer_fourier=true;
calculado = leido = solucionado = false;
}
2.
Funci n Leer(...): se incorporan algunas instrucciones adicionales (comparado
o
con la funci n Leer de diffgeneral) como el llenado de las propiedades de la placa, k,
o
rho, cp, alph.
int DifusionTransitoria::Leer(Cadena archivo,
Cadena solucionador, Cadena def_tiempo, real phi_o)
{
...
rho.chaSize(nelementos); rho.llenar(500.0);
cp.chaSize(nelementos); cp.llenar(1.0);
alph.chaSize(nelementos);
for (i=1;i<=nelementos;i++)
109
alph(i)=k(i)/(rho(i)*cp(i));
...
Adicionalmente, se llena el vector x (tiempo actual) y el vector x_futuro (tiempo futuro)
con el valor de la temperatura inicial mediante la llamada a la funci n llenar de la clase
o
Vector<real>, la temperatura inicial se da en el argumento phi_o de la funci n Leer.
o
...
x.chaSize(nelementos); x.llenar(phi_o);
x_futuro.chaSize(nelementos);x_futuro.llenar(phi_o);
...
La Cadena def_tiempo permite introducir los datos del tiempo para el an lisis transitorio
a
o el an lisis en estado estable. Para denir el estado transitorio, la cadena debe tener el fora
mato dt=6 t en [0,30] en donde t = 6[s], tinicial = 0[s] y t f inal = 30[s]. Por otro lado,
para seleccionar el an lisis en estado estable, se debe introducir la cadena "dt=0". La caa
dena def_tiempo es leda por una instancia de Puntero<prmTiempo>, la clase prmTiempo
dene una serie de funciones para el manejo de los par metros del tiempo. Teniendo en
a
cuenta esto, se inicializa la memoria del Puntero<prmTiempo> tiempo_p, se llama a la
funci n Leer dando como argumento la cadena def_tiempo y se inicia el ciclo del tiempo
o
con iniciarCicloTiempo().
...
tiempo_p.vincular(new prmTiempo);
tiempo_p->Leer(def_tiempo);
tiempo_p->iniciarCicloTiempo();
...
}
3.
Funci n CalcularYResolver: en un an lisis transitorio, se requiere una gran cano
a
tidad de memoria para almacenar el valor de la propiedad calculada en cada uno de los
tiempos, es por esta raz n que es necesario calcular los coecientes de la matriz, resolver
o
las ecuaciones y nalmente guardar los datos en un archivo compatible con Paraview.
Vericaci n de los par metros de control: se verica si se ha ledo los datos o se haba
o
a
II.
Selecci n del tipo de an lisis: el procedimiento es algo diferente para el estado estable
o
a
y el estado transitorio, por esta raz n se hace la distinci n del proceso.
o
o
A. An lisis en estado estable: es necesario denir theta=1 para que la llamada
a
de CalculoUnTiempo()obtenga los coecientes correspondientes a un an lisis en
a
estado estable. Posteriormente se resuelve el sistema de ecuaciones y se guardan los
resultados.
...
if (tiempo_p->estacionario())
{
theta=1;
CalculoUnTiempo();
SolucionUnTiempo();
Reportarresultados();
}
...
B. An lisis en estado transitorio: se asigna el valor de theta con el valor dado
a
en el argumento de la funci n, posteriormente, se exportan los resultados de la
o
condici n inicial del problema que corresponden al tiempo inicial.
o
...
else
{
theta=dependencia_futuro;
gdl->vector2campo(x_futuro,phi());
Reportarresultados();
...
Se utiliza un ciclo repetitivo que naliza cuando se ha llegado o sobrepasado el
tiempo nal especicado. Dentro del bucle se realiza el incremento del tiempo,
se calcula los coecientes de la matriz, se resuelve el sistema de ecuaciones y se
exportan los resultados.
...
do
{
tiempo_p->incrementarTiempo();
CalculoUnTiempo();
SolucionUnTiempo();
Reportarresultados();
}
while(!tiempo_p->finalizo());
std_o<<"\nMinimo Fourier "<<Fo_min
<<"\nMaximo Fourier "<<Fo_max<<"\n";
}
Para el caso transitorio puede ser conveniente mostrar el valor m ximo del n mero
a
u
111
4.
Funci n CalculoUnTiempo(): el procedimiento de asignaci n de los coecientes a
o
o
la matriz y al vector de t rminos independientes se realiza en esta funci n.
e
o
I.
Declaraci n de las variables del m todo: se declaran contadores, variables de tipo
o
e
real, un vector de posici n Vector_xyz<real> y dos cadenas de texto para el manejo
o
de las condiciones de frontera.
int DifusionTransitoria::CalculoUnTiempo()
{
int i , j , l, veci, conx, conxvec;
int h, nbi=malla->obtNoIndFront ();
real aj, vol, tr, hfrontera, bc, u1, u2, ut, valor;
Vector_xyz <real> posicion(3);
Cadena boname, bovalue;
...
II. Asignaci n del valor inicial: para el an lisis transitorio es importante guardar el
o
a
valor de la propiedad calculada en el tiempo anterior, tambi n, se asigna el valor a 0 a la
e
matriz de coecientes y al vector de t rminos independientes:
e
...
x=x_futuro;
matriz.llenar(0.0);
b.llenar(0.0);
...
III. Se realiza un bucle que recorre cada uno de los vol menes de control del an lisis.
u
a
Se asigna al vector de t rminos independientes el efecto de la generaci n representado
e
o
por bgen en la (Ec 5.8).
...
for(i=1;i<=nelementos;i++)
{
posicion = elems(i)->centroid(malla->obtCoorElem(i));
vol = elems(i)->getVolume();
b(i) = vol * S_fuente( posicion(1),posicion(2) );
112
...
conx=elems(i)->GetNumOfConex();
for( j=1 ; j<=conx ; j++ )
{
veci=malla->getConx(i,j);
...
A. Si no es una condici n de frontera, se calcula la conductancia y se asigna los valoo
res correspondientes al vector de t rminos independientes y a la matriz de coecientes.
e
Solo en el caso que el an lisis sea transitorio se llama a la funci n Fourier(...) que
a
o
posteriormente se explicar .
a
...
if (veci!=0)
{
conxvec=elems(veci)->GetNumOfConex();
for ( l=1 ; l<=conxvec ; l++ )
{if(malla->getConx(veci,l)==i)
break; }
u1=k(i)/(cp(i)*elems(i)->getDelta(j));
u2=k(veci)/(cp(veci)*elems(veci)->getDelta(l));
ut = 1.0 / ( (1.0/u1)+ (1.0/u2) );
aj = ut* elems(i)->getArea(j);
matriz( i, i ) += theta*aj;
matriz( i,veci) = -theta*aj;
b(i)-= (1-theta)*aj*(x(i)-x(veci));
if (!tiempo_p->estacionario())
{
Fourier(alph(i),tiempo_p->Delta(),
elems(i)->getDelta(j)+elems(veci)->getDelta(l));
}
}
...
113
}
5.
Funci n Fourier: se calcula el valor del n mero discreto de Fourier y se almacena
o
u
el valor mnimo y el valor m ximo.
a
real DifusionTransitoria::Fourier(real alpha, real dt, real dx)
{
real fo;
fo = alpha*dt/(dx*dx);
if (primer_fourier) { Fo_min=Fo_max=fo; primer_fourier=false;}
if (fo < Fo_min) {Fo_min=fo;}
if (fo > Fo_max) {Fo_max=fo;}
return fo;
}
6.
Funci n S_fuente: se devuelve un valor de tipo real que corresponde a la geneo
raci n de calor del problema a resolver presentado en la secci n 3.1.
o
o
real DifusionTransitoria::S_fuente(real x, real y)
{
return 5000;
}
7.
Funci n SolucionUnTiempo: para el an lisis transitorio, es necesario solucionar el
o
a
sistema de ecuaciones varias veces, pero, la llamada a adjuntar de la clase AdmonEcLin
solo se debe realizar una vez; esta labor se realiza mediante la vericaci n del par metro
o
a
de control primera_solucion.
bool DifusionTransitoria::SolucionUnTiempo()
{
if (primera_solucion)
{
admlin().adjuntar(matriz, x_futuro, b);
primera_solucion=false;
}
bool solucion=admlin().solve();
gdl->vector2campo(x_futuro,phi());
return solucion;
}
8.
Funci n Reportarresultados: para exportar los resultados, ya sea en estado
o
estable o transitorio, se llama a la funci n GuardarEnsight::volcar(...)con
o
tiempo_p.obtPtr() como segundo argumento, de esta forma, se indica el tiempo al cual
corresponde la soluci n.
o
115
void DifusionTransitoria::Reportarresultados()
{
GuardarEnsight::volcar(phi(),tiempo_p.obtPtr());
}
Paso 4. Crear un objeto de la clase. Como primer paso, se declara una instancia de la clase
DifusionTransitoria. Posteriormente, se llama a la funci n Leer()con los siguientes
o
par metros:
a
1.
Nombre del archivo de denici n del problema "ARCH=datos_difusion.txt":este
o
archivo fue presentado en la p gina 79 y contiene el nombre del archivo de geometra
a
o
mostrada en la p gina 79, el archivo de las particiones fue modicado y contiene la siguiente
a
informaci n:
o
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[36,36];>grad=[1,1];
2.
Nombre del archivo de denici n del m todo de soluci n "ARCH=Solve_datos.txt":
o
e
o
el contenido de este archivo fue presentado en la p gina 67.
a
3.
Cadena de denici n de los par metros del tiempo: para el an lisis en estado estable
o
a
a
se utiliza la cadena dt=0 y para el an lisis en estado transitorio se usa "dt=6 t en
a
[0,30]".
4.
Temperatura inicial: un valor de tipo real que corresponde en este caso a 100.0.
Una vez se ha ledo los par metros de entrada, se llama a la funci n CalcularYResolver en
a
o
la cual se usa = 1 para que el an lisis sea incondicionalmente estable.
a
...
DifusionTransitoria temp;
temp.Leer("ARCH=datos_difusion.txt",
"ARCH=Solve_datos.txt","dt=6 t en [0,30]",100.0);
temp.CalcularYResolver(1.0);
...
116
5.1.2
Resultados
En la gura 26 se presenta los resultados del an lisis en el tiempo (lneas de colores) seg n los
a
u
par metros especicados anteriormente y se comparan con los resultados en estado estable
a
mostrados con lneas grises. Se aplic los ltros CellDataToPointData y Contour. El
o
m ximo valor obtenido del n mero discreto de Fourier es 1058.
a
u
Figura 26: Presentaci n de los resultados para la clase DifusionTransitoria
o
(a) t = 0 s
(b) t = 6 s
(c) t = 12 s
(d) t = 18 s
(e) t = 24 s
(f) t = 30 s
117
5.2
( V T ) =
k
Cp
T)+
q
Cp
(Ec 5.9)
p
t
l=1
p
q
C p p + t
5.2.1
t+t
l=1
t
Tp ) + max(0, Fl ) Tlt
t
max(0, Fl ) Tp ]
(Ec 5.10)
Implementaci n
o
Se desarrollar el mismo problema propuesto en la secci n 4.2 para poner a prueba el an lisis
a
o
a
transitorio, la temperatura inicial del problema ser T = 1[C].
a
En la (Ec 5.11) se presenta la forma general de la ecuaci n a aplicar teniendo en cuenta
o
las condiciones de frontera y en la (Ec 5.12) se denen los coecientes usados en la (Ec
5.11).
t+t
a p Tp
En donde
a p = atr +
nnb
[ae Tet+t ] = b
(Ec 5.11)
e=1
nnb
e=1
nb
[ae + Fe ] + [ab, j ]
(Ec 5.12a)
j=1
t
ae = De A(Pee , metodo) + max(0, Fe )
(Ec 5.12b)
Fe = e Vn S
(Ec 5.12d)
atr =
De =
k
Cp
k Se
C p e
si
Se
si
C p e ee C p p pe
ke + k p
(Ec 5.12c)
118
(Ec 5.12e)
ab, j =
nb
nnb
j=1
e=1
t
t
b = bgen + [bb, j (1)ab, j Tp ]+atr Tp +(1)
bgen =
bb, j =
(Ec 5.12f)
Cp
(Ec 5.12h)
(Ec 5.12g)
si es
1.
2.
3.
4.
Paso 1. Declarar la clase ConveccionTransitoria y agregar las variables correspondientes. La declaraci n de la clase se hace de la misma forma que la clase DifusionTransitoria;
o
adem s de las variables presentadas en DifusionTransitoria se crean las siguientes variaa
bles.
...
class ConveccionTransitoria : protected GuardarEnsight
{
...
Puntero<CamposFVM>
campo_vel;
Vector<real> u;
Vector<real> v;
...
bool primer_peclet;
real phi_inicial;
real pe_min ;
real pe_max ;
...
Se dene un objeto de tipo Puntero<CamposFVM> que permite denir campos vectoriales
como sucede en el caso de la velocidad. Adicionalmente se denen los vectores que contienen la velocidad en cada volumen de control en direcci n x y en direcci n y, u y v , se
o
o
119
...
protected:
virtual int CalculoUnTiempo();
virtual bool SolucionUnTiempo();
virtual void Reportarresultados();
public:
ConveccionTransitoria(void);
ConveccionTransitoria(void){}
int Leer (Cadena archivo,Cadena solucionador,
Cadena def_tiempo, real T_inicial=1);
int CalcularYResolver(real dependencia_futuro);
virtual real S_fuente (real x, real y);
real funcion_a ( real pe, Cadena modo);
real difusion(int vol1, int dir1, int vol2, int dir2, real area);
real difusion(int vol1, int dir1, real area);
real difusion(int vol1, int dir1, real area, real conveccion_f);
real conveccion( int vol1, int dir1 ,real area, Vector_xyz<real> Vel);
real peclet_min(void);
real peclet_max(void);
real peclet(real F, real D);
};
Se denen las funciones Leer(...), CalculoUnTiempo(), SolucionUnTiempo(),
Reportarresultados(), CalcularYResolver(...) y S_fuente(...) que dieren en su
procedimiento de las funciones hom nimas denidas en la clase DifusionTransitoria.
o
La denici n completa del archivo de encabezado de la clase ConveccionTransitoria.h
o
se encuentra en el anexo J y la denici n de las funciones en el archivo de c digo fuente
o
o
(ConveccionTransitoria.cpp) se encuentra en el anexo K.
Paso 3. Denici n de las funciones. Se muestran las modicaciones realizadas en las funo
ciones que han sido previamente denidas.
1.
Funci n Leer(): se dene la velocidad del uido para cada volumen de control y las
o
propiedades de acuerdo al problema presentado en la secci n 4.2. Seguidamente, se asigna
o
la memoria al puntero inteligente campo_vel del campo vectorial.
int ConveccionTransitoria::Leer(Cadena archivo,Cadena solucionador,
120
}
std_o<<"Peclet minimo "<< peclet_min() <<
"Peclet maximo "<< peclet_max() << "\n";
solucionado=true;
return 1;
}
Adicionalmente se exporta el m ximo y mnimo valor absoluto del n mero discreto de
a
u
Fourier y del Peclet.
3.
Funci n S_fuente(...): para resolver el problema de la secci n 4.2 se debe denir
o
o
la generaci n de calor como 0.
o
real ConveccionTransitoria::S_fuente(real x, real y)
{
return 0.0;
}
4.
Funci n CalculoUnTiempo(): se declaran las siguientes variables para realizar el
o
c lculo de los coecientes del sistema de ecuaciones.
a
int ConveccionTransitoria::CalculoUnTiempo()
{
real tr, hfrontera;
int e, h, l;
int veci; int conx;
Cadena boname, bovalue;
int nbi = malla->obtNoIndFront ();
double valor;
real F, D, Pe, a_e, a_bj, b_bj, A;
real area, y, volumen,d1,d2;
Vector_xyz<real> vel(2), pos;
...
Se destaca la creaci n de vel de tipo Vector_xyz<real> en la cual se almacenar el vector
o
a
de velocidad en una supercie. Posteriormente se guarda la informaci n del vector soluci n
o
o
x_futuro en el vector x actualizando de esta forma el valor en el tiempo pasado.
...
x=x_futuro;
matriz.llenar(0.0);
b.llenar(0.0);
for(e=1;e<=nelementos;e++)
122
{
...
if (!tiempo_p->estacionario() )
{
...
}
for( l=1 ; l<=conx ; l++ )//por cada conexion
{
...
Se verica si existe o no una condici n de frontera en el lado l del volumen de control e y
o
se asignan los coecientes de acuerdo a (Ec 5.11) y (Ec 5.12).
...
if (veci!=0)
{
for ( h=1 ; h<=conx ; h++ )
{ if(malla->getConx(veci,h)==e)
break;}
d1 = elems(e)->getDelta(l);
d2 = elems(veci)->getDelta(h);
vel(1) = ( u(e)*d2 + u(veci)*d1 )/(d1+d2);
vel(2) = ( v(e)*d2 + v(veci)*d1 )/(d1+d2);
F = conveccion(e,l,area,vel);
D = difusion( e, l, veci, h, area);
Pe = peclet( F,D );
A = funcion_a(Pe, "UDS");
a_e = D * A + std::max( 0.0 , -F );
matriz(e,e
) +=
(a_e + F) * theta ;
matriz(e,veci) = -a_e * theta;
b(e) += (1 - theta) * (-(a_e + F)*x(e) + a_e*x(veci)) ;
if (!tiempo_p->estacionario())
{
Fourier(alph(e),tiempo_p->Delta(),
elems(e)->getDelta(l) + elems(veci)->getDelta(h));
}
}
else
{
for (h=1; h<=nbi; h++)
{
if ( malla->LadoFront(e,l,h,elems(e)())
)
{
vel(1) = elems(e)->centroArea(malla->obtCoorElem(e),l)(1) ;
123
vel(2) = -elems(e)->centroArea(malla->obtCoorElem(e),l)(2) ;
F
= conveccion(e,l,area,vel) ;
boname = malla->obtNombreIndFront(h);
bovalue = boname.despues(=);
valor
= atof(bovalue.carts());
D
= difusion(e,l,area);
if ( boname.contiene("T") || boname.contiene("dirichlet")
|| boname.contiene("Dirichlet")
)
{
if( boname.contiene("h=") )
{
bovalue = boname.despues("T=");
valor
= atof(bovalue.carts());
bovalue = boname.despues("h=");
hfrontera
= atof(bovalue.carts());
D = difusion(e,l,area,hfrontera);
}
if( boname.contiene("L") )
{
y
= elems(e)->centroArea(malla->obtCoorElem(e),l)(2);
valor = 1.0 + valor * ( (1-y) );
}
Pe = peclet(F,D);
A = funcion_a(Pe,UDS);
a_bj = D*A + std::max(F,0.0);
b_bj = (D*A + std::max(-F,0.0))*valor;
}
if ( boname.contiene("Q") )
{
a_bj = F;
b_bj = valor * area/cp(e) ;
}
if ( boname.contiene("Neumann")||boname.contiene("neumann") )
{
a_bj = F;
b_bj = valor * area * k(e)/cp(e);
}
matriz (e,e) += a_bj * theta;
b (e) += b_bj - (1-theta)*a_bj ;
}
}
}
124
}
}
return 1;
}
5.
Funci n SolucionUnTiempo(): se resuelve el sistema de ecuaciones y se actualiza
o
el valor del campo escalar de la temperatura y el campo vectorial de la velocidad.
bool ConveccionTransitoria::SolucionUnTiempo()
{
if (primera_solucion)
{ admlin().adjuntar(matriz, x_futuro, b);
primera_solucion=false; }
bool solucion=admlin().solve();
gdl->vector2campo(x_futuro,phi());
gdl->vector2campo(u,campo_vel()(1));
gdl->vector2campo(v,campo_vel()(2));
return solucion;
}
6.
Funci n Reportarresultados(): de nuevo se usa la funci n volcar de GuardarEnsight
o
o
para exportar los resultados, ya sea de un campo escalar o vectorial.
void ConveccionTransitoria::Reportarresultados()
{
GuardarEnsight::volcar(phi(),tiempo_p.obtPtr());
GuardarEnsight::volcar(campo_vel(),tiempo_p.obtPtr());
}
Paso 4. Crear un objeto de la clase. La clase ConveccionTransitoria permite resolver la
ecuaci n de convecci n-difusi n ya sea en estado transitorio o en estado estable; un ejemplo
o
o
o
de la creaci n de un objeto de la clase es presentado en el siguiente fragmento de c digo.
o
o
ConveccionTransitoria conv;
conv.Leer ("ARCH=datos_conveccion_difusion.txt",
"ARCH=Solve_datos.txt","dt=[1.0 5.0] t en [0.0 4.0 9.0]",1.0);
conv.CalcularYResolver(1.0);
Con la cadena de texto "dt=[1.0 5.0] t en [0.0 4.0 9.0]" se utiliza la capacidad del
objeto prmTiempo de denir diferentes avances en el tiempo, la cadena usada implica que se
tomar t = 1 para t [0, 4] y t = 5 para t (4, 9].
a
Los archivos datos_conveccion_difusion.txt, datos_conv_dif.geom y
Solve_datos.txt ya fueron presentados en el captulo 4. Ahora se presenta la modicaci n
o
realizada al archivo datos_conv_dif.parts en el cual se denen 3600 particiones.
125
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[60,60];>grad=[1,1];
5.2.2
Resultados
e
color corresponden al estado estable y las lneas isot rmicas negras corresponden al estado
e
transitorio, se puede ver que las lneas isot rmicas en el estado transitorio tienden a acercarse
e
a las lneas isot rmicas en el estado estable.
e
Figura 27: Presentaci n de los resultados para la clase ConveccionTransitoria.
o
(a) t = 0 s
(b) t = 1 s
(c) t = 2 s
(d) t = 3 s
(e) t = 4 s
(f) t = 9 s
126
6. CFD DEL FLUJO EN LA CAPA LIMITE
Se presentan dos m todos para resolver las ecuaciones de la capa lmite, el primer m todo
e
e
tiene en cuenta las ecuaciones completas de Navier-Stokes y la ecuaci n de la energa para
o
bajas velocidades como se muestra en la tabla 13. El segundo m todo resuelve las ecuaciones
e
simplicadas de la capa lmite donde la presi n se asume conocida.
o
Tabla 13: Ecuaciones conservativas
Principio de
conservaci n
o
T rmino
e
transitorio
Continuidad
( V )
Cant. mov.
( u)
t
( u V )
Eje x
Cant. mov.
Eje y
Cant. mov.
Eje z
Energa
bu =
( T )
t
v
y
( w V )
V )] + z
z [(
u
x
( v V )
V )] + y
y [(
( w)
t
bw =
V )] + x
x [(
( v)
t
bv =
T rmino
e
convectivo
w
z
( T V )
T rmino
e
difusivo
T rmino
e
fuente
+
u)
p + bu
x
+ y ( x + u ) + z ( w + u )
y
x
z
v)
p + bv
y
+ x ( u + x ) + z ( w + v )
y
y
z
w)
p + bw
z
+ x ( u + w ) + y ( v + w )
z
x
z
y
k
Cp
bT
q
1
bT = Cp + Cp p
t
v
( x + u )
=
y
( w + u )
x
z
u
x
p
= ( p) j
y
bv = ( ) j
p
= ( p) k
z
bw = ( ) k
v
( x + u )
( w + u )
y
x
z
2
v
v
w
3 ( V ) + y
( z + y )
v
w
2
( z + y )
3 ( V ) +
127
(Ec 6.1a)
(Ec 6.1b)
w
z
(Ec 6.1c)
6.1
METODO SIMPLE
(V V ) =
V)
b
p +bV
aV Vp =
p
nnb
i=1
aV Vi
i
p p p + bV p
p
(Ec 6.2)
Para escribir la (Ec 6.2) en forma vectorial se denen los
como matrices
diagonales (Ec 6.3) pero, se debe recalcar que la soluci n de cada una de las componentes de
o
la velocidad se halla de forma independiente a las otras velocidades. En general se cumple
que au = av = aw y au = av = aw ya que cada ecuaci n de (Ec 6.2) tiene los mismos
o
p
p
p
i
i
i
t rminos de V y , solo son diferentes los t rminos que tienen distintos tipos de condie
e
ciones de frontera, por ejemplo, un lado con una condici n de frontera tipo Dirichlet para la
o
velocidad u y condici n de frontera tipo Neumann para la velocidad v.
o
u
ap 0 0
u
ai 0 0
V
V
v
0 av 0
0 av 0
ap =
ai =
V=
(Ec 6.3)
p
i
w
w
0 0 ai
w
0 0 ap
coecientes aV
p
y aV
i
nnb
i=1
pm1 p + bV p
p
p
aV Vim
i
(Ec 6.4)
p = pm1 + p
(Ec 6.5)
V = V m + V
(Ec 6.6)
El proceso iterativo del m todo SIMPLE tiene como primer paso1 la soluci n de (Ec 6.4) en
e
o
V , aV ,
m1 y bV con el valor del campo de la velocidad y
la cual se realiza el c lculo de a p i
a
pp
p
la presi n hallados en la iteraci n anterior. La (Ec 6.4) es una ecuaci n lineal de convecci no
o
o
o
difusi n cuyo proceso de soluci n se present en los captulos 4 y 5.
o
o
o
Una vez se ha calculado el valor de V m se debe hallar el valor de V y para ello, se resta
(Ec 6.4) de (Ec 6.2) obteniendo (Ec 6.7).
aV
p
m
(Vp Vp ) =
nnb
i=1
aV (Vi Vim )
i
(p p pm1 ) p
p
(Ec 6.7)
Recordando la denici n de (Ec 6.6) y (Ec 6.5) se puede re-escribir (Ec 6.7) como (Ec 6.8).
o
aV Vp =
p
nnb
i=1
aV Vi
i
SIMPLE
p p p
(Ec 6.8)
pp
(Ec 6.9)
El segundo paso del m todo consiste en resolver la ecuaci n de continuidad con el campo
e
o
de correci n de presi n. Como la ecuaci n de continuidad no depende directamente del
o
o
o
campo de presi n se usan las deniciones de (Ec 6.6) y (Ec 6.9) para resolver la ecuaci n de
o
o
continuidad, la ecuaci n resultante se muestra en (Ec 6.11).
o
0=
(V ) =
[(V m + V )] =
[V m ] +
[V ]
(Ec 6.10a)
1 Se recuerda que en todo proceso iterativo se debe dar un valor inicial a las variables de manera que se pueda
129
[V ] =
ap
(aV )1
[V m ]
(Ec 6.10b)
m
( Vp )
pp =
(Ec 6.11)
Residuo m sico
a
La (Ec 6.11) es una ecuaci n de Poisson que se resuelve de la misma forma que se present
o
o
m hallado en el primer
en el captulo 3 o 5. El t rmino del lado derecho, que usa el valor de Vp
e
paso, es llamado residuo m sico y se usa como criterio de convergencia para el m todo.
a
e
Cabe resaltar que el residuo m sico es positivo cuando el volumen de control est perdiendo
a
a
masa, este signo se tiene en cuenta en la implementaci n del m todo.
o
e
Una vez se ha calculado la correci n de presi n se actualiza el valor del campo de la veo
o
locidad y el campo de presi n. El tercer paso del m todo consiste en aplicar (Ec 6.12).
o
e
pm = pm1 + p
(Ec 6.12a)
ap
V m = V m (aV )1
pp
(Ec 6.12b)
o
estado para los gases se resuelve en el cuarto paso como se indica en (Ec 6.13 ) y (Ec 6.14).
( T m )
+
t
T mV =
p
=RT
k
Cp
T m + bT
(Ec 6.13)
(Ec 6.14)
Finalmente se comprueba si el valor del residuo m sico (especcamente la norma del residuo
a
6.1.1
m
Para calcular el residuo m sico, ( Vp ), se debe conocer la velocidad del ujo en la
a
frontera de cada volumen de control pero no siempre se tiene directamente este valor.
El caso en el que el valor de la velocidad est ubicado en el centro de cada cara y el valor de
a
la presi n se ubica en el centro del volumen de control corresponde al uso de una malla deso
plazada. La malla desplazada facilita el c lculo del gradiente de la velocidad, sin embargo,
a
la malla desplazada solo se puede construir en el caso de tener una malla ortogonal.
130
(Ec 6.4)
(Ec 6.11)
(Ec 6.17)
(Ec 6.13)
(Ec 6.14)
Por otro lado se encuentra la malla colocada. En la malla colocada, la velocidad se calcula a
partir del mismo punto donde est n ubicadas las otras variables del problema, de esta forma
a
se pueden obtener soluciones para mallas no ortogonales. Sin embargo, el uso de una malla
colocada ocasiona un efecto de zigzag en la soluci n de la ecuaci n para la correci n de
o
o
o
131
Malla colocada
Malla desplazada
pe
dEP n j
a
((aV )1 ) pe (pE pP ) ( p) pe dEP
D
(Ec 6.15)
En (Ec 6.16) se especica cada uno de los t rminos usados en (Ec 6.15):
e
m
(Vpe ) =
pe
dEP n j
m
m
(VP + VE )
2
P
(d p, j +de,k )n j
pe
dEP n j
a
((aV )1 ) pe =
(Ec 6.16a)
o
(Ec 6.16b)
= A p, j
aP
aE
(aV )1 + (aV )1
2
(Ec 6.16c)
( p)P + ( p)E
(d p, j + de,k )
(Ec 6.16e)
2
El volumen pe de (Ec 6.15) se interpreta como el volumen alrededor de la fronterape. Este
volumen dividido en la distancia dEP resulta igual al area de la frontera del volumen p por el
lado j independientemente de la forma del volumen de control.
( p) pe dEP =
132
6.2
(Ec 6.17a)
p p ] + (1 V ) V m1
Se recomienda V = 1 p
(Ec 6.17b)
(Ec 6.17c)
Por otro lado, el m todo SIMPLEC (gura 30) aproxima de una forma distinta la correcci n
e
o
2 (Ec 6.18c). De esta forma, la ecuaci n de correci n
de la velocidad (Ec 6.18a) obteniendo
o
o
de presi n a resolver es (Ec 6.18d).
o
ap
Vp = Vp (aV )1
pp
(Ec 6.18a)
nnb
aV
i
Vp Vp i=1V
ap
ap
Vp = (aV +
ap
(aV +
6.3
nnb
aV )1
i
i=1
nnb
aV )1
i
i=1
pp =
(Ec 6.18b)
pp
m
( Vp )
(Ec 6.18c)
(Ec 6.18d)
Residuo m sico
a
IMPLEMENTACION SIMPLE
133
(Ec 6.4)
(Ec 6.18)
(Ec 6.12)
(Ec 6.13)
(Ec 6.14)
son:
1.
2.
3.
4.
Paso 1. Declarar la clase NavierStokes y agregar las variables: se incluyen las libreras
de ConveccionTransitoria y DifusionTransitoria. Posteriormente, se declaran algunos vectores de caracteres que denen las opciones disponibles para procesos especcos.
En esta clase tambi n se usa la herencia al declarar la clase GuardarEnsight como clase
e
padre de NavierStokes.
//NavierStokes.h
#pragma once
#include "ConveccionTransitoria.h"
#include "DifusionTransitoria.h"
static const char *MACD[] = {"UDS", "Upwind","CDS", "upwind","hybrid",
"hibrido", "power", "law", "exp", "Exp", NULL};
static const char *MSNS[] = {"SIMPLE","NOSIMPLE", "SIMPLEC", NULL};
const char Separador = ,;
const bool MULT_POR_RHO_ON = true;
const bool MULT_POR_RHO_OFF = false;
class NavierStokes : protected GuardarEnsight
{
...
1.
Se declaran tres instancias de la clase ConveccionTransitoria para resolver cada
una de las componentes de la ecuaci n vectorial de la cantidad de movimiento. Para el
o
m todo SIMPLE, la soluci n de cada una de las ecuaciones de la cantidad de movimiento se
e
o
almacenar en VmAstU, VmAstV y VmAstW seg n corresponda; posteriormente, se agregar n
a
u
a
a estas velocidades el efecto de la correcci n de presi n resultando el valor de VelU, VelV
o
o
y VelW que representa el valor de la velocidad en la iteraci n m. El valor de la velocidad en
o
la iteraci n anterior es necesario para el uso del par metro de subrelajaci n de la presi n y
o
a
o
o
la velocidad, es por esto que se crea los vectores VelU_ant, VelV_ant y VelW_ant.
...
ConveccionTransitoria ConvVu, ConvVv, ConvVw;
Vector<real> VelU, VelV, VelW;
Vector<real> VelU_ant, VelV_ant, VelW_ant;
Vector<real> VmAstU, VmAstV, VmAstW;
...
135
2.
Se declaran las variables en las cuales se almacenar n el gradiente de cada una de las
a
componentes de la velocidad, ya sea en el presente (GU_ant,...), en el futuro (GU_n,...) o
un valor dependiente de ambos (GU,...). Se utiliza la clase Vector_basico con la plantilla
Vector_xyz<real> debido a que el resultado del gradiente de un escalar es un vector para
cada volumen de control.
...
Vector_basico<Vector_xyz<real>> GU, GV, GW, GP, Gtau;
Vector_basico<Vector_xyz<real>> GU_n, GV_n, GW_n, GP_n;
Vector_basico<Vector_xyz<real>> GU_ant, GV_ant, GW_ant, GP_ant;
Vector_basico<Vector_xyz<real>> Fcalor;
Vector<real> GVel, GVel_ant,GVel_n ;
Vector_basico<Matriz<real>> Tau_n, Tau_ant, Tau;
...
Se declaran GVel, GVel_ant y GVel_n para almacenar el valor de
V en el pasado, el
...
Vector<real> Volumen;
Vector<real> Fuente;
Vector<real> ResiduoMasico;
...
5.
Se dene la malla como un Puntero a MallaFV de manera que solo es necesario
generar la malla una vez y acceder a ella mediante punteros. Para calcular la geometra de
...
Vector<real>
Vector<real>
Vector<real>
Vector<real>
real Rgas;
...
rho;
k;
cp;
mu;
7.
Se denen los par metros del tiempo theta, tiempo_p y t_aux; t_aux se usa para
a
no exportar los resultados a trav s del tiempo y solo mostrar los resultados nales en caso
e
que el an lisis sea en estado transitorio. Se declara Nitera para almacenar el n mero lmite
a
u
o
a
...
void Condiciones_iniciales();
138
void DimensionarVectoresMatrices();
void CalcPresRef();
real DensidadfPyT (int nvol);
...
2.
La funci n CalculoUnCiclo() realiza la llamada a los m todos correspondientes de
o
e
acuerdo al esquema de soluci n seleccionado. La funci n CuartoPasoSIMPLE(...) es
o
o
un proceso com n para calcular la ecuaci n de la energa que, para el caso de densidad y
u
o
4.
Los siguientes m todos son p blicos, se declara la funci n Leer() encargada de
e
u
o
tomar algunos de los datos iniciales del problema y, se declara Calcular() como el procedimiento que calcula la soluci n del problema a partir de los par metros anteriormente
o
a
indicados.
...
public:
NavierStokes(void);
NavierStokes(void) {}
int Leer(Cadena archivo,Cadena solucionador,
Cadena def_tiempo, real dep_futuro=1.0 ,
Cadena solucionadorTemp = "Igual");
int Calcular ();
...
5.
C lculo de operaciones matem ticas: los siguientes procedimientos son usados para
a
a
denir cada una de las formas de utilizar el operador , algunos de los datos se toman por
referencia para evitar el gasto de tiempo al crear las copias de los vectores y para entregar
el resultado de las operaciones.
...
bool NablaEsc ( Vector<real> &Entrada,
Vector_basico< Vector_xyz <real>> &Salida, Cadena Frontera = "Ninguna");
bool NablaDotVec ( Vector_basico< Vector_xyz <real>> &Entrada,
Vector<real> &Salida, Cadena Frontera = "Ninguna");
bool NablaDotVecEspecial ( Vector_basico< Vector_xyz <real>> &Entrada,
Vector<real> &Salida, bool MultRho = false);
bool TensorPorVector_xyz (Matriz<real> Me,
Vector_xyz<real> Ve, Vector_xyz<real> &Salida);
bool NablaPorMatriz ( Vector_basico< Matriz <real>> &Entrada,
140
Vector_basico<Vector_xyz<real>> &Salida);
Matriz<real> PromMatriz(Matriz<real> E1, real , Matriz<real> E2, real );
...
Se dene la funci n GuardarDatos() m s una sobrecarga para almacenar en archivos de
o
a
texto los valores necesarios para continuar en otro momento la soluci n del problema. A
o
continuaci n se declaran varios m todos para modicar el valor de los par metros de cono
e
a
trol.
...
bool
bool
bool
void
bool
bool
void
void
void
void
void
bool
void
GuardarDatos();
GuardarDatos(real minvel,real maxvel);
SetCargarDatos(bool opcion);
SetNoIterExt(int set);
SetTipoMetodoSolucion(Cadena tipo);
SetEsquemaConveccion(Cadena tipo);
SetMinimaPresion(real min);
SetMaximaPresion(real max);
SetTrefyDensidad(real tt, bool densidad_constante);
SetPresAtmosf(real pp);
ResetMinMaxPresion ();
SetMAssThreshold(real MaxResMas);
SubRelajaSIMPLE(real);
...
6.
Adicionalmente a la funci n Leer() que toma los datos m s esenciales para soluo
a
cionar el problema, se dene la funci n SetParametros(...) en la cual se modican los
o
procedimientos a usar para calcular y solucionar el problema.
...
bool SetParametros (bool Datos_iniciales_externos = false,
int N_iteraciones = 100, Cadena Esquema_conveccion = "UDS" ,
Cadena Esquema_solucion ="SIMPLE", bool Resultados_indep_tiempo=true);
...
};
Denici n de las funciones: a continuaci n se muestra el c digo que se ejecuta al realizar
o
o
o
la llamada de cada uno de los m todos anteriormente declarados.
e
1.
El constructor: el constructor sin argumentos da valores por defecto a algunas de las
variables de la clase.
141
NavierStokes::NavierStokes(void)
{
leido = solucionado = CargarDatos = minPres = maxPres = false;
ResEstable = true;
Nitera = 1000; MAssThreshold = 1e-10;
MetodoSolveNS = "SIMPLE"; MetodoAprox = "UDS";
Rgas = 0.2870; densidad_kte = true;
TrefparaDensidad = 273.0; Patm = 101325;
t_aux.vincular(new prmTiempo()); t_aux->Leer("dt=0");
}
2.
M todo Leer(..): este m todo toma como argumentos el nombre del archivo que
e
e
contiene la denici n del problema, el nombre del archivo que contiene el m todo de
o
e
soluci n del problema, la denici n del tiempo en el cual se realizar el an lisis, ya sea
o
o
a
a
en estado transitorio o en estado estable, por ultimo, el valor de que dene la dependencia
del futuro y del presente para calcular las propiedades.
...
int NavierStokes::Leer(Cadena archivo,Cadena solucionador,
Cadena def_tiempo, real dep_futuro , Cadena solucionadorTemp)
{
int i;
...
I.
La creaci n de la malla se realiza con la llamada a Leer() de ConvVu, no sin antes
o
llamar a SetPropiedadesExternas(true). Debido a que Leer(...) no toma como
par metro el nombre de la condici n de frontera de la propiedad que va a calcular, se debe
a
o
llamar a CadenaFrontera(...) con el argumento "VelU". Posteriormente, se toma el
puntero de la malla generada por ConvVu y se asigna a malla de la clase NavierStokes,
tambi n se extrae el puntero del objeto prmTiempo.
e
...
std_o<<"\n::::::::Malla Velocidad U::::::::::\n";
ConvVu.SetPropiedadesExternas(true);
ConvVu.Leer (archivo ,solucionador,def_tiempo,0);
ConvVu.CadenaFrontera("VelU");
ConvVu.GetMalla(malla);
ndim = malla->obtNoDimEspacio();
nvol = malla->obtNoElem();
tiempo_p = ConvVu.GetTiempo();
...
II. Para las dem s instancias de ConveccionTransitoria se sigue un procedimiento
a
diferente. Primero se ejecuta SetPropiedadesExternas(true) y posteriormente se
142
campo_corr_vel.vincular(new CampoFVM(malla(),"CorrVelV"));
campo_vel.vincular(new CamposFVM(malla(),"Velocidad"));
campo_u.vincular (new CampoFVM(malla(),"Velocidad_U"));
campo_residuo.vincular (new CampoFVM(malla(),"Residuo_Masico"));
campo_GTau.vincular (new CamposFVM(malla(),"GradTau"));
campo_GU.vincular (new CamposFVM(malla(),"GU"));
campo_GV.vincular (new CamposFVM(malla(),"GV"));
campo_GW.vincular (new CamposFVM(malla(),"GW"));
campo_GP.vincular (new CamposFVM(malla(),"GP"));
campo_Q.vincular (new CamposFVM(malla(),"Qcond"));
gdl.vincular(new GradoLibertadFV(malla(),1));
...
VI. En esta oportunidad se proporciona una serie de par metros para modicar la forma
a
como se exportan los datos a Paraview.
...
Is iss("ARCH=Infomacion_grafica.txt");
GuardarEnsight::Leer(iss, ndim);
theta = dep_futuro;
...
El archivo Infomacion_grafica.txt al cual se hace referencia contiene la siguiente informaci n:
o
Parametros para Guarda para visualizacion
>puntos_tiempo = [0:10,0.01]
>linea1:inicio = NONE
>linea1:parada = NONE
>linea1:resolucion = 31
>linea2:inicio = NONE
>linea2:parada = NONE
>linea2:resolucion = 31
>linea3:inicio = NONE
>linea3:parada = NONE
>linea3:resolucion = 31
>series_tiempo = d=2 n=0 <
>formato_campo =ASCII
>formato_malla = ASCII
>verbose = OFF
VII. Debido a la cantidad de vectores que se deben dimensionar, se proporciona una
funci n especca para esta tarea. Una vez se han dimensionado los vectores, se procede
o
...
DimensionarVectoresMatrices();
for (i=1; i<=nvol;i++) {
elems(i).refill( malla->obtTipoElem(i), malla->obtNoDimEspacio() );
elems(i)->CalcGeomParameters( malla->obtCoorElem(i) );
}
for (i=1; i<=nvol; i++) Volumen(i) = elems(i)->getVolume();
Condiciones_iniciales();
leido = true;
return 1;
}
Se naliza la ejecuci n de Leer(...) con la modicaci n del par metro de control y la
o
o
a
devoluci n del valor 1.
o
3.
M todo DimensionarVectoresMatrices(): se dene un procedimiento encargado
e
de dimensionar cada uno de los vectores seg n sea el caso. Para las variables de tipo
u
Vector<real> como VelU es suciente con llamar a chaSize(nvol) en cambio,
para dimensionar elementos del tipo Vector_basico<Vector_xyz<real>> como GU o
Vector_basico<Matriz<real>> como Tau adicionalmente se debe llenar cada uno de
los elementos del vector b sico, raz n por la cual es necesario utilizar un bucle repetitivo
a
o
for(i=1;i<=nvol;i++).
void NavierStokes::DimensionarVectoresMatrices()
{
int i;
CoefU.chaSize(nvol); CoefV.chaSize(nvol); CoefW.chaSize(nvol);
VmAstU.chaSize(nvol); VmAstV.chaSize(nvol); VmAstW.chaSize(nvol);
VelU.chaSize(nvol); VelU_ant.chaSize(nvol);
VelV.chaSize(nvol); VelV_ant.chaSize(nvol);
if (ndim==3) { VelW.chaSize(nvol); VelW_ant.chaSize(nvol); }
GVel.chaSize(nvol); GVel_ant.chaSize(nvol); GVel_n.chaSize(nvol);
Presion_ant.chaSize(nvol); Presion.chaSize(nvol);
Presion_n.chaSize(nvol); Presionprima.chaSize(nvol);
Fuente.chaSize(nvol); ResiduoMasico.chaSize (nvol);
Tau.chaSize(nvol); Tau_n.chaSize(nvol); Tau_ant.chaSize(nvol);
Gtau.chaSize(nvol); Fcalor.chaSize(nvol);
GU.chaSize (nvol); GU_ant.chaSize(nvol);
GU_n.chaSize (nvol); GV_n.chaSize (nvol);
GV.chaSize (nvol); GV_ant.chaSize(nvol);
if (ndim == 3 )
{GW.chaSize (nvol);GW_ant.chaSize(nvol);
GW.chaSize (nvol); }
GP.chaSize (nvol); GP_ant.chaSize(nvol);
145
GP_n.chaSize (nvol);
for (i=1; i <= nvol; i++) {
GU(i).chaSize(ndim); GU_ant(i).chaSize(ndim);
GU_n(i).chaSize(ndim);GV_ant(i).chaSize(ndim);
GV(i).chaSize(ndim); GV_n(i).chaSize(ndim);
if (ndim == 3 )
{GW(i).chaSize(ndim);GW_ant(i).chaSize(ndim);
GW_n(i).chaSize(ndim);}
GP(i).chaSize(ndim); GP_n(i).chaSize(ndim);
GP_ant(i).chaSize(ndim);
Tau(i).chaSize(ndim);Tau_n(i).chaSize(ndim);
Tau_ant(i).chaSize(ndim); Gtau(i).chaSize(ndim);
Fcalor(i).chaSize(ndim);
}
Temp.chaSize(nvol); Temp_ant.chaSize(nvol);
rho.chaSize(nvol); k.chaSize(nvol);
cp.chaSize(nvol); mu.chaSize(nvol);
Volumen.chaSize(nvol);
elems.chaSize(nvol);
}
4.
M todo Condiciones_iniciales(): se asigna un valor a las propiedades del mae
terial y a la velocidad inicial, adicionalmente se realiza el llenado de otros vectores con
el valor 0. Se agrega el condicional if(CargarDatos) para tener la opci n de cargar las
o
condiciones iniciales a partir de los archivos generados de una iteraci n anterior o realizar
o
un procedimiento normal de inicializaci n de las variables.
o
void NavierStokes::Condiciones_iniciales()
{
int i;
if (CargarDatos) {CargadoDeDatos();}
else {
rho.llenar(1.172); k.llenar(0.02566);
cp.llenar(1007); mu.llenar(1.858e-5);
VelU.llenar(1.0); VelU_ant = VelU;
VelV.llenar(0.00);VelV_ant = VelV;
VelW.llenar(0.0); VelW_ant = VelW;
Presion.llenar(0.0);
Presion_ant = Presion_n= Presion;
for (i=1; i<= nvol; i++) {
GU_ant(i).llenar(0.0);GU_n(i).llenar(0.0);
GV_ant(i).llenar(0.0);GV_n(i).llenar(0.0);
146
if (ndim == 3 )
{GW_ant(i).llenar(0.0); GW_n(i).llenar(0.0);}
GP_n(i).llenar(0.0);GP_ant(i).llenar(0.0);
Tau_n(i).llenar(0.0);Tau_ant(i).llenar(0.0);
Fcalor(i).llenar(0.0);
}
GVel.llenar(0.0);
Temp.llenar(0.0);Temp_ant.llenar(0.0);
}
VmAstU = VelU; VmAstV = VelV;
if (ndim == 3) VmAstW= VelW;
Presionprima = Presion; vcor.llenar(0.0);
}
5.
M todo Calcular(): antes de denir el procedimiento que realiza las iteraciones
e
exteriores se verica el par metro de control leido, se declaran e inicializan algunas vaa
riables y se llama al m todo SetPasadoPartida(...) de ConveccionTransitoria y
e
DifusionTransitoria, es importante realizar esta llamada para proporcionar el valor de
las propiedades en el tiempo anterior y un punto de partida para la soluci n de cada una de
o
las ecuaciones lineales.
int NavierStokes::Calcular()
{
if (!leido) return 0;
bool NIterAlc = false, convergio = false;
int m=0; real norma; Cadena temm;
Vector<real> uno(nvol); uno.llenar(1.0);
Vector<real> cero(nvol); cero.llenar(0.0);
solucionado = true;
tiempo_p->iniciarCicloTiempo(); t_aux->iniciarCicloTiempo();
ConvVu.SetPasadoPartida(VelU_ant,uno);
ConvVv.SetPasadoPartida(VelV_ant,uno);
if (ndim == 3)
ConvVw.SetPasadoPartida(VelW_ant,VmAstW);
Pprima.SetPasadoPartida(Presionprima,cero);
Corrv.SetPasadoPartida(VelV_ant,uno);
Temperatura.SetPasadoPartida (Temp_ant,cero);
...
La soluci n de las ecuaciones de Navier-Stokes por el m todo SIMPLE se puede realizar
o
e
en estado estable o en estado transitorio. A continuaci n se muestra el procedimiento a
o
realizar para un an lisis en estado estable. B sicamente, se realizan los c lculos de cada
a
a
a
147
...
if (tiempo_p->estacionario())
{
theta= 1.0 ;
do {
m++;
CalculoUnCiclo();
norma = ResiduoMasico.norma();
std_o<<" RM norma "<<norma<<" ";
if (m>=Nitera)
{std_o<<"\nNo.limite iteraciones alcanzado\n";NIterAlc=true;}
if ( norma<MAssThreshold)
convergio = true;
std_o<<" Iteracion exterior No. "<<m<<" \n\n\n";
} while (!convergio && !NIterAlc);
if (ResEstable) CuartoPasoSIMPLE(true);
SolucionUnTiempo();
Reportarresultados();
}
...
Para el caso transitorio se tiene el tiempo m ximo de simulaci n como criterio adicional
a
o
de parada, si se excede este valor no se continuar con el an lisis. Cabe agregar que la
a
a
forma c mo se calcula el estado transitorio no permite obtener exactamente el resultado del
o
an lisis a trav s del tiempo, la raz n de esto es que solo se realiza una iteraci n exterior por
a
e
o
o
cada avance del tiempo, los resultados siempre ser n aproximados para un tiempo intermea
dio ya que no se cumplen al mismo tiempo con las ecuaciones de la cantidad de movimiento
y de continuidad. A partir de este hecho, se propone la creaci n del par metro de control
o
a
ResEstable en el cual se indica si se quiere realizar el reporte de los resultados en estado
estable a pesar que el an lisis haya sido realizado en estado transitorio.
a
...
else {
if (!ResEstable) {
SolucionUnTiempo();
Reportarresultados();
}
m=0;
148
do {
tiempo_p->incrementarTiempo();
m++;
CalculoUnCiclo();
norma = ResiduoMasico.norma();
std_o<<" RM norma "<<norma<<" ";
if (m>=Nitera)
NIterAlc=true;
if ( norma<MAssThreshold)
{convergio = true; NIterAlc = false;}
std_o<<" Iteracion exterior No. "<<m<<" \n\n\n";
ActualizarPyTau();
if (!ResEstable) {
SolucionUnTiempo();
Reportarresultados();
}
} while (!tiempo_p->finalizo() && !convergio && !NIterAlc);
if (ResEstable) {
CuartoPasoSIMPLE(true);
SolucionUnTiempo();
Reportarresultados();
}
}
solucionado=true;
return 1;
}
Para exportar los resultados en cada tiempo es necesario llamar a SolucionUnTiempo() y
Reportarresultados(). Posteriormente se explicar la funci n de cada uno de estos dos
a
o
m todos. Para el an lisis transitorio tambi n se debe llamar a ActualizarPyTau() que se
e
a
e
encarga de pasar los valores recientemente calculados a las variables del tiempo anterior.
6.
M todo CalculoUnCiclo(): la vericaci n del m todo a seguir para resolver las
e
o
e
ecuaciones de NavierStokes se realiza en el siguiente fragmento de c digo, de esta manera,
o
resulta sencillo utilizar otros m todos para resolver las ecuaciones.
e
int NavierStokes::CalculoUnCiclo()
{
int i;
if (MetodoSolveNS=="SIMPLE")
{PrimerPasoSIMPLE();SegundoPasoSIMPLE();
TercerPasoSIMPLE();CuartoPasoSIMPLE();
}
149
if (MetodoSolveNS=="NOSIMPLE") {
PrimerPasoNOSIMPLE();
std_o<<"VelV Min "<<VelV.minValor()<<" Max "<<VelV.maxValor()<<" \n";
SegundoPasoNOSIMPLE();
TercerPasoNOSIMPLE();
CuartoPasoSIMPLE();
}
if (MetodoSolveNS=="SIMPLEC")
{ PrimerPasoSIMPLE();SegundoPasoSIMPLEC();
TercerPasoSIMPLE();CuartoPasoSIMPLE();
}
CalcularTauyGVs();
CalcularPyG();
return 1;
}
Al nal de cada ciclo se debe calcular el gradiente de cada una de las componentes de la
velocidad y la presi n entre otros t rminos, para realizar este trabajo se llama a
o
e
CalcularTauyGVs() y CalcularPyG().
7.
M todo CalcularTauyGVs(): realiza el c lculo de todas las operaciones necesarias
e
a
que est n relacionadas con el operador y la velocidad.
a
I.
El primer paso a realizar es la declaraci n de variables. Se declara VelVec como
o
Vector_basico<Vector_xyz<real>> y se inicializa con las componentes de la velocidad para posteriormente calcular V .
bool NavierStokes::CalcularTauyGVs( )
{
int i;
Vector_basico<Vector_xyz<real>> VelVec;
VelVec.chaSize(nvol);
for (i=1; i <= nvol; i++) {
VelVec(i).chaSize(ndim);
VelVec(i)(1)= VelU(i);
VelVec(i)(2)= VelV(i);
if (ndim == 3 )
VelVec(i)(3)= VelW(i);
}
....
II. El siguiente paso es calcular u, v y w mediante la llamada a NablaEsc(...),
el ultimo par metro que se entrega es una Cadena la cual permite identicar la condici n
a
o
de frontera que se debe seleccionar. En este fragmento de c digo tambi n se puede ver la
o
e
instrucci n NablaDotVec(...) que se encarga de calcular V .
o
150
...
NablaEsc (VelU, GU_n, "VelU");
if (theta!=1.0) NablaEsc (VelU_ant, GU_ant, "VelU");
NablaEsc (VelV, GV_n, "VelV");
if (theta!=1.0) NablaEsc (VelV_ant, GV_ant, "VelV");
if (ndim == 3) NablaEsc (VelW, GW_n, "VelW");
if (theta!=1.0 && ndim == 3) NablaEsc (VelW_ant, GW_ant, "VelW");
NablaDotVec(VelVec,GVel_n, "Vel");
...
III. Los valores calculados en el anterior fragmento de c digo fueron almacenados en
o
las variables terminadas con "*_n. Para calcular los valores que realmente van a ser
utilizados, se debe tener en cuenta el par metro theta que dene la dependencia del
a
tiempo futuro e indirectamente la dependencia del tiempo actual.
...
for (i=1; i<= nvol; i++) {
GVel(i) = (GVel_n(i))*theta
GU(i) = (GU_n(i)) * theta +
GV(i) = (GV_n(i)) * theta +
if (ndim == 3)
GW(i) = (GW_n(i)) * theta +
}
...
+ (GVel_ant(i))*(1-theta);
(GU_ant(i))*(1-theta);
(GV_ant(i))*(1-theta);
(GW_ant(i))*(1-theta);
IV. El llenado del tensor o Tau se realiza en las siguientes instrucciones. Tambi n se
e
tiene en cuenta el c lculo en el tiempo futuro Tau_n y en el tiempo presente Tau_ant para
a
realizar la asignaci n a Tau.
o
...
for (i=1; i <= nvol; i++) {
Tau_n(i)(1,1) = (-2.0* mu(i) / 3.0) * GVel_n(i) +
(1.0*mu(i)*GU_n(i)(1));
Tau_n(i)(1,2) = Tau_n(i) (2,1) = mu(i)*(GU_n(i)(2)+GV_n(i)(1));
Tau_n(i)(2,2) = (-2.0* mu(i) / 3.0) * GVel_n(i) +
(1.0*mu(i)*GV_n(i)(2));
if (ndim==3) {
Tau_n(i)(3,3) = (-2.0* mu(i) / 3.0) * GVel_n(i) +
(1.0*mu(i)*GW_n(i)(3));
Tau_n(i)(1,3) = Tau_n(i) (3,1) = mu(i)*(GU_n(i)(3)+GW_n(i)(1));
Tau_n(i)(2,3) = Tau_n(i) (3,2) = mu(i)*(GV_n(i)(3)+GW_n(i)(2));
}
Tau(i)(1,1) = Tau_n(i)(1,1) *theta + (1-theta) * Tau_ant(i)(1,1);
Tau(i)(1,2) = Tau(i)(2,1) = Tau_n(i)(1,2) *theta +
(1-theta) * Tau_ant(i)(1,2);
151
return true;
}
10. M todo ActualizarPyTau(): en el an lisis transitorio, se debe actualizar los valores
e
a
de las propiedades en el presente por los valores del futuro para continuar con el siguiente
tiempo, esta es la funci n de ActualizarPyTau().
o
bool NavierStokes::ActualizarPyTau()
{
int i;
VelU_ant = VelU; VelV_ant = VelV;
if (ndim == 3)
VelW_ant = VelW;
for (i=1; i<=nvol ; i++)
{
GU_ant(i) = GU_n(i);
GV_ant(i) = GV_n(i);
if (ndim == 3)
GW_ant(i) = GW_n(i);
GVel_ant(i)=GVel_n(i); Tau_ant(i) =Tau_n(i);
}
Presion_ant = Presion_n;
for (i=1; i<=nvol ; i++) GP_ant(i) = GP_n(i);
Temp_ant = Temp ;
return true;
}
11. M todo PrimerPasoSIMPLE(): en este procedimiento se resuelven las ecuaciones
e
de la cantidad de movimiento de acuerdo a como se present en el primer paso del m todo
o
e
SIMPLE. El procedimiento seguido para cada una de las componentes es muy similar.
I.
bool NavierStokes::PrimerPasoSIMPLE()
{
bool correcto; int i;
Vector<real> dPdn(nvol), EfVisc(nvol);
...
II. Antes de asignar los coecientes a la ecuaci n de cantidad de movimiento en x,
o
se debe calcular el t rmino fuente como se muestra en la tabla 13. El t rmino fuente
e
e
est compuesto por el efecto del gradiente de la presi n y el efecto del gradiente de la
a
o
viscosidad. Una vez se realiza la suma algebraica, se multiplica por el volumen de cada
VC y se procede a ejecutar ConvVu.SetFuenteYFlujo(...) la cual introduce el valor
del t rmino fuente y las componentes de la velocidad, seguidamente se asigna el valor de
e
la propiedad en el tiempo pasado (VelU_ant) y se actualiza el valor de las propiedades
del material. Para asignar = en la clase ConveccionTransitoria se debe llamar a
la versi n sobrecargada de SetPropiedades de dos par metros,
o
a
153
...
Fuente.llenar( 0.0 );
for (i=1; i<=nvol; i++) {dPdn (i) = GP (i)(1); }
Fuente -= dPdn;
for (i=1; i<=nvol; i++) {EfVisc(i) = Gtau(i)(1);}
Fuente += EfVisc;
for (i=1; i<=nvol; i++) Fuente(i) = Fuente(i) * Volumen(i);
ConvVu.SetFuenteYFlujo(Fuente,VelU,VelV, VelW);
ConvVu.SetPasado(VelU_ant);
ConvVu.SetPropiedades (rho, mu);
CoefU = ConvVu.CalcularCoefUnTiempo
(theta, tiempo_p, MetodoAprox, correcto);
VmAstU = ConvVu.SolucionCoefUnTiempo (CargarDatos,correcto);
En este punto ya es posible calcular la matriz de coecientes y el vector de t rminos
e
independientes, la llamada a CalcularCoefUnTiempo(...) devuelve el valor de los ele
mentos en la diagonal principal y modica el valor de la variable de tipo bool en el ultimo
par metro para indicar si el proceso termin correctamente. Por ultimo, para la ecuaci n
a
o
o
de la cantidad de movimiento en x, se resuelve el sistema de ecuaciones y se obtiene el
valor de um representado por la variable VmAstU.
III. Se sigue un procedimiento similar para las dem s componentes de la velocidad, se
a
debe seleccionar el valor correcto del gradiente de la presi n y del gradiente del tensor de
o
esfuerzos. El procedimiento se muestra a continuaci n:
o
Fuente.llenar(0.0);
for (i=1; i<=nvol; i++) {dPdn (i) = GP (i)(2); }
Fuente -= dPdn;
for (i=1; i<=nvol; i++) {EfVisc(i) = Gtau(i)(2);}
Fuente += EfVisc;
for (i=1; i<=nvol; i++) Fuente(i) = Fuente(i) * Volumen(i);
ConvVv.SetFuenteYFlujo(Fuente,VelU,VelV, VelW);
ConvVv.SetPasado(VelV_ant);
ConvVv.SetPropiedades (rho, mu);
CoefV=ConvVv.CalcularCoefUnTiempo
(theta, tiempo_p,MetodoAprox, correcto);
VmAstV = ConvVv.SolucionCoefUnTiempo (CargarDatos, correcto );
if (ndim == 3 ) {
Fuente.llenar(0.0);
for (i=1; i<=nvol; i++) {dPdn (i) = GP (i)(3); }
Fuente -= dPdn;
for (i=1; i<=nvol; i++) {EfVisc(i) = Gtau(i)(3);}
Fuente += EfVisc;
for (i=1; i<=nvol; i++) Fuente(i) = Fuente(i) * Volumen(i);
ConvVw.SetFuenteYFlujo(Fuente,VelU,VelV, VelW);
154
InvVec(2)
vprima(i)
vAst(i) =
VelV(i) =
= 1 / CoefV(i);
= -Volumen(i) * InvVec(2) *Gradiente(i)(2);
VmAstV(i) + vprima(i);
alpV * vAst(i) + (1-alpV) * VelV(i);
if (ndim == 3) {
InvVec(3) = 1 / CoefW(i);
wprima(i) = -Volumen(i) * InvVec(3)*Gradiente(i)(3);
wAst(i) = VmAstW(i) + wprima(i);
VelW(i) = alpV * wAst(i) - (1.0 - alpV) * VelW(i);
}
}
return true;
}
Para nalizar, se entrega el valor true como respuesta al segmento del programa que
realiz la llamada del m todo.
o
e
14.
la energa y se actualiza el valor de la densidad en caso que sea variable. Se incorpora una
serie de condicionales que permiten omitir el c lculo del balance de energa en caso que la
a
a
o
introducir los datos a los campos vectoriales es necesario declarar tres vectores adicionales
de tipo Vector<real>.
int NavierStokes::SolucionUnTiempo()
{
CalcPresRef();
Vector<real> gtu(nvol), gtv(nvol), gtw(nvol);
gdl->vector2campo(VelU,campo_u());
gdl->vector2campo(Presion,campo_pres());
gdl->vector2campo(Presionprima,campo_pres_prima());
158
gdl->vector2campo(vcor,campo_corr_vel());
gdl->vector2campo(Temp,campo_T());
gdl->vector2campo(ResiduoMasico,campo_residuo());
gdl->vector2campo(VelU,campo_vel()(1));
gdl->vector2campo(VelV,campo_vel()(2));
if ( malla->obtNoDimEspacio()==3)
gdl->vector2campo(VelW,campo_vel()(3));
for (int i=1; i<= nvol; i++) {
gtu(i)=Gtau(i)(1);
gtv(i)=Gtau(i)(2);
if (ndim==3)
gtw(i)=Gtau(i)(3);
}
gdl->vector2campo(gtu,campo_GTau()(1));
gdl->vector2campo(gtv,campo_GTau()(2));
if (ndim==3)
gdl->vector2campo(gtw,campo_GTau()(3));
for (int i=1; i<= nvol; i++) {
gtu(i)=GU(i)(1);
gtv(i)=GU(i)(2);
if (ndim==3)
gtw(i)=GU(i)(3);
}
gdl->vector2campo(gtu,campo_GU()(1));
gdl->vector2campo(gtv,campo_GU()(2));
if (ndim==3)
gdl->vector2campo(gtw,campo_GU()(3));
for (int i=1; i<= nvol; i++) {
gtu(i)=GV(i)(1);
gtv(i)=GV(i)(2);
if (ndim==3)
gtw(i)=GV(i)(3);
}
gdl->vector2campo(gtu,campo_GV()(1));
gdl->vector2campo(gtv,campo_GV()(2));
if (ndim==3)
gdl->vector2campo(gtw,campo_GV()(3));
for (int i=1; i<= nvol; i++) {
gtu(i)=GP(i)(1);
gtv(i)=GP(i)(2);
159
if (ndim==3)
gtw(i)=GP(i)(3);
}
gdl->vector2campo(gtu,campo_GP()(1));
gdl->vector2campo(gtv,campo_GP()(2));
if (ndim==3)
gdl->vector2campo(gtw,campo_GP()(3));
for (int i=1; i<= nvol; i++) {
gtu(i)=Fcalor(i)(1);
gtv(i)=Fcalor(i)(2);
if (ndim==3)
gtw(i)=Fcalor(i)(3);
}
gdl->vector2campo(gtu,campo_Q()(1));
gdl->vector2campo(gtv,campo_Q()(2));
if (ndim==3)
gdl->vector2campo(gtw,campo_Q()(3));
return true;
}
volcar(campo_T(),0);
volcar(campo_Q(),0);
}
else
{
volcar(campo_T(),tiempo_p.obtPtr());
volcar(campo_vel(),tiempo_p.obtPtr());
volcar(campo_pres(),tiempo_p.obtPtr());
volcar(campo_u(),tiempo_p.obtPtr());
if (MetodoSolveNS=="NOSIMPLE")
{volcar(campo_corr_vel(),tiempo_p.obtPtr());}
else { volcar(campo_pres_prima(),tiempo_p.obtPtr());}
volcar(campo_residuo(),tiempo_p.obtPtr());
volcar(campo_Q(),tiempo_p.obtPtr());
}
}
Seg n el m todo de soluci n escogido, se debe guardar los resultados del campo de correu
e
o
cci n de presi n o el campo de correci n de la velocidad3 .
o
o
o
17. M todo LeerFrontEsp(...): se dene este procedimiento como una forma com n
e
u
para todos los procesos que necesiten obtener el valor de una propiedad en la frontera
siendo fr la Cadena en la cual se encuentra la informaci n del tipo y valor de la condici n
o
o
de frontera.
real NavierStokes::LeerFrontEsp(int i, int j, real muestra, Cadena fr )
{
real valor = muestra, valor2, px, py; Cadena bovalue = fr.despues("=");
Vector_xyz<real> minc, maxc; malla->obtCoorMinMax(minc, maxc);
if (fr.contiene("Dirichlet") ) {
valor
= atof(bovalue.carts());
px = elems(i)->centroArea(malla->obtCoorElem(i),j)(1);
py = elems(i)->centroArea(malla->obtCoorElem(i),j)(2);
if (fr.contiene("e")) {
bovalue = fr.despues("e"); valor2 = atof(bovalue.carts());
valor = valor * exp( valor2*(px-minc(1)) );
}
if (fr.contiene("x")){
bovalue = fr.despues("x"); valor2 = atof(bovalue.carts());
valor = valor * pow( px-minc(1) ,valor2);
}
if (fr.contiene("rooty")){
3 Posteriormente
161
bool NavierStokes::LeerFronteras
(Cadena TomarFrontera, Vector_basico<Cadena> &fr)
{
int i, j, k, nbi;
Cadena med;
nbi = malla->obtNoIndFront();
fr.chaSize (nbi);
for (i=1; i<=nbi; i++) {
fr(i) = malla->obtNombreIndFront(i);
if (fr(i).contiene(TomarFrontera)) {
j = fr(i).Buscar(0,TomarFrontera);
k = fr(i).tam();
med = fr(i).subCadena(j, k-j );
if (med.contiene(Separador)) {
j = med.Buscar(0,Separador);
med = med.subCadena(0,j);
}
fr(i) = med;
}
}
162
return true;
}
La siguiente sobrecarga a la funci n LeerFronteras() retorna el valor de las condiciones
o
de frontera para la velocidad.
bool NavierStokes::LeerFronteras
(Vector_basico<Cadena> &fr1, Vector_basico<Cadena> &fr2,
Vector_basico<Cadena> &fr3)
{
int i,j,k, nbi;
nbi = malla->obtNoIndFront();
Cadena med, ap;
fr1.chaSize(nbi);fr2.chaSize(nbi);fr3.chaSize(nbi);
for (i=1; i<=nbi; i++)
fr1(i)=fr2(i)=fr3(i) = malla->obtNombreIndFront(i);
for (i=1; i<=nbi; i++){
if (fr1(i).contiene("VelU"))
{ j = fr1(i).Buscar(0,"VelU");
k = fr1(i).tam();
med = fr1(i).subCadena(j,k-j);
if (med.contiene(Separador))
{j = med.Buscar(0,Separador);
med = med.subCadena(0,j);
}
fr1(i) = med;
}
if (fr2(i).contiene("VelV"))
{ j = fr2(i).Buscar(0,"VelV");
k = fr2(i).tam();
med = fr2(i).subCadena(j,k-j);
if (med.contiene(Separador))
{j = med.Buscar(0,Separador);
med = med.subCadena(0,j);
}
fr2(i) = med;
}
if (fr3(i).contiene("VelW"))
{ j = fr3(i).Buscar(0,"VelW");
k = fr3(i).tam();
med = fr3(i).subCadena(j,k-j);
if (med.contiene(Separador))
{ j = med.Buscar(0,Separador);
163
med = med.subCadena(0,j);
}
fr3(i) = med;
}
}
return true;
}
19. M todo NablaEsc(): esta funci n realiza el c lculo del gradiente de cualquier vae
o
a
riable escalar. Para disminuir el tiempo necesario para pasar el vector Entrada se pasa
por referencia. Adicionalmente, Salida es la variable en la cual se almacena el resultado obtenido por el m todo, raz n por la que tambi n es necesario pasar por referencia.
e
o
e
La funci n toma el argumento Cadena TomarFrontera para determinar la forma correcta
o
de hallar el valor de Entrada en la frontera, por defecto, TomarFrontera tiene el valor
de "Ninguna" caso en el que se asume que el valor de Entrada en la frontera puede ser
representado por el valor en el centro del volumen de control.
I.
El primer paso es declarar las variables a usar en la ejecuci n de la funci n. Se
o
o
declara fr como una instancia de Vector_basico<Cadena> para almacenar la informaci n de la condici n de frontera correcta para cada lado.
o
o
bool NavierStokes::NablaEsc ( Vector<real> &Entrada,
Vector_basico<Vector_xyz<real>> &Salida, Cadena TomarFrontera )
{ int i, j, k, veci, conx; int nbi= malla->obtNoIndFront();
real prom, area, d1, d2;
Vector_xyz<real> dir(ndim); Vector_basico<Cadena> fr;
if (TomarFrontera!="Ninguna") LeerFronteras(TomarFrontera,fr);
...
II. Se realiza un bucle repetitivo que recorre cada volumen de control, seguidamente
se llenan todas las componentes del Vector_xyz<real> Salida(i) con el valor 0. Se
determina el n mero de lados del volumen de control actual y se realiza un bucle repetitivo
u
para cada lado del VC actual.
...
for (i= 1 ; i<= nvol ; i++) {
Salida(i).llenar(0.0);
conx = elems(i)->GetNumOfConex();
for ( j=1; j<=conx ; j++) {
...
III. Para cada lado se encuentra el VC que comparte dicho lado, si el lado j es una
frontera (veci=0) se procede a calcular el valor de prom de acuerdo al tipo de condici n
o
de frontera y el valor de esta. Si TomarFrontera tiene el valor especicado por defecto,
se realiza la asignaci n prom=Entrada(i).
o
164
...
veci = malla->getConx (i, j); area = elems(i)->getArea(j);
if ( veci==0) {
if (TomarFrontera!="Ninguna") {
for (k=1; k<=nbi; k++)
if ( malla->LadoFront(i,j,k,elems(i)())) break;
prom = LeerFrontEsp (i,j, Entrada (i),fr(k));
}
else {prom = Entrada(i);}
}
...
IV. Para el caso que el lado j sea compartido con otro VC, se asigna a prom el valor
promedio de la propiedad entre los dos vol menes de control. Finalmente, se multiplica
u
el valor encontrado por el area y el vector unitario del lado, se suma el efecto de todas
las caras y se divide el valor encontrado por el volumen correspondiente.
...
else {for ( k=1 ; k<=conx ; k++ )
if(malla->getConx(veci,k)==i) break;
d1 = elems(i)->getDelta(j);
d2 = elems(veci)->getDelta(k);
prom = (Entrada(veci) * d1 + Entrada (i) * d2)/(d1+d2);
}
Salida(i) = Salida(i) + (elems(i)->GetDirSide(j)*(area*prom));
}
Salida(i) = Salida(i) / Volumen(i);
if(nvol == 9)
{Salida(i).Escribir(std_o);std_o<<"\n";}
}
return true;
}
20. M todo NablaDotVec(...): esta funci n calcula la operaci n
e
o
o
quier propiedad vectorial, por ejemplo V .
F siendo F cual-
I.
Se declaran las variables que van a ser utilizadas para la ejecuci n de la funci n. Se
o
o
destaca la creaci n de fr1, fr2 y fr3 del tipo Vector_basico<Cadena> en las cuales se
o
almacenar n los tipos de frontera para cada una de las componentes de V .
a
bool NavierStokes::NablaDotVec ( Vector_basico< Vector_xyz <real>>
&Entrada, Vector<real> &Salida, Cadena Frontera)
{
int i, j, k, veci, conx; int nbi= malla->obtNoIndFront();
real area, rx,ry,rz,d1,d2; Vector_xyz<real> prom (ndim);
165
Vector_basico<Cadena> fr1,fr2,fr3;
if (Frontera=="Vel") LeerFronteras(fr1, fr2, fr3);
...
II. Para recorrer cada uno de los lados de cada volumen de control se utilizan dos
bucles anidados. Las condiciones de frontera se hallan con LeerFrontEsp(...) si y
solo si Frontera contiene la cadena Vel.
...
Salida.llenar (0.0);
for (i= 1 ; i<= nvol ; i++) {
conx = elems(i)->GetNumOfConex(); rx = ry =rz = 0;
for ( j=1; j<=conx ; j++) {
veci = malla->getConx (i, j); area = elems(i)->getArea(j);
if ( veci==0) {
if (Frontera.contiene("Vel")) {
for (k=1; k<=nbi; k++)
if ( malla->LadoFront(i,j,k,elems(i)())) break;
prom(1) = LeerFrontEsp(i,j,Entrada (i)(1),fr1(k));
prom(2) = LeerFrontEsp(i,j,Entrada (i)(2),fr2(k));
if (ndim == 3)
prom(3) = LeerFrontEsp(i,j,Entrada (i)(3),fr3(k));
}
else {prom = Entrada(i);}
}
else {
for ( k=1 ; k<=conx ; k++ )
if(malla->getConx(veci,k)==i)
break;
d1 = elems(i)->getDelta(j);
d2 = elems(veci)->getDelta(k);
prom = (Entrada(veci) * d1 + Entrada (i) * d2)/(d1+d2);
}
...
III. Se almacena parcialmente el valor del producto punto en rx, ry, rz y, nalmente
se suman y se divide el valor obtenido por Volumen(i).
...
rx += (prom(1)*elems(i)->GetDirSide(j)(1))*area;
ry += (prom(2)*elems(i)->GetDirSide(j)(2))*area;
if (ndim==3)
rz += (prom(3)*elems(i)->GetDirSide(j)(3))*area;
}
Salida(i) = rx + ry ;
if (ndim==3) Salida(i) += rz;
166
volumen de control. El ultimo par metro, MultRho, es utilizado como control para el caso
a
en que se deba multiplicar el valor de prom por el valor de la densidad.
bool NavierStokes::NablaDotVecEspecial ( Vector_basico< Vector_xyz
<real>> &Entrada, Vector<real> &Salida, bool MultRho )
{
int i, j, k, veci, conx; int nbi= malla->obtNoIndFront();
real area, coefar, deltap, gradp, sum, act, densidadprom, d1, d2;
Vector_xyz<real> prom (ndim), coefvel(ndim), GPprom(ndim), efec(ndim);
Vector_basico<Cadena> fr1,fr2,fr3; LeerFronteras(fr1, fr2, fr3);
Salida.llenar (0.0);
for (i= 1 ; i<= nvol ; i++) {
conx = elems(i)->GetNumOfConex(); sum = 0.0;
for ( j=1; j<=conx ; j++) {
veci = malla->getConx (i, j);
area = elems(i)->getArea(j);
if ( veci==0) {
for (k=1; k<=nbi; k++)
if ( malla->LadoFront(i,j,k,elems(i)())) break;
prom(1) = LeerFrontEsp(i,j,Entrada (i)(1),fr1(k));
prom(2) = LeerFrontEsp(i,j,Entrada (i)(2),fr2(k));
if (ndim == 3)
prom(3) = LeerFrontEsp(i,j,Entrada (i)(3),fr3(k));
densidadprom = rho(i);
coefar = elems(i)->getArea(j);//Volumen(i)/ elems(i)->getDelta(j);
coefvel(1) = (1.0/CoefU(i)) *
elems(i)->GetDirSide(j)(1) ;
coefvel(2) = (1.0/CoefV(i))*
elems(i)->GetDirSide(j)(2) ;
if (ndim == 3) coefvel(3) = (1.0/CoefW(i))*
elems(i)->GetDirSide(j)(3) ;
deltap = 0.0;
GPprom.llenar(0.0);
gradp = GPprom * elems(i)->GetDirSide(j);
167
168
muestra un error en pantalla y no se guardan los datos. Por otro lado, si las velocidades
est n dentro de los lmites esperados se realiza la llamada a la funci n GuardarDatos()
a
o
sin argumentos.
bool NavierStokes:: GuardarDatos(real minvel,real maxvel)
{
real minu, minv, minw, minimo;
real maxu, maxv, maxw, maximo;
minu = VelU.minValor(); minv = VelV.minValor();
if (ndim == 3) minw = VelW.minValor();
else
minw = 1e6;
minimo = minu; if (minv<minimo) minimo = minv;
if ( minw<minimo) minimo =minw;
maxu = VelU.maxValor(); maxv = VelV.maxValor();
if (ndim == 3) maxw = VelW.maxValor();
else maxw =-1e6;
maximo = maxu; if (maxv>maximo) maximo = maxv;
if (maxw>maximo) maximo = maxw;
if (minimo>minvel && maximo<maxvel)
{return GuardarDatos();}
else
{std_o<<"Error:: no se exportan los datos a *.m porque se excedio"
<<" el limite de la velocidad establecida\n"; }
return false;
}
La versi n sin argumentos guarda en archivos el valor de algunos de los vectores declarados
o
de manera que posteriormente se puede continuar el c lculo. Los datos se almacenan en
a
170
varios archivos con el nombre del caso, el nombre de la variable y el n mero de vol menes
u
u
de control. De esta manera, se evitan posibles errores por datos incongruentes. Un ejemplo
del nombre de un archivo generado es CLimiteTemp900.m.
bool NavierStokes:: GuardarDatos()
{
if (!solucionado)
{std_o<<"\nError: no se ha solucionado el problema\n";}
char nv [10]; Cadena nArchivo; _itoa(nvol,nv,10); strcat (nv,".m");
nArchivo = NombreCaso + "rho"; nArchivo += nv;
rho.guardar(nArchivo.carts(),"rho");
nArchivo = NombreCaso + "k"; nArchivo += nv;
k.guardar(nArchivo.carts(),"k");
nArchivo = NombreCaso + "cp"; nArchivo += nv;
cp.guardar(nArchivo.carts(),"cp");
nArchivo = NombreCaso + "mu"; nArchivo += nv;
mu.guardar(nArchivo.carts(),"mu");
nArchivo = NombreCaso + "VelU"; nArchivo += nv;
VelU.guardar(nArchivo.carts(),"VelU");
nArchivo = NombreCaso + "VelV"; nArchivo += nv;
VelV.guardar(nArchivo.carts(),"VelV");
nArchivo = NombreCaso + "VelW"; nArchivo += nv;
if (ndim==3)
VelW.guardar(nArchivo.carts(),"VelW");
nArchivo = NombreCaso + "VelU_ant"; nArchivo += nv;
VelU_ant.guardar(nArchivo.carts(),"VelU_ant");
nArchivo = NombreCaso + "VelV_ant"; nArchivo += nv;
VelV_ant.guardar(nArchivo.carts(),"VelV_ant");
nArchivo = NombreCaso + "VelW_ant"; nArchivo += nv;
if (ndim==3)
VelW_ant.guardar(nArchivo.carts(),"VelW_ant");
nArchivo = NombreCaso + "Presion_n"; nArchivo += nv;
Presion_n.guardar(nArchivo.carts(),"Presion_n");
nArchivo = NombreCaso + "Presion_ant"; nArchivo += nv;
Presion_ant.guardar(nArchivo.carts(),"Presion_ant");
nArchivo = NombreCaso + "Temp"; nArchivo += nv;
Temp.guardar(nArchivo.carts(),"Temp");
nArchivo = NombreCaso + "Temp_ant"; nArchivo += nv;
Temp_ant.guardar(nArchivo.carts(),"Temp_ant");
return true;
}
26. M todo CargadoDeDatos(): este m todo no toma ning n par metro y se encarga de
e
e
u
a
leer los datos de los vectores para poder continuar con la soluci n del problema. Una vez
o
171
27.
173
diferente al deseado. Es por esto que se denen las siguientes cuatro funciones.
void NavierStokes::SetMaximaPresion(real max)
{maxPres= true; minPres= false; maxP = max;}
void NavierStokes::SetMinimaPresion(real min)
{maxPres= false; minPres= true; minP = min;}
void NavierStokes::CalcPresRef()
{
int i; real r;
if (maxPres || minPres) {
if(maxPres){r=Presion.maxValor(); r= maxP-r;}
if(minPres){r=Presion.minValor(); r= minP-r;}
for (i=1; i<=nvol; i++)
Presion(i) = Presion(i) + r;
}
}
void NavierStokes::ResetMinMaxPresion() { minP = maxP = false;}
32. M todo SetParametros(...): en este m todo se asignan los valores a los par metros
e
e
a
m s importantes que denen el modo de realizar el c lculo.
a
a
bool NavierStokes::SetParametros (bool Datos_iniciales_externos ,
int N_iteraciones_ext, Cadena Esquema_conveccion,
Cadena Esquema_solucion, bool Resultados_indep_tiempo )
{
bool correcto = true;
SetCargarDatos(Datos_iniciales_externos);
SetNoIterExt(N_iteraciones_ext);
correcto = correcto && SetEsquemaConveccion(Esquema_conveccion);
correcto = correcto && SetTipoMetodoSolucion (Esquema_solucion);
ResEstable = Resultados_indep_tiempo;
return correcto;
}
174
6.4
o
la presi n puede variar tanto en el eje x como en el eje y. Las ecuaciones simplicadas de la
o
capa lmite se resuelven por otro m todo que se presentar posteriormente ya que, partiendo
e
a
del m todo SIMPLE que halla una correci n de presi n para satisfacer la ecuaci n de cone
o
o
o
tinuidad, sera il gico determinar la correci n de presi n que de antemano se conoce es cero.
o
o
o
En esta secci n se comparan los resultados obtenidos con respecto de la soluci n presentada
o
o
por Blasius.
El problema del ujo en la capa lmite con las condiciones de frontera se muestra en la
gura 31. La frontera sur es una placa plana isot rmica ja, la frontera oeste es la zona de
e
entrada del ujo con velocidad y temperatura conocida, la frontera norte se encuentra en la
zona de ujo no viscoso y se considera que se conoce la velocidad en direcci n x, la variaci n
o
o
de la velocidad v y la temperatura; por ultimo, la frontera este es la zona de salida del ujo y
se asume que la variaci n de la velocidad y temperatura es nula en la direcci n normal a la
o
o
supercie.
La velocidad en la frontera norte se dene de manera general como u = Ue (x) y no se res
tringe a un unico valor ya que existen varias soluciones analticas que se basan en un perl
de velocidad expecco para resolver las ecuaciones del ujo en la capa lmite.
la p gina 66.
a
6 Aunque se conociera la presi n en las fronteras su valor no puede ser directamente aplicado como condici n
o
o
de frontera dado que se soluciona la ecuaci n de correcci n de presi n mas no una ecuaci n de presi n.
o
o
o
o
o
176
Se escoge el aire como el uido a utilizar en los an lisis. Se utilizan las siguientes propiedades:
a
Pre f = 101325[Pa]
(Ec 6.19a)
(Ec 6.19b)
Rgas = 287.0
= 1.172
k = 0.02566
177
Pa m3
KgK
(Ec 6.19c)
Kg
m3
(Ec 6.19d)
W
mK
(Ec 6.19e)
C p = 1007
J
Kg K
= 1.858 e 5
Kg
ms
(Ec 6.19f)
(Ec 6.19g)
6.4.1
(Ec 6.20)
t = 0.1 [s]
El archivo de denici n de la geometra contiene:
o
> nsd = 2;
> subdominios = 1;
> no_de_superels = 1;
>nbind = 4
>bname VelUNeumann=0,VelVNeumann=0,PNeumann=0,TempNeumann=0
VelUDirichlet=1,VelVNeumann=0,PNeumann=0,TempDirichlet=1
VelUDirichlet=1,VelVDirichlet=0,PNeumann=0,TempDirichlet=1
VelUDirichlet=0,VelVDirichlet=0,PNeumann=0,TempDirichlet=0
>SupEl;
>subdominio_no = 1;
>tipoelemento = ElmB4n2D;
>fronteras = [1(1)] [2 (2)] [3 (3)] [4(4)];
>nodos = [1(0 0)]+[2(8.0 0)]+[3(0 0.6)]+[4(8.0 0.6)];
>lados=;
Para mostrar que sucede al aumentar el n mero de vol menes de control se realizan tres
u
u
particiones diferentes:
1.
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[60,90];>grad=[-0.8,-0.5];
178
2.
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[300,90];>grad=[-0.8,-0.5];
3.
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[800,150];>grad=[-0.8,-0.6];
El m todo de soluci n para las ecuaciones de la cantidad de movimiento y conservaci n de
e
o
o
la energa es el siguiente:
monitor de convergencia:
>monitor_tp = MCResidualRel
>residual_type = RES_ORIGINAL
>maxerr = 1.0e-9
>norm_type = l2
>monitor = ON
>graficar_ejec = OFF
>criterio = ON
>insertar = ON
>relop = CM_AND
>usar_info_vp = OFF
>rel_a_rhs = OFF
>chunk_size = 100
>base_usua = 1.0
Se usa el precondicionador RILU (descomposici n incompleta LU) para disminuir el n mero
o
u
de iteraciones interiores necesarias para resolver las ecuaciones convectivas.
Para resolver la ecuaci n de correcci n de presi n se us el gradiente conjugado ya que
o
o
o
o
la matriz de coecientes de esta ecuaci n es sim trica.
o
e
Parametros de la matriz (clase prmMatriz);
>guarda = Matriz;
>guarda_sim = FALSE
>pivoteo = FALSE
>umbral =0.0
prm_solucionEcLin parametros:
>solver_classname=GradConj
>metodo=R-OM(7)
>cambiar=0.0
>pivoteo=NO_PIVOT
>relajacion=0.1
>startvector=USER_START
>criterio_def=TRUE
>nextern_crit=1
>maxit=3000
>estimate_eigvals=FALSE
Parametros del precondiciondor:
>precondicionador=PrecRILU
>left_prec=TRUE
>auto_iniciar=TRUE
180
>nivel_llenado=0
>prec_RILU=1
>prec_SSOR=1
>pasos_int=1
monitor de convergencia:
>monitor_tp = MCResidualRel
>residual_type = RES_ORIGINAL
>maxerr = 1.0e-8
>norm_type = l2
>monitor = ON
>graficar_ejec = OFF
>criterio = ON
>insertar = ON
>relop = CM_AND
>usar_info_vp = OFF
>rel_a_rhs = OFF
>chunk_size = 100
>base_usua = 1.0
Con el precondicionador RILU la ecuaci n de correcci n de presi n puede ser resuelta en 40
o
o
o
iteraciones interiores comparada con m s de 600 iteraciones sin el precondicionador. Como
a
dato adicional, la soluci n de las tres ecuaciones lineales para cada iteraci n exterior toma
o
o
alrededor de 2 segundos para 120000 vol menes de control; la construcci n de las matrices
u
o
y el c lculo de los gradientes, entre otros, toma alrededor de 2 minutos7 .
a
Los resultados del espesor de la capa lmite hidr ulica para las simulaciones propuestas y
a
el espesor te rico de la capa lmite hidr ulica se muestra en la gura 33. El valor te rico se
o
a
o
tom de la ecuaci n Ec 1.10. Para la capa lmite t rmica se presentan los resultados en la
o
o
e
gura 34. La escala en direcci n y en las siguientes guras se ha exagerado para facilitar la
o
visualizaci n de los resultados.
o
7 Datos
aproximados para un computador Toshiba Satellite L505-GS5037, procesador core i3 de 2.2 GHz,
3.8GB de memoria RAM 1066MHz, Windows 7 64 bits.
181
182
Para comparar los datos obtenidos, se determina el espesor de la capa hidr ulica y t rmica
a
e
cada metro para la simulaci n de 120000 vol menes de control. El primer dato se toma para
o
u
Re = 1000 recordando que la ecuaci n de Blasius es v lida para Re > 1000.
o
a
Tabla 14: Comparaci n de resultados para el grosor de la capa lmite hidr ulica del caso
o
a
NSCL.
Re
[]
1000
25231
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,01585
0,4
1
2
3
4
5
6
7
8
a
Valor
Valor
Error
Error
Calculado Te rico absoluto porcentual
o
[m]
[m]
[m]
[%]
0,0021
0,0026 0,0005
19
0,0119
0,0126 0,0006
5
0,0196
0,0199 0,0003
1
0,0281
0,0282 0,0001
0
0,0344
0,0345 0,0001
0
0,0396
0,0398 0,0002
1
0,0440
0,0445 0,0005
1
0,0479
0,0488 0,0009
2
0,0514
0,0527 0,0013
2
0,0545
0,0563 0,0018
3
Tabla 15: Comparaci n de resultados para el grosor de la capa lmite t rmica del caso NSCL.
o
Re
[]
1000
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,01585
1
2
3
4
5
6
7
8
Valor
Te rico
o
[m]
0,0029
0,0221
0,0313
0,0383
0,0442
0,0495
0,0542
0,0585
0,0626
e
Valor
Error
Error
Calculado absoluto porcentual
[m]
[m]
[%]
0,0037
-0,0008
-28
0,0239
-0,0018
-8
0,0334
-0,0021
-7
0,0406
-0,0023
-6
0,0467
-0,0025
-6
0,0520
-0,0025
-5
0,0568
-0,0026
-5
0,0611
-0,0026
-4
0,0651
-0,0026
-4
Tomando como error permisible el 5%, son aceptables los valores del espesor de la capa lmite
hidr ulica para Re 25000. Con respecto al espesor de la capa lmite t rmica, se presentan
a
e
183
valores con un mayor margen de error alcanzando un error menor al 5% para Re > 316000.
Para el aire el espesor de la capa lmite t rmica es mayor que el espesor de la capa lmite
hidr ulica debido al valor del Prandtl Praire = 0.729 < 1, es por esto que el campo de tema
peratura se ve afectado por la velocidad del uido fuera de la capa lmite. En la gura 35 se
muestra un sobrepaso del valor de la velocidad umax > 1 que afecta al campo de temperatura.
La temperatura no presenta un sobrepaso por dos motivos. En primer lugar, no existe generaci n de calor para el uido y en segundo lugar, el cumplimiento del balance de masa elimina
o
este tipo de problemas.
Para las ecuaciones de la cantidad de movimiento se agrega el gradiente del tensor de esfuerzos y el gradiente de la presi n como t rmino fuente por lo que es posible que se presente
o
e
un sobrepaso de la velocidad u. En la ecuaci n de la cantidad de movimiento en y el t rmino
o
e
fuente es el encargado que se produzca valores diferentes de cero porque las condiciones de
frontera son Dirichlet=0 y Neumann=0 para la velocidad v.
De acuerdo a las ecuaciones (Ec 1.27b) y (Ec 1.27c) el valor de la velocidad v fuera de
la capa lmite tiene una mayor variaci n en la direcci n x que en la direcci n y. En direcci n
o
o
o
o
y+ el valor de v crece hasta un valor m ximo.
a
184
Los resultados encontrados no tienen este comportamiento como se muestra en la gura 36.
La ecuaci n de la cantidad de movimiento en y se linealiza como una ecuaci n de convecci n
o
o
o
difusi n para v, la convecci n en x (u >> v) y la difusi n son las encargadas de disipar la
o
o
o
velocidad v. El valor inferior de la velocidad v es la responsable del sobrepaso de la velocidad
u (por el balance de masa) y en general de modicar el perl de la velocidad u.
Para continuar la comparaci n de los resultados se presenta ahora el valor de f |y=0 = 0.332
o
mostrado en la ecuaci n (Ec 1.27d). El valor de f encontrado a lo largo de la placa para las
o
simulaciones propuestas se muestra en la gura 37 y en la tabla 16 se presentan los valores
para la simulaci n de 120000 vol menes de control.
o
u
Figura 37: Valor f en la supercie para NSCL.
185
El valor de f |y=0 encontrado vara signicativamente para los primeros 3[m] de la placa y
a partir de x = 1.5[m] es una funci n creciente para las tres simulaciones. En la gura 37 se
o
observa que el valor encontrado es muy inferior al valor predecido por Blasius; la teora de
Re
[]
1000
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,01585
1
2
3
4
5
6
7
8
Valor
Te rico
o
[]
0,332
0,332
0,332
0,332
0,332
0,332
0,332
0,332
0,332
Valor de f en la supercie
Valor
Error
Error
Calculado absoluto porcentual
[]
[]
[%]
0,060
0,272
82
0,274
0,058
17
0,275
0,057
17
0,276
0,056
17
0,279
0,053
16
0,281
0,051
15
0,283
0,049
15
0,285
0,047
14
0,288
0,044
13
El valor de f |y=0 est relacionado con el coeciente local de fricci n que se muestra en la
a
o
gura 38 y en la tabla 17. El valor te rico de C f ,x se muestra en (Ec 1.26).
o
Figura 38: Coeciente local de fricci n para NSCL.
o
186
Re
[]
1000
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,01585
1
2
3
4
5
6
7
8
Como era de esperarse, si el valor encontrado de f |y=0 diere del valor te rico, el valor de
o
C f ,x encontrado tambi n diere del valor te rico. El valor de f |y=0 y C f ,x depende de la
e
o
variaci n de la velocidad u en direcci n y, como se mostr en la gura 35, aunque el espesor
o
o
o
de la capa lmite hidr ulica encontrado sea aceptable, el perl de la velocidad u en direcci n
a
o
y es diferente porque se presenta el sobresalto en el valor de la velocidad u, por esta raz n, el
o
valor de f |y=0 y C f ,x no se acerca al valor te rico.
o
Figura 39: T rmino fuente para la ecuaci n de la cantidad de movimiento en direcci n x.
e
o
o
gradiente de la presi n en la misma direcci n; los valores negativos (color azul) producen
o
o
una disminuci n en la velocidad u, estos valores no se presentan en la frontera con la placa
o
por lo que modican el perl de velocidad.
[]
1000
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,01585
1
2
3
4
5
6
7
8
Valor
Te rico
o
[]
9
75
106
130
150
168
184
199
212
Error
porcentual
[%]
57
7
7
6
6
6
6
5
5
De la gura 40 se deduce que la variaci n del Nu con la malla es mnima en comparaci n con
o
o
el error existente entre los valores encontrados y el valor te rico. De la tabla 18 se observa
o
188
porcentajes de error menores para el Nu comparado con el error del valor hallado de C f ,x ,
excepto para Re = 1000.
A continuaci n se muestra el valor de la presi n sobre la placa en la gura 41 en la que,
o
o
se puede ver un aumento signicativo de la presi n para bajos valores de Re. El comporo
tamiento de la presi n en la gura 41 conrma la existencia de un gradiente de presi n para
o
o
bajos valores de Re. Un estudio detallado del c lculo de la presi n, coeciente de arrastre y
a
o
transferencia de calor para bajos valores de Re, especcamente para placas nitas puede ser
Por ultimo, se analiza la convergencia del m todo con la simulaci n de 5400 vol menes de
e
o
u
control. En la gura 42 se muestra la norma del residuo m sico como se present en la teora,
a
o
en esta se puede ver que el valor es a n alto y no vara signicativamente con las iteraciones,
u
189
Figura 43: Norma del residuo m sico sin tener en cuenta el volumen de control de referencia
a
para la ecuaci n de correcci n de presi n
o
o
o
derecha la cual est muy lejos de la zona en donde se desarrolla la capa lmite y est en la
a
a
zona de salida del ujo por lo que no es posible que se propague este error a otros vol menes
u
de control.
Otra forma de comparar la convergencia del m todo es la variaci n de la velocidad u en
e
o
cada iteraci n de acuerdo a (Ec 6.21), los resultados se muestran en la gura 44. De nuevo
o
el valor disminuye hasta llegar a las 800 iteraciones exteriores en donde presenta peque as
n
oscilaciones por la precisi n seleccionada para la soluci n de las ecuaciones lineales.
o
o
u = ||Velu Velu,ant ||
(Ec 6.21)
Finalmente se presenta Pcorr,max denido en (Ec 6.22). La correcci n de presi n debe ser
o
o
cercana a cero cuando se ha alcanzado la convergencia, en la gura 45 se presenta este comportamiento limitado al n mero de decimales de los resultados exportados, debido a que el
u
residuo m sico del punto tomado como referencia no es cero, el valor mnimo de la cora
o
o
modica la precisi n de los resultados para la soluci n de la ecuaci n lineal, sin embargo, ya
o
o
o
se ha alcanzado la convergencia del problema al llegar a este punto.
Pcorr,max = Pcorr,max Pcorr,min
191
(Ec 6.22)
6.5
e
la ecuaci n de la continuidad se resuelve a partir de una correci n de presi n. Dadas las
o
o
o
simplicaciones realizadas en la capa lmite, el gradiente de presi n en direcci n normal a la
o
o
supercie es 0. El m todo presentado a continuaci n resuelve directamente la correci n de
e
o
o
la velocidad v sin necesidad de acudir a la correcci n de presi n.
o
o
Se re-escriben las ecuaciones simplicadas de la capa lmite para facilitar el entendimiento
del m todo:
e
(V ) = 0
(Ec 6.23)
u
u
dp
2 u
u
+ v = + 2
x
y
dx
y
(Ec 6.24)
T
T
k 2 T
+v
=
x
y
C p y2
(Ec 6.25)
192
nnb
i=1
[ au um ]
i i
pm1 p i + bu p
p
p
vm = vm1
p
p
(Ec 6.26a)
(Ec 6.26b)
La (Ec 6.26a) puede converger por s misma para un valor de v por lo que la correcci n de la
o
velocidad u se asume cero.
0
m
U
u = u +
u
(Ec 6.27)
Por otro lado, para obtener los valores correctos en la ecuaci n de cantidad de movimiento en
o
x es necesario corregir la velocidad v en direcci n y. Esta correci n se muestra en (Ec 6.28).
o
o
v = vm + v
(Ec 6.28)
(v )
=
y
[V m ]
La (Ec 6.29a), que corresponde al segundo paso, es una ecuaci n de convecci n con una
o
o
constante difusiva 0; para resolver esta ecuaci n se puede usar el m todo presentado en el
o
e
captulo 4 o 5 para un valor de = 0. El esquema de aproximaci n para el t rmino convectivo
o
e
no puede ser CDS ya que generara oscilaciones, se sugiere el esquema UDS.
[v ] = [V m ]
0
1
=
0
(Ec 6.29a)
(Ec 6.29b)
Las condiciones de frontera para la velocidad v son utilizadas para hallar el residuo m sico
a
de las celdas en la frontera por lo que se asegura que el ujo en la placa sea cero.
En el tercer paso se corrige el valor de la velocidad u y v como se muestra en (Ec 6.30).
um = V um + (1 V ) um1
(Ec 6.30a)
vm = vm + V v
(Ec 6.30b)
193
o
o
(Ec 6.26a)
(Ec 6.29)
(Ec 6.30)
(Ec 6.13)
El cuarto paso consiste en resolver las dem s ecuaciones, en este caso, la ecuaci n de la
a
o
8 . Para el caso que solo se presenten los resultados nales, es eciente resolver la
energa
8 Se
asume la densidad es constante por lo que no se corrige el valor de esta en cada iteraci n.
o
194
6.6
IMPLEMENTACION
Los pasos especcos que se agregan para utilizar el m todo NOSIMPLE recientemente ex
e
plicado son:
...
class NavierStokes : protected GuardarEnsight
{
...
protected:
...
bool PrimerPasoNOSIMPLE();
bool SegundoPasoNOSIMPLE();
bool TercerPasoNOSIMPLE();
...
}
Para resolver el cuarto paso del m todo se utiliza el mismo proceso realizado por el m todo
e
e
SIMPLE.
1.
M todo PrimerPasoNOSIMPLE(): la ecuaci n de la cantidad de movimiento en x
e
o
obtenida por las simplicaciones de la capa lmite se resuelve como una ecuaci n de con
o
vecci n-difusi n en donde, el t rmino fuente es el gradiente de la presi n en direcci n x10 .
o
o
e
o
o
9 La
cercana al valor 0 est limitada por el tama o de los vol menes de control en la zona.
a
n
u
este caso el gradiente del tensor de esfuerzos no contribuye al t rmino fuente en la ecuaci n de cantidad
e
o
de movimiento en direcci n x.
o
10 En
195
bool NavierStokes::PrimerPasoNOSIMPLE()
{
bool correcto; int i;
Vector<real> dPdn(nvol);
Fuente.llenar(0.0);
for (i=1; i<=nvol; i++) {dPdn (i) = GP (i)(1); }
Fuente -= dPdn;
for (i=1; i<=nvol; i++) Fuente(i) = Fuente(i) * Volumen(i);
ConvVu.SetFuenteYFlujo(Fuente,VelU,VelV, VelW);
ConvVu.SetPasado(VelU_ant);
ConvVu.SetPropiedades (rho, mu);
CoefU = ConvVu.CalcularCoefUnTiempo
(theta, tiempo_p, MetodoAprox, correcto);
VmAstU = ConvVu.SolucionCoefUnTiempo (correcto);
////No se resuelve la ecuacion de cant. mov. en y///////////////
//////////////////////, se realiza lo siguiente//////////
CoefV = CoefU;//aproximacion
VmAstV = VelV;//asignacion
return true;
}
La ecuaci n de la cantidad de movimiento en y no se resuelve, en cambio, se actualiza el
o
valor de VmAstV que ser utilizado para hallar el residuo m sico.
a
a
2.
M todo SegundoPasoNOSIMPLE(): en este paso se calcula la correci n de la velocie
o
dad v.
I.
La primera tarea a realizar es declarar e inicializar las variables a utilizar en el
m todo. Una vez realizado este proceso se puede calcular el valor del residuo m sico de
e
a
cada volumen de control.
bool NavierStokes::SegundoPasoNOSIMPLE()
{
bool triunfo; int i;
Vector<real> cero, uno;
Vector_basico<Vector_xyz<real>> Velvec(nvol);
cero.chaSize (nvol); uno.chaSize(nvol);
cero.llenar (0.0), uno.llenar(1.0);
for ( i=1 ; i<=nvol ; i++) {
Velvec(i).chaSize(ndim);
Velvec(i)(1) = VmAstU(i);
Velvec(i)(2) = VmAstV(i);
if (ndim == 3)
Velvec(i)(3) = VmAstW(i);
196
}
NablaDotVecEspecial(Velvec,ResiduoMasico, MULT_POR_RHO_ON );
for(i=1;i<=nvol;i++) ResiduoMasico(i) = ResiduoMasico(i)*Volumen(i);
Fuente = ResiduoMasico * (-1.0);
...
II. Se introduce el t rmino fuente, el campo de la velocidad y la constante difusiva
e
seg n se especic en la (Ec 6.29). La ecuaci n se resuelve en estado estable y por
u
o
o
triunfo);
3.
M todo TercerPasoNOSIMPLE(): teniendo en cuenta el par metro de sobrerelae
a
m1 y el valor hallado
jaci n, se actualiza el valor de la velocidad u con el valor anterior u
o
um en el presente ciclo. Para la velocidad v se agrega la correci n de la velocidad al valor
o
de la velocidad en la iteraci n anterior.
o
bool NavierStokes::TercerPasoNOSIMPLE()
{
int i;
real alpV = Subrelajacion;
for (i=1; i<= nvol ; i++) {
VelU(i) = alpV * VmAstU(i) + (1.0-alpV) * VelU(i);
VelV(i) = VelV(i) + alpV*vcor(i);
}
return true;
}
El siguiente fragmento de c digo es un ejemplo de la creaci n de un objeto que utilice el
o
o
m todo simplicado para resolver el problema del ujo en la capa lmite.
e
NavierStokes NS;
NS.SubRelajaSIMPLE(1.2);
NS.SetParametros( false, 100, "hibrido", "NOSIMPLE",true);
NS.SetMAssThreshold(1e-9); NS.SetMinimaPresion(0.0);
NS.Leer("ARCH=NOSIMPLELIMITE4.txt", "ARCH=Solve_datos.txt",
"dt=[0.10 1.0] t en [0 2.1 1000.0]",1.0,
"ARCH=Solve_datostemp.txt");
NS.CalcularTeoriaCLimite(); NS.Calcular();
197
giere para facilitar el cambio de m todo de soluci n. Por ultimo el archivo de las particiones
e
o
contiene la siguiente informaci n:
o
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[150,60];>grad=[-0.9,-0.6];
El volumen de control general a simular est limitado en direcci n x por el nal de la zona
a
o
5 . Para la direcci n y se tiene en cuenta la recomendaci n de
de ujo laminar Re = 5 10
o
o
Cebeci11 ( = 8) para simular el ujo laminar en la capa lmite por el m todo de diferencias
e
nitas, para el presente caso se usa la relaci n dada en (Ec 6.31).
o
(Re=5E5,y=ymax) 8 1.6 hid
ymax = 1.6 max(hid , ter )
11 CEBECI,
(Ec 6.31)
TUNCER, et al. Computational uid dynamics for engineers, Berlin: Springer, 2005. p. 225
198
6.7
Para probar el m todo NOSIMPLE se desarrollan dos ejemplos. Por un lado se resuelven las
e
ecuaciones sin gradiente de presi n y en un segundo an lisis se dene un perl de velocidad
o
a
externo.
Los datos te ricos para la presente secci n se toman de las ecuaciones (Ec 1.26) y (Ec 1.27)
o
o
a excepci n que se indique una fuente bibliogr ca externa.
o
a
6.7.1
En este caso (de ahora en adelante se llamar Blasius1) se simular las ecuaciones de Blasius
a
a
2 u/x2 ) junto con la capa t rmica. De nuevo se usa al aire como el
(incluyendo el t rmino
e
e
uido de an lisis con las propiedades mostradas en (Ec 6.19). Los par metros de simulaci n
a
a
o
son los siguientes:
x = 8[m]
U = 1[m/s] Rex=8[m] = 504629
ter,t = 0, 06256[m]
y = 0.1[m] nvol = variable
M todo:NOSIMPLE mitera = 100 V = 1.2
e
(Ec 6.32)
1
si 2.1 < t < 1000
El par metro de sobrerelajaci n de la velocidad ha sido tomado como V = 1.2 con el cual
a
o
se alcanza un residuo m sico menor a 1e-8 para aproximadamente 75 iteraciones exteriores
a
en casi todos los casos desarrollados. Un valor superior para el par metro de sobrerelajaci n
a
o
de la velocidad puede conducir a una soluci n no convergente.
o
La simulaci n se realiza bajo los siguientes par metros geom tricos:
o
a
e
> nsd = 2;
> subdominios = 1;
> no_de_superels = 1;
>nbind = 4
>bname VelUNeumann=0,VelVNeumann=0,PNeumann=0,VcorNeumann=0,TempNeumann=0
VelUDirichlet=1,VelVNeumann=0,PNeumann=0,VcorNeumann=0,TempDirichlet=1
VelUDirichlet=1,VelVDirichlet=0,PNeumann=0,VcorNeumann=0,TempDirichlet=1
VelUDirichlet=0,VelVDirichlet=0,PNeumann=0,VcorDirichlet=0,TempDirichlet=0
199
>SupEl;
>subdominio_no = 1;
>tipoelemento = ElmB4n2D;
>fronteras = [1(1)] [2 (2)] [3 (3)] [4(4)];
>nodos = [1(0 0)]+[2(8.0 0)]+[3(0 0.1)]+[4(8.0 0.1)];
>lados=;
Como primera comparaci n se muestra la inuencia del n mero de vol menes de control en
o
u
u
la soluci n, un fragmento de cada uno de los archivos de particiones es el siguiente:
o
1.
>div=[48,30];>grad=[1.0,1.0];
2.
>div=[120,48];>grad=[-0.9,-0.6];
3.
>div=[150,60];>grad=[-0.9,-0.6];
4.
>div=[200,54];>grad=[-0.9,-0.6];
5.
>div=[254,42];>grad=[-0.9,-0.6];
El primer conjunto de datos a comparar es el espesor de la capa lmite hidr ulica. En la gura
a
47 se muestra el espesor de la capa hidr ulica para cada uno de los casos planteados, en esta
a
se puede ver que al aumentar el n mero de vol menes de control se obtienen mejores resulu
u
tados que tienden al caso te rico de Blasius. En la gura 48 se muestra en mayor detalle las
o
diferencias para bajos n meros de Reynolds.
u
Tomando como datos experimentales los obtenidos por la simulaci n de 10800 vol menes
o
u
200
Figura 48: Espesor hidr ulico del caso Blasius1 en x < 1.5[m].
a
a
Blasius1.
Re
[]
9998
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,1585
1
2
3
4
5
6
7
8
Valor
Te rico
o
[m]
0,0079
0,0199
0,0282
0,0345
0,0398
0,0445
0,0488
0,0527
0,0563
a
Valor
Error
Error
Calculado absoluto porcentual
[m]
[m]
[%]
0,0102
-0,0023
-29
0,0212
-0,0013
-6
0,0289
-0,0008
-3
0,0351
-0,0006
-2
0,0403
-0,0005
-1
0,0447
-0,0002
-0
0,0490
-0,0002
-0
0,0528
-0,0001
-0
0,0562
0,0001
0
12 Los
datos de todas las tablas presentadas en esta secci n se tomar n de la simulaci n con 10800 vol menes
o
a
o
u
de control con el m todo NOSIMPLE.
e
201
A partir de la tabla 19 e interpolando los valores se deduce que los resultados obtenidos son
v lidos para x > 1.39[m] que equivale a Re > 87500.
a
Ahora se compara el espesor de la capa lmite t rmica y se muestra en la gura 49.
e
Figura 49: Espesor de la capa lmite t rmica del caso Blasius1.
Tabla 20: Comparaci n de resultados para el grosor de la capa lmite t rmica del caso Blao
e
sius1.
Re
[]
9998
63079
126157
189236
252314
315393
378471
441550
504629
[m]
0,1585
1
2
3
4
5
6
7
8
Valor
Te rico
o
[m]
0,0088
0,0221
0,0313
0,0383
0,0442
0,0495
0,0542
0,0585
0,0626
e
Valor
Error
Error
Calculado absoluto porcentual
[m]
[m]
[%]
0,0112
-0,0024
-27
0,0237
-0,0016
-7
0,0326
-0,0013
-4
0,0393
-0,0010
-3
0,0452
-0,0009
-2
0,0504
-0,0009
-2
0,0551
-0,0009
-2
0,0594
-0,0009
-2
0,0632
-0,0007
-1
202
Ahora se compara el valor de f |y0 en la supercie el cual desde la base te rica es una
o
constante igual a 0.332 como se muestra en la (Ec 1.27d) que se re-escribe a continuaci n
o
para mayor comodidad:
Rex u
( )|y=0 = 0.332 = cte
U 2 y
Para un margen de error del 5% se aceptan los valores entre 0.3154 < f |y0 < 0.3486 que,
de acuerdo a la gura 51, se cumple para cualquier valor de x > 0.08[m] o Re > 5000.
De forma similar se compara el coeciente local de fricci n de (Ec 1.26), los resultados se
o
muestran el la gura 52 y en la tabla 21.
1/2
C f , x = 0.664 Rex
203
Tabla 21: Comparaci n de resultados para el coeciente de fricci n local C f ,x del caso Blao
o
sius1.
Re
[]
5046
65602
126157
191759
252314
317916
378471
444073
504629
[m]
0,08
1,04
2,00
3,04
4,00
5,04
6,00
7,04
8,00
Por ultimo para el problema hidr ulico, se compara el valor m ximo te rico de la velocia
a
o
dad en direcci n y con el valor encontrado para el ymax . Los resultados se muestran en la
o
gura 53 y en la tabla 22.
204
Re
[]
5046
65602
126157
191759
252314
317916
378471
444073
504629
[m]
0,08
1,04
2,00
3,04
4,00
5,04
6,00
7,04
8,00
Valor
Te rico
o
[m/s]
0,01218
0,00336
0,00242
0,00196
0,00171
0,00153
0,00140
0,00129
0,00121
La mayor parte de los datos de la tabla 22 se ajustan a la teora excepto para x = 8[m]. En
o
variaci n de la velocidad u en x, tampoco existir variaci n de la velocidad v en y por lo
o
a
o
que se deduce es la fuente del error encontrado. El error introducido por la denici n de las
o
205
condiciones de la frontera este se admite y no debera afectar en gran medida los resultados
de otras zonas porque el caracter parab lico de las ecuaciones solo permite la propagaci n de
o
o
la informaci n en la direcci n del ujo.
o
o
Retomando el problema t rmico en el caso Blasius1, se compara el valor del coeciente
e
adimensional de transferencia de calor Nu en la tabla 23 y en la gura 54.
Figura 54: Comparaci n del coeciente adimensional de transferencia de calor.
o
206
[]
5046
65602
126157
191759
252314
317916
378471
444073
504629
[m]
0,08
1,04
2,00
3,04
4,00
5,04
6,00
7,04
8,00
Valor
Te rico
o
[]
21,2
76,5
106,1
130,8
150,1
168,5
183,8
199,1
212,3
Valor
Calculado
[]
21,3
75,2
104,7
129,3
148,5
166,5
180,1
190,1
194,9
Error
absoluto
[]
-0,1
1,3
1,4
1,5
1,6
2,0
3,7
9,0
17,4
Error
porcentual
[%]
-1
2
1
1
1
1
2
5
8
De nuevo se presentan diferencias signicativas para x = 8[m] agregando en este caso, una
fuente de error al denir la condici n de frontera este para la temperatura como tipo Neumann=0.
o
Como comentario adicional, la simulaci n Blasius1 se realiz teniendo en cuenta el t rmino
o
o
e
2 u/x2 lo cual es v lido para Re > 1000 o, en este caso en especco, x > 0.0159[m]. Otras
(Ec 6.33)
eliminar el t rmino 2 u/x2 se deni la viscosidad de cada volumen de control como un vector que
e
o
luego era multiplicado por el vector unitario normal a la cara. No se recomienda seguir este proceso porque en
un caso real, la viscosidad no es seleccionada de acuerdo a la direcci n, solo se realiz con nes comparativos.
o
o
207
6.7.2
Las ecuaciones del ujo en la capa lmite son parab licas lo que signica que la informaci n
o
o
solo se propaga en la direcci n del ujo. Es posible resolver las ecuaciones parab licas por
o
o
un m todo explicito como el presentado en los anexos O, P y Q en los cuales se explica una
e
teora b sica y se muestra el c digo desarrollado.
a
o
Se presentan dos ejemplos, el primer caso se realiza con una malla de 300 nodos en x y
30 nodos en y y el segundo ejemplo con una malla de 600x40. El espesor de la capa lmite
Figura 57: Espesor de la capa lmite t rmica e hidr ulica para 300x30 nodos.
e
a
Grosor capa hidraulica y termica
0.1
0.09
0.08
0.07
delta [m]
0.06
0.05
0.04
0.03
0.02
0.01
0
4
Eje x[m]
15
10
10
Porcentaje error [%]
20
15
20
5
0
5
5
0
5
10
10
15
15
20
4
x [m]
20
4
x [m]
En el caso presentado en la secci n 6.7.1 se utiliz 10800 vol menes de control para lograr un
o
o
u
porcentaje de error de 5 % en x = 1.39[m], en el m todo explcito se necesitan 24000 nodos
e
para lograr un nivel similar de precisi n. El m todo explcito es f cil de implementar, r pido
o
e
a
a
en encontrar la soluci n y no requiere grandes cantidades de memoria para el procesamiento
o
de los datos, sin embargo, es inestable, est limitado en la geometra a la cual se puede aplicar
a
y, solo puede ser utilizado para resolver las ecuaciones simplicadas de la capa lmite.
209
Figura 58: Espesor de la capa lmite t rmica e hidr ulica para 600x40 nodos.
e
a
Grosor capa hidraulica y termica
0.1
0.09
0.08
0.07
delta [m]
0.06
0.05
0.04
0.03
0.02
0.01
0
6.7.3
4
Eje x[m]
C = 1[1/s] m = 1[]
u x
=
=1
x x
u
dp
u = 1 x =
x
dx
2
x
p=
[Pa]
2
dp
|
= 2.344 [Pa/m]
dx x=2[m]
Se simular una regi n de 2 metros en direcci n x y 0.015 metros en direcci n y.
a
o
o
o
210
v
u
= = 1
y
x
o
> nsd = 2;
> subdominios = 1;
> no_de_superels = 1;
>nbind = 4
>bname VelUNeumann=-1.0,VelVNeumann=0,PNeumann=2.344,
VcorNeumann=0,TempNeumann=0
VelUDirichlet=1x1,VelVNeumann=1.0,PNeumann=0,
VcorNeumann=0,TempDirichlet=1
VelUDirichlet=0,VelVNeumann=0,PNeumann=0,
VcorNeumann=0,TempDirichlet=0.0
VelUDirichlet=0,VelVDirichlet=0,PNeumann=0,
VcorDirichlet=0,TempDirichlet=0
>SupEl;
>subdominio_no = 1;
>tipoelemento = ElmB4n2D;
>fronteras = [1(1)] [2 (2)] [3 (3)] [4(4)];
>nodos = [1(0 0)]+[2(2.0 0)]+[3(0 0.015)]+[4(2.0 0.015)];
>lados=;
Se realizan dos simulaciones para el caso Falkner1 mostrando la inuencia del n mero de
u
vol menes de control, las particiones usadas son las siguientes:
u
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[60,30];>grad=[1.0,1.0];
>nsd = 2;
>no_de_superels = 1;
>SE;>d=2;>e=ElmB4n2D;>div=[180,48];>grad=[1.0,1.0];
Los resultados se presentan en la gura 60 y en la tabla 24, adicionalmente, se muestran las
lneas de ujo en la gura 61.
Para comparar los resultados con un modelo te rico se puede interpolar los datos de las
o
211
gr cas de la ecuaci n de Falkner-Skan ( gura 4) o tomar los datos del modelo de Howarth1415 .
a
o
El modelo de Howarth asume que la velocidad del uido fuera de la capa lmite tiene un perl
a
99 =
a
h =
1
h = 2.4
1.172/1.858e 5
h = 0.00956[m]
(Ec 6.34)
Para el caso Falkner1 el espesor hidr ulico es una constante. A partir de esta constante se
a
calcul la altura a simular que nalmente fue 0.015[m].
o
Figura 60: Espesor de la capa lmite hidr ulica del caso Falkner1.
14 Es
posible tomar los datos del modelo de Howarth porque el exponente usado para el modelo de FalknerSkan es igual a 1.0.
15 SCHLICHTING, H. Teora de la capa lmite, 3 ed. New York: McGraw Hill, 1968. p.102.
212
Tabla 24: Comparaci n de resultados para el espesor de la capa hidr ulica del caso Falkner1.
o
a
x
[m]
0,2
0,4
0,6
0,8
1
1,2
1,4
1,6
1,8
Valor
Te rico
o
[m]
0,00956
0,00956
0,00956
0,00956
0,00956
0,00956
0,00956
0,00956
0,00956
hid
Valor
Calculado
[m]
0,00823
0,00876
0,00898
0,00909
0,00917
0,00922
0,00925
0,00928
0,00930
Error
absoluto
[m]
0,00133
0,00079
0,00057
0,00046
0,00039
0,00034
0,00030
0,00028
0,00026
Error
porcentual
[%]
14
8
6
5
4
4
3
3
3
213
6.8
ANALISIS DE RESULTADOS
Para cualquier an lisis en la CFD se debe vericar que se cumplan las siguientes caraca
tersticas16 :
1.
Consistencia.
2.
Estabilidad.
3.
Convergencia.
4.
Precisi n.
o
5.
Conservaci n.
o
6.
Soluci n acotada.
o
En los m todos SIMPLE y NOSIMPLE se asume la velocidad del uido como un valor
e
conocido para resolver la ecuaci n de cantidad de movimiento en x, este valor puede diferir
o
signicativamente del valor que se halla en esa ecuaci n de la velocidad para las primeras
o
iteraciones exteriores, de esta forma, se cumple con la consistencia de las ecuaciones cuando
se tenga el campo de la velocidad correcto.
Los dos m todos presentados son condicionalmente estables. Se dene un par metro de
e
a
subrelajaci n para la presi n en el m todo SIMPLE P = 0.1 y en el m todo NO SIMPLE
o
o
e
e
un par metro de sobrerelajaci n para la velocidad V = 1.2 para que el proceso sea estable.
a
o
El valor optimo de estos par metros depende, entre otros factores, del avance en el tiempo
a
y este ultimo depende del tama o de los vol menes de control. Para el ujo sobre una sun
u
percie plana los m todos resultan inestables si se utiliza un avance de tiempo relativamente
e
grande y se dene la velocidad inicial del uido como cero17 .
La convergencia del m todo SIMPLE es baja, para las tres simulaciones presentadas18 la
e
norma del residuo m sico alcanz valores menores a O (1e 7) para m s de 300 iteraciones
a
o
a
exteriores y la actualizaci n del valor de la velocidad u es menor a O (1e 7) para m s de
o
a
500 iteraciones.
Por otro lado, la velocidad de convergencia del m todo NOSIMPLE es m s alta, para ale
a
gunos de los casos presentados la norma del residuo m sico fue del O (1e 8) en solo 75
a
iteraciones exteriores.
16 Este
problema es el resultado del ingreso de una gran cantidad de uido en la frontera tipo Dirichlet del
oeste y una mnima salida de uido por la velocidad inicial denida como cero.
214
algunas diferencias en la frontera este y oeste; en la frontera de entrada del uido se presentan errores por la resoluci n de la malla usada y, en la zona cercana a la frontera este debido
o
a la simplicaci n realizada para denir las condiciones de frontera las cuales son v lidas
o
a
fuera de la capa lmite.
laciones con diferentes mallados en las que la variaci n de los resultados era mnima con
o
respecto al error existente con el valor te rico. La principal causa de error se atribuye a la
o
ecuaci n de cantidad de movimiento en y; en esta ecuaci n se dene la velocidad de entrada
o
o
del uido como u = 1 y v = 0 correspondientes al problema del ujo en la capa lmite; la
aumenta como es descrito por algunos autores que han investigado en el tema. Por ultimo, las
ecuaciones simplicadas de Blasius no explican cu l es la fuerza responsable de generar la
a
o
por ejemplo, 1000[K] y 1001[K], adem s de desperdiciar algunas cifras signicativas.
a
Como resultado de las pruebas realizadas y de la comparaci n con la teora de Blasius, se
o
215
7. CONCLUSIONES
1.
La soluci n de las ecuaciones de la mec nica de uidos se puede llevar a cabo al tratar
o
a
las ecuaciones como un acoplamiento de las ecuaciones de difusi n con las ecuaciones de
o
convecci n-difusi n.
o
o
2.
La simulaci n en la capa lmite sobre una placa plana es un problema de ujo viscoso
o
con una geometra sencilla que requiere, para n meros de Reynolds bajos, una resoluci n
u
o
relativamente mayor para lograr captar los detalles del comportamiento del uido en esta
zona.
3.
Las ecuaciones de la capa lmite de car cter parab lico pueden ser resueltas como
a
o
2 u/x2 ) sin incorporar un error signiecuaciones elpticas (teniendo en cuenta el t rmino
e
cativo para n meros de Reynolds moderados.
u
4.
El m todo SIMPLE es capaz de resolver las ecuaciones completas de Navier Stokes
e
aplicadas al ujo en la capa lmite cuyos resultados pueden diferir ligeramente de los resul
tados obtenidos a partir de las simplicaciones realizadas por Blasius. Este m todo presenta
e
una tasa de convergencia m s lenta comparada con el m todo NOSIMPLE.
a
e
5.
El uso de un valor de referencia para la ecuaci n de correcci n de presi n en el
o
o
o
m todo SIMPLE introduce un error en el residuo m sico que no afecta signicativamente
e
a
los resultados.
6.
La soluci n de las ecuaciones de Navier-Stokes aplicadas a la capa lmite demuestran
o
8.
Aunque se usen esquemas de discretizaci n incondicionalmente estables (esquema
o
hbrido para el t rmino convectivo y esquema implcito para el an lisis transitorio) en el
a
m todo SIMPLE o NOSIMPLE, el proceso es condicionalmente estable de acuerdo al valor
e
del par metro de subrelajaci n y el avance en el tiempo seleccionado.
a
o
216
8. RECOMENDACIONES Y OBSERVACIONES
1.
El prop sito del presente trabajo de grado fue simular el ujo de un uido a bajas
o
velocidades sobre una supercie plana en r gimen laminar con propiedades constantes por
e
medio del m todo de vol menes nitos. Se podran desarrollar otros trabajos de grado que
e
u
a
cilindros o perles de ala de avi n e incluso, considerar las variaciones de las propiedades
o
por la temperatura a altas velocidades.
2.
El m todo NOSIMPLE fue puesto a prueba con el ujo sobre una placa plana, se
e
pueden desarrollar otras pruebas para vericar su capacidad de resolver las ecuaciones de
la capa lmite bajo otras condiciones, por ejemplo, simular otras geometras, supercies
procesamiento. Se modic el proceso para hacer uso de las matrices dispersas que junto
o
con el precondicionador RILU redujo dr sticamente el tiempo de soluci n de las ecuaa
o
ciones. Aun queda por optimizar, entre otros, el preprocesamiento de las condiciones de
frontera que actualmente se repite para cada volumen de control en la frontera.
4.
La soluci n de problemas netamente convectivos ( = 0) se puede llevar a cabo por
o
ConveccionTransitoria con el m todo UDS; el uso del esquema de diferencias centradas
e
conducira a soluciones divergentes por la evaluaci n del Peclet innito.
o
5.
Aunque gran parte del c digo desarrollado fue pensado para cualquier tipo de malla,
o
incluyendo la simulaci n en tres dimensiones, se deben realizar algunas modicaciones que
o
permiten obtener resultados precisos en mallados no estructurados.
6.
Se pueden cometer errores en la implementaci n de las condiciones de frontera los
o
cuales son m s f cilmente detectados al evaluar casos en donde el valor de la condici n de
a a
o
frontera es diferente de cero, por ejemplo, simulando el problema modicado para el ujo
convectivo utilizado en el presente trabajo en vez del problema original de Ferziger.
7.
Los resultados de la simulaci n de la difusi n transitoria pueden ser vericados con
o
o
las soluciones te ricas existentes para una pared plana de propiedades homog neas e inio
e
cialmente isot rmica.
e
217
BIBLIOGRAFIA
[1] BAKKER, A.
Lecture 5- solution methods: Applied computational uid
dynamics, Fluent: 2006 [citado 13 Junio 2012], 45 p.
Disponible en :
http://www.bakker.org/dartmouth06/engs150/05-solv.pdf.
[2] BALTAZAR, J. M.Y EC A, L. R.
a
2009. 361 p.
[4] BLAZEK, J. Computational uid dynamics: principles and applications. Oxford:
Elsevier, 2011. p. 1-128.
[5] CEBECI, T. Y COUSTEIX, J. Modeling and computation of boundary-layer ows.
California: Horizons Publishing Inc., 2005. p. 211-241.
[6] C ENGEL, Y.A. Y BOLES, M. Termodin mica: un enfoque pr ctico, 6 ed. M xico:
a
a
e
McGraw Hill, 2009. p 70-71, 222-225.
[7] C ENGEL, Y. A. Transferencia de calor y masa: un enfoque pr ctico, 3 ed. M xico:
a
e
McGraw Hill, 2007. p.355-394.
[8] CFD ONLINE. History of cfd. [online], CFD online: 2008 [citado 16 Abril 2012].
Disponible en internet: http://www.cfd-online.com/Wiki/History of CFD.
[9] CHUNG, T. J. Computational uid dynamics. Cambridge University, 2002. p. 29-42.
[10] DAILY, J. W. Y HARLEMAN, D. R. Din mica de los uidos: Con aplicaciones a
a
la ingeniera. M xico: F. Trillas, 1969. p.15-16.
e
[11] DENNIS, S. Y DUNWOODY, J. The steady ow of a viscous uid past a at plate.
En: Journal of Fluids Mechanics 1966. vol. 24, no. 3, 18 p.
[12] DENNIS, S. Y SMITH, N. Forced convection from a heated at plate. En: Journal
of Fluids Mechanics 1966. vol. 24, no. 3, 10 p.
218
[13] D
IEZ, P. F. Vii. teora elemental de la capa lmite bidimensional. [online], Red
Sauce [Cantabria, Espa a]: 2009. [citado 5 Agosto 2012], 17 p. Disponible en internet:
n
http://libros.redsauce.net/MecanicaFluidos/PDFs/07MecFluidos.pdf.
[14] FERZIGER, J.H. Y PERI C , M. Computational Methods for Fluid Dynamics, 3 ed.
Berlin: Springer, 2002. 423 p.
[15] FUENTES, D. Soluci n de las ecuaciones de NS en geometras complejas mediante
o
[27] SOUALEM, N. Jacobi method. [online], Math Linux: 2006. [citado 15 Julio 2012].
Disponible en: http://www.math-linux.com/spip.php?article49.
[28] STEWART, J. C lculo de varias variables: trascendentes tempranas, 6 ed. M xico:
a
e
Cengage Learning, 2008. p. 1055-1103.
[29] TU, J.; HENG, G. Y. L. C. Computational uid dynamics : a practical approach.
Burlington : Elsevier, 2008. p. 126-223.
[30] WHITE, F. M. Fluid mechanics. McGraw-Hill series in mechanical engineering.
WCB/McGraw-Hill, 1999. p. 3-46, 434-451.
[31] WHITE, F. M. Viscous uid ow, 3 ed. New York: McGraw Hill, 2006. p. 218-334.
[32] WIKIPEDIA. Mec nica de uidos. [online], 14 de Mayo WIKIPEDIA 2012, [citado
a
12 Junio 2012]. http://es.wikipedia.org/wiki/Mec nica de uidos.
a
220
Una clase es una construcci n que se utiliza como un modelo (o plantilla) para crear objetos
o
de ese tipo. Un objeto se dene como la unidad que en tiempo de ejecuci n realiza las tareas
o
de un programa. Un objeto es una instancia de una clase.
Un ejemplo de una clase creada en Visual C++ es:
#pragma once
//Archivo Fluido_base.h
class Fluido_base
{
public:
Fluido_base(void);
Fluido_base(void);
};
#include "Fluido_base.h"
//Archivo Fluido_base.cpp
Fluido_base::Fluido_base(void)
{
}
Fluido_base::Fluido_base(void)
{
}
C++ dene algunas caractersticas para los miembros de las clases que pueden ser implemen
tadas para explotar las funciones del lenguaje. Se resaltan algunas caracteristicas a continuaci n.
o
SOBRECARGA DE FUNCIONES
La sobrecarga es la capacidad de tener dos o m s funciones diferentes con un mismo nombre.
a
Las funciones sobrecargadas se diferencian por los par metros de entrada. Se presenta un
a
ejemplo de sobrecarga de la funci n Conductividad en el siguiente c digo:
o
o
...
class Fluido_base
{
...
public:
...
real Conductividad ( real temperatura);
real Conductividad ( void );
};
221
CONSTRUCTOR COPIA
El constructor copia es el m todo encargado para realizar la copia de un objeto en otro; por
e
defecto, existe un constructor que se encarga de asignar exactamente los mismos valores al
objeto destino pero puede ser necesario denir un constructor propio, la forma m s com n
a
u
de declarar el constructor copia es la siguiente:
...
class Fluido_base
{
...
public:
...
Fluido_base ( const Fluido_base &copia);//copyconstructor
bool SonIguales (Fluido_base copia);
};
Si se crea un objeto Fluido_base fluido1 y se da al m todo SonIguales una instancia de
e
Fluido_base como par metro de entrada, se realiza una llamada al constructor copia en las
a
siguientes tres instrucciones:
222
...
Fluido_base fluido2 (fluido1);
Fluido_base fluido3 = fluido1;
fluido3.SonIguales(fluido1);
...
Si la funci n SonIguales tomara como argumento &Fluido_base copia, es decir la dio
recci n de un objeto Fluido_base, no se hara internamente la llamada al constructor copia.
o
DEFINICION DE OPERADORES
En C++ es posible denir operaciones como +, -, [], <, ... en las clases como se muestra a
continuaci n:
o
...
class Fluido_base
{
private:
...
protected:
...
...
public:
...
Fluido_base
Fluido_base
Fluido_base
Fluido_base
Fluido_base
Fluido_base
Fluido_base
Fluido_base
Fluido_base
};
Los operadores tambi n pueden ser sobrecargados y se recomienda que la denici n del
e
o
operador sea similar a la denici n com nmente usada. Los operadores que no se pueden
o
u
sobrecargar en C++ son (.) (:) (.*) (?).
223
Funciones de acceso
En algunos casos puede ser necesario obtener o modicar el valor de un dato de un objeto
//Archivo Fluido_base.cpp
...
void Fluido_base::
SetPropiedadesConstantes (bool tipo)
{
if (tipo)
{
prop_constantes=tipo;
temp_min=temp_max=temp_muestra;
}
else
{prop_constantes=tipo;}
public:
...
void SetPropiedadesConstantes
(bool tipo);
bool GetPropiedadesConstantes
(void);
};
}
bool Fluido_base::
GetPropiedadesConstantes (void)
{
return prop_constantes;
}
224
...
class Fluido_Agua:
private Fluido_base
{
real k;
protected:
...
public:
...
real Prandtl ( real temperatura);
};
Al usar la herencia por extensi n se debe denir el tipo de acceso a la clase base. Para
o
el ejemplo presentado, la funci n conductividad(...) que era public en Fluido_base
o
es ahora private para Fluido_Agua, es decir, la clase Fluido_Agua puede acceder a la
funci n conductividad(...) pero el bloque de c digo en el cual se cre la instancia de
o
o
o
Fluido_Agua no puede acceder a dicha funci n. En general, se modica el tipo de acceso
o
225
Funciones virtuales
Una funci n virtual es usada para denir en las clases derivadas nuevas funciones con el
o
mismo nombre y los mismos argumentos. Para declarar una funci n como virtual se agrega
o
la palabra virtual a la funci n en la clase base.
o
...
class Fluido_base
{
...
public:
...
virtual real C_v()
{return 0.0;}
};
...
class Fluido_Agua:
public Fluido_base
{
...
public:
...
real C_v ()
{return 4120;}
real acceso() {return 1.0;}
};
Polimorsmo
El polimorsmo es la posibilidad de llamar a varias funciones mediante una misma sentencia.
La forma de utilizar el polimorsmo es declarar un puntero de una clase base y apuntar a una
clase derivada.
...
Fluido_base *Pbase1 = new Fluido_base;
Fluido_base *Pbase2 = new Fluido_Agua;
cout<<"\nPuntero a clase base"<< Pbase1->C_v();
cout<<"\nPuntero a clase derivada"<< Pbase2->C_v();
...
En el anterior fragmento de c digo, se devuelve el valor 0 como resultado de la llamada a
o
Pbase1->C_v() porque se est apuntando a un objeto de tipo Fluido_base, por otro lado,
a
al ejecutar la instrucci n Pbase2->C_v() se devuelve el valor 4120 porque se est apuno
a
tando a un objeto de tipo Fluido_Agua. Para el ejemplo presentado, no es posible llamar
a Pbase2->acceso() porque la clase base no conoce la existencia de ese m todo, por esta
e
raz n es necesario declarar las funciones virtuales en la clase base.
o
226
...
class Fluido_Agua:
public Fluido_base
{
...
public:
...
real C_v ( )
{return 4120;}
};
227
ANEXO B. SOLUCION INTUITIVA DE LA
10
15
20
25
30
# pragma once
// Encabezado de la clase diftemp : metodo intuitivo de c\ alculo de
// la ecuaci \ on de difusi \ on
// Archivo " diftemp .h"
# include < real .h >
# include < AdmonEcLin .h >
# include < Matriz .h >
# include < Vector .h >
class diftemp
{
private :
real longx , longy ;
// longitud x e y de la placa
int nx ,
ny
;
// numero de nodos en la direccion x e y
real dx ,
dy
;
// ancho y alto de un volumen de control
real k;
// conductividad del material
Matriz < real >
matriz_a ;
// matriz que contiene los coeficientes de las ecuaciones
Vector < real >
b;
// vector que contienen las terminos independientes
Vector <real >
x;
// vector solucion
Matriz < real >
temp ;
// almacenar el valor de la temperatura en una matriz
prm_Matriz <real > pm ;
// parametros de matriz , no es necesario en este caso
// pero se recomienda ,
Cadena x0tipo , y0tipo , xfinaltipo , yfinaltipo ;
// seleccion del tipo de condicion de frontera
Puntero < AdmonEcLin > admlin ;
35
228
bool
bool
40
45
50
55
calculado ;
leido ;
public :
diftemp () { leido = false ; calculado = false ;}
diftemp () {}
void Leer ( real ancho , real alto , real divx , real divy );
void Leer ( void ) { Leer (1.0 ,1.0 ,20 ,20) ;}
real condx0 ( real y); // funcion para la condicion de frontera x0
real condy0 ( real x); // funcion para la condicion de frontera y0
real condxf ( real y); // funcion para la condicion de frontera
yfinal
real condyf ( real x); // funcion para la condicion de frontera
xfinal
real q ( real x , real y ); // funcion para la generacion de calor
// asignar los coeficientes de las ecuaciones
void calcular () ;
// resolver el sistema de ecuaciones
bool resolver () ;
// guardar los resultados y presentarlos en matlab
void exportar ( Cadena archivo );
}; // //// fin de la declaraci \ on de la clase diftemp ////////
229
ANEXO C. SOLUCION INTUITIVA DE LA
CODIGO FUENTE
10
15
20
25
void diftemp :: Leer ( real ancho , real alto , real divx , real divy )
{
longx = ancho ;
longy = alto ;
nx
= divx ;
ny
= divy ;
dx
= longx / nx ;
dy
= longy / ny ;
// //// dimensionamiento de la matriz y el vector //////////
matriz_a . chaSize ( nx * ny );
matriz_a . llenar (0.0) ;
// es importante la inicializacion en 0.0
b. chaSize ( nx * ny );
b. llenar (0.0) ;
x. chaSize ( nx * ny );
x. llenar (170.0) ;
temp . chaSize (nx , ny );
temp . llenar (0.0) ;
// /////// seleccion del tipo de condicion de frontera ////
x0tipo = " Dirichlet "; xfinaltipo = " Dirichlet ";
y0tipo = " Neuman ";
yfinaltipo = " Neum ";
// ////////////// propiedades de material /////////////////
k = 50;
// ////////////// lectura metodo solucion ///////////////
Is is (" ARCH = Solve_datos . txt ");
pm . Leer ( is );
admlin . vincular ( new AdmonEcLin ( EXTERNAL_STORAGE ));
admlin () . Leer ( is );
leido = true ; // bandera
calculado = false ; // al realizar esta asignaci \ on se permite que
el objeto creado pueda calcular varios problemas
}
30
35
real
real
real
real
real
230
40
45
50
55
60
65
70
231
75
80
// elementos intermedios
for (i =2;i <= nx -1; i ++)
{
for (j =1;j <= ny ;j ++) {
matriz_a ((j -1) * nx +i , (j -1) * nx +i )
// nodo actual
matriz_a ((j -1) * nx +i , (j -1) * nx +i +1)
// nodo east
matriz_a ((j -1) * nx +i , (j -1) * nx +i -1)
// nodo west
-= 2.0* k/ dxsy ;
+= 1.0* k/ dxsy ;
+= 1.0* k/ dxsy ;
85
90
95
100
105
110
115
232
// elementos intermedios
for (i =1;i <= nx ;i ++)
{
for (j =2;j <= ny -1; j ++)
{
matriz_a ((j -1) * nx +i , (j -1) * nx +i) -= 2.0* k* dxsy ; // nodo
actual
matriz_a ((j -1) * nx +i , (j -0) * nx +i) = 1.0* k* dxsy ; // nodo norte
matriz_a ((j -1) * nx +i , (j -2) * nx +i) = 1.0* k* dxsy ; // nodo sur
}
}
// frontera yfinal
for (i =1;i <= nx ;i ++)
{
if ( yfinaltipo . contiene (" Diri ") || yfinaltipo . contiene (" diri "))
{
matriz_a ( (ny -1) * nx +i , (ny -1) * nx +i ) -= 3.0* k* dxsy ;
// nodo actual
matriz_a ( (ny -1) * nx +i , (ny -2) * nx +i ) = 1.0* k* dxsy ;
// nodo sur
b ( (ny -1) * nx +i ) -= condyf ( (i -0.5) * dx ) *2.0* k* dxsy ;
}
else
{
matriz_a ( (ny -1) * nx +i , (ny -1) * nx +i ) -= k* dxsy ;
// actual
matriz_a ( (ny -1) * nx +i , (ny -2) * nx +i ) = k* dxsy ;
// sur
b(
(ny -1) * nx +i
) -= k* dx * condyf ((i -0.5) * dx ) ;
}
} // fin del for que recorre cada elemento en la frontera norte
120
125
130
135
140
145
150
}
155
160
233
165
}
170
175
180
185
190
195
234
ANEXO D. PROCESO DE SOLUCION DE LA
10
15
20
25
30
235
35
40
45
50
236
ANEXO E. PROCESO DE SOLUCION DE LA
CODIGO FUENTE
10
15
20
25
30
237
35
40
45
50
55
60
65
70
75
b. chaSize ( nelementos );
b. llenar (0.0) ;
// importante la inicializacion por 0
x. chaSize ( nelementos );
x. llenar (224.0) ;
// Importante la inicializacion para obtener rapida convergencia
// ///// propiedades de material /////////////
k. chaSize ( nelementos );
k. llenar (50) ;
// // calculo de la geometr \ ia de cada volumen de control
elems . chaSize ( nelementos );
// Dimensionamiento del vector de punteros
for ( int i =1; i <= nelementos ;i ++)
{
elems (i). refill ( malla -> obtTipoElem (i) , malla -> obtNoDimEspacio
() );
elems (i) -> CalcGeomParameters ( malla -> obtCoorElem (i) );
}
// //////// solucionador de ecuaciones lineales /////////////////
Is sol ( solucionador );
// Se abre el archivo
pm . Leer ( sol );
// Se lee los parametros respectivos a la matriz
admlin . vincular ( new AdmonEcLin ( EXTERNAL_STORAGE ));
// Se inicializa la memoria dinamica del puntero
admlin () . Leer ( sol );
// Se lee la informacion del metodo de solucion
leido = true ;
// Cambio de valor del parametro de control
return 1;
}
real diffgeneral :: q( real x , real y) { return 5000.0; }
int diffgeneral :: calcular ( void )
{
// control de errores
if ( leido == false )
{ std_o <<" Advertencia : no se ha leido los datos "
<<" del problema \n"; return 0;
}
if ( calculado )
{ std_o <<" Ya se habia calculado los coeficientes \n"; return 0;}
int i , j , l ; // contadores
int veci ; // vecino numero veci
int conx , conxvec ; // numero de conexiones para el elemento actual
y el vecino
int h , nbi = malla -> obtNoIndFront () ;; // Contador para el numero de
fronteras , numero de fronteras
238
80
85
90
95
100
105
110
115
239
120
125
130
135
140
145
150
155
240
165
170
175
180
185
241
10
15
20
25
# pragma once
// Archivo convdiff .h
# include < MallaFV .h >
# include < ConstOLeemalla .h >
# include < AdmonEcLin .h >
# include < GuardarEnsight .h >
# include < GradoLibertadFV .h >
// PROCEDIMIENTO : DECLARACION DE VARIABLES : se necesita una
// serie de variables y funciones para el correcto funcionamiento
// de la clase
class convdiff : public GuardarEnsight
{
private :
protected :
// es necesario declarar la clase base GuardarEnsight como public
pues se utilizar \ an algunas funciones para exportar los
resultados a matlab
// Aunque no son estrcitamente necesarias , se declaran las
variables que definen el ancho y alto del elemento a analizar .
Dicha definicion puede no ser correcta para mas de un
superelemento
real longx , longy ;
// Es necesario conocer el numero de volumenes de control
int nelementos ;
// Se define puntero de MallaFV
Puntero < MallaFV > malla ;
// Se define un vector que contenga la informacion geometrica de
cada volumen de control
Vector_basico < PunteroElmDefs > elems ;
// En el MVF es necesario conocer el numero de lados que tiene
cada volumen de control , raz \ on por la cual se debe definir una
variable del tipo VecinoFVM que permita obtener dicha
informacion .
VecinoFVM vecino ;
242
30
35
40
45
50
243
55
60
65
70
75
80
244
ANEXO G. ARCHIVO DE CODIGO FUENTE
DE LA CLASE CONVDIFF
10
15
20
25
245
30
35
40
45
50
55
60
65
70
246
75
real convdiff :: difusion ( int vol1 , int dir1 , int vol2 , int dir2 ,
real area )
{
real D1 , D2 , Dt , gamma ;
gamma = k( vol1 )/ C_p ( vol1 ) ;
D1 = gamma / elems ( vol1 ) -> getDelta (
dir1 );
gamma = k( vol2 )/ C_p ( vol2 ) ;
D2 = gamma / elems ( vol2 ) -> getDelta (
dir2 );
Dt
= area / (1.0/ D1 + 1.0/ D2 );
return Dt ;
80
85
90
95
100
105
110
}
// version de la funcion de calculo de la difusividad
// para un lado que limita con una condicion de frontera
// en donde se define el coeficiente de conveccion
// esta funcion solo es validad cuando \ phi =T
real convdiff :: difusion ( int vol1 , int dir1 , real area , real
conveccion_f )
{
real D1 , D2 , Dt , gamma ;
gamma = k( vol1 )/ C_p ( vol1 )
;
D1 = gamma / elems ( vol1 ) -> getDelta ( dir1 );
D2 = conveccion_f ;
Dt = area / (1.0/ D1 + 1.0/ D2 );
return Dt ;
}
// version de la funcion de calculo de la difusividad
// para un lado que limita con una condicion de frontera
real convdiff :: difusion ( int vol1 , int dir1 , real area )
{
real Dt , gamma ;
gamma = k( vol1 )/ C_p ( vol1 ) ;
Dt = gamma / elems ( vol1 ) -> getDelta ( dir1 );
Dt = area * Dt ;
return Dt ;
}
// Calculo del flujo convectivo
real convdiff :: conveccion ( int vol1 , int dir1 , real area ,
Vector_xyz < real > Vel )
{
real F ;
F = rho ( vol1 ) * area * ( elems ( vol1 ) -> GetDirSide ( dir1 ) * Vel ) ;
return F;
}
// generacion de calor
247
115
120
125
130
135
140
145
150
155
248
160
165
170
175
180
185
190
195
249
200
205
210
215
220
225
230
235
250
a_b
b_b
= F;
= valor * area / C_p (e);
}
if ( boname . contiene (" Neumann ") || boname . contiene ("
neumann ") )
{
a_b
= F;
b_b
= valor * area * k(e)/ C_p (e);
}
matriz_a (e ,e) += a_b ; // Sp ;
b (e)
+= b_b ; // Su ;
240
245
}
}
}
250
}
}
calculado = true ;
return 1;
255
260
265
270
275
251
ANEXO H. CLASE PARA LA SOLUCION DE
10
15
20
25
30
// Archivo DifusionTransitoria .h
# pragma once
# include < AdmonEcLin .h >
# include < MallaFV .h >
# include < ConstOLeemalla .h >
# include < GuardarEnsight .h >
# include < GradoLibertadFV .h >
class DifusionTransitoria :
public GuardarEnsight
{
int nelementos ; // numero de volumenes de control
// //////// MALLA DE VOLUMENES FINITOS //////////////
Puntero < MallaFV > malla ;
Vector_basico < PunteroElmDefs > elems ;
VecinoFVM vecino ;
Puntero < CampoFVM >
phi ;
Puntero < GradoLibertadFV > gdl ;
Vector < real > S_fuente_ext ; // Agregado N -S
// //////// PROPIEDADES DEL MATERIAL ///////////////
Vector < real > rho ;
Vector < real > k;
Vector < real > cp ;
Vector < real > alph ;
Vector_basico < Vector_xyz < real >> Gamma ; // Agregado N -S
// ///////// SISTEMA // DE // ECUACIONES //////////////
// Matriz < real > matriz ;
Puntero < Matriz_Dispersa < real >> matriz ;
EstDispersa disp ;
prm_Matriz <real > pm ; // parametros de la matriz
Vector < real >
b;
Vector < real >
x;
Vector < real >
x_futuro ;
// // SOLUCION // DEL // SISTEMA // DE // ECUACIONES //////
Puntero < AdmonEcLin > admlin ;
252
35
40
45
50
55
60
65
70
75
253
bool SetPropiedades ( Vector < real > Gx , Vector < real > Gy , Vector <
real > Gz );
Vector_basico < PunteroElmDefs > GetElmDefs () ;
Puntero < prmTiempo > GetTiempo () ;
void SetNombreCampo ( char * ncampo );
Vector < real > CalcularCoefUnTiempo ( real
dependencia_futuro ,
Puntero < prmTiempo > t_ext , bool & triunfo );
Vector < real > CalcularCoefUnTiempo ( real dependencia_futuro , bool &
triunfo );
Vector < real > SolucionCoefUnTiempo ( bool & triunfo , bool vector2campo
= false );
80
85
};
254
ANEXO I. CLASE PARA LA SOLUCION DE
10
15
20
25
30
255
35
40
45
50
55
60
65
70
75
256
80
85
90
95
100
105
110
115
120
return 1;
}
real DifusionTransitoria :: Fourier ( real alpha , real dt , real dx )
{
real fo ; fo = alpha * dt /( dx * dx );
if ( primer_fourier ) { Fo_min = Fo_max = fo ; primer_fourier = false ;}
if ( fo < Fo_min ) { Fo_min = fo ;}
if ( fo > Fo_max ) { Fo_max = fo ;}
return fo ;
}
int DifusionTransitoria :: CalcularYResolver ( real dependencia_futuro )
{
if (! leido || calculado ) return 0;
// Para el caso estacionario solo se resuelve una vez
if ( tiempo_p -> estacionario () ) {
theta =1; // Este valor es por defecto en el
CalculoUnTiempo () ; // estado transitorio
SolucionUnTiempo () ;
Reportarresultados () ;
}
else { // Se asigna el valor del parametro de entrada
theta = dependencia_futuro ;
gdl -> vector2campo ( x_futuro , phi () );
Reportarresultados () ;
do {
tiempo_p -> incrementarTiempo () ;
CalculoUnTiempo () ;
SolucionUnTiempo () ;
Reportarresultados () ;
}
while (! tiempo_p -> finalizo () );
std_o <<"\ nMinimo Fourier " << Fo_min
<<"\ nMaximo Fourier " << Fo_max <<"\n";
}
calculado = solucionado = true ;
return 1;
}
real DifusionTransitoria :: S_fuente ( real x , real y)
{ return 5000; }
int DifusionTransitoria :: CalculoUnTiempo ()
{
int i , j , l ; // contadores
int veci ; // vecino numero veci
int conx , conxvec ; // numero de conexiones
257
125
130
135
140
145
150
155
160
258
165
170
175
180
185
190
195
200
259
205
210
215
220
225
230
235
240
245
260
if (! PropiedadesExternas || UnSoloGamma ) { //
Agregado N -S
bc = valor * k(i) * elems (i) -> getArea (j)/ cp (i);
} // Agregado N -S
else { // Agregado N -S
bc = valor *
abs ( Gamma (i) * elems (i) -> GetDirSide (j))
* elems (i) -> getArea (j); // Agregado N -S // Agregado N
-S
} // Agregado N -S
250
b(i) += bc ;
} // condicion de frontera dirichlet en la cual
// se da el valor de la derivada en direccion
// normal a la superficie
if ( boname . contiene ("Q")) {
bc = valor * elems (i) -> getArea (j)/ cp (i);
b(i) += bc ;
} // tipo especial de condicion de frontera
// dirichlet que solo es aplicada a la
// temperatura
255
260
265
}
}
} // final condicional frontera o volumen vecino
} // final del for para cada lado
}; // final for para cada volumen
return 1;
270
}
275
280
285
261
290
295
if ( vector2campo )
gdl -> vector2campo ( x_futuro , phi () );
return solucion ;
300
305
310
315
320
325
262
330
335
340
345
350
355
360
365
263
370
375
380
385
390
395
400
405
410
264
415
420
425
430
if (! PropiedadesExternas )
{ std_o <<"\ nError ConveccionTransitoria :: CalcularCoefUnTiempo \n\n"
;
triunfo = false ; return Salida ; // Salida sin dimensionalizar
}
// Asignacion de la dependencia del tiempo
theta = dependencia_futuro ; tiempo_p = t_ext ;
// Llamada a la funcion protected
CalculoUnTiempo () ;
// Dimensionamiento de Salida
Salida . chaSize ( nelementos );
for (i =1; i <= nelementos ; i ++) Salida (i) = matriz () (i ,i);
triunfo = true ;
return Salida ;
}
// Version para el calculo en estado transitorio como ocurre
// con la ecuacion de correccion de la presion en SIMPLE
Vector < real > DifusionTransitoria :: CalcularCoefUnTiempo ( real
dependencia_futuro , bool & triunfo )
{
int i; Vector < real > Salida ;
if (! PropiedadesExternas )
{ std_o <<"\ nError DifusionTransitoria :: CalcularCoefUnTiempo \n\n";
triunfo = false ; return Salida ;
}
435
440
445
450
theta = dependencia_futuro ;
CalculoUnTiempo () ;
Salida . chaSize ( nelementos );
for (i =1; i <= nelementos ; i ++) Salida (i) = matriz () (i ,i);
triunfo = true ;
return Salida ;
}
// Solucion de la ecuacion de difusion , el valor devuelto por la
funcion
// es el resultado , triunfo es modificado para informar si se
encontro
// la solucion
Vector < real > DifusionTransitoria :: SolucionCoefUnTiempo ( bool &
triunfo , bool vector2campo )
{
if (! PropiedadesExternas )
{ std_o <<"\ nError ConveccionTransitoria :: SolucionCoefUnTiempo \n\n"
;
triunfo = false ; return x_futuro ;
}
265
266
ANEXO J. CLASE PARA LA SOLUCION DE
LA ECUACION DE CONVECCION-DIFUSION
EN ESTADO TRANSITORIO: ENCABEZADO
DE LA CLASE
// Archivo ConveccionTransitoria .h
// El comentario // Agregado N -S se usa para indicar que la
instruccion
// fue agregada para resolver las ecuaciones del flujo en la capa
limite
# pragma once
# include < AdmonEcLin .h >
# include < MallaFV .h >
# include < ConstOLeemalla .h >
# include < GuardarEnsight .h >
# include < GradoLibertadFV .h >
10
15
20
25
30
267
35
40
45
50
55
60
65
70
75
268
80
85
90
95
100
105
};
269
ANEXO K. CLASE PARA LA SOLUCION DE
LA ECUACION DE CONVECCION-DIFUSION
EN ESTADO TRANSITORIO: ARCHIVO DE
CODIGO FUENTE
10
15
20
25
30
270
35
40
45
50
55
60
65
70
75
271
80
85
90
95
100
105
110
115
120
}
// Calculo y Solucion de la ecuaci \ on de conveccion - difusion
int ConveccionTransitoria :: CalcularYResolver ( real
dependencia_futuro )
{
if (! leido ) return 0;
tiempo_p -> iniciarCicloTiempo () ;
if ( tiempo_p -> estacionario () ) {
theta = 1.0;
CalculoUnTiempo () ;
SolucionUnTiempo () ;
Reportarresultados () ;
}
else {
theta = dependencia_futuro ;
gdl -> vector2campo ( x_futuro , phi () );
gdl -> vector2campo (u , campo_vel () (1) );
gdl -> vector2campo (v , campo_vel () (2) );
Reportarresultados () ;
do {
tiempo_p -> incrementarTiempo () ;
CalculoUnTiempo () ;
SolucionUnTiempo () ;
Reportarresultados () ;
}
while (! tiempo_p -> finalizo () );
if ( Fo_min == Fo_max )
{ std_o <<"\ nFourier " << Fo_min <<"\n"; }
else
{ std_o <<"\ nMinimo Fourier " << Fo_min <<
"\ nMaximo Fourier " << Fo_max <<"\n" ;}
}
std_o <<" Peclet minimo " << peclet_min () <<
" Peclet maximo " << peclet_max () << "\n";
solucionado = true ;
return 1;
}
int ConveccionTransitoria :: CalculoUnTiempo ()
{
if ( ! PropiedadesExternas ) // Agregado N -S
x= x_futuro ; // se actualiza el valor del pasado
matriz -> llenar (0.0) ; b. llenar (0.0) ;
real tr ; // transitorio ,
real hfrontera ; // conveccion en la frontera
int m ,n ,o ,p; // Agregado N -S
272
125
130
135
140
145
150
155
160
165
273
170
175
180
185
190
195
200
205
274
210
215
220
225
230
235
240
245
275
250
255
260
265
270
275
280
285
290
}
// /********* fronteras
if ( malla -> obtNoDimEspacio () == 3)
if ( elems (e) -> GetDirSide (l) (3) !=0) {
if ( fv3 . contiene (" Dirichlet "))
{ bovalue = fv3 . despues ( = );
valor
= atof ( bovalue . carts () );
vel (3) = valor ;
}
else
if ( fv3 . contiene (" Neumann ") )
{ bovalue = fv3 . despues ( = );
valor
= atof ( bovalue . carts () );
vel (3) = w(e) - valor * elems (e) -> getDelta (l);
}
}
// Caso especial de la velocidad en la frontera para
la ec . de corr . de velocidad .
if ( LecturaCadena . contiene (" Vcor "))
{
vel (1) = u(e); vel (2) =v(e);
if ( malla -> obtNoDimEspacio () == 3)
vel (3) = w(e);
}
}
// /********* fronteras
F
= conveccion (e ,l , area , vel ) ;
boname = malla -> obtNombreIndFront (h); // Obtener la
cadena exacta del tipo y valor de condicion de
frontera
if ( PropiedadesExternas ) { // Agregado N -S
med = boname . despues ( LecturaCadena ); // Agregado N -S
if ( med . contiene ( ,)) { // Agregado N -S
o = med . Buscar (0 , ,);
boname = med . subCadena (0 ,o);
} // Agregado N -S
else { boname = med ;} // Agregado N -S
} // Agregado N -S
bovalue = boname . despues ( = );
valor
= atof ( bovalue . carts () );
D
= difusion (e ,l , area );
if ( boname . contiene ("T") || boname . contiene (" dirichlet
")
|| boname . contiene (" Dirichlet ") ) {
if ( boname . contiene ("h=") ){
bovalue = boname . despues ("T=");
276
295
300
305
310
315
320
325
330
valor
= atof ( bovalue . carts () );
bovalue = boname . despues ("h=");
hfrontera
= atof ( bovalue . carts () );
D = difusion (e ,l , area , hfrontera );
}
if ( boname . contiene ("L") )
{
y
= elems (e) -> centroArea ( malla -> obtCoorElem (e) ,
l) (2) ;
valor = 1.0 + valor * ( (1 -y) );
}
if ( boname . contiene ("e")) {
px = elems (e) -> centroArea ( malla -> obtCoorElem (e) ,l)
(1) ;
bovalue = boname . despues ("e"); valor2 = atof (
bovalue . carts () );
valor = valor * exp ( valor2 *( px - minc (1) ) );
}
if ( boname . contiene ("x")){
px = elems (e) -> centroArea ( malla -> obtCoorElem (e) ,l)
(1) ;
bovalue = boname . despues ("x"); valor2 = atof (
bovalue . carts () );
valor = valor * pow ( px - minc (1) , valor2 );
}
Pe
= peclet (F ,D);
A
= funcion_a (Pe , metodo_aprox ); // Agregado N -S
a_bj = D*A + std :: max (F ,0.0) ;
b_bj = (D*A + std :: max (-F ,0.0) )* valor ;
}
if ( boname . contiene ("Q") ) {
a_bj = F;
b_bj = valor * area / cp (e) ;
}
if ( boname . contiene (" Neumann ") || boname . contiene ("
neumann ") ) {
a_bj = F;
if (! PropiedadesExternas || UnSoloGamma )
{ b_bj = valor * area * k(e)/ cp (e); }
else {
b_bj = valor * area *
abs ( Gamma (e)* elems (e) -> GetDirSide (l));
}
}
matriz () (e ,e) += a_bj * theta ;
b (e)
+= b_bj - (1 - theta )* a_bj *x(e) ;
277
}
}
}
335
}
}
return 1;
340
}
bool ConveccionTransitoria :: SolucionUnTiempo ( bool vector2campo )
{
int itera ; bool conv , solucion ;
if ( primera_solucion )
{ admlin () . adjuntar ( matriz () , x_futuro , b); primera_solucion =
false ; }
solucion = admlin () . solve () ;
345
350
355
360
365
370
375
278
380
385
390
395
400
405
410
415
if ( modo . contiene (" power ") || modo . contiene (" law ") )
{ return max (0.0 , pow (1.0 -0.1* fabs ( pe ) ,5)); }
if ( modo . contiene (" exp ") || modo . contiene (" Exp ") )
{ return fabs ( pe ) /( exp ( fabs ( pe )) -1.0) ; }
return 0; // Devolver este valor implica error
}
// se calcula la difusividad entre dos nodos vecinos
// vol1 numero correspondiente al volumen de control actual
// vol2 numero correspondiente al volumen de control vecino
// dir1 corresponde al numero del lado del volumen
// de control vol1 en la cual se realizan los calculos
real ConveccionTransitoria :: difusion ( int vol1 , int dir1 , int vol2 ,
int dir2 , real area )
{
real D1 , D2 , Dt , gamma ;
if (! PropiedadesExternas || UnSoloGamma ) { // Agregado N -S
gamma = k( vol1 )/ cp ( vol1 ) ; D1 = gamma / elems ( vol1 ) -> getDelta (
dir1 );
gamma = k( vol2 )/ cp ( vol2 ) ; D2 = gamma / elems ( vol2 ) -> getDelta (
dir2 );
} // Agregado N -S
else { // Agregado N -S
gamma = abs ( Gamma ( vol1 ) * elems ( vol1 ) -> GetDirSide ( dir1 )) ;
D1 = gamma / elems ( vol1 ) -> getDelta ( dir1 );
gamma = abs ( Gamma ( vol2 ) * elems ( vol2 ) -> GetDirSide ( dir2 )) ;
D2 = gamma / elems ( vol2 ) -> getDelta ( dir2 );
} // Agregado N -S
Dt
= area / (1.0/ D1 + 1.0/ D2 );
return Dt ;
}
// version de la funcion de calculo de la difusividad
// para un lado que limita con una condicion de frontera
// en donde se define el coeficiente de conveccion
// esta funcion solo es validad cuando \ phi =T
real ConveccionTransitoria :: difusion ( int vol1 , int dir1 , real area
, real conveccion_f )
{
real D1 , D2 , Dt , gamma ;
if (! PropiedadesExternas || UnSoloGamma ) { // Agregado N -S
gamma = k( vol1 )/ cp ( vol1 ) ; D1 = gamma / elems ( vol1 ) -> getDelta (
dir1 );
}
else { // Agregado N -S
gamma = abs ( Gamma ( vol1 ) * elems ( vol1 ) -> GetDirSide ( dir1 )) ;
D1 = gamma / elems ( vol1 ) -> getDelta ( dir1 );
279
} // Agregado N -S
420
425
430
435
440
445
450
455
460
D2 = conveccion_f / cp ( vol1 );
Dt = area / (1.0/ D1 + 1.0/ D2 );
return Dt ;
}
// version de la funcion de calculo de la difusividad
// para un lado que limita con una condicion de frontera
real ConveccionTransitoria :: difusion ( int vol1 , int dir1 , real area )
{
real Dt , gamma ;
if (! PropiedadesExternas || UnSoloGamma ) { // Agregado N -S
gamma = k( vol1 )/ cp ( vol1 ) ;
}
else { // Agregado N -S
gamma = abs ( Gamma ( vol1 ) * elems ( vol1 ) -> GetDirSide ( dir1 )) ;
}
Dt = gamma / elems ( vol1 ) -> getDelta ( dir1 );
Dt = area * Dt ;
return Dt ;
}
// Calculo del flujo convectivo
real ConveccionTransitoria :: conveccion ( int vol1 , int dir1 , real
area , Vector_xyz < real > Vel )
{
real F ;
Vector_xyz < real > side = elems ( vol1 ) -> GetDirSide ( dir1 ); // Agregado
N -S
F = ( side * Vel );
F = rho ( vol1 ) * area * F ; // Agregado N -S
return F;
}
real ConveccionTransitoria :: peclet_min ( void ) { return pe_min ;}
real ConveccionTransitoria :: peclet_max ( void ) { return pe_max ;}
real ConveccionTransitoria :: peclet ( real F , real D)
{
real peclet =F/D;
if ( primer_peclet )
{ pe_max = pe_min = abs ( peclet ); primer_peclet = false ; }
if ( abs ( peclet ) > pe_max ) pe_max = abs ( peclet );
if ( abs ( peclet ) < pe_min ) pe_min = abs ( peclet );
return peclet ;
}
// /////////////////// METODOS // Agregado N -S ///////////////////
void ConveccionTransitoria :: SetPropiedadesExternas ( bool opcion )
{ PropiedadesExternas = opcion ;}
280
465
470
475
480
485
490
495
281
500
505
510
515
520
525
530
535
return Salida ;
}
theta = dependencia_futuro ; tiempo_p = t_ext ;
metodo_aprox = mAproximacion ;
CalculoUnTiempo () ;
for (i =1; i <= nelementos ; i ++) Salida (i) = matriz () (i ,i);
triunfo = true ;
return Salida ;
}
Vector < real > ConveccionTransitoria :: GetCoefVecinos ()
{
int i , j , k , conx ; Vector < real > Salida ( nelementos );
Salida . llenar (0.0) ;
for (i =1; i <= nelementos ; i ++) {
conx = elems (i) -> GetNumOfConex () ;
for ( j =1; j <= conx ; j ++) {
k = malla -> getConx (i ,j);
if (k !=0) Salida (i) -= matriz () (i ,k);
}
}
return Salida ;
}
// M\ etodo public para solucionar el sistema de ecuaciones
externamente
Vector < real > ConveccionTransitoria :: SolucionCoefUnTiempo ( bool &
triunfo , bool vector2campo )
{
if (! PropiedadesExternas ) {
std_o <<"\ nError ConveccionTransitoria :: SolucionCoefUnTiempo \n\n
";
triunfo = false ;
return x_futuro ;
}
triunfo = SolucionUnTiempo ( vector2campo );
return x_futuro ;
}
// Introduccion del vector solucion en el pasado y el punto de
partida
// para encontrar la solucion de los mismos iterativos
bool ConveccionTransitoria :: SetPasadoPartida ( Vector < real >
phi_pasado , Vector < real > phi_pto_partida_iteracion )
{
if (! PropiedadesExternas ) { return false ; }
x = phi_pasado ;
x_futuro = phi_pto_partida_iteracion ;
return true ;
282
540
545
550
555
560
565
570
575
580
}
bool ConveccionTransitoria :: SetPasado ( Vector < real > phi_pasado )
{
if (! PropiedadesExternas ) { return false ; }
x = phi_pasado ;
return true ;
}
bool ConveccionTransitoria :: SetPropiedades ( Vector < real > set_rho ,
Vector < real > set_k , Vector < real > set_cp )
{
int i;
if (! PropiedadesExternas ) { return false ; }
rho = set_rho ;
k = set_k ;
cp
= set_cp ;
for (i =1;i <= nelementos ;i ++)
alph (i)=k(i) /( rho (i)* cp (i));
return true ;
}
bool ConveccionTransitoria :: SetPropiedades ( Vector < real > set_rho ,
Vector < real > set_gamma )
{
int i;
if (! PropiedadesExternas ) { return false ; }
rho = set_rho ; k = set_gamma ; cp . llenar (1.0) ;
for (i =1;i <= nelementos ;i ++)
alph (i)=k(i) /( rho (i)* cp (i));
return true ;
}
bool ConveccionTransitoria :: SetPropiedades ( Vector < real > set_rho ,
Vector < real > Gx , Vector < real > Gy , Vector < real > Gz )
{
int i; UnSoloGamma = false ;
if (! PropiedadesExternas ) { return false ; }
rho = set_rho ; cp . llenar (1.0) ;
for (i =1; i <= nelementos ; i ++) {
Gamma (i) (1) = Gx (i);
Gamma (i) (2) = Gy (i);
if ( malla -> obtNoDimEspacio () == 3)
Gamma (i) (3) = Gz (i);
}
for (i =1;i <= nelementos ;i ++)
alph (i)= Gx (i) /( rho (i)* cp (i));
return true ;
}
283
585
284
sin embargo, para resolver las ecuaciones de Navier-Stokes es ahora necesario calcular el
campo de la velocidad tomando como punto de partida los valores en la iteraci n anterior o
o
los valores de entrada.
Anteriormente, se utiliz un m todo para el c lculo del t rmino fuente que dependa de la
o
e
a
e
efecto de la generaci n en funci n del n mero que identica a cada volumen de control. Para
o
o
u
el caso de las ecuaciones de la cantidad de movimiento, el t rmino de la generaci n repree
o
senta las fuerzas viscosas y de presi n.
o
Se hace necesario exportar el valor de algunos t rminos de la matriz de coecientes1 e introe
ducirlos como parte del valor de la constante difusiva en la ecuaci n de corrreci n de presi n.
o
o
o
Los t rminos de la matriz de coecientes de cada una de las ecuaciones de la cantidad de moe
vimiento son, en su mayor parte, iguales pero varan en caso de denir para alg n lado m s
u
a
de un tipo de condici n de frontera.
o
Se modica la denici n de la matriz de coecientes a matriz dispersa para disminuir el
o
tiempo requerido para resolver el sistema de ecuaciones por m todos iterativos, adicionale
mente, esta modicaci n permite usar la descomposici n incompleta LU como precondio
o
cionador reduciendo en la mayora de los casos el n mero de iteraciones requerido.
u
Las variables que se agregan a la clase ConveccionTransitoria son:
....
class ConveccionTransitoria : protected GuardarEnsight
{
Vector<real>w;
Vector<real>S_fuente_ext;
Cadena metodo_aprox;
1 Especcamente
los t rminos de la diagonal principal de cada una de las instancias para resolver las ecuae
ciones de la cantidad de movimiento. Adicionalemente, el m todo SIMPLEC requiere de la sumatoria de los
e
dem s t rminos.
a e
285
Cadena LecturaCadena;
bool PropiedadesExternas;
bool mallaExterna;
EstDispersa disp;
...
};
La variable que se modica en la clase ConveccionTransitoria es:
....
class ConveccionTransitoria : protected GuardarEnsight
{
Puntero<Matriz_Dispersa<real>>matriz;
...
};
Se dene la variable w para almacenar el valor de la velocidad del uido para an lisis en tres
a
dimensiones. Se dene el vector S_fuente_ext en el cual se almacena la informaci n del
o
t rmino fuente para cada volumen de control. La Cadena metodo_aprox se dene con el
e
objetivo de almacenar el tipo de esquema y la Cadena LecturaCadena almacena el nombre
de la condici n de frontera que ser leido para calcular la velocidad del uido en la frontera
o
a
o el valor de una propiedad en ella. Por otro lado, se denen PropiedadesExternas que
modica la forma como se calculan algunos valores y mallaExterna que modica la forma
de generar la malla.
Los m todos que se agregan son:
e
....
class ConveccionTransitoria : protected GuardarEnsight
{
...
void EstructurarDisp();
public:
...
void SetPropiedadesExternas ( bool opcion );
bool SetMalla ( Puntero<MallaFV> &MallaEntrada );
bool SetMallaeIniciar ( Puntero<MallaFV> &MallaEntrada ,
Cadena solucionador, Puntero<prmTiempo> &def_tiempo, Cadena );
void GetMalla ( Puntero<MallaFV> &Salida);
bool SetFuenteYFlujo
(Vector<real> S_f, Vector<real> uu, Vector<real> vv, Vector<real> ww);
bool SetPasadoPartida
(Vector<real> phi_pasado, Vector<real> phi_pto_partida_iteracion) ;
bool SetPasado (Vector<real> phi_pasado);
bool SetPropiedades
286
1 1.1 0
0
4.1 5.2 5.6 0
287
III. Se realiza un primer bucle repetitivo que recorre cada volumen de control en donde
se asigna al vector irow el valor del siguiente entero del contador de elementos m.
...
jcol.llenar(0);
m=0;
for(i=1;i<=nelementos;i++) {
irow(i) = m+1;
conx=elems(i)->GetNumOfConex();
ord.llenar(0);
...
IV. Para cada volumen de control se llena el vector ord con el n mero correspondiente
u
a cada una de las celdas que intervienen en la ecuaci n del volumen i. Una vez se llena el
o
vector, se ordena y se asigna a jcol los valores diferentes de cero.
...
for ( j=1;j<=conx;j++){
veci = malla->getConx(i,j);
ord(j) = veci;
}
ord(conx+1)= i;
ord.OrdPila();
for ( j=1;j<=conx+1;j++){
if (ord(j)!=0) {
jcol(++m)=ord(j);
}
}
}
...
V.
El valor de los vectores irow y jcol se introduce en la instancia disp de tipo
EstDispersa la cual contiene la informaci n de la estructura de la matriz. Finalmente,
o
se asigna la memoria al puntero matriz con la informaci n recopilada en disp.
o
...
irow(nelementos+1) = m+1;
disp.chaSize(nelementos,m);
for(i=1 ; i<=nelementos+1;i++) disp.irow(i) = irow(i);
disp.chaSizeColJ(jcol,m);
matriz.vincular(new Matriz_Dispersa<real>(disp));
}
2.
M todo SetPropiedadesExternas(...): modica el valor de PropiedadesExternas
e
para permitir la introducci n de valores como la velocidad, el t rmino fuente, etc.
o
e
288
3.
M todo SetMalla(...): el procedimiento que se usar , genera una unica malla la
e
a
cual es llamada por las dem s instancias de ConveccionTransitoria y DifusionTransitoria
a
por lo que se hace necesario denir un m todo que permita introducir la malla para el proe
blema especicado. En este m todo al igual que en otros, se verica el valor del par metro
e
a
de control PropiedadesExternas,si este valor no ha sido establecido en true,no se realizar la asignaci n de la malla.
a
o
bool ConveccionTransitoria::SetMalla ( Puntero<MallaFV> &MallaEntrada )
{ if (!PropiedadesExternas) return false;
malla=MallaEntrada; return true;
}
4.
M todo SetMallaeIniciar(): Se dene un m todo alternativo a Leer(...) para
e
e
introducir los datos del problema como la malla, la denici n del tiempo y el nombre a
o
buscar en la condici n de frontera.
o
bool ConveccionTransitoria::SetMallaeIniciar
( Puntero<MallaFV> &MallaEntrada , Cadena solucionador,
Puntero<prmTiempo> &def_tiempo, Cadena nombreFrontera )
{
if (!PropiedadesExternas) return false;
mallaExterna = true; malla = MallaEntrada;
tiempo_p = def_tiempo; Leer(" ",solucionador,"");
LecturaCadena=nombreFrontera;
return true;
}
5.
de la velocidad u, v y w debe ser introducido adem s del valor del t rmino fuente. La
a
e
asignaci n de la velocidad w solo se realiza si la malla usada es tridimensional.
o
bool ConveccionTransitoria::SetFuenteYFlujo (Vector<real> S_f,
Vector<real> uu, Vector<real> vv, Vector<real> ww)
{ if (!PropiedadesExternas) return false;
S_fuente_ext.chaSize(nelementos); S_fuente_ext = S_f+;
u = uu; v = vv;
if (malla->obtNoDimEspacio() == 3) w = ww;
return true;
}
289
7.
M todo SetPasadoPartida(...): este m todo actualiza el valor de la variable a
e
e
calcular y permite introducir un valor inicial para las iteraciones interiores.
bool ConveccionTransitoria::SetPasadoPartida
(Vector<real> phi_pasado, Vector<real> phi_pto_partida_iteracion)
{
if (!PropiedadesExternas) { return false; }
x = phi_pasado ;
x_futuro = phi_pto_partida_iteracion ;
return true;
}
8.
M todo SetPasado(...): es necesario dar un punto de partida para resolver por
e
m todos iterativos el sistema de ecuaciones lineales almacenado en la matriz de coee
cientes y el vector de t rminos independientes; para lograr esto, se llama inicialmente
e
SetPasadoPartida(...) pero, para un segundo ciclo, es suciente con actualizar el valor
de en el pasado2 . Se dene el m todo SetPasado(...) para actualizar el valor de en
e
el pasado.
bool ConveccionTransitoria::SetPasado(Vector<real> phi_pasado)
{
if (!PropiedadesExternas) { return false; }
x = phi_pasado ;
return true;
}
9.
M todo SetPropiedades(...): se introduce el valor de y de correspondiente
e
para el problema de convecci n-difusi n; para la ecuaci n de la energa, = k/C p , para la
o
o
o
290
bool ConveccionTransitoria::SetPropiedades
( Vector<real> set_rho , Vector<real> set_gamma)
{
int i;
if (!PropiedadesExternas) { return false; }
rho = set_rho;
k = set_gamma;
cp.llenar(1.0);
for (i=1;i<=nelementos;i++)
alph(i)=k(i)/(rho(i)*cp(i));
return true;
}
10. M todo GetTiempo(...): se devuelve el Puntero al objeto prmTiempo de mae
nera que solo es necesario crear un objeto que ser llamado por las dem s instancias de
a
a
ConveccionTransitoria y DifusionTransitoria.
Puntero<prmTiempo> ConveccionTransitoria::GetTiempo()
{ return tiempo_p;}
11. M todo S_fuente(...): se proporciona una sobrecarga a la funci n S_fuente que
e
o
toma como argumento el n mero que identica al volumen de control.
u
real ConveccionTransitoria::S_fuente (int nvol)
{ return S_fuente_ext(nvol); }
12. M todo CalcularCoefUnTiempo(...): se dene una funci n que, adem s de recibir
e
o
a
varios par metros y llamar a CalculoUnTiempo(), devuelve el valor de los elementos de
a
la diagonal principal de la matriz de coecientes. El valor del Vector devuelto es utilizado
en conjunto con y para denir el valor de en la ecuaci n de correcci n de presi n.
o
o
o
Vector<real> ConveccionTransitoria::CalcularCoefUnTiempo
(real dependencia_futuro, Puntero<prmTiempo> t_ext,
Cadena mAproximacion, bool &triunfo)
{
int i; Vector<real> Salida (nelementos);
if (!PropiedadesExternas) {
std_o<<"\nError ConveccionTransitoria::CalcularCoefUnTiempo\n\n";
triunfo = false;
return Salida;
}
theta=dependencia_futuro;
tiempo_p = t_ext;
291
metodo_aprox = mAproximacion;
CalculoUnTiempo();
for (i=1; i<=nelementos; i++) Salida(i) = matriz()(i,i);
triunfo= true;
return Salida;
}
13. M todo SolucionCoefUnTiempo(...): se dene un m todo que, adem s de ree
e
a
solver el sistema de ecuaciones lineales, devuelve el Vector<real> de la soluci n e indica
o
en la variable triunfo si se encontr la soluci n.
o
o
Vector<real> ConveccionTransitoria::SolucionCoefUnTiempo
(bool &triunfo, bool vector2campo )
{
if (!PropiedadesExternas) {
std_o<<"\nError ConveccionTransitoria::SolucionCoefUnTiempo\n\n";
triunfo = false;
return x_futuro;
}
triunfo = SolucionUnTiempo();
return x_futuro;
}
14. M todo CadenaFrontera(...): el ujo de la propiedad en la frontera se determina
e
a partir del tipo de frontera y el valor indicado en el archivo *.geom. Para seleccionar
el valor correcto se debe indicar el nombre de la propiedad a leer3 el cual se introduce en
la clase mediante la funci n CadenaFrontera(...) que modica el valor de la Cadena
o
LecturaCadena.
bool ConveccionTransitoria::CadenaFrontera ( Cadena cad)
{
if (!PropiedadesExternas) { return false; }
LecturaCadena = cad;
return true;
}
Se realizaron algunas modicaciones a funciones previamente denidas que permiten un uso
m s general para la clase.
a
1.
3 Por
292
ConveccionTransitoria::ConveccionTransitoria(void)
{
primera_solucion=primer_fourier=true;
PropiedadesExternas=false;//Agregado N-S
metodo_aprox = "UDS";//Agregado N-S
mallaExterna = false;//Agregado N-S
tiempo_p.vincular(new prmTiempo);
}
2.
Modicaci n a la funci n Leer(...): se agregan algunos condicionales para restrino
o
gir la ejecuci n de ciertas instrucciones.
o
int ConveccionTransitoria::Leer
(Cadena archivo,Cadena solucionador, Cadena def_tiempo, real T_inicial)
{
...
I.
}
...
IV. Como ya se haba mencionado, la funci n SetMallaeIniciar(...) tambi n de
o
e
ne los par metros del tiempo, es por esto que si la malla es externa, no se debe leer los
a
datos del tiempo.
if (!mallaExterna)//Agregado N-S
tiempo_p->Leer(def_tiempo);
...
V.
Si las propiedades son externas, no es necesario asignar un valor a k, rho, cp y
x_futuro. El dimensionamiento de la matriz de coecientes no se realiza con la llamada
a chasize(...), en cambio, se llama al m todo EstructurarDisp() para realizar esta
e
labor.
if (!PropiedadesExternas) {//Agregado N-S
k.llenar(0.01);
rho.llenar(1.0);
cp.llenar(1.0);
for (i=1;i<=nelementos;i++)
alph(i)=k(i)/(rho(i)*cp(i));
}//Agregado N-S
//matriz->chaSize(nelementos, nelementos);
EstructurarDisp();//Agregado N-S
b.chaSize(nelementos);
x.chaSize(nelementos); x_futuro.chaSize(nelementos);//Propiedad
if (! PropiedadesExternas) {//Agregado N-S
x_futuro.llenar(T_inicial);
}
...
return 1;
}
3.
Modicaci n a la funci n CalculoUnTiempo(): se agregan varias instrucciones eno
o
tre las que se destaca la lectura de la condici n de frontera en cada lado.
o
I.
La actualizaci n del valor de la propiedad en el pasado no se realiza en la funci n
o
o
CalculoUnTiempo() si PropiedadesExternas ha sido denido como true, en cambio,
se debe llamar al m todo SetPasadoPartida(...) o SetPasado(...) seg n sea el
e
u
caso.
int ConveccionTransitoria::CalculoUnTiempo()
{
if ( !PropiedadesExternas ) //Agregado N-S
x=x_futuro;
294
...
II. Se denen otras variables que ser n necesarias para el c lculo del tipo y valor de la
a
a
condici n de frontera:
o
int m,n,o,p;//Agregado N-S
Cadena fv1,fv2,fv3, med;//Agregado N-S
Vector_xyz<real> minc, maxc; real px,py, valor2;//Agregado N-S
real area, y, volumen, d1, d2; //Agregado N-S
...
III. El modo de asignar el efecto del t rmino fuente diere si las propiedades son exe
ternas o internas. Para el caso que PropiedadesExternas sea true, se llama a la sobrecarga S_fuente(int nvol), en caso contrario, se introduce las coordenadas del volumen
de control actual.
for(e=1;e<=nelementos;e++) {
pos=elems(e)->centroid(malla->obtCoorElem(e));
volumen=elems(e)->getVolume();
if (!PropiedadesExternas) {//Agregado N-S
b(e) = S_fuente (pos(1), pos(2)) * volumen;
}//Agregado N-S
else {//Agregado N-S
b(e) = S_fuente (e) ; //Agregado N-S
}//Agregado N-S
...
IV. Determinaci n de la velocidad en la frontera: se debe realizar el llenado de vel
o
(de tipo Vector_xyz<real>) de acuerdo a las condiciones de frontera especicadas en el
archivo *.geom,el procedimiento para realizar el llenado se muestra en el siguiente
fragmento de c digo.
o
for( l=1 ; l<=conx ; l++ ) {
...
if (veci!=0)
{...}
else
{
for (h=1; h<=nbi; h++)
{
if ( malla->LadoFront(e,l,h,elems(e)())
{
}//Agregado N-S
else
{
vel.llenar(0.0);
boname = malla->obtNombreIndFront(h);
o = m=0; n=boname.tam();
while (o<n )
{ if (boname(o,1) == ,) m++; o++;}
n=0;
for (o=1; o<=m; o++) {
p=n;
n= boname.Buscar(n,,);
if (p!=n) {
med =boname.subCadena(p,n-p);
if (med.contiene("VelU"))
fv1 = med;
if (med.contiene("VelV"))
fv2 = med;
if (med.contiene("VelW"))
fv3 = med;
}
n++;
}
p = boname.tam();
med = boname.subCadena(n,p-n);
if (med.contiene("VelU"))
fv1 = med;
if (med.contiene("VelV"))
fv2 = med;
if (med.contiene("VelW"))
fv3 = med;
///*********fronteras
if (fv1.contiene("Dirichlet")) {
bovalue = fv1.despues(=);
valor
= atof(bovalue.carts());
vel(1) = valor;
px = elems(e)->centroArea(malla->obtCoorElem(e),l)(1);
py = elems(e)->centroArea(malla->obtCoorElem(e),l)(2);
if (fv1.contiene("e")) {
bovalue = fv1.despues("e"); valor2 = atof(bovalue.carts());
vel(1) = valor * exp( valor2*(px-minc(1)) );
}
if (fv1.contiene("x")){
296
{bovalue = fv3.despues(=);
valor
= atof(bovalue.carts());
vel(3) = w(e) - valor* elems(e)->GetDirSide(l)(3);
}
}
///*********fronteras
...
V.
Adem s de determinar el valor de la velocidad en la frontera, tambi n se debe detera
e
minar el valor de la propiedad (ya sea la temperatura o una componente de la velocidad)
en la frontera, el siguiente procedimiento realiza esta tarea.
...
F
= conveccion(e,l,area,vel) ;
boname = malla->obtNombreIndFront(h);
if (PropiedadesExternas){//Agregado N-S
med = boname.despues(LecturaCadena);
if (med.contiene(,)){//Agregado N-S
o = med.Buscar(0,,);
boname =med.subCadena(0,o);
}//Agregado N-S
else//Agregado N-S
{boname=med;}//Agregado N-S
}//Agregado N-S
...
4.
Modicaci n del m todo SolucionUnTiempo(): se redene la funci n de manera
o
e
o
que acepte un par metro (vector2campo) el cual ser vericado para realizar o no la transa
a
formaci n de los vectores de velocidad y la propiedad hacia los correspondientes campos.
o
bool ConveccionTransitoria::SolucionUnTiempo( bool vector2campo )
{
...
if (vector2campo) {
gdl->vector2campo(x_futuro,phi());
gdl->vector2campo(u,campo_vel()(1));
gdl->vector2campo(v,campo_vel()(2));
if ( malla->obtNoDimEspacio()==3)
gdl->vector2campo(x,campo_vel()(3));//Agregado N-S
}
return solucion;
}
Para un correcto funcionamiento, se debe modicar la declaraci n en el encabezado de la
o
clase por la siguiente instrucci n.
o
298
299
ANEXO M. CLASE PARA EL CALCULO DEL
10
15
20
25
30
// NavierStokes .h
# pragma once
# include " ConveccionTransitoria .h"
# include " DifusionTransitoria .h"
// metodo de aproximacion para el metodo de conveccion difusion
static const char * MACD [] = {" UDS " , " Upwind " ," CDS " , " upwind " ,"
hybrid " ,
" hibrido " , " power " , " law " , " exp " , " Exp " , NULL };
// metodo de solucion de las ecuaciones de navier stokes
static const char * MSNS [] = {" SIMPLE " ," NOSIMPLE " , " SIMPLEC " , NULL };
// Calculo del tipo de problema especificado
const char Separador = ,;
const bool MULT_POR_RHO_ON = true ;
const bool MULT_POR_RHO_OFF = false ;
class NavierStokes : protected GuardarEnsight
{
// Clase para la solucion de la ec . de cant . movimiento .
ConveccionTransitoria ConvVu , ConvVv , ConvVw ;
// Velocidad en el tiempo futuro
Vector < real > VelU , VelV , VelW ;
// Velocidad en el tiempo presente
Vector < real > VelU_ant , VelV_ant , VelW_ant ;
// Velocidad calculada en cada ec . de cant . de mov .
Vector < real > VmAstU , VmAstV , VmAstW ;
// Gradientes para cada componente de la velocidad , presion , etc
Vector_basico < Vector_xyz < real >> GU , GV , GW , GP , Gtau ;
Vector_basico < Vector_xyz < real >> GU_n , GV_n , GW_n , GP_n ;
Vector_basico < Vector_xyz < real >> GU_ant , GV_ant , GW_ant , GP_ant ;
Vector_basico < Vector_xyz < real >> Fcalor ;
Vector < real > GVel , GVel_ant , GVel_n ;
// Tensor de esfuerzos
Vector_basico < Matriz < real >> Tau_n , Tau_ant , Tau ;
Vector < real > CoefU , CoefV , CoefW ; // En estos se almacenar \ an los
coeficientes de la diagonal principal que son necesarios en la
ecuacion de correcion de presion
// Clase para la solucion de la ec . de la energia
300
35
40
45
50
55
60
65
70
75
ConveccionTransitoria Temperatura ;
// Almacenamiento de la temperatura actual y anterior .
Vector < real > Temp , Temp_ant ;
// Clase para la solucion de la ec . de correcion de presion
DifusionTransitoria Pprima ;
// Almacenamiento de la correcion de presion
Vector < real > Presionprima ;
// Presion para varios tiempo
Vector < real > Presion , Presion_ant , Presion_n ;
// Correcion de la velocidad .
ConveccionTransitoria Corrv ;
Vector < real > vcor ;
// Vector para almacenar el volumen de cada VC
Vector < real > Volumen ;
Vector < real > Fuente ; // La variable Fuente se usa para almacenar la
informaci \ on del t\ ermino fuente de cualquiera de las
ecuaciones
Vector < real > ResiduoMasico ;
// //////// MALLA DE VOLUMENES FINITOS //////////////
Puntero < MallaFV > malla ;
Vector_basico < PunteroElmDefs > elems ;
Puntero < CampoFVM >
campo_T ;
Puntero < CampoFVM >
campo_u ;
Puntero < CampoFVM >
campo_residuo ;
Puntero < CampoFVM >
campo_pres ;
Puntero < CampoFVM >
campo_pres_prima ;
Puntero < CampoFVM >
campo_corr_vel ;
Puntero < CamposFVM >
campo_vel ;
Puntero < CamposFVM >
campo_GTau ;
Puntero < CamposFVM >
campo_GU , campo_GV , campo_GW ;
Puntero < CamposFVM >
campo_GP ;
Puntero < CamposFVM >
campo_Q ;
Puntero < GradoLibertadFV > gdl ;
// //////// PROPIEDADES DEL MATERIAL ///////////
Vector < real > rho ;
Vector < real > k;
Vector < real > cp ;
Vector < real > mu ;
real Rgas ; // Constante del gas , para cuando se considere rho
variable
// /////// DEPENDENCIA // DEL // TIEMPO ///////////
real theta ;
Puntero < prmTiempo > tiempo_p ;
Puntero < prmTiempo > t_aux ;
// //// NUMERO // ITERACIONES // MAXIMAS /////////
int Nitera ;
301
80
85
90
95
100
105
110
115
120
302
125
130
135
140
145
150
155
160
bool GuardarDatos () ;
bool GuardarDatos ( real minvel , real maxvel );
bool SetCargarDatos ( bool opcion );
void SetNoIterExt ( int set );
bool SetTipoMetodoSolucion ( Cadena tipo );
bool SetEsquemaConveccion ( Cadena tipo );
void SetMinimaPresion ( real min );
void SetMaximaPresion ( real max );
void SetTrefyDensidad ( real tt , bool densidad_constante );
void SetPresAtmosf ( real pp );
void ResetMinMaxPresion () ;
bool SetParametros ( bool Datos_iniciales_externos = false , int
N_iteraciones = 100 , Cadena Esquema_conveccion = " UDS " ,
Cadena Esquema_solucion =" SIMPLE " , bool Resultados_indep_tiempo =
true );
bool SetMAssThreshold ( real MaxResMas );
303
304
ANEXO N. CLASE PARA EL CALCULO DEL
CODIGO FUENTE.
10
15
20
25
30
305
35
40
45
50
55
60
65
70
}
std_o <<"\n ::::::::: Malla Correcion Presion :::::::::\ n";
Pprima . SetPropiedadesExternas ( true );
Pprima . SetMallaeIniciar ( malla , solucionador ," dt =0 " , "P");
std_o <<"\n ::::::::: Malla Correccion v :::::::::\ n";
Corrv . SetPropiedadesExternas ( true );
Corrv . SetMallaeIniciar ( malla , solucionador , t_aux ," Vcor ");
std_o <<"\n ::::::::: Malla Energia :::::::::\ n";
Temperatura . SetPropiedadesExternas ( true );
if ( solucionadorTemp . contiene (" Igual "))
solucionadorTemp = solucionador ;
Temperatura . SetMallaeIniciar ( malla , solucionadorTemp , tiempo_p ,"
Temp ");
std_o <<"\n ::::::::: FIN LECTURA MALLAS :::::::::\ n";
// Se calcula la conectividad con ayuda de una instancia de
VecinoFVM Se inicia cada uno de los punteros de campo
campo_T . vincular ( new CampoFVM ( malla () ," Temperatura "));
campo_pres . vincular ( new CampoFVM ( malla () ," Presion "));
campo_pres_prima . vincular ( new CampoFVM ( malla () ," CorreccionPresion
"));
campo_corr_vel . vincular ( new CampoFVM ( malla () ," CorrVelV "));
campo_vel . vincular ( new CamposFVM ( malla () ," Velocidad "));
campo_u . vincular ( new CampoFVM ( malla () ," Velocidad_U "));
campo_residuo . vincular ( new CampoFVM ( malla () ," Residuo_Masico "));
campo_GTau . vincular ( new CamposFVM ( malla () ," GradTau "));
campo_GU . vincular ( new CamposFVM ( malla () ," GU "));
campo_GV . vincular ( new CamposFVM ( malla () ," GV "));
campo_GW . vincular ( new CamposFVM ( malla () ," GW "));
campo_GP . vincular ( new CamposFVM ( malla () ," GP "));
campo_Q . vincular ( new CamposFVM ( malla () ," Qcond "));
// Se inicia el objeto de tipo Puntero < GradoLibertadFV > con un
solo grado de libertad por cada volumen de control
gdl . vincular ( new GradoLibertadFV ( malla () ,1));
Is iss (" ARCH = Informacion_grafica . txt ");
GuardarEnsight :: Leer (iss , ndim );
GuardarEnsight :: ponModoGuardar ( BINARY , BINARY );
theta = dep_futuro ; // Dependencia futuro
DimensionarVectoresMatrices () ; // DIMENSIONAMIENTO DE VECTORES
for (i =1; i <= nvol ;i ++)
{
elems (i). refill ( malla -> obtTipoElem (i) , malla -> obtNoDimEspacio
() );
elems (i) -> CalcGeomParameters ( malla -> obtCoorElem (i) );
}
for (i =1; i <= nvol ; i ++) Volumen (i) = elems (i) -> getVolume () ;
// LECTURA DE LOS VALORES INICIALES PARA EL PROBLEMA
306
75
80
85
90
95
100
105
110
115
Condiciones_iniciales () ;
leido = true ; // PARAMETRO DE CONTROL
return 1;
} // Agregado N -S
// Funcion encargada de dimensionar todos los vectores
void NavierStokes :: DimensionarVectoresMatrices ()
{
int i;
CoefU . chaSize ( nvol ); CoefV . chaSize ( nvol ); CoefW . chaSize ( nvol );
VmAstU . chaSize ( nvol ); VmAstV . chaSize ( nvol ); VmAstW . chaSize ( nvol );
VelU . chaSize ( nvol ); VelU_ant . chaSize ( nvol );
VelV . chaSize ( nvol ); VelV_ant . chaSize ( nvol );
if ( ndim ==3) { VelW . chaSize ( nvol ); VelW_ant . chaSize ( nvol ); }
GVel . chaSize ( nvol ); GVel_ant . chaSize ( nvol ); GVel_n . chaSize ( nvol );
Presion_ant . chaSize ( nvol ); Presion . chaSize ( nvol );
Presion_n . chaSize ( nvol ); Presionprima . chaSize ( nvol );
Fuente . chaSize ( nvol ); ResiduoMasico . chaSize ( nvol );
Tau . chaSize ( nvol ); Tau_n . chaSize ( nvol ); Tau_ant . chaSize ( nvol );
Gtau . chaSize ( nvol ); Fcalor . chaSize ( nvol );
GU . chaSize ( nvol ); GU_ant . chaSize ( nvol ); GU_n . chaSize ( nvol );
GV . chaSize ( nvol ); GV_ant . chaSize ( nvol ); GV_n . chaSize ( nvol );
if ( ndim == 3 )
{ GW . chaSize ( nvol ); GW_ant . chaSize ( nvol ); GW . chaSize ( nvol ); }
GP . chaSize ( nvol ); GP_ant . chaSize ( nvol ); GP_n . chaSize ( nvol );
for (i =1; i <= nvol ; i ++) {
GU (i). chaSize ( ndim ); GU_ant (i). chaSize ( ndim );
GU_n (i). chaSize ( ndim ); GV_ant (i). chaSize ( ndim );
GV (i). chaSize ( ndim ); GV_n (i). chaSize ( ndim );
if ( ndim == 3 )
{ GW (i). chaSize ( ndim ); GW_ant (i). chaSize ( ndim );
GW_n (i). chaSize ( ndim ) ;}
GP (i). chaSize ( ndim ); GP_n (i). chaSize ( ndim );
GP_ant (i). chaSize ( ndim ); Tau_ant (i). chaSize ( ndim );
Tau (i). chaSize ( ndim ); Tau_n (i). chaSize ( ndim );
Gtau (i). chaSize ( ndim ); Fcalor (i). chaSize ( ndim );
}
Temp . chaSize ( nvol ); Temp_ant . chaSize ( nvol );
rho . chaSize ( nvol ); k. chaSize ( nvol );
cp . chaSize ( nvol ); mu . chaSize ( nvol );
Volumen . chaSize ( nvol );
elems . chaSize ( nvol );
vcor . chaSize ( nvol );
}
void NavierStokes :: Condiciones_iniciales ()
{
307
120
125
130
135
140
145
150
155
160
308
165
170
175
180
185
190
195
200
205
309
SolucionUnTiempo () ;
Reportarresultados () ;
}
m =0;
do {
tiempo_p -> incrementarTiempo () ;
m ++; // Contador iteraciones exteriores
CalculoUnCiclo () ;
norma = ResiduoMasico . norma () ;
std_o <<" RM norma " << norma <<" ";
if (m >= Nitera )
NIterAlc = true ;
if ( norma < MAssThreshold )
{ convergio = true ; NIterAlc = false ;}
std_o <<" Iteracion exterior No . " <<m <<" \n\n\n";
ActualizarPyTau () ;
if (! ResEstable ) {
SolucionUnTiempo () ;
Reportarresultados () ;
}
// Prevenir que lamentar : Guardado automatico de datos
int ds = m /20; ds = ds *20;
if ( ds == m || m ==10) {
temm = NombreCaso ; NombreCaso = NombreCaso + " temp ";
GuardarDatos ( -0.5 ,2.5) ;
NombreCaso = temm ;
}
} while (! tiempo_p -> finalizo () && ! convergio && ! NIterAlc );
// criterios de parada
// * finalizacion del tiempo de analisis
// * convergencia de la solucion
// * numero de iteraciones alcanzado
if ( ResEstable ) {
// CuartoPasoSIMPLE ( true );
SolucionUnTiempo () ;
Reportarresultados () ;
}
210
215
220
225
230
235
240
}
solucionado = true ;
return convergio ;
245
250
310
255
260
265
270
275
280
285
290
295
{ PrimerPasoSIMPLE () ; SegundoPasoSIMPLE () ;
TercerPasoSIMPLE () ; CuartoPasoSIMPLE () ;
}
if ( MetodoSolveNS == " NOSIMPLE ") {
PrimerPasoNOSIMPLE () ;
std_o <<" VelV Min " << VelV . minValor () <<" Max " << VelV . maxValor () <<
" \n";
SegundoPasoNOSIMPLE () ;
TercerPasoNOSIMPLE () ;
CuartoPasoSIMPLE () ;
}
if ( MetodoSolveNS == " SIMPLEC ")
{ PrimerPasoSIMPLE () ; SegundoPasoSIMPLEC () ;
TercerPasoSIMPLE () ; CuartoPasoSIMPLE () ;
}
CalcularTauyGVs () ;
CalcularPyG () ;
return 1;
}
bool NavierStokes :: CalcularTauyGVs ( )
{
int i;
Vector_basico < Vector_xyz < real >> VelVec ;
VelVec . chaSize ( nvol );
for (i =1; i <= nvol ; i ++) {
VelVec (i). chaSize ( ndim );
VelVec (i) (1) = VelU (i);
VelVec (i) (2) = VelV (i);
if ( ndim == 3 )
VelVec (i) (3) = VelW (i);
}
NablaEsc ( VelU , GU_n , " VelU ");
if ( theta !=1.0) NablaEsc ( VelU_ant , GU_ant , " VelU ");
NablaEsc ( VelV , GV_n , " VelV ");
if ( theta !=1.0) NablaEsc ( VelV_ant , GV_ant , " VelV ");
if ( ndim == 3) NablaEsc ( VelW , GW_n , " VelW ");
if ( theta !=1.0 && ndim == 3) NablaEsc ( VelW_ant , GW_ant , " VelW ");
NablaDotVec ( VelVec , GVel_n , " Vel ");
for (i =1; i <= nvol ; i ++) {
GVel (i) = ( GVel_n (i))* theta + ( GVel_ant (i)) *(1 - theta );
GU (i) = ( GU_n (i)) * theta + ( GU_ant (i)) *(1 - theta );
GV (i) = ( GV_n (i)) * theta + ( GV_ant (i)) *(1 - theta );
if ( ndim == 3)
GW (i) = ( GW_n (i)) * theta + ( GW_ant (i)) *(1 - theta );
}
for (i =1; i <= nvol ; i ++) {
Tau_n (i) (1 ,1) = 1.0*( -2.0* mu (i) / 3.0) * GVel_n (i) +
311
300
305
310
315
320
325
330
335
312
340
345
350
355
360
365
370
375
380
313
385
390
395
400
405
410
415
420
314
425
430
435
440
445
450
455
460
315
465
470
475
480
485
490
495
500
505
316
510
515
520
525
530
535
540
InvVec (2)
vprima (i)
vAst (i) =
VelV (i) =
545
550
if ( ndim ==
InvVec (3)
wprima (i)
wAst (i) =
VelW (i) =
}
3) { // zzzzzzzzzzzz
= 1.0 / CoefW (i);
= - Volumen (i) * InvVec (3) * Gradiente (i) (3) ;
VmAstW (i) + wprima (i);
alpV * wAst (i) + (1.0 - alpV ) * VelW (i);
}
return true ;
317
555
560
565
570
575
580
585
590
595
}
bool NavierStokes :: TercerPasoNOSIMPLE ()
{
int i;
real alpV = Subrelajacion ;
// No se corrige la presion
for (i =1; i <= nvol ; i ++) { // Correccion de Velocidad
VelU (i) = alpV * VmAstU (i) + (1.0 - alpV ) * VelU (i);
VelV (i) = VelV (i) + alpV * vcor (i);
}
return true ;
}
bool NavierStokes :: TercerPasoSIMPLEC ()
{
int i;
real alpP = 1.0; real alpV = 1.0;
Vector_xyz < real > InvVec ( ndim );
Vector_basico < Vector_xyz < real >> Gradiente ( nvol );
Vector < real > uprima ( nvol ) , vprima ( nvol ) , wprima ( nvol );
Vector < real > uAst ( nvol ) , vAst ( nvol ) , wAst ( nvol );
for (i =1;i <= nvol ;i ++) Gradiente (i). chaSize ( ndim );
Presion_n += ( Presionprima * alpP ); // Correccion de Presion
NablaEsc ( Presionprima , Gradiente , "P");
for (i =1; i <= nvol ; i ++) { // Correccion de Velocidad
InvVec (1) = 1.0 / CoefU (i); // xxxxxxxxxxx
uprima (i) = - Volumen (i) * InvVec (1) * Gradiente (i) (1) ;
uAst (i) = VmAstU (i) + uprima (i);
VelU (i) = alpV * uAst (i) + (1.0 - alpV ) * VelU (i);
InvVec (2) = 1.0 / CoefV (i); // yyyyyyyyyy
vprima (i) = - Volumen (i) * InvVec (2) * Gradiente (i) (2) ;
vAst (i) = VmAstV (i) + vprima (i);
VelV (i) = alpV * vAst (i) + (1 - alpV ) * VelV (i);
if ( ndim == 3) { // zzzzzzzzzzzz
InvVec (3) = 1.0 / CoefW (i);
wprima (i) = - Volumen (i) * InvVec (3) * Gradiente (i) (3) ;
wAst (i) = VmAstW (i) + wprima (i);
VelW (i) = alpV * wAst (i) - (1.0 - alpV ) * VelW (i);
}
}
return true ;
}
// Calculo otras ecuaciones ,
bool NavierStokes :: CuartoPasoSIMPLE ( bool forzar )
{
bool correcto ; int i; Vector < real > cero ( nvol ); cero . llenar (0.0) ;
318
600
605
610
615
620
625
630
635
640
645
319
650
655
660
665
670
675
680
685
690
320
695
700
705
710
715
720
725
730
735
321
740
745
750
755
760
765
770
775
322
780
785
790
795
800
805
810
815
820
323
825
830
835
840
845
850
855
860
324
865
870
875
880
885
890
895
900
905
if ( veci ==0) {
if ( Frontera . contiene (" Vel ")) {
for (k =1; k <= nbi ; k ++)
if ( malla -> LadoFront (i ,j ,k , elems (i) () )) break ;
prom (1) = LeerFrontEsp (i ,j , Entrada (i) (1) ,fr1 (k));
prom (2) = LeerFrontEsp (i ,j , Entrada (i) (2) ,fr2 (k));
if ( ndim == 3)
prom (3) = LeerFrontEsp (i ,j , Entrada (i) (3) ,fr3 (k));
}
else { prom = Entrada (i) ;}
}
else {
for ( k =1 ; k <= conx ; k ++ )
if ( malla -> getConx ( veci ,k) == i)
break ;
d1 = elems (i) -> getDelta (j);
d2 = elems ( veci ) -> getDelta (k);
prom = ( Entrada ( veci ) * d1 + Entrada (i) * d2 ) /( d1 + d2 );
}
rx += ( prom (1) * elems (i) -> GetDirSide (j) (1) )* area ;
ry += ( prom (2) * elems (i) -> GetDirSide (j) (2) )* area ;
if ( ndim ==3)
rz += ( prom (3) * elems (i) -> GetDirSide (j) (3) )* area ;
}
Salida (i) = rx + ry ;
if ( ndim ==3) Salida (i) += rz ;
Salida (i) = Salida (i) / Volumen (i);
}
return true ;
}
// Funcion para el c\ alculo del gradiente de la velocidad mAsterico
teniendo en cuenta
// la correccion de presion debida al uso de una malla colocada . No
ser \ ia necesario
// llamar a esta funcion si se usara una malla escalonada .
bool NavierStokes :: NablaDotVecEspecial ( Vector_basico < Vector_xyz
<real >>
& Entrada , Vector < real > & Salida , bool MultRho )
{
int i , j , k , veci , conx ; int nbi = malla -> obtNoIndFront () ;
real area , coefar , deltap , gradp , sum , act , densidadprom , d1 , d2 ;
Vector_xyz < real > prom ( ndim ) , coefvel ( ndim ) , GPprom ( ndim ) , efec (
ndim );
// Condiciones de frontera para uvw
Vector_basico < Cadena > fr1 ,fr2 , fr3 ; LeerFronteras (fr1 , fr2 , fr3 );
Salida . llenar (0.0) ;
if ( nvol == 9) std_o <<"\ nNablaDotEspecial \n";
325
910
915
920
925
930
935
940
945
326
950
955
960
965
970
975
980
985
990
327
995
1000
1005
1010
1015
1020
1025
1030
1035
328
1040
1045
1050
1055
1060
1065
1070
1075
329
1080
1085
1090
1095
1100
1105
1110
1115
1120
330
CalcularTauyGVs () ;
CalcularPyG () ;
CalcQcalor () ;
return true ;
1130
1135
1140
1145
1150
1155
1160
1165
}
// Cuando el tiempo necesario para calcular los datos
// es alto puede ser conveniente continuar las iteraciones
// a partir del ultimo valor obtenido
bool NavierStokes :: SetCargarDatos ( bool opcion )
{ CargarDatos = opcion ; return true ; }
// Asignacion del numero de iteraciones externas maximo para
calcular
// cada ciclo de tiempo
void NavierStokes :: SetNoIterExt ( int set ){ Nitera = set ;}
// Metodo solucion
bool NavierStokes :: SetTipoMetodoSolucion ( Cadena tipo )
{
bool coincide = false ; int i =0; const char * cad = tipo . carts () ;
while ( MSNS [i ]) {
if ( strcmp (cad ,( MSNS [i ]) ) ==0 ) { coincide = true ; break ;}
i ++; }
if ( coincide ) MetodoSolveNS = tipo ;
else {
std_o <<"\ nMetodo no encontrado : se toma valor por defecto \n";
system (" pause ");
// se toma el valor por defecto del constructor
}
return coincide ;
}
// Funcion para la asignacion del esquema de conveccion a usar para
resolver
// las ecuaciones de conveccion difusion
bool NavierStokes :: SetEsquemaConveccion ( Cadena tipo )
{
bool coincide = false ; int i =0;
while ( MACD [i ]) {
if ( tipo . contiene ( MACD [i ]) ) { coincide = true ; break ;}
i ++;}
if ( coincide ) MetodoAprox = tipo ;
else {
std_o <<"\ nEsquema no encontrado : se toma valor por defecto \n";
system (" pause ");
// se toma el valor por defecto del constructor
}
return coincide ;
}
331
1170
1175
1180
1185
1190
1195
1200
1205
332
CAPA LIMITE
La clase desarrollada para la soluci n de las ecuaciones de la capa lmite se pone a prueba
o
con los resultados analticos de la soluci n planteada por Blasius. Sin embargo, debido a
o
la existencia de un m todo explicito, resulta conveniente explicar el m todo y comparar los
e
e
resultados con este m todo de r pida soluci n y mayor n mero de restricciones.
e
a
o
u
El m todo que se explica a continuaci n es descrito por Schetz [25] y fue originalmente
e
o
desarrollado por Wu 1 . El proceso est basado en el m todo de diferencias nitas y es explia
e
cado para un an lisis en estado estable, propiedades constantes y ujo sobre una placa plana.
a
Antes de comenzar a explicar el m todo, se reescriben las ecuaciones de continuidad (Ec
e
O.1), cantidad de movimiento (Ec O.2) y energa (Ec O.3) del ujo en la capa lmite las
u v
+ =0
x y
u
(Ec O.1)
u
u
dp
2 u
+ v = + 2
x
y
dx
y
(Ec O.2)
T
k 2 T
T
+v
=
x
y
C p y2
(Ec O.3)
En la gura 62 se muestra una malla ortogonal de MxN elementos, el ujo entra en direcci n
o
x+ por la frontera oeste (nodos 1, j) con una velocidad Uo y sale por la frontera este (nodos
M, j) con componentes en x e y para la velocidad. El uido limita en la frontera sur con una
supercie plana ja, es decir u = 0 y v = 0 para los nodos i, 1. La frontera norte (nodos i, N)
se encuentra en la zona de ujo no viscoso2 . El m todo explcito plantea las ecuaciones para
e
1 WU,
J. C. On the Finite Difference Solution of Laminar Boundary Layer Problems. En: Heat Transfer and
Fluid Mechanics Institute, 1961.
2 Como se explicar posteriormente, la frontera norte debe estar fuera de la capa lmite para poder calcular
a
la velocidad en todos los puntos; el valor de la velocidad en esta frontera se halla a partir del gradiente de la
presi n el cual es dado como dato de entrada.
o
333
En primer lugar se discretiza cada uno de los t rminos de la ecuaci n de cantidad de movie
o
miento (Ec O.1) obteniendo (Ec O.4). Se utiliza el m todo UDS para discretizar dos t rminos,
e
e
dp
u
u
2 u
e
x y dx , en cambio, se usa el m todo CDS para y y y2 .
u ui+1, j ui, j
=
x
x
d p pi+1 pi
=
dx
x
ui, j
ui+1, j ui, j
ui, j+1 ui, j1
ui, j+1 2 ui, j + ui, j1
pi+1 pi
+ vi, j
=
+
x
2 y
x
(y)2
(Ec O.4)
El unico valor desconocido de (Ec O.4) es ui+1, j y para hallarlo se usa el valor de ui, j , ui, j+1 ,
ui, j1 y vi, j . En (Ec O.5) se despeja el valor de ui+1, j de forma conveniente para introducir la
variable Qi, j .
ui+1, j =
vi, j x
1
x
[pi+1 pi ] +
2u
ui, j
(y) i, j 2 y ui, j
334
ui, j+1 +
vi, j x
x
+
2u
(y) i, j 2 y ui, j
ui, j1
2x
ui, j
(y)2
En la ecuaci n de continuidad (Ec O.6) se discretiza el t rmino u como una diferencia ceno
e
x
v
trada en i + 1/2, j 1/2 y el t rmino x como una diferencia centrada en i + 1, j 1/2.
e
vi+1, j vi+1, j1
1 ui+1, j ui, j ui+1, j1 ui, j1
+
+
=0
2
x
x
y
(Ec O.6)
al valor de Qi, j o como una restricci n al m ximo valor de x. Por otro lado, en (Ec O.8b)
o
a
se dene un valor m ximo para y si la velocidad vi, j es positiva; la velocidad vi, j puede ser
a
positiva si se utiliza un gradiente de presi n adverso que cause la separaci n de la capa lmite,
o
o
Qi, j <
1
2
x <
1 ui, j (y)2
2
(Ec O.8a)
2
si vi, j > 0
(Ec O.8b)
vi, j
La ecuaci n de conservaci n de la energa (Ec O.3) se puede discretizar de modo similar a
o
o
1 vi, j x
1 vi, j x
Ti, j+1 + E +
Ti, j1
2 ui, j y
2 ui, j y
E=
1 k x
ui, j C p (y)2
3 No
(Ec O.10a)
(Ec O.10b)
se pretende explicar la forma de obtener las condiciones de estabilidad pues est fuera del alcance del
a
presente proyecto.
335
IMPLEMENTACION
Se crea la clase climiteexplicito encargada de resolver el problema y exportar los resultados a Matlab. Se da un ejemplo de las gr cas generadas por Matlab en la gura 63 en la
a
cual se compara el valor te rico y el valor hallado del grosor de la capa lmite hidr ulica y
o
a
t rmica sobre una placa plana con propiedades constantes y sin gradiente de presi n para el
e
o
r gimen laminar.
e
Figura 63: Resultados de un m todo explcito para hallar el grosor de la capa lmite t rmica
e
e
e hidr ulica sobre un placa plana
a
Grosor capa hidraulica y termica
0.016
Grosor capa hidraulica
Formula analitica deltah con dp/dx=0
0.014
0.012
delta [m]
0.01
0.008
0.006
0.004
0.002
0
0.1
0.2
0.3
0.4
0.5
Eje x[m]
0.6
0.7
0.8
0.9
entrada del uido vv0,la temperatura de la supercie o placa ttsup y nalmente, la temperatura de entrada del uido ttflu.
Dentro de los resultados se muestra el campo de velocidad ( gura 66) y temperatura en
la gura 67, el grosor de la capa lmite hidr ulica y t rmica en la gura 63, un informe de la
a
e
revisi n de las condiciones de estabilidad para el an lisis en la gura 65 y la direcci n del
o
a
o
ujo del uido en la gura 64.
336
337
110
Temperatura [K]
108
106
104
102
100
0.02
0.015
1
0.8
0.01
0.6
0.4
0.005
Eje y [m]
0.2
0
Eje x[m]
338
ANEXO P. CLASE PARA LA SOLUCION
EXPLICITA DE LAS ECUACIONES DE LA
// Archivo climiteexplicito .h
# pragma once
# include
# include
class climiteexplicito
{
10
15
20
25
30
protected :
Os salida ; // guardar datos , mostrar datos , etc
Boolean vinculado ;
// verificar el estado de salida
int
lx ; // numero elementos en x
int
ly ; // numero elementos en y
int transicion ; // se almacena el valor del indice en el cual se
deja de estar en la zona laminar
real
longitud ; // total de la longitud en el eje x
real
altitud ; // total de la altura en el eje y para el mallado ,
la verdadera altura del liquido es variable
real
tempsup ;
// temperatura de la superficie , por ahora se
asume isotermica
real
tflu ; // temperatura inicial del fluido
real
v0 ; // velocidad incial del fluido
Puntero < MallaCuadricula > malla ;
Puntero < MallaCuadricula > mallax ; // malla unidimensional para los
elementos que solo dependen de x
CampoDifFin
u ;
CampoDifFin
v ;
CampoDifFin
p ;
CampoDifFin
T ;
CampoDifFin
estabilidad ; // verifica si se cumplio la condicion
de estabilidad en cada punto ademas verifica si la capa limite es
inferior a la altura de la simulacion
CampoDifFin
DeltaHidr ; // grosor capa hidraulica
CampoDifFin
DeltaTerm ; // grosor capa termica
// *************** PROPIEDADES DEL FLUIDO ***************//
339
35
40
45
};
340
ANEXO Q. CLASE PARA LA SOLUCION
EXPLICITA DE LAS ECUACIONES DE LA
{
{}
vinculado =0; }
10
15
20
25
30
341
mallax ->
Leer ( // malla UNIDIMENSIONAL
aform ( "d =1 dominio = [0 ,%10 g] indices = [1: %5 d]" , longitud ,
lx )
);
DeltaHidr . chaSize ( mallax () ," Grosor capa hidraulica "); DeltaHidr .
llenar (0.0) ;
DeltaTerm . chaSize ( mallax () ," Grosor capa Termica "); DeltaTerm .
llenar (0.0) ;
p.
chaSize ( mallax () ," Presion
");
p.
llenar (100.0) ;
35
ixy (1) = 1;
for ( int i =1;i <= ly ;i ++)
{
ixy (2) = i;
u. valorIndice ( ixy )= v0 ; // velocidad inicial en la direccion x ,
condicion de entrada del fluido
}
40
45
50
55
60
65
70
void
climiteexplicito :: calcular ( void )
{
int i , j;
real param ; real Rex ; // parametro de estabilidad , reynolds x
real Q ,E;
// /////////////////////////////////////////////////////////
// ///////////// CALCULO DE LA VELOCIDAD DE ENTRADA //////////
// /////////////////////////////////////////////////////////
for ( i =1; i <= ly ; i ++)
{
u. valorIndice (1 ,i)= v0 ;
}
// /////////////////////////////////////////////////////////
// //// CALCULO DE LAS COMPONENTE DE LA VELOCIDAD EXTERNA ////
// /////////////////////////////////////////////////////////
for ( i = 2; i <= lx ; i ++)
{
u. valorIndice (i , ly )= u. valorIndice (i -1 , ly )
(
p. valorIndice (i) -p. valorIndice (i -1)
) /
( rho *u. valorIndice (i -1 , ly ) );
}
// /////////////////////////////////////////////////////////
// ////// CALCULO DE LA TEMPERATURA DE LA PLACA //////////////
// /////////////////////////////////////////////////////////
for ( i =2; i <= lx ; i ++)
342
{
T. valorIndice (i ,1) = tempsup ;
75
80
85
90
95
100
105
110
115
}
// /////////////////////////////////////////////////////////
// ////////// CALCULO DE LAS COMPONENTE DE LA VELOCIDAD //////
// /////////////////////////////////////////////////////////
for (i =1;i <= lx -1; i ++)
{
for (j =2;j <= ly -1; j ++) // iniciar en 2 y terminar en ly -1
{
Q = mu * malla -> Delta (1) / ( rho *u. valorIndice (i , j)* pow ( malla ->
Delta (2) ,2.0) );
u. valorIndice (i +1 , j) =
Q * ( u. valorIndice (i , j +1) + u. valorIndice (i , j -1) )
- (2* Q -1) *u. valorIndice (i , j)
-( p. valorIndice (i +1) -p. valorIndice (i) ) /( rho *u. valorIndice (i ,
j ) )
-(v. valorIndice (i ,j )/u. valorIndice (i ,j )) *( malla -> Delta (1) /
malla -> Delta (2) )*
( (u. valorIndice (i ,j +1) -u. valorIndice (i , j -1) ) /(2.0) )
;
}
for (j =2;j <= ly ;j ++) // iniciar en 2 y terminar en ly , NO HASTA ly -1
{
v. valorIndice (i+1 ,j ) = v. valorIndice (i+1 ,j -1)
- ( malla -> Delta (2) /(2* malla -> Delta (1) ))*
( u. valorIndice ( i+1 , j) - u. valorIndice ( i , j) +
u. valorIndice ( i+1 ,j -1) -u. valorIndice (i ,j -1)
)
;
}
}
// /////////////////////////////////////////////////////////
// ////////// CALCULO DE LA TEMPERATURA //////////////////////
// /////////////////////////////////////////////////////////
for (i =1;i <= lx -1; i ++)
{
for (j =2;j <= ly -1; j ++) // iniciar en 2 y terminar en ly -1
{
E = k * malla -> Delta (1) /
( rho * u. valorIndice (i , j)* c_p * pow ( malla -> Delta (2) ,2.0) );
param = 0.5* ( v. valorIndice (i , j) / u. valorIndice (i , j))*
( malla -> Delta (1) / malla -> Delta (2) );
T. valorIndice (i +1 , j) =
-(2.0*E -1.0) * T. valorIndice (i , j )
343
125
130
135
140
145
150
}
// /////////////////////////////////////////////////////////
// ////// CALCULO DE LA ZONA DE ESTABILIDAD Y OTROS ERRORES //
// /////////////////////////////////////////////////////////
for (i =2;i <= lx ;i ++)
{
Rex = rho *u. valorIndice (i , ly )* malla -> obtPunto (1 ,i)/ mu ;
for (j =2;j <= ly -1; j ++)
{
param =0.5* rho *u. valorIndice (i ,j )* pow ( malla -> Delta (2) ,2.0) / mu ;
if ( malla -> Delta (1) >= param ) // if (\ Delta x > permitido )
{ estabilidad . valorIndice (i ,j ) =1; } // 1-> error de
inestabilidad
if (Rex >500000)
// si esta fuera del regimen de laminar
{ estabilidad . valorIndice (i ,j ) +=2; if ( transicion == lx +10) {
transicion =i ;}; }
param = 2.0* mu / ( rho *v. valorIndice (i ,j));
if (v. valorIndice (i ,j) >0 && malla -> Delta (2) > param ) // if (\
Delta y > permitido )
{ estabilidad . valorIndice (i ,j ) +=4; }
}
if (u. valorIndice (i ,ly -1) < 0.99* u. valorIndice (i ,ly ))
//
if ( grosor_capa_limite > altura_simulacion )
{ estabilidad . valorIndice (i ,ly -1) += 8; estabilidad . valorIndice
(i ,ly ) += 8; } // +8 - > error por grosor de la capa limite
hidraulica
}
// /////////////////////////////////////////////////////////
// ////////////// CALCULO DE LA CAPA LIMITE HIDRAULICA ///////
// /////////////////////////////////////////////////////////
// debido al comportamientode la capa limite similar a sqrt (x) es
mas eficiente buscar el grosor de la
// capa limite desde ly en vez de comenzar desde j =1;
for (i =2;i <= lx ;i ++)
{
j= ly - 1 ;
while (u. valorIndice (i ,j) > 0.99* u. valorIndice (i ,ly )) j - -;
// mientra la velocidad sea mayor a 99%
if (j >1)
{
344
155
}
160
165
170
175
}
// por otro lado , se puede buscar la posicion en la cual se
encuentra la capa limite a partir
// de la posicion de la capa en el punto anterior ( en x) , el
problema es que si la solucion es
// inestable , la forma de hallar la capa limite tambien
// /////////////////////////////////////////////////////////
// ////////////// CALCULO DE LA CAPA LIMITE TERMICA //////////
// /////////////////////////////////////////////////////////
for (i =2;i <= lx ;i ++)
{
j= ly - 1 ;
while ( abs (T. valorIndice (i ,j) - tempsup ) > 0.99* abs (T. valorIndice (
i ,ly ) - tempsup )) j - -;
// mientra la temperatura sea mayor al 99%
if (j >1)
{
DeltaTerm . valorIndice (i) =( ( malla -> Delta (2) ) /( T. valorIndice (i ,j
+1) -T. valorIndice (i ,j)) )
* abs ( 0.99*( T. valorIndice (i ,ly ) - tempsup ) (T. valorIndice (i ,j) - tempsup ) )
+ malla -> obtPunto (2 ,j)
;
}
180
185
190
}
void
climiteexplicito :: expmatlab ( Cadena Nombre )
{
int i ,j; real param ;
Cadena NombreArch ;
NombreArch = Nombre ;
if (! Nombre . contiene (" ARCH =")) NombreArch =" ARCH =" + Nombre ;
Os exportar ( NombreArch );
exportar <<"% Metodo numerico explicito para la simulacion de la
capa limite \n"
<<"% Parametros de entrada \n% Fluido :";
exportar <<" mu =" <<mu <<" ;k=" <<k <<" ; rho =" <<rho <<" ; cp =" <<c_p <<";";
exportar << "\n% Mallado : "
345
195
200
205
210
215
220
225
230
<< aform ( "d =2 dominio = [0 ,%10 g]x [0 ,%10 g] indices = [1: %5 d]x
[1:%5 d]" ,
longitud , altitud , lx , ly ) <<"\n\n";
exportar << " Posicion x ,Px = zeros (1 ," <<lx <<") ;\ n" ;
exportar <<" Px =[ " <<
malla -> obtPunto (1 ,1) ;
for (i =2;i <= lx ;i ++)
exportar << " ," << malla -> obtPunto (1 ,i);
exportar << " ];\ n";
exportar << " P2x = zeros (" <<ly <<" ," <<lx <<") ;\ n" ;
exportar << " for indice =1: " << ly << "\n P2x ( indice ,:) = Px ;
\n
end \n";
exportar << " Posicion y ,Py = zeros (1 ," <<ly <<") ;\ n" ;
exportar <<" Py =[ " <<
malla -> obtPunto (2 ,1) ;
for (j =2;j <= ly ;j ++)
exportar << " ," << malla -> obtPunto (2 ,j);
exportar << " ];\ n";
exportar << " P2y = zeros (" <<ly <<" ," <<lx <<") ;\ n" ;
exportar << " for indice =1: " << lx << "\n P2y (: , indice )= Py ;
end \n";
\n
exportar << "\n " << u. obtNombreCampo () << " ,u= zeros (" <<ly <<" ," <<
lx <<") ;\ n" ;
for (j =1;j <= ly ;j ++)
{
exportar <<"u(" <<j <<" ,:) =[ " <<u. valorIndice (1 ,j);
for (i =2;i <= lx ;i ++) exportar << " ," << u. valorIndice (i ,j);
exportar << " ];\ n";
}
exportar << "\n " << v. obtNombreCampo () << " ,v= zeros (" <<ly <<" ," <<
lx <<") ;\ n" ;
for (j =1;j <= ly ;j ++)
{
exportar <<"v(" <<j <<" ,:) =[ " <<v. valorIndice (1 ,j);
for (i =2;i <= lx ;i ++) exportar << " ," << v. valorIndice (i ,j);
exportar << " ];\ n";
}
exportar << "\n " << T. obtNombreCampo () << " ,T= zeros (" <<ly <<" ," <<
lx <<") ;\ n" ;
for (j =1;j <= ly ;j ++)
{
exportar <<"T(" <<j <<" ,:) =[ " <<T. valorIndice (1 ,j);
for (i =2;i <= lx ;i ++) exportar << " ," << T. valorIndice (i ,j);
exportar << " ];\ n";
}
exportar << "\n " << p. obtNombreCampo () << " , Presion = zeros (1 ," <<
lx <<") ;\ n" ;
346
235
240
245
250
255
260
265
347
<<" plot (Px ,5.0*(1/ " << param <<")* Px .(0.5) , color ,[1 0.1 0.5] ,
LineWidth ,2)\n"
<<" legend (" << DeltaHidr . obtNombreCampo () <<" , Formula analitica \
delta_h con dp / dx =0 , "
<< DeltaTerm . obtNombreCampo () <<" , Formula analitica \ delta_T con
dp / dx =0 ) \n";
exportar <<" for indice =1: " << ceil ( ly /50.0) <<":" <<ly <<"; plot (Px , Py (
indice ) +0* Px , color ,[0.5 0.5 1]) ; end ;\ n";
if ( transicion < lx )
{
exportar <<" for indice =1: " << ceil ( lx /50.0) <<":" << transicion -1 < <";
plot ( Px ( indice ) +0* Py ,Py , color ,[0.5 0.5 1]) ; end ;\ n";
exportar <<" for indice =" << transicion <<":" <<lx <<"; plot ( Px (
indice ) +0* Py ,Py , color ,[1 0 0]) ; end ;\ n";
}
else
{
exportar <<" for indice =1: " <<lx <<"; plot ( Px ( indice ) +0* Py ,Py , color
,[0.5 0.5 1]) ; end ;\ n";
}
exportar << "\ nfigure (4) ; hold off ; surf (Px ,Py ,u) ;\ n"
<<" title ( Componentes de la velocidad ); hold on ; surf (Px ,Py ,v);
shading flat ; \n"
<<" xlabel ( Eje x[m] ); ylabel ( Eje y [m] ); zlabel ( Velocidad [m/s
] )\n"
<<" legend (" <<u. obtNombreCampo () <<" ," <<v. obtNombreCampo () <<" )\
n";
exportar << "\ nfigure (6) ; hold off ; surf (Px ,Py ,T) ; shading flat ;\ n
"
<<" title ( Campo de la Temperatura ); hold on ;\ n"
<<" xlabel ( Eje x[m] ); ylabel ( Eje y [m] ); zlabel ( Temperatura [K
] )\n"
<<" legend (" <<T. obtNombreCampo () <<" )\n";
exportar -> actualizar () ; exportar -> cerrar () ;
270
275
280
285
290
348