Está en la página 1de 30

Unidad 4

MODO
PROGRAMACIÓN

UNIDAD TEMATICA 4: MODO PROGRAMACIÓN


INTRODUCCIÓN

El uso del Modo Consola es muy útil para realizar cálculos de baja complejidad y que no se repetirán
nuevamente. En la realidad este tipo de cálculos constituyen la minoría de los casos, ya que en la gran mayoría
de las veces, seguramente será necesario repetir la secuencia de cálculos o los mismos son de tal grado de
complejidad, que justifican una resolución minuciosa y documentada.

El Modo Programación permite escribir funciones específicas de cálculo y almacenarlas en archivos, de manera
tal de poder utilizarlas todas las veces que sea necesario, sin tener que escribir las expresiones matemáticas que
conforman los cálculos ingenieriles una y otra vez.

La esencia del Modo Programación es la posibilidad de crear funciones adaptadas a las necesidades de cálculo
del ingeniero, y este es el punto en donde se centrará la discusión en este apunte.

FUNCIONES

Aspectos Generales

En un curso de Análisis Matemático se aprende que una función, en su caso más sencillo, es una relación con
ciertas restricciones, que se establece entre dos conjuntos numéricos, y simbólicamente se representa como
𝑦 = 𝑓(𝑥), donde x es la variable independiente e y es la dependiente. También se puede decir que x es un dato
de entrada de la función, mientras que y es el dato de salida que resulta al aplicarle a x la función f.

Desde el punto de vista de programación, una función tiene muchos puntos en común con lo dicho en el párrafo
1
anterior, sin embargo hay diferencias que es necesario resaltar. Una función está compuesta por:

1- Encabezado de la función, que incluye:


a- Nombre de la función.
b- Variables de entrada o argumentos.
c- Variables de salida.

2- Cuerpo de la función, que incluye todas las instrucciones de cálculo y decisiones lógicas.

3- Final de la función.

Así por ejemplo, si se desea hacer una función para calcular el número de Reynolds, el cual responde a la
siguiente expresión matemática:
𝐷𝑣𝜌
𝑅𝑒 =
𝜇

Se observa que se necesitan cuatro argumentos, o variables de entrada (diámetro, velocidad, densidad y
viscosidad), y hay dos variables de salida: una que es el número de Reynolds, representada en la expresión
dada, y otra que es la condición de error, la cual siempre debe ser tenida en cuenta, con el objeto de determinar
la posibilidad de existencia de errores en los cálculos. De esta manera se debe especificar la siguiente
información:
2
Nombre de la función: reynolds
3
Variables de entrada: diam, vel, dens, visc .
Variable de salida: re, er.

1
Cuando se haga uso de la palabra función será desde el punto de vista de programación, caso contrario se hará la correspondiente
aclaración.
2
Los nombres de las funciones responden a las mismas reglas que los de las variables, pero no puede haber una variable y una función que
tengan el mismo nombre.
3
Se recuerda que los caracteres alfabéticos utilizados en nombres de variables y funciones deben corresponder a las 26 letras del alfabeto
inglés, en su versión minúscula o mayúscula.

Ing. Juan E. Núñez Mc Leod Página 1 de 30


Unidad 4
MODO
PROGRAMACIÓN

Definida esta información se puede plantear el siguiente algoritmo:

1- Inicio
2- Leer diam, vel, dens, visc
3- Asignar er=0
4- Asignar re=0
5- Si visc <= 0 entonces er=1. Ir al paso 7
6- Calcular re=diam*vel*dens/visc
7- Escribir re, er
8- Fin

Siendo el diagrama de flujo el indicado en la figura 1.

Fig. 1. Diagrama de flujo para el cálculo del Reynolds.

Con esta información se puede escribir el código de la función de la siguiente manera:

// Función de cálculo del número de Reynolds


// Variables de entrada
// diam: diámetro de la tubería, m
// vel: velocidad del fluido, m/s
// dens: densidad del fluido, kg/m3
// visc: viscosidad del fluido, kg/m s
// Variables de salida
// re: número de reynolds, adimensional
// er: código de error
// 0: no hay errores
// 1: la viscosidad es nula o negativa
function [re, er]=reynolds(diam, vel, dens, visc)
er=0
re=0

if visc<=0 then
er=1
return
end

re=diam*vel*dens/visc

endfunction

Ing. Juan E. Núñez Mc Leod Página 2 de 30


Unidad 4
MODO
PROGRAMACIÓN

La función está compuesta de las siguientes partes:

1- Los comentarios son las líneas que comienzan con //. Los mismos se utilizan para hacer descripciones de
las distintas partes de la función. En este caso se utiliza para documentar las características básicas de la
función reynolds y dichos comentarios están compuestos de la siguiente manera:

a- Una descripción de lo que hace la función.


b- Una descripción de los nombres de las variables de entrada con su respectivo significado y las
unidades utilizadas en cada caso.
c- Una descripción de los nombres de las variables de salida con su respectivo significado y sus
unidades.

Esta información es importante, ya que al documentar cada una de las funciones que se hagan, permite
recordar para qué sirve, qué datos necesita y qué información devuelve. El lector debe imaginar el caso
en que ya hayan desarrollado muchas funciones, por lo que se vuelve muy difícil recordar las
3 3 4
características específicas de cada una, por ejemplo: ¿la densidad se expresaba en g/cm o kg/m ?

Scilab hace caso omiso de todo lo escrito como comentario, por lo que se puede escribir haciendo uso de
cualquier carácter; de esta manera, se pueden usar eñes y acentos.

2- El encabezado de toda función tiene la siguiente estructura:

function [variables de salida]=nombre de la función(variables de entrada)

Si hay más de una variable de salida o de entrada, la lista de las mismas va separada por comas. El
nombre de la función cumple con las mismas reglas que los nombres de las variables, no pudiendo tener
el mismo nombre una variable y una función.

Es importante observar que la lista de variables de salida van encerradas entre corchetes, mientras que
las variables de entrada están encerradas entre paréntesis.

3- El cuerpo de la función: es la parte principal, corresponde a la parte operativa, donde se encuentran


todas las instrucciones de cálculo. El cuerpo puede ser muy sencillo, como en el caso del ejemplo, que
contiene un condicional y un par de líneas con un cálculo y una asignación, o sumamente compleja con
decenas de cálculos.

4- El final de la función indicada con la palabra endfunction.

Modo Programación

Como se vio anteriormente, Scilab puede funcionar en el Modo Consola, en el cual se realizan los cálculos en
forma inmediata, como si se tratara de una calculadora. Otra forma de operación corresponde al Modo
Programación, en la cual se escriben las instrucciones en un archivo, para ser ejecutadas con posterioridad,
todas las veces que sea necesaria. Básicamente el archivo al que se hace alusión está constituido por funciones
que realizan los cálculos necesarios para resolver el problema que se desee. El conjunto de todo lo escrito en
este archivo recibe el nombre de código fuente.

Para poder escribir este archivo se hace uso de un editor específico, el cual es invocado escribiendo la siguiente
instrucción en la consola:

-->scinotes

Tras lo cual se abre una nueva ventana con un editor a pantalla completa, la que se puede apreciar en la figura 2.

4
El manejo de las unidades de medida es absoluta responsabilidad de quien utiliza la función. La función recibe valores numéricos en la
entrada, realiza cálculos con dichos valores y devuelve un resultado numérico, es el ingeniero el responsable de verificar que dicho resultado
sea consistente con la realidad.

Ing. Juan E. Núñez Mc Leod Página 3 de 30


Unidad 4
MODO
PROGRAMACIÓN

Fig. 2. Ventana del editor de programas.

La primera vez que se ejecute se seleccionará el menú Opciones y allí se verá el menú Auto-completion on, el
cual tiene dos opciones: (, [, … y if, function, … las cuales se encuentran marcadas con una tilde. Se deben
seleccionar las dos para eliminar las tildes. Esta operación evita que el editor de Scilab realice tareas para
autocompletar las líneas de código que se escriban, ya que esta facilidad complica la comprensión de lo que se
está escribiendo. Esta operación se realiza una sola vez, tras lo cual se puede comenzar a escribir el código de
las distintas funciones que se necesite.

Para grabar el archivo se recurre a la opción Guardar del menú Archivo, en donde se tendrá que asignar un
nombre la primera vez que se haga la grabación, se supondrá que el archivo se grabará con el nombre
funciones.sci. La extensión del archivo será en general sci pero también puede ser sce, si bien existe una
diferencia entre los dos tipos de archivo, a los efectos prácticos se considerarán iguales.

Para poder utilizar las funciones así definidas, deben ser incorporadas a la base de datos de las funciones
utilizadas por Scilab, para lo cual se debe hacer clic en el ícono Ejecutar de la barra de herramientas, el cual está
encerrado en un círculo rojo en la figura 3.

Fig. 3. Botón de ejecución para incorporar las funciones del usuario a las nativas de Scilab.

Al realizar esta operación Scilab envía un eco a la pantalla similar al siguiente:

-->exec('C:\Users\PC01\Fundamentos\Material\2015\Apuntes Unidad 04\funciones.sci', -1)

Si se encuentra algún error sintáctico en el archivo, aparecerá un mensaje indicando la situación.

Para utilizar la función reynolds lo haremos como si se tratara de cualquier función de Scilab, así se puede
escribir la siguiente instrucción:

Ing. Juan E. Núñez Mc Leod Página 4 de 30


Unidad 4
MODO
PROGRAMACIÓN

-->[re,er]=reynolds(0.01,2,1000,0.001)
er =

0.
re =

20000.

Es importante acotar que Scilab no es capaz de manejar unidades, ni tampoco es capaz de saber si el orden en
que se han escrito los valores de los datos coinciden con las respectivas variables de entrada, por lo que el
usuario es el responsable de colocar los datos en las unidades adecuadas y en el orden correcto, de acuerdo a
como fue escrita la función. Por este motivo es muy importante colocar los comentarios necesarios delante de
cada función que se haga.

ATRIBUTOS DE UNA FUNCIÓN

Toda función debe ser diseñada con el objeto no solo de resolver una problemática, sino también lo debe hacer
5
de forma eficiente, flexible, robusta y confiable .

Eficiencia

Significa que el código que se está escribiendo debe ser pensado para simplificar los cálculos a
su mínima expresión, de esta forma el microprocesador de la computadora no es utilizado
innecesariamente en operaciones extras que no aportan nada al resultado final: por ejemplo,
para calcular una raíz cuadrada se pueden escribir las dos instrucciones siguientes:

y = sqrt(x) o y = x^(1/2)

cualquiera de las dos instrucciones devolverá la raíz cuadrada de x; sin embargo, la primera es
más eficiente, ya que utiliza una función específica, mientras que la segunda obliga al
microprocesador a realizar dos operaciones: la primera resolver el exponente y después resolver
la potencia.

Otro ejemplo puede ser el cálculo de una función trigonométrica. Suponemos que se desea
calcular el coseno de un ángulo expresado en grados sexagesimales, entonces se puede realizar
la operación de las siguientes maneras:

y =cos(x*%pi/180) o y = cosd(x)

En el primer caso, dentro del argumento de la función, se realiza la conversión del argumento en
grados sexagesimales a radianes (ya que la función cos requiere que el argumento esté
expresado en radianes); mientras que en el segundo caso se hace uso de la función que
requiere el argumento directamente en grados sexagesimales. Naturalmente la segunda forma
es más eficiente que la primera.

Flexibilidad

Esta característica nos permite evaluar la capacidad que tiene una función de adaptarse a
distintas condiciones de cálculo. Así por ejemplo, supongamos una función para hacer cálculos
que involucren la presión atmosférica y la aceleración de la gravedad; por lo general, por una
cuestión de simplicidad, estos datos se considerarán constantes, de esta manera la presión será
2
igual a una atmósfera y la aceleración de la gravedad será igual a 9.81 m/s . Sin embargo, es
más flexible una función que permitiera trabajar con otras presiones y otras aceleraciones, esto
teniendo en cuenta que difícilmente el sistema al que se desee aplicar el cálculo se encuentre a
45º de latitud y a nivel del mar.

5
Estos cuatro conceptos están basado en la experiencia del autor en trabajos realizados sobre confiabilidad de software.

Ing. Juan E. Núñez Mc Leod Página 5 de 30


Unidad 4
MODO
PROGRAMACIÓN

Robustez

En su enorme mayoría las funciones reciben información a través de sus argumentos. Esta
información es procesada, mediante cálculos matemáticos de la más variada complejidad, y los
resultados obtenidos son devueltos a través de las variables de salida de dicha función.

La robustez de una función está dada por la capacidad de reaccionar correctamente frente a
valores inadecuados de los argumentos o situaciones no previstas, como puede ser una división
por cero. Por ejemplo, si se desea calcular una velocidad conociendo el valor de la distancia y
del tiempo, se podría escribir el código de la siguiente función:

// Función para calcular la velocidad de un móvil


// Variables de entrada
// d: distancia recorrida por el móvil, m
// t: tiempo en recorrar la distancia d, s
// Variables de salida
// vel: velocidad media del móvil, m/s
function [vel]=velocidad(d, t)
vel=d/t
endfunction

Esta función devuelve el valor 45 si d vale 90 y t vale 2, por otro lado devuelve 10 si d vale 200 y
t vale 20. En el caso en que t valga cero, la función devuelve el siguiente error:

vel=velocidad(10,0)
!--error 27
División por cero...

at line 2 of function velocidad called by :


vel=velocidad(10,0)

Claramente la función velocidad no está preparada para interpretar adecuadamente esta


división por cero, por lo cual se aborta su ejecución, dejando al usuario la responsabilidad de
revisar datos, procedimientos, etc. para intentar nuevamente el cálculo.

Este es el caso de una función poco robusta. Una función robusta no debe producir el aborto de
la ejecución, por lo que siempre debe terminar devolviendo un resultado. En pocas palabras se
puede decir que una función robusta es aquella que devuelve resultados sin importar el valor de
sus argumentos; es decir, la función no se bloquea ni emite errores de mal funcionamiento.

Confiabilidad

Las funciones deben devolver resultados correctos si los argumentos de entrada son correctos, y
deberían indicar la situación eventual en la que los parámetros de entrada son incorrectos y no
realizar ningún cálculo. Para ejemplificar esta situación se puede recurrir al ejemplo de función
visto al principio de este apunte, en el cálculo del número de Reynolds, por lo menos se debe
verificar que las variables de entrada (diámetro, velocidad, densidad y viscosidad) sean valores
positivos, para evitar que la función devuelva un valor de Reynolds negativo o nulo, algo que
desde el punto de vista físico carece de sentido.

Los conceptos de robustez y confiabilidad, si bien pueden parecer similares, apuntan a dos aspectos distintos.
Haciendo una analogía un poco burda, se puede decir que robustez y confiabilidad son conceptos similares a
precisión y exactitud en metrología. La robustez nos indica que el código va a devolver resultados, sin bloquearse
ni detenerse, siempre hace su trabajo y entrega un resultado; por otro lado, la confiabilidad asegura que ese
6
resultado es correcto .

6
Un resultado correcto se debe entender como un valor numérico cuando los datos son adecuados, o como un mensaje de aviso cuando se
detectan problemas con los datos.

Ing. Juan E. Núñez Mc Leod Página 6 de 30


Unidad 4
MODO
PROGRAMACIÓN

ESTRUCTURAS DE CONTROL

Las estructuras de control son un conjunto de instrucciones que permiten modificar el funcionamiento de un
código, de acuerdo a determinados parámetros. Estas estructuras dan una enorme versatilidad a la hora de
programar funciones, y su estudio y dominio es fundamental para poder desarrollar códigos de gran potencia de
cálculo y que además, tengan los atributos ya vistos.

Al escribir una función por primera vez, nunca es todo lo eficiente, flexible, robusta o confiable que podría ser, por
lo que siempre va a haber un proceso de maduración, donde la función se va enriqueciendo a través de la
experiencia adquirida por su uso.

A continuación se verá un proceso simple de maduración de un código. Se recuerda que este proceso se da a
través de la experiencia en el uso del código, detectando falencias, errores o simplemente identificando posibles
mejoras que se puedan realizar para aumentar la velocidad de cálculo, la precisión, etc.

Si se definiera una función reynolds según el código dado a continuación:

function [re]=reynolds(diam, vel, dens, visc)

re=diam*vel*dens/visc

endfunction

Al ser llamada la función mediante la siguiente instrucción:

re=reynolds(0.01,2,1000,0.001);

En este caso se utilizó un diámetro de tubería de 0.01 metros, una velocidad de fluido de 2 m/s, una densidad de
3
fluido de 1000 kg/m y una viscosidad de 0.001 kg/m s. Para ver el resultado se escribe el nombre de la variable
7
de salida , en este caso re y el resultado que muestra Scilab es 20000.

Seguidamente se hace el siguiente cálculo con su correspondiente resultado:

--> re=reynolds(0.01,2,1000,0)
re =

Inf

Se observa como Scilab devuelve un resultado no adecuado ingenierilmente, debido a que la viscosidad tiene un
valor nulo. Sin importar las causas por las que el valor de la viscosidad es cero, se demuestra que el código de la
función es poco confiable ya que no devuelve una respuesta adecuada.

Primer estructura de control: Instrucción condicional

Para resolver este problema se va a utilizar la capacidad de un lenguaje de programación para tomar decisiones.
En el caso de Scilab se usará la instrucción if – then – else, que recibe el nombre de condicional.

La sentencia if evalúa una expresión lógica (condición), cuyo resultado puede ser verdadero o falso
exclusivamente, y ejecuta un grupo de instrucciones solo si el resultado fue verdadero, caso contrario puede
ejecutar otro conjunto de instrucciones o simplemente no hacer nada.

Para construir una expresión lógica se utilizan los denominados operadores lógicos, los cuales tienen la
característica de comparar los valores almacenados en variables, dando como resultado verdadero o falso, de
acuerdo al resultado de comparación que se utilice. En ningún caso los valores de las variables son modificados.
Los distintos comparadores lógicos se observan en la tabla que se da a continuación:

7
Nótese que la instrucción de cálculo termina con punto y coma, por lo que no hay un eco en la pantalla.

Ing. Juan E. Núñez Mc Leod Página 7 de 30


Unidad 4
MODO
PROGRAMACIÓN

Símbolo Significado Ejemplo


== Igual a radio == 1.5
8
<> Distinto de tiempo <> 10
< Menor a pos < posFinal
<= Menor a igual a potencia <= potMax
> Mayor a altura > 0
>= Mayor o igual a altura >= altMin
9
& Y x > 0 & x < 10
10
| O x <0 | x > 10

Teniendo en cuenta lo dicho, la nueva lógica de la función del cálculo del número de Reynolds, sería la siguiente:

Si el valor de la viscosidad es menor o igual a cero entonces retornar sin calcular el número de
Reynolds.

Esto se implementa de la siguiente manera en la función:

function [re]=reynolds(diam,vel,dens,visc)
re=0
if visc<=0 then
return
end

re=diam*vel*dens/visc

endfunction

De acuerdo a la nueva lógica, el número de Reynolds a veces será calculado y otras veces no, de acuerdo al
valor de la viscosidad. Sin embargo, las funciones siempre deben devolver valores en sus variables de salida.
Esta es la razón por la cual se debe agregar la instrucción re=0, ya que al ser re una variable de salida sí o sí
hay que asignar un valor, de lo contrario se obtendrá un error como el que se ve a continuación:

re=reynolds(0.01,2,1000,0.0)
!--error 4
Variable indefinida: re

at line 3 of function reynolds called by :


re=reynolds(0.01,2,1000,0.0)

Se observa que la expresión lógica justamente está preguntando si (if) el valor almacenado en la variable visc,
es nula o negativa, y si esto es cierto entonces (then) se sale de la función mediante la instrucción return, sin
hacer nada, y a continuación finaliza la instrucción condicional (end).

Si el valor de la viscosidad es positivo, la condición de la estructura de control es falsa, por lo que el condicional
no se ejecuta y directamente es salteado hasta la siguiente instrucción, que es el cálculo del número de
Reynolds.

Finalmente la función termina, devolviendo el valor calculado del número de Reynolds.

8
Como símbolo de desigualdad también se puede utilizar ~=, pero el símbolo tilde “~” sólo está disponible en teclado inglés o en los
españoles con distribución latinoamericana, pero este último no es muy común en la actualidad.
9
Esta expresión lógica permite saber cuándo una variable se encuentra comprendida en un determinado intervalo. En este caso el resultado
es verdadero sólo cuando el valor de x está entre 0 y 10, sin tomar ninguno de estos valores.
10
Esta expresión lógica se utiliza cuando se desea comprobar si una variable está fuera de un determinado intervalo. En este caso el
resultado es verdadero si la variable x contiene un valor menor a 0 o mayor a 10.

Ing. Juan E. Núñez Mc Leod Página 8 de 30


Unidad 4
MODO
PROGRAMACIÓN

Manejo de errores

Con esta modificación se ha mejorado la robustez de la función, porque no se detiene o aborta por problemas
con el valor de la viscosidad; pero no su confiabilidad, ya que en caso que la viscosidad sea nula o negativa no
devuelve un resultado válido, de todas maneras no se puede hacer ningún cálculo en estas circunstancias. Para
solucionar este problema, es decir, que la función devuelva información que permita saber si el resultado es
válido o no, se va a utilizar el concepto de manejo de errores visto con anterioridad, como se puede observar en
el siguiente código de la función:

function [re, er]=reynolds(diam,vel,dens,visc)


er=0
re=0
if visc<=0 then
er=401
return
end

re=diam*vel*dens/visc

endfunction

El análisis de esta función permite identificar una nueva variable de salida, er, cuya finalidad es la de devolver un
código de error, para este caso se supone el valor 0 si el cálculo se realizó con éxito y 401 si no se pudo realizar
porque la viscosidad es nula. Es importante aclarar que como convenio se utilizará para los códigos de error el
formato x01, x02, etc. donde x será la unidad temática en la que se esté trabajando. Esto se debe a que cuando
se estudie métodos numéricos se mezclarán funciones de diversas unidades, y de esta manera no se producirán
conflictos debido a códigos de error repetidos.

Se asigna el valor 0 a la variable er al principio de la función. De esta manera sólo es necesario asignar los
valores correspondientes a las condiciones de error, a medida que se vayan sucediendo.

De esta forma, cuando se utilice la función, se debe revisar el valor de la variable er, si el valor es cero entonces
la variable re contiene un resultado válido, si por el contrario er contiene el valor 1, significa que la viscosidad,
por alguna razón que habrá que averiguar, vale cero y el valor de la variable re no es válido. De esta manera se
consigue una función más robusta y confiable que la primera que se hizo.

Análisis de resultados

Una característica interesante, al hacer el desarrollo de una función, es implementar la capacidad de analizar los
resultados obtenidos, con el objeto de facilitar la interpretación de los mismos. En el caso del cálculo del número
de Reynolds se sabe que el valor define el tipo de flujo, el cual se clasifica de acuerdo a lo detallado en la
siguiente tabla:

Reynolds Tipo de flujo


Re < 2100 Laminar
2100 <= Re < 10000 Transición
Re >= 10000 Turbulento

La nueva función de cálculo podría ser como se muestra a continuación:

function [re, flujo, er]=reynolds(diam, vel, dens, visc)


er=0
re=0
flujo= ""
if visc<=0 then
er=401

Ing. Juan E. Núñez Mc Leod Página 9 de 30


Unidad 4
MODO
PROGRAMACIÓN

return
end

re=diam*vel*dens/visc

if re<2100 then
flujo="laminar"
else
if re<10000 then
flujo="transición"
else
flujo="turbulento"
end
end
endfunction

Como se observa se han agregado un par de condicionales al final de la función. Estas instrucciones se pueden
interpretar de la siguiente manera: si el número de Reynolds es menor que 2100 entonces (if re<2100 then)
el flujo es laminar (flujo="laminar"), de lo contrario (else) si el número de Reynolds es menor que 10000
entonces (if re<10000 then) el flujo es de transición (flujo="transición"), de lo contrario (else) el flujo
es turbulento (flujo="turbulento"). Para terminar se encuentran las dos instrucciones de finalización de
cada uno de los condicionales (end).

A continuación se muestran los resultados obtenidos para distintos conjuntos de datos:

1- [re,flujo,er]=reynolds(0.01,2,1000,0.001)
er =
0.

flujo =
turbulento

re =
20000.

2- [re,flujo,er]=reynolds(0.01,0.9,1000,0.001)
er =
0.

flujo =
transición

re =
9000.

3- [re,flujo,er]=reynolds(0.01,0.02,1000,0.001)
er =
0.

flujo =
laminar

re =
200.

Con este ejemplo también se muestra la forma de asignar cadenas de caracteres (texto) a una variable. En este
caso se han utilizado comillas para encerrar el texto, pero también es posible utilizar apóstrofes.

Ing. Juan E. Núñez Mc Leod Página 10 de 30


Unidad 4
MODO
PROGRAMACIÓN

AUTODOCUMENTACIÓN

Como se ha observado en los sucesivos agregados que se han hecho a la función de cálculo del número de
Reynolds, la complejidad de la misma ha ido aumentando, haciendo cada vez más difícil una rápida
interpretación del funcionamiento de la función. Incluso para el mismo programador, que diseñó, escribió y
corrigió la función. Después de algún tiempo, se va a ir olvidando de los detalles de la misma, por lo que si debe
hacer modificaciones va a tener que estudiarla previamente para recordar todos los pormenores.

Para evitar esta pérdida de tiempo, es que se deben autodocumentar las funciones, mediante el uso de
comentarios con textos concisos pero clarificadores. A modo de ejemplo se reproduce la última versión de la
función vista, en su versión autodocumentada.

// Función de cálculo del número de Reynolds


// Variables de entrada
// diam: diámetro de la tubería, m
// vel: velocidad del fluido, m/s
// dens: densidad del fluido, kg/m3
// visc: viscosidad del fluido, kg/m s
// Variables de salida
// re: número de reynolds, adimensional
// flujo: tipo de flujo, texto
// er: código de error
// 0: no hay errores
// 1: la viscosidad es nula
function [re, flujo, er]=reynolds(diam, vel, dens, visc)
// Se inicializa la variable er en su condición de no error
er=0
// Se asigna a la variable re un valor para el caso en que no se pueda calcular
re=0
// Se verifica la validez de la viscosidad,
// debe ser no nula para continuar con el cálculo
if visc==0 then
// Se establece la condición de error para viscosidad nula
er=1
return
end
// Se calcula el número de Reynolds
re=diam*vel*dens/visc

// De acuerdo al resultado del Reynolds, se determina el tipo de flujo presente


if re<2100 then
flujo="laminar"
else
if re<10000 then
flujo="transición"
else
flujo="turbulento"
end
end

endfunction

OTRAS ESTRUCTURAS DE CONTROL

Como se describió anteriormente, la instrucción condicional corresponde a una estructura de control, lo que
significa que permite controlar la forma en que el código se ejecuta, otorgando flexibilidad al mismo ya que
permite realizar tareas que de otra manera serían difíciles de ejecutar. A continuación se verán el resto de las
estructuras de control.

Ing. Juan E. Núñez Mc Leod Página 11 de 30


Unidad 4
MODO
PROGRAMACIÓN

Segunda estructura de control: Instrucción select

Consiste en una instrucción de selección múltiple, permitiendo escribir un código claro y limpio. Así por ejemplo,
anteriormente se habló de la necesidad de manejar los errores, para lograr códigos más robustos, de manera tal
que a cada error se le asignaba un número; sin embargo, cuando se tienen muchos códigos de error es difícil
recordarlos y se vuelve conveniente convertirlos a una expresión literal que explique el error de manera clara y
precisa. En la siguiente tabla se reproduce un ejemplo hipotético de errores.

Código
Descripción
de error
0 No se han producido errores.
401 División por cero en el cálculo del Reynolds, la viscosidad es nula.
402 La velocidad del fluido excede el máximo admitido.
403 La temperatura supera la temperatura crítica del fluido.
404 La presión de vapor excede la presión exterior. El sistema no está en equilibrio.
405 El sistema de ecuaciones es indeterminado, hay dependencia lineal entre ecuaciones.

Una forma sencilla y clara para traducir los códigos de error a su correspondiente significado literal, es mediante
la instrucción select como se observa en el siguiente ejemplo de código:

// Función ejemplo del uso de la instrucción Select


// Variable de entrada
// er: código de error
// Variable de salida
// txtEr: descripción del error
function [txtEr]=describeError(er)
select er
case 0
txtEr="No se han producido errores"
case 401
txtEr="División por cero en el cálculo del Reynolds, la viscosidad es nula"
case 402
txtEr="La velocidad del fluido excede el máximo admitido"
case 403
txtEr="La temperatura supera la temperatura crítica del fluido"
case 404
txtEr="La presión de vapor excede la presión exterior. El sistema no está en
equilibrio"
case 405
txtEr="El sistema de ecuaciones es indeterminado, hay dependencia lineal
entre ecuaciones"
else
txtEr="Error desconocido"
end

endfunction

Para utilizar esta función se debe introducir como argumento el código de error que corresponda, según se
observa en el siguiente ejemplo:

error=describeError(3);

error =
La temperatura supera la temperatura crítica del fluido

Ing. Juan E. Núñez Mc Leod Página 12 de 30


Unidad 4
MODO
PROGRAMACIÓN

Tercera estructura de control: La instrucción for

Esta instrucción permite realizar lo que en programación se denomina lazo; es decir, una porción de código que
para el caso de la instrucción for se repite una cantidad determinada de veces.

Para ejemplificar el uso de esta instrucción se supondrá la siguiente situación problemática: Supóngase el tanque
que se muestra en la figura, el cual contiene un sistema multicomponente bifásico, representando con V la fase
vapor y con L la fase líquida.

Con el objeto de no complicar en exceso el ejemplo, se supondrá que


ambas fases se encuentran en equilibrio fisicoquímico; por lo tanto, las
presiones y temperaturas son iguales en la interfase, mientras que las
composiciones en ambas fases, si bien son distintas, se encuentran en
equilibrio. Por lo dicho, se puede asegurar que no hay transferencia neta
de materia ni energía entre fases.

La estructura de datos que se eligió, para almacenar la información


referida a la composición, consiste en un único vector fila (llamado
compos), cuyos elementos contienen los moles de cada una de las
especies químicas intervinientes, tanto en fase vapor como líquida.
Asociado a este vector compos se encuentra otro vector fila (llamado
fase), con el mismo tamaño, cuyos elementos representan con un 1 la
fase vapor y con un 0 la fase líquida. Así por ejemplo, si el primer
elemento del vector compos contiene el valor 4.5 y el primer elemento
del vector fase contiene 1, significa que en la fase vapor hay 4.5 moles
de un determinado compuesto.

Se desea diseñar una función que permita calcular la fracción molar de todos los compuestos de la fase vapor,
para lo cual se debe realizar el siguiente cálculo:

𝑛𝑖
𝑦𝑖 =
𝑛𝑖

Se observa que se debe dividir la cantidad de moles en la fase vapor, de cada especie química, por el total de
moles en dicha fase. Debido a que la información de cada fase se encuentra mezclada en un único vector, es
conveniente separar en un nuevo vector toda la información relativa a la fase vapor exclusivamente. Para lograr
esto, se debe hacer una lectura, elemento por elemento del vector compos, analizando a qué fase pertenece, y
en caso de corresponder, se hace la copia de la información en otro vector, que se llamará yi. Este último vector
contendrá una cantidad indefinida de elementos, ya que no necesariamente la fase vapor y líquida contienen
todas las especies químicas involucradas, téngase en cuenta que bien podría haber un compuesto no volátil en la
fase líquida, como podría ser un compuesto iónico, o una sustancia incondensable en la fase gaseosa, por
ejemplo nitrógeno.

Para determinar el tamaño del vector yi se utiliza un criterio de máximo; es decir, no puede ser más grande que
el tamaño del vector compos. Sin embargo sigue existiendo el problema de indicar cuántos datos válidos
contiene el vector yi. Esto se solucionará mediante el uso de lo que en programación se denomina flag o
bandera, que consiste básicamente en colocar después del último dato un valor no válido; así por ejemplo, a
continuación del último valor, se colocará un -1, que constituye un valor imposible para un número de moles. Por
este motivo, el vector yi será dimensionado con un elemento más que compos, previendo la posibilidad que en
algún caso particular, todo el contenido del tanque sea vapor.

A continuación se transcribe una función que cumple con los lineamientos discutidos, además de incluir al
principio la gestión de errores. En este ejemplo se ha hecho uso de la función size, la cual devuelve el tamaño
de la matriz que se le ha pasado como primer argumento, mientras que el segundo argumento indica qué es lo
que se desea conocer, si la cantidad de columnas (c) o de filas (r), este último argumento puede ir entre comillas
o apóstrofes.

Ing. Juan E. Núñez Mc Leod Página 13 de 30


Unidad 4
MODO
PROGRAMACIÓN

// Función ejemplo del uso de la instrucción for


// Cálculo de la fracción molar de una mezcla de vapores
// en contacto con su líquido.
// Variable de entrada
// compos: vector fila con los moles de un sistema multicomponente
// fase: vector fila indicando la fase correspondiente
// de cada dato contenido en el vector ni
// 0: Fase líquida.
// 1: Fase vapor.
// Variables de salida
// yi: vector fila con la concentración de la fase vapor
// expresada como fracciones molares
// er: código de error
// 0: no hubieron errores
// 401: el vector compos tiene más de una fila
// 402: el vector fase tiene más de una fila
// 403: los vectores compos y fase tiene distinta cantidad de datos
function [yi, er]=FraccionMolar(compos, fase)
yi=0
er=0
if size(compos,'r')<>1 then
er=401
return
end
if size(fase,'r')<>1 then
er=402
return
end
nDatos=size(compos,'c')
if nDatos<>size(fase,'c') then
er=403
return
end
yi=zeros(1,nDatos+1)
k=1
for i=1:nDatos
if fase(i)==1 then
yi(k)=compos(i)
k=k+1
end
end
yi=yi./sum(yi)
yi(k)=-1
endfunction

A continuación se reproduce el código de la función nuevamente, pero con comentarios que explican el
funcionamiento de cada una de las partes de la misma:

// Función ejemplo del uso de la instrucción for


// Cálculo de la fracción molar de una mezcla de vapores
// en contacto con su líquido.
// Variable de entrada
// compos: vector fila con los moles de un sistema multicomponente
// fase: vector fila indicando la fase correspondiente
// de cada dato contenido en el vector ni
// 0: Fase líquida.
// 1: Fase vapor.
// Variables de salida
// yi: vector fila con la concentración de la fase vapor

Ing. Juan E. Núñez Mc Leod Página 14 de 30


Unidad 4
MODO
PROGRAMACIÓN

// expresada como fracciones molares


// er: código de error
// 0: no hubieron errores
// 401: el vector compos tiene más de una fila
// 402: el vector fase tiene más de una fila
// 403: los vectores compos y fase tiene distinta cantidad de datos
function [yi, er]=FraccionMolar(compos, fase)
yi=0
er=0
// se verifica la cantidad de filas ('rows') del vector compos
if size(compos,'r')<>1 then
er=401
return
end
// se verifica la cantidad de filas ('rows') del vector fase
if size(fase,'r')<>1 then
er=402
return
end
// se determina la cantidad de datos en compos ('columns')
nDatos=size(compos,'c')
// se verifica que fase tenga la misma cantidad de datos
if nDatos<>size(fase,'c') then
er=403
return
end
// se asigna a yi un vector fila con un dato más que ni para
// almacenar el flag de fin de datos
yi=zeros(1,nDatos+1)
// se inicializa el índice k en 1, para transferir al vector yi
// sólo los datos que correspondan a la fase vapor
k=1
// se inicia un lazo para recorrer todo el vector compos
for i=1:nDatos
// se analiza si el dato apuntado por i corresponde a
// la fase vapor o líquida
if fase(i)==1 then
// si es fase vapor se transfiere el dato de compos a yi
yi(k)=compos(i)
// se incrementa el índice de yi en una unidad
k=k+1
end
end
// se calculan las fracciones molares
yi=yi./sum(yi)
// se coloca con último dato en yi el flag (-1)
yi(k)=-1
endfunction

Para utilizar esta función se ingresarán en Scilab los siguientes vectores de datos:

-->compos=[2.2 1.01 0.54 3.42 1.98 0.12 1.39];

-->fase=[1 0 0 1 0 1 1];

La función es llamada y devuelve los resultados, tal como se aprecia a continuación:

-->[yi,er]=FraccionMolar(compos,fase)

Ing. Juan E. Núñez Mc Leod Página 15 de 30


Unidad 4
MODO
PROGRAMACIÓN

er =
0.

yi =
0.3085554 0.4796634 0.0168303 0.1949509 -1. 0. 0. 0.

Como se observa, el vector yi contiene cuatro valores antes de encontrarse el -1, indicador de finalización.
Analizando el vector fase, se aprecia que justamente hay cuatro datos correspondientes a la fase vapor. Para
hacer una última verificación, se sumarán esos cuatro valores del vector yi:

-->sum(yi(1:4))
ans =

1.

Verificando de esta manera, que los datos contenidos en yi son las fracciones molares de todas las especies
químicas en la fase vapor. Es importante destacar que si se hubiera utilizado la instrucción sum(yi) se sumarían
todos los elementos del vector, incluyendo el -1, dando como resultado cero si todo está en orden.

La instrucción for incluye el nombre de una variable, que recibe el nombre de índice, y en el caso del ejemplo
precedente es i, seguida de una expresión similar a la utilizada para declarar matrices, tema visto anteriormente.
Se verán distintos ejemplo con sus correspondientes resultados:

Instrucción Valores del índice


for i=1:5 i = 1, 2, 3, 4, 5
for j=2:2:10 j = 2, 4, 6, 8, 10
for ndx=20:-1:15 ndx = 20, 19, 18, 17, 16, 15
for masa=1.2:0.25:2.4 masa = 1.2, 1.45, 1.7, 1.95, 2.2

Como se aprecia, los valores pueden ir tanto en sentido ascendente como descendente, incluso no es necesario
que sean números enteros, pero en este caso no se puede utilizar el contenido de la variable masa como índice
de un vector o matriz, pero sí se lo puede usar para realizar cálculos matemáticos.

Cuarta estructura de control: La instrucción while

La instrucción while también permite realizar lazos, pero que se repiten una cantidad indeterminada de veces,
esto significa que no se puede establecer a ciencia cierta cuántas veces se ejecutará el lazo, a diferencia de la
instrucción for, en la cual es fácil determinar cuántas veces se repite el lazo.

La indeterminación del lazo while se debe fundamentalmente a que se va a ejecutar mientras se cumpla una
condición. Para ejemplificar su uso, se continuará con el ejemplo visto previamente. Una vez calculadas las
fracciones molares de la fase gaseosa, si se conoce la presión total de la misma, se pueden calcular las
presiones parciales, de acuerdo a la siguiente expresión:

𝑝𝑖 = 𝑦𝑖 ∙ 𝑃

Por lo que simplemente se deben multiplicar las fracciones molares por la presión total; sin embargo, si bien se
tiene un vector con las fracciones molares, la cantidad de datos válidos es desconocida de antemano, y sólo se
dispone de un flag, ubicado en algún lugar del vector. Por este motivo, se dice que el cálculo se va a hacer
mediante un lazo que va a funcionar una cantidad indeterminada de veces, por lo cual se utilizará el lazo while
en lugar del for.

La función que realiza esta operación se reproduce a continuación, en la cual se puede observar una estructura
similar a la anterior respecto de la gestión de errores. El vector Pi, que va a contener todas las presiones
parciales, se dimensiona con el mismo tamaño que yi, que ya incluye un lugar adicional para almacenar el flag.

Ing. Juan E. Núñez Mc Leod Página 16 de 30


Unidad 4
MODO
PROGRAMACIÓN

El lazo while se ejecutará hasta que se encuentre el flag en el vector yi; mientras esto no ocurra, se irán
multiplicando una a una las fracciones molares por la presión total y almacenando el resultado en el vector Pi.
Una vez alcanzada la condición de salida del lazo, se almacena el flag correspondiente en el vector Pi y se
finaliza la función.

// Función ejemplo del uso de la instrucción while


// Cálculo de la presión parcial en una mezcla de vapores
// Variable de entrada
// yi: vector fila con las fracciones molares de la mezcla
// P: presión total del sistema
// Variables de salida
// Pi: vector fila con las presiones parciales
// er: código de error
// 0: no hubieron errores
// 404: el vector yi tiene más de una fila
// 405: la presión total es negativa o nula
// 406: en el vector yi no hay datos
function [Pi, er]=PresionParcial(yi, P)
Pi=0
er=0
if size(yi,'r')<>1 then
er=404
return
end
if P<=0 then
er=405
return
end
nDatos=size(yi,'c')
if nDatos<2 then
er=406
return
end
Pi=zeros(1,nDatos)
k=1
while yi(k)<>-1
Pi(k)=yi(k)*P
k=k+1
end
Pi(k)=-1
endfunction

A continuación se reproduce la misma función con los comentarios correspondientes respecto del funcionamiento
de la misma.

// Función ejemplo del uso de la instrucción while


// Cálculo de la presión parcial en una mezcla de vapores
// Variable de entrada
// yi: vector fila con las fracciones molares de la mezcla
// P: presión total del sistema
// Variables de salida
// Pi: vector fila con las presiones parciales
// er: código de error
// 0: no hubieron errores
// 404: el vector yi tiene más de una fila
// 405: la presión total es negativa o nula
// 406: en el vector yi no hay datos
function [Pi, er]=PresionParcial(yi, P)
Pi=0

Ing. Juan E. Núñez Mc Leod Página 17 de 30


Unidad 4
MODO
PROGRAMACIÓN

er=0
// se verifica la cantidad de filas ('rows') del vector yi
if size(yi,'r')<>1 then
er=404
return
end
// se verifica que la presión no sea negativa o nula
if P<=0 then
er=405
return
end
nDatos=size(yi,'c')
// se verifica que el vector yi tenga por lo menos un dato válido
if nDatos<2 then
er=406
return
end
// se dimensiona el vector Pi con el mismo tamaño que yi
Pi=zeros(1,nDatos)
// se inicializa el índice para recorrer el vector yi
k=1
// se repite el lazo mientras no se encuentre el flag
while yi(k)<>-1
// se calcula la presión parcial del vapor k-ésimo
Pi(k)=yi(k)*P
// se avanza al siguiente componente
k=k+1
end
// se coloca el flag después del último dato del vector Pi
Pi(k)=-1
endfunction

Para analizar el funcionamiento de esta instrucción se utilizará el vector yi anteriormente calculado y se


supondrá una presión total de 15 at en la fase gaseosa, de esta manera la función devuelve los siguientes
resultados:

-->[Pi,er]=PresionParcial(yi,15)
er =
0.

Pi =

4.628331 7.1949509 0.2524544 2.9242637 -1. 0. 0. 0.

Como la suma de las presiones parciales es igual a la presión total, se puede realizar la siguiente verificación:

-->sum(Pi(1:4))
ans =

15.

Las instrucciones break y continue

Estas dos instrucciones se utilizan tanto con los lazos for como con los lazos while. La instrucción break
fuerza la interrupción del lazo, continuando la ejecución del programa en la instrucción siguiente al fin del lazo,
mientras que la instrucción continue fuerza el fin del ciclo actual del lazo, comenzando la ejecución del lazo en
el ciclo siguiente.

Ing. Juan E. Núñez Mc Leod Página 18 de 30


Unidad 4
MODO
PROGRAMACIÓN

El ejemplo siguiente muestra un uso de la instrucción break. En la función PresionParcial, anteriormente


vista, el final del lazo while depende exclusivamente de la existencia del flag. Si por algún motivo el mismo no
estuviera ubicado en el vector de fracciones molares yi, se generaría un error como el que se muestra a
continuación:

yi =

0.3085554 0.4796634 0.0168303 0.1949509 0. 0. 0. 0.


-->[Pi,er]=PresionParcial(yi,15)
!--error 21
Índice inválido.
at line 34 of function PresionParcial called by :
[Pi,er]=PresionParcial(yi,15)

De esta manera la función demuestra que no es robusta. Seguidamente se muestra una función mejorada,
mediante el uso de la instrucción break y con un nuevo código de error, el número 7, que indica de manera
explícita la inexistencia del flag en el vector yi. Tal como se observa a continuación:

// Función ejemplo del uso de la instrucción while


// Cálculo de la presión parcial en una mezcla de vapores
// Variable de entrada
// yi: vector fila con las fracciones molares de la mezcla
// P: presión total del sistema
// Variables de salida
// Pi: vector fila con las presiones parciales
// er: código de error
// 0: no hubieron errores
// 404: el vector yi tiene más de una fila
// 405: la presión total es negativa o nula
// 406: en el vector yi no hay datos
// 407: no se encontró el flag
function [Pi, er]=PresionParcial(yi, P)
Pi=0
er=0

// se verifica la cantidad de filas ('rows') del vector yi


if size(yi,'r')<>1 then
er=404
return
end
// se verifica que la presión no sea negativa o nula
if P<=0 then
er=405
return
end
nDatos=size(yi,'c')
// se verifica que el vector yi tenga por lo menos un dato válido
if nDatos<2 then
er=406
return
end

// se dimensiona el vector Pi con el mismo tamaño que yi


Pi=zeros(1,nDatos)
// se inicializa el índice para recorrer el vector yi
k=1
// se repite el lazo mientras no se encuentre el flag
while yi(k)<>-1
// se calcula la presión parcial del vapor k-ésimo

Ing. Juan E. Núñez Mc Leod Página 19 de 30


Unidad 4
MODO
PROGRAMACIÓN

Pi(k)=yi(k)*P
// se avanza al siguiente componente
k=k+1
if k>nDatos then
// si el índice k supera la longitud del vector yi
// significa que el flag no está, por lo que se asigna
// el código de error y se cancela el lazo
er=407
break
end
end

// al terminar el lazo, se debe verificar si la salida fue normal


// o no, con el objeto de colocar el flag correspondiente en Pi
if er==0 then
// se coloca el flag después del último dato del vector Pi
Pi(k)=-1
end

endfunction

Al ser llamada, con el vector yi sin el flag correspondiente, la función se comporta de una forma adecuada, como
se ve en el siguiente caso:

-->[Pi,er]=PresionParcial(yi,15)
er =

407.
Pi =

4.628331 7.1949509 0.2524544 2.9242637 0. 0. 0. 0.

Se debe recordar que lo primero que se debe analizar, cuando se obtienen resultados de una función, es el valor
de la variable er, si la misma es distinta de cero, se deben descartar los resultados y revisar la situación. En el
caso anterior, los resultados entregados son correctos; sin embargo, la inexistencia del flag genera el error, esto
puede significar que hay más datos, que por algún motivo se han perdido. Hasta no definir adecuadamente el
motivo por el cual apareció el error, los resultados no pueden darse como válidos.

FUNCIÓN DE FUNCIÓN

Al estudiar las instrucciones for y while, se desarrollaron dos funciones de cálculo aplicables a mezclas de
gases, las cuales están íntimamente relacionadas.

La primera de dichas funciones permite el cálculo de la fracción molar de una mezcla, la cual se llama
FraccionMolar; mientras que la segunda, denominada PresionParcial, utiliza el resultado de la primera
para calcular las presiones parciales de cada componente de la mezcla. Tal cual se ha presentado el desarrollo
de las funciones mencionadas, el uso de las mismas es independiente. Se puede pensar en ir aumentando la
cantidad de funciones aplicable a mezclas gaseosas, que permitan determinar valores como: densidades, masas,
volúmenes parciales, etc. Todas estas funciones deberían ser llamadas una por una, para poder realizar los
cálculos correspondientes, volviéndose la tarea bastante tediosa, sobre todo si se tienen muchas mezclas de
gases que resolver.

Con el objeto de simplificar toda la operación de resolución, es que se escribe lo que se llama una función de
función, que consiste en una función que va llamando en secuencia lógica a cada una de las funciones
individuales, obteniendo todos los resultados. De esta manera, se llama a una única función para poder resolver
la mezcla de gases en forma completa.

De esta manera se pueden armar funciones que llamen a otras funciones y a su vez, éstas últimas pueden seguir
llamando a más funciones, lográndose una estructura de cálculo bastante compleja y potente.

Ing. Juan E. Núñez Mc Leod Página 20 de 30


Unidad 4
MODO
PROGRAMACIÓN

Para ejemplificar lo dicho, se puede hacer una función que abarque las dos funciones vistas anteriormente; por lo
tanto, no es necesario estar llamando a cada una por separado, sino a una sola y que esta última devuelva todos
los resultados.

La función de función se llamará CalcularMezcla y el código de la misma se transcribe a continuación.

// Función de función ejemplo de implementación


// Cálculo de fracciones molares y presiones parciales
// de una mezcla gaseosa
// Variable de entrada
// compos: vector fila con los moles de un sistema multicomponente
// fase: vector fila indicando la fase correspondiente
// de cada dato contenido en el vector ni
// 0: Fase líquida.
// 1: Fase vapor.
// P: presión total del sistema
// Variables de salida
// yi: vector fila con la concentración de la fase vapor
// expresada como fracciones molares
// Pi: vector fila con las presiones parciales
// er: código de error
// 0: no hubieron errores
// 401: el vector compos tiene más de una fila
// 402: el vector fase tiene más de una fila
// 403: los vectores compos y fase tiene distinta cantidad de datos
// 404: el vector yi tiene más de una fila
// 405: la presión total es negativa o nula
// 406: en el vector yi no hay datos
// 407: no se encontró el flag
function [yi, Pi, er]=CalcularMezcla(compos, fase, P)
[yi,er]=FraccionMolar(compos,fase)
if er<>0 then
return
end
[Pi,er]=PresionParcial(yi,P)
endfunction

Seguidamente se puede ver la misma función de función con los comentarios explicativos de cada una de las
partes de la misma:

// Función de función ejemplo de implementación


// Cálculo de fracciones molares y presiones parciales
// de una mezcla gaseosa
// Variable de entrada
// compos: vector fila con los moles de un sistema multicomponente
// fase: vector fila indicando la fase correspondiente
// de cada dato contenido en el vector ni
// 0: Fase líquida.
// 1: Fase vapor.
// P: presión total del sistema
// Variables de salida
// yi: vector fila con la concentración de la fase vapor
// expresada como fracciones molares
// Pi: vector fila con las presiones parciales
// er: código de error
// 0: no hubieron errores
// 401: el vector compos tiene más de una fila
// 402: el vector fase tiene más de una fila
// 403: los vectores compos y fase tiene distinta cantidad de datos

Ing. Juan E. Núñez Mc Leod Página 21 de 30


Unidad 4
MODO
PROGRAMACIÓN

// 404: el vector yi tiene más de una fila


// 405: la presión total es negativa o nula
// 406: en el vector yi no hay datos
// 407: no se encontró el flag
function [yi, Pi, er]=CalcularMezcla(compos, fase, P)
// se llama a la primera función en la secuencia lógica de cálculo
[yi,er]=FraccionMolar(compos,fase)
// se verifica la condición de error
if er<>0 then
// si hubo un error se termina la ejecución de la función
return
end
// si no hubo error se continúa con el siguiente cálculo
[Pi,er]=PresionParcial(yi,P)
// después del último cálculo no es necesario verificar
// la condición de error, ya que sí o sí termina la función
endfunction

En las siguientes líneas se transcriben las instrucciones necesarias para poder hacer uso de esta nueva función,
con las verificaciones correspondientes, las cuales nunca están de más.

-->compos=[2.2 1.01 0.54 3.42 1.98 0.12 1.39];

-->fase=[1 0 0 1 0 1 1];

-->[yi,Pi,er]=CalcularMezcla(compos,fase,15)
er =

0.
Pi =

4.628331 7.1949509 0.2524544 2.9242637 -1. 0. 0. 0.

yi =

0.3085554 0.4796634 0.0168303 0.1949509 -1. 0. 0. 0.

-->sum(yi(1:4))
ans =

1.

-->sum(Pi(1:4))
ans =

15.

USO DE EXPRESIONES RACIONALES EN FUNCIONES

Las funciones permiten que sus argumentos sean expresiones racionales y también pueden devolverlas como
resultados.

Para ejemplificar lo expresado se utilizará la ecuación de Van der Waals de gases reales, que se expresa
habitualmente de la siguiente manera:

𝑛2 𝑎
𝑃+ . 𝑉 − 𝑛𝑏 = 𝑛𝑅𝑇
𝑉2

Ing. Juan E. Núñez Mc Leod Página 22 de 30


Unidad 4
MODO
PROGRAMACIÓN

Sin embargo, para poder trabajar la misma, es común desarrollarla algebraicamente hasta obtener una ecuación
cúbica en V, tal como se expresa a continuación:

𝑃 ∙ 𝑉 3 − 𝑛𝑏𝑃 + 𝑛𝑅𝑇 ∙ 𝑉 2 + 𝑛2 𝑎 ∙ 𝑉 − 𝑛3 𝑎𝑏 = 0

Si los coeficientes de la ecuación los simbolizamos con 𝑐𝑖 la misma queda:

𝑐3 ∙ 𝑉 3 + 𝑐2 ∙ 𝑉 2 + 𝑐1 ∙ 𝑉 + 𝑐0 = 0

En donde cada coeficiente se calcula de la siguiente manera:

𝑐3 = 𝑃

𝑐2 = − 𝑛𝑏𝑃 + 𝑛𝑅𝑇

𝑐1 = 𝑛2 𝑎

𝑐0 = −𝑛3 𝑎𝑏

Por lo que conociendo, P, T, n, R y las constantes de Van der Waals a y b del gas en cuestión, se puede definir la
ecuación en V. Como es un trabajo arduo, sobre todo si se está trabajando con varios gases, se diseñó una
función para definirlo, pero la misma sólo trabajará con valores escalares en sus argumentos, de esta manera es
posible definir una única ecuación a la vez.

// Función para definir la ecuación en V de Van der Waals


// Esta función sólo admite valores escalares en sus argumentos
// Variables de entrada
// P: presión del gas, at
// T: temperatura del gas, K
// R: constante universal de los gases, l at/mol K
// n: número de moles del gas
// a y b: constantes de Van der Waals del gas
// Variables de salida
// pVdW: polinomio de Van der Waals
// er: código de error
// 0: no hay error
// 408: la presión es negativa o es una matriz
// 409: la temperatura es negativa o es una matriz
// 410: la constante R es negativa o es una matriz
// 411: los números de moles son negativos o es una matriz
// 412: la constante a es negativa o es una matriz
// 413: la constante b es negativa o es una matriz
function [pVdW, er]=VanderWaals(P, T, R, n, a, b)
pVdW=0
er=0
if P<=0 | length(P)>1 then
er=408
return
end
if T<=0 | length(T)>1 then
er=409
return
end
if R<=0 | length(R)>1 then
er=410
return
end
if n<=0 | length(n)>1 then
er=411

Ing. Juan E. Núñez Mc Leod Página 23 de 30


Unidad 4
MODO
PROGRAMACIÓN

return
end
if a<=0 | length(a)>1 then
er=412
return
end
if b<=0 | length(b)>1 then
er=413
return
end

c3=P
c2=-(n*b*P+n*R*T)
c1=n^2*a
c0=-n^3*a*b
pVdW=poly([c0 c1 c2 c3],'V','c')
endfunction

En la función se ha hecho uso de la instrucción length que devuelve como resultado la cantidad de elementos
de la matriz que se pasa como argumento, al tratarse de valores escalares, dicha cantidad necesariamente debe
ser 1.

Para ejemplificar el uso de la función se supondrán 10 moles de nitrógeno, a 1 at de presión y 300 K de


temperatura. Las constantes correspondientes son:

𝑎 = 1.390 𝑎𝑡/𝑙 2 𝑚𝑜𝑙2

𝑏 = 0.03913 𝑙/𝑚𝑜𝑙

Con estos datos se llama a la función VanderWaals, obteniendo el siguiente resultado:

-->a=1.390;b=0.03913;

-->T=300;P=1;n=10;

-->R=0.0820562;

-->[pVdW,er]=VanderWaals(P,T,R,n,a,b)
er =

0.
pVdW =

2 3
- 54.3907 + 139V - 246.5599V + V

Si se calculan las raíces del polinomio resultante, se obtendrán los volúmenes del fluido a la presión y
temperatura dadas. En el caso del ejemplo:

-->v=roots(pVdW)
v =

245.99575
0.2820758 + 0.3762147i
0.2820758 - 0.3762147i

Analizando la respuesta, se encuentra una raíz real y dos complejas conjugadas (estas últimas se descartan), por
lo tanto el fluido tiene un único estado cuyo volumen es de 245.996 litros.

Ing. Juan E. Núñez Mc Leod Página 24 de 30


Unidad 4
MODO
PROGRAMACIÓN

Para verificar si este valor es correcto, primero se calculará la densidad del fluido, teniendo en cuenta que la
masa molar de una molécula de nitrógeno es de 28.0134 g/mol, el resultado será:

-->dens=28.0134*10/v(1)
dens =

1.1387758

Una densidad de 1.139 g/l corresponde a un gas o vapor, por lo que se utilizará la ecuación de los gases ideales
para calcular el volumen de los 10 moles de nitrógeno:

-->10*R*T/P
ans =

246.1686

Como se observa se obtiene un valor bastante cercano al calculado por la ecuación de Van der Waals. Se debe
aclarar que esta verificación es posible ya que la condición utilizada, de presión y temperatura, se encuentra
bastante alejada del punto crítico del nitrógeno.

PRECAUCIÓN AL USAR VECTORES COMO ARGUMENTOS DE FUNCIONES

Si se observa la función de cálculo del número de Reynolds, vista al principio de este apunte, se verá que dicha
función permite calcular un valor determinado, de acuerdo a los distintos argumentos de la misma. De esta forma
se puede conocer un determinado valor de Reynolds para cada conjunto de valores de entrada.

Una característica de Scilab es que permite definir vectores, que incluyan como componentes distintos valores de
un determinado argumento. De esta manera, si se desean calcular los valores del número de Reynolds para
velocidades desde 0.2 m/s hasta los 2 m/s, con un intervalo de 0.1 m/s, se pueden escribir las siguientes
instrucciones:

-->vel=[0.1:0.1:2]

vel =
column 1 to 13

0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. 1.1 1.2 1.3

column 14 to 20

1.4 1.5 1.6 1.7 1.8 1.9 2.

-->re=reynolds(0.01,vel,1000,0.001)

re =
column 1 to 10

1000. 2000. 3000. 4000. 5000. 6000. 7000. 8000. 9000. 10000.

column 11 to 19

11000. 12000. 13000. 14000. 15000. 16000. 17000. 18000. 19000.

column 20

20000.

Como se observa el cálculo ha sido realizado en forma correcta por Scilab, dando por resultado veinte valores de
Reynolds, correspondientes a cada una de las velocidades del vector vel.

Ing. Juan E. Núñez Mc Leod Página 25 de 30


Unidad 4
MODO
PROGRAMACIÓN

A continuación se desea calcular los distintos valores de Reynolds para cambios de la viscosidad, desde 0.001
kg/m s hasta 0.002 kg/m s, en incrementos de 0.0001 kg/m s. Para realizar esta tarea se escriben las siguientes
instrucciones:

-->visc=[0.001:0.0001:0.002]

visc =
column 1 to 9
0.001 0.0011 0.0012 0.0013 0.0014 0.0015 0.0016 0.0017 0.0018

column 10 to 11
0.0019 0.002

-->re=reynolds(0.01,2,1000,visc)

re =
773.69439
851.06383
928.43327
1005.8027
1083.1721
1160.5416
1237.911
1315.2805
1392.6499
1470.0193
1547.3888

Al analizar el resultado se observa que el primer valor de Reynolds es de 773.69439, el cual corresponde a una
viscosidad de 0.001, sin embargo este cálculo ya se había realizado con anterioridad, dando como resultado
20000. Por otro lado, la variable visc es un vector fila, mientras la variable re es un vector columna, lo que da la
pauta que Scilab está haciendo un cálculo matricial y no un cálculo elemento a elemento.

La instrucción de cálculo del número de Reynolds es la siguiente:

re=diam*vel*dens/visc

Al ser la variable visc un vector, la operación de división Scilab la resuelve en forma matricial, por lo que se
debe modificar la instrucción de cálculo por esta otra:
11
re=diam*vel*dens./visc

Una vez hecha esta modificación, el cálculo de los números de Reynolds para las distintas viscosidades dará el
siguiente resultado:

-->re=reynolds(0.01,2,1000,visc)

re =
column 1 to 7
20000. 18181.818 16666.667 15384.615 14285.714 13333.333 12500.

column 8 to 11
11764.706 11111.111 10526.316 10000.

En este caso los resultados obtenidos son los correctos.

11
Nótese la presencia del punto antes de la barra de división, indicando una operación elemento a elemento.

Ing. Juan E. Núñez Mc Leod Página 26 de 30


Unidad 4
MODO
PROGRAMACIÓN

Con este ejemplo se desea hacer hincapié en la importancia de escribir en forma adecuada las expresiones de
cálculo. En la medida que se utilicen valores escalares las funciones devolverán valores correctos, pero si se
utilizan vectores, con el objeto de armar tablas de valores, el resultado puede ser incorrecto.

APLICACIONES DE EXPRESIONES LÓGICAS

Las expresiones lógicas dan una gran versatilidad a la hora de procesar información. Si bien ya se han utilizado a
lo largo del apunte, se hará una discusión más profunda de sus posibilidades.

Instrucción Descripción
La condición es verdadera para todos aquellos valores de x que sean
mayores a 1000. Si x es una matriz, devuelve otra matriz del mismo
tamaño, donde cada elemento es T o F, según si se cumple o no la
condición para cada elemento de la matriz original.
a- if x>1000 then …
El comportamiento es similar para los símbolos relacionales:
<: menor que
>=: mayor o igual que
<=: menor o igual que
La condición es verdadera si el valor de x es igual a 1000. Si x es una
if x==1000 then … matriz, devuelve otra matriz del mismo tamaño, donde cada elemento es
b-
T o F, según si se cumple o no la igualdad con cada elemento de la matriz
original.
La condición es verdadera si el valor de x es distinto a 1000. Si x es una
if x<>1000 then … matriz, devuelve otra matriz del mismo tamaño, donde cada elemento es
c-
T o F, según si se cumple o no la desigualdad con cada elemento de la
matriz original.
Este tipo de expresión lógica se utiliza para saber si un determinado valor
de la variable se encuentra dentro de ciertos límites. Se utiliza el conector
lógico Y, simbolizado por &.

El ejemplo dado, en un lenguaje coloquial, se lee: “Si x es mayor que 100


if x>100 & x<1000 then … y menor que 1000, entonces… “
d-
Si x es una matriz, devuelve otra matriz del mismo tamaño, donde cada
elemento es T o F, según si se cumple o no las condiciones para cada
elemento de la matriz original.

El comportamiento es similar para los símbolos relacionales: <, >=, <=


Este tipo de expresión lógica se utiliza para saber si un determinado valor
de la variable se encuentra por debajo o por encima de ciertos límites. Se
utiliza el conector lógico O, simbolizado por |.

El ejemplo dado, en un lenguaje coloquial, se lee: “Si x es menor que 100


if x<100 | x>1000 then … o mayor que 1000, entonces… “
e-
Si x es una matriz, devuelve otra matriz del mismo tamaño, donde cada
elemento es T o F, según si se cumple o no las condiciones para cada
elemento de la matriz original.

El comportamiento es similar para los símbolos relacionales: <, >=, <=


Si bien la instrucción sum(x) suma todos los elementos de la matriz x, al
utilizar una expresión lógica como la dada, el resultado será la cantidad
sum(x>1000) de elementos que cumplen con dicha condición. En el ejemplo, la
f-
instrucción devuelve la cantidad de elementos que son mayores a 1000.

Se pueden usar también los símbolos relacionales: <, >=, <=, ==, <>

Ing. Juan E. Núñez Mc Leod Página 27 de 30


Unidad 4
MODO
PROGRAMACIÓN

Instrucción Descripción
La instrucción sum(x>0) indica cuantos elementos de la matriz x son
positivos, mientras que la instrucción length(x) indica cuantos
elementos hay en la matriz x en total.
if sum(x>0)==length(x)
g- then … La expresión dada en el ejemplo es verdadera si la cantidad de elementos
positivos es igual a la cantidad de elementos totales de la matriz x. En
otras palabras, la expresión es verdadera si todos los elementos de x son
positivos.

Se verán a continuación ejemplos de los dos últimos casos, ya que los anteriores han sido utilizados a lo largo del
apunte.

Caso f

--> x=[-200 400 800 1100 1500 2300];

--> sum(x>=1100)
ans =

3.

Caso g

--> x=[-200 400 800 1100 1500 2300];

--> sum(x>0)
ans =

5.

--> length(x)
ans =

6.

--> if sum(x>0)==length(x) then f=1 else f=2 end


f =

2.

LAS IGUALDADES EN PUNTO FLOTANTE

Como se discutió previamente, las computadoras representan los números en un formato de punto flotante. Los
números irracionales y periódicos deben ser redondeados a 16 dígitos, ya que la representación exacta requiere
de infinitos dígitos, produciendo un error de truncamiento. Esto ocasiona problemas inevitables que deben ser
tenidos en cuenta al programar. Además, las computadoras utilizan el sistema binario para codificar la
información, por lo que números que en sistema decimal tienen representación finita, en binario pueden ser
periódicos.

Así por ejemplo, el número 0,1 en decimal tiene una representación finita; sin embargo, en binario es periódica,
como se muestra a continuación:

1
= 0,110 = 0,0001100110011001100110011 …2
10

Ing. Juan E. Núñez Mc Leod Página 28 de 30


Unidad 4
MODO
PROGRAMACIÓN

Por lo que este número es almacenado con un error de truncamiento, lo cual puede ser fácilmente verificado
mediante el uso de la siguiente función:

function [s]=suma(n)
s=0
for i=1:n
s=s+0.1
end
endfunction

Analizando la misma se puede ver que se trata de un simple acumulador, que suma 0.1 tantas veces como
indique el argumento de entrada n.

Como se va a analizar la exactitud de cálculo de la computadora, se utilizará la función format para visualizar
los 16 dígitos de precisión, con la siguiente instrucción:

--> format('v',18)

Seguidamente se llamará a la función suma(n) con distintos argumentos, y se analizarán los resultados:

--> s=suma(10)
s =
1.

--> s=suma(15)
s =
1.5

--> s=suma(20)
s =
2.

--> s=suma(30)
s =
3.000000000000001

Como se observa, en las primeras sumas los resultados son exactos; sin embargo, cuando se utiliza n=30
aparece un residuo, producto de la acumulación de errores de truncamiento del valor 0,1. Esta situación se va
empeorando a medida que aumenta n, como se aprecia en los siguientes cálculos:

--> s=suma(100)
s =
9.999999999999981

--> s=suma(1000)
s =
99.99999999999859

--> s=suma(10000)
s =
1000.000000000159

--> s=suma(100000)
s =
10000.00000001885

--> s=suma(1000000)
s =
100000.0000013329

Ing. Juan E. Núñez Mc Leod Página 29 de 30


Unidad 4
MODO
PROGRAMACIÓN

Si bien, el residuo mencionado se mantiene relativamente despreciable, frente al valor del resultado, su presencia
hace que ciertas instrucciones de comparación puedan ser evaluadas como falsas, cuando en realidad no lo son.
12
Analícense las siguientes instrucciones :

--> suma(1)==0.1
ans =

--> suma(2)==0.2
ans =

--> suma(3)==0.3
ans =

Todos los casos son estrictamente verdaderos; sin embargo, el último es evaluado como falso debido a la
presencia del residuo mencionado. Recuérdese que las computadoras son estrictas, la mínima diferencia indica
desigualdad.

Dada esta explicación es fácil entender que cuando se trabaja con valores en punto flotante, expresiones como:

if vel==0 then …

if vel==100 then …

pueden fallar aunque la variable vel sea técnicamente nula o valga “casi” 100, debido a la presencia de los
mencionados residuos.

Por este motivo, nunca se utiliza la igualdad en expresiones lógicas con números en punto flotante, sino que se
usan expresiones del siguiente tipo:

if abs(vel)<1d-7 then …

if abs(vel-100)<1d-7 then …

Al analizar las expresiones lógicas se observa que se está preguntando si la variable vel está dentro de un
entorno de radio 10−7 del valor de referencia (0 ó 100), lógicamente el valor del radio debe ser ajustado al nivel
de precisión deseado. Sin embargo, este radio no debe ser excesivamente reducido, ya que se puede dar el caso
de que nunca se alcance ese nivel de precisión, debido a una oscilación permanente alrededor del resultado final.

12
Se recuerda que al evaluar expresiones lógicas, los resultados dados por Scilab son T para verdadero (true) y F para falso (false).

Ing. Juan E. Núñez Mc Leod Página 30 de 30

También podría gustarte