Académique Documents
Professionnel Documents
Culture Documents
M2235 PDF
M2235 PDF
ANNÉE 1999/2000
RAPPORT FINAL
PFE – LMS – ESP 1
NOMBRE DE PAGES : 16 + 72
1. REMERCIEMENTS
2. SOMMAIRE
1. REMERCIEMENTS ............................................................................... 3
2. SOMMAIRE ........................................................................................... 4
3. INTRODUCTION ................................................................................... 5
4. CONTEXTE ............................................................................................ 6
4.1. Paris ...............................................................................................................6
4.2. Bilbao ............................................................................................................ 6
3. INTRODUCTION
Ce Projet de Fin d’Etudes a été réalisé dans le cadre des échanges entre l’ Ecole
Nationale Supérieure d’Arts et Métiers (ENSAM) et l’Ecole Supérieure d’Ingénieurs de
Bilbao (ETSII e IT)
Connaissances nécessaires :
• Théorie de la mécanique,
• Méthode des coefficients d’influence,
• Méthodes de dérivation numérique,
• Programmation avec FORTRAN Powerstation de Microsoft,
• Affichage graphique sur ordinateurs.
4. CONTEXTE
4.1. Paris
Pendant le premier semestre, le projet a progressé assez lentement puisqu’une
journée par semaine lui était consacré. Il était difficile de se familiariser avec le Fortran
car l’ENSAM ne possède pas le logiciel en question. Par conséquent, mon travail à
Paris a été essentiellement théorique : recherche et consultation de livres et revues
scientifiques sur le langage Fortran et sur la méthode des coefficients d’influence.
4.2. Bilbao
Pour commencer, je me suis familiarisé avec le langage Fortran en utilisant le
programme FORTRAN Powerstation de Microsoft, et en particulier avec la
programmation graphique.
FORTRAN :
Le programme à été développé sur Fortran Powerstation de Microsoft qui offre
la possibilité d’écrire des programmes qui permettent de faire de l’affichage graphique.
De ce point de vue, ce langage est plus efficace que d’autres (comme le C++ par
exemple).
Programme principal :
Le programme principal a été développé par des étudiants de l’Ecole Supérieure
d’Ingénieurs de Bilbao. Il permet de simuler des mécanismes plans à un degré de
liberté.
Il existe une première partie pour dessiner le système. On peut créer un nouveau
système (avec le clavier ou la souris) et le sauvegarder pour le conserver et l’ouvrir plus
tard. Pour créer un nouveau modèle, il faut créer des points et les unir avec des éléments
(barres) et insérer des liaisons (rotules, rotules fixes, glissières...).
Après, il faut revenir au menu initial où on peut intervenir sur le système par
différentes options.
Les deux autres menus correspondent aux deux parties de calcul de vitesses et
accélérations avec la méthode MEF et la méthode des coefficients d’influence (ma
partie).
Ma partie du programme :
Pour utiliser mon menu (“análisis”), l’utilisateur doit créer ou ouvrir un système
à un degré de liberté. Après, il faut utiliser le menu “posiciones sucesivas” et donner un
incrément pour l’angle d’entrée pour que la barre d’entrée bouge.
Les deux parties de mon programme, c’est-à-dire le calcul des vitesses et des
accélérations sont semblables. C’est pourquoi il sera seulement détaillée la partie sur les
vitesses par la suite.
dθ
dt
Or,
dϕ dϕ dt
= ⋅
dθ dt dθ
dϕ
dt
6. Dérivée numérique
Néanmoins, il faut savoir qu’on ne peut pas utiliser la même formule suivant que
l’on calcule la dérivée pour un point quelconque ou pour les premiers ou les derniers
points.
Premiers points (i = 1, 2) :
2 f i + 3 − 9 f i + 2 + 18 f i +1 − 11 f i
f 'i =
6h
Premiers points (i = 1, 2) :
− f i + 3 + 4 f i + 2 − 5 f i +1 + 2 f i
f ' 'i =
h2
2 f i − 5 f i −1 + 4 f i − 2 − f i − 3
f ' 'i =
h2
Sj(x) = aj + bj(x - xj) + cj(x - xj)2 + dj(x - xj)3 , pour j = 0, 1,..., n-1.
Voici le processus de calcul simplifié des vitesses tel qu’il est effectué par le
programme (le listing est présenté en annexe).
5. Rangement par ordre croissant des angles de la barre étudiée en fonction des angles
de la barre d’entrée (nécessaire pour le bon fonctionnement du programme).
6. Calcul des coefficients d’influence des vitesses avec l’utilisation des formules de
dérivation numérique.
2. Sélectionner :
/ File / New...
⇒ ouverture d’une fenêtre
3. Sélectionner :
Project Workspace
OK
⇒ ouverture d’une fenêtre
6. Sélectionner :
/ Insert / Files into Project...
⇒ ouverture d’une fenêtre
8. Sélectionner :
/ Build / Build nombre.exe
9. Sélectionner :
/ Build / Execute nombre.exe
6. Lancer l’analyse :
Séléctionner / Análisis / velocidades
ou / Análisis / aceleraciones
9. Données :
Introduire le module de la vitesse (ou de l’accélération) de la barre d’entrée.
Celui-ci doit être positif puisque le sens du mouvement a déjà été définit lors de
l’introduction de l’incrément.
OK
10. Graphique :
Il s’ouvre une fenêtre dans laquelle est affiché le graphique de la vitesse (ou
accélération) de la barre étudiée en fonction de l’angle de la barre d’entrée.
Les informations sont les suivantes :
Deux axes :
L’axe des abscisses représente les angles de la barre d’entrée (valeurs croissantes
de la gauche vers la droite) pour une vitesse (ou accélération) nulle.
L’axe des ordonnées représente la vitesses(ou l’accélération) de la barre étudiée
et est tracé pour l’angle minimum de la barre d’entrée.
Quatre valeurs :
Par conséquent, il est intéressant de comparer les résultats des deux méthodes à
travers un exemple simple.
Il est à noter que les valeurs données pour la méthode des coefficients
d’influence sont celles avant interpolation (sans quoi il n’aurait pas été possible d’avoir
des valeurs correspondant au mêmes angles).
On peut s’apercevoir que pour un système à un degré de liberté (celui étant assez
simple), les deux méthodes donnent des résultats assez similaires.
Par conséquent, il faudra choisir une méthode plutôt que l’autre en fonction du
développement futur du programme et après avoir testé des cas particuliers avec les
deux méthodes afin de conserver celle qui fonctionne le mieux.
11. LIMITES
Quelques cas particuliers ont été testés et des modifications ont été apporté en
conséquence; néanmoins, certains problèmes subsistent :
Sur certaines études, la courbe ressemble à une sinusoïde dont les extremis
sortent très loin de l’échelle de la fenêtre. Après analyse, il apparaît que ce problème
vient de l’interpolation et qu’il survient le plus souvent lorsque l’angle de la barre
étudiée n’évolue que très peu.
12. CONCLUSION
• programmation.
Lors de l’utilisation du programme, il est apparu divers problèmes qui ont été
résolus pour une part. Néanmoins, l’objet du projet étant plus la programmation du
logiciel que son utilisation, il semble nécessaire de faire des tests plus poussés pour
relever les disfonctionnements éventuels.
De plus, les professeurs et les élèves de l’école ont toujours été très disponibles
quand j’avais besoin de leur aide. Je tiens à les en remercier, et grâce à eux, mon séjour
à Bilbao fut d’un grand plaisir.
Procedimiento de cálculo de
velocidades y aceleraciones
en mecanismos planos
Alumno : Profesores :
Alexis MEUNIER Alfonso HERNÁNDEZ FRÍAS
Víctor PETUYA ARCOCHA
André BARRACO
Procedimiento de cálculo de
velocidades y aceleraciones
en mecanismos planos
Alumno : Profesores :
Alexis MEUNIER Alfonso HERNÁNDEZ FRÍAS
Víctor PETUYA ARCOCHA
André BARRACO
1. AGRADECIMIENTOS
2. INDICE
1. AGRADECIMIENTO ............................................................................. 3
2. INDICE ................................................................................................... 4
3. INTRODUCCIÓN ................................................................................... 6
4. CONTEXTO ........................................................................................... 8
4.1. París .............................................................................................................. 8
Disquete
3. INTRODUCCIÓN
Este proyecto de fin de carrera fue realizado con arreglo a los intercambios entre
la Escuela Nacional Superior de Ingenieros ENSAM y la Escuela Superior de
Ingenieros de Bilbao (ETSII e IT).
El tema es el siguiente :
Conocimientos necesarios :
• Teoría de mecanismos,
• Método de los coeficientes de influencia,
• Métodos de derivación numérica,
• Programación en FORTRAN Powerstation de Microsoft,
• Gráficos con computadoras.
4. CONTEXTO
4.1. París
Durante el primer semestre, el proyecto progreso lentamente ya que tenía un día
cada semana para adelantarlo. Fue muy difícil familiarizarme con el FORTRAN porque
la ENSAM no tenía este tipo de programa. Por consiguiente, mi trabajo en París fue
esencialmente un trabajo de investigación y de estudio bibliográfico. Consulté libros
sobre la programación en lenguaje FORTRAN y consulté libros y revistas científicas
sobre el método de los coeficientes de influencia.
4.2. Bilbao
Al principio, me familiaricé con el lenguaje FORTRAN, utilizando el programa
FORTRAN Powerstation de Microsoft, especialmente con la programación gráfica.
FORTRAN :
El programa fue programado con Fortran Powerstation de Microsoft que ofrece
la posibilidad de escribir programas que permiten hacer visualización gráfica.
De este punto de vista, este lenguaje es más eficiente que otros (como el C++
por ejemplo).
Programa principal :
El programa principal fue desarrollado por algunos alumnos de la Escuela
Superior de Ingenieros de Bilbao. Permite simular mecanismos planos de un grado de
libertad con pares de rotación y prismáticos.
Hay una primera parte para dibujar sistemas. Se puede crear un nuevo sistema
(con ratón o teclado) y salvarlo para conservarlo y abrirlo después. Para crear un nuevo
modelo, hay que crear puntos, unirlos con elementos (barras, ternario, cuaternario,
deslizadera) y poner uniones (rotulas, rotulas fijas).
Los dos otros menús corresponden a los dos partes de cálculo de velocidades y
aceleraciones con el método MEF y con el método de los coeficientes de influencia (mi
parte).
5. Diferenciación numérica
Se construye una hoja corrugada para techado, usando una máquina que
comprime una hoja plana de aluminio, y la transforma en una hoja cuya sección
transversal tiene la forma de onda de la función seno.
Se necesita hoja corrugada de 4 pies de largo cuyas ondas tienen una altura de 1
plg. desde la línea central, y cada onda tiene aproximadamente un periodo de 2π plg. El
problema de calcular la longitud de la primera hoja plana consiste en determinar la
longitud de la onda dada por f(x) = sen x de x = 0 a x = 48 plg. Por el cálculo sabemos
que esta longitud es
2
48 df ( x ) 48
L=∫ 1+ dx = ∫0 1 + (cos x ) dx,
2
0
dx
de modo que el problema consistirá en evaluar esta integral. Aunque la función seno es
una de las más comunes en las matemáticas, el cálculo de su longitud da origen a una
integral elíptica de segunda clase, la cual no puede evaluarse con métodos normales.
La derivada de la función f en x0 es
lim f ( x0 + h ) − f ( x0 )
f ' ( x0 ) =
h→0 h
Para aproximar este número, supongamos primero que x0 ∈ (a, b), donde f ∈
C [a, b], y que x1 = x0 + h para alguna h ≠ 0 que es lo bastante pequeña para asegurarnos
2
( x − x0 )( x − x1 )
f ( x0 ) = P0,1 ( x ) + f ' ' (ξ ( x )).
2!
f ( x0 )( x − x0 − h ) f ( x0 + h )( x − x0 )
= +
−h h
( x − x0 )( x − x0 − h )
+ f ' ' (ξ ( x ))
2
f ( x0 + h ) − f ( x0 ) ( x − x0 )( x − x0 − h )
f ' ( x) = + Dx f ' ' (ξ ( x ))
h 2
f ( x0 + h ) − f ( x0 ) 2( x − x0 ) − h
= + f ' ' (ξ ( x ))
h 2
( x − x0 )( x − x0 − h )
+ Dx ( f ' ' (ξ ( x ))),
2
de modo que
f ( x0 + h ) − f ( x0 )
f ' ( x) ≈ .
h
Un problema que presenta esta fórmula cuando aproximamos f’(x) para los
valores arbitrarios de x radica en que carecemos de información sobre Dxf’’(ξ(x)) = f
(ξ(x)).ξ’(x), por lo cual no podemos estimar el error de truncamiento. Pero cuando x es
x0 el coeficiente de Dxf’’(ξ(x)) será cero y la fórmula se simplifica como sigue
f ( x0 + h ) − f ( x0 ) h
(1) f ' ( x) = − f ' ' (ξ ).
h 2
f (1.8 + h ) − f (1.8)
, para h>0
h
| hf ' ' (ξ ) | | h | |h |
= 2≤ , donde 1.8<ξ<1.8+h.
2 2ξ 2(1.8)2
Puesto que f’(x) = 1/x, el valor exacto de f’(1.8) es 0.555 y las cotas de error son
adecuados.
Para obtener fórmulas de aproximación a la derivada más generales, supongamos
que {x0, x1,...,xn} son (n + 1) números distintos en algún intervalo I y que f ∈ Cn+1(I).
n
( x − x0 )...( x − xn ) ( n +1)
f ( x ) = ∑ f ( xk ) Lk ( x ) + f (ξ ( x ))
k =0 ( n + 1)!
n
( x − x0 )...( x − xn ) ( n +1)
f ' ( x ) = ∑ f ( xk ) L'k ( x ) + Dx f (ξ ( x ))
k =0 (n + 1)!
+
( x − x0 )...( x − xn )
( n + 1)!
[
Dx f ( n +1) (ξ ( x )) . ]
( x − x1 )( x − x2 ) 2 x − x1 − x2
L0 ( x ) = , tenemos L' 0 ( x ) = .
( x0 − x1 )( x0 − x2 ) ( x0 − x1 )( x0 − x2 )
De manera análoga,
2 x − x0 − x2y 2 x − x0 − x1
L'1 ( x ) = L' 2 ( x ) = .
( x1 − x0 )( x1 − x2 ) ( x2 − x0 )( x2 − x1 )
2 x j − x1 − x2 2 x j − x0 − x 2
f ' ( x1 ) = f ( x0 ) + f ( x1 )
( x0 − x1 )( x0 − x2 ) ( x1 − x0 )( x1 − x2 )
2 x j − x0 − x1 1 ( 3) 2
+ f ( x2 ) +
6 f (ξ j ∏ ( x j − xk ),
)
2
( x − x 0 )( x 2 − x1
) k =0
k≠ j
Las tres fórmulas de la ecuación (3) son de gran utilidad si los nodos son
equidistantes, es decir, cuando
1 3 1 h ( 3)
2
f ' ( x0 ) = − f ( x0 ) + 2 f ( x1 ) − f ( x2 ) + f (ξ 0 ).
h 2 2 3
1 1 1 h ( 3)
2
f ' ( x1 ) = − f ( x ) + f ( x ) − f (ξ1 ),
h 2
0 2
2 6
y para xj = x2,
1 1 3 h ( 3)
2
f ' ( x2 ) = − f ( x ) − 2 f ( x ) + f ( x ) + f (ξ 2 ).
h 2
0 1 2
2 3
1 3 1 h ( 3)
2
f ' ( x0 ) = −
h 2
f ( x 0 ) + 2 f ( x 0 + h ) −
2
f ( x0 + 2 h ) 3 f (ξ 0 ),
+
1 1 1 h ( 3)
2
f ' ( x0 + h ) = −
h 2
f ( x 0 ) +
2
f ( x 0 + 2 h ) 6 f (ξ1 ), y
−
1 1 3 h ( 3)
2
f ' ( x0 + 2h ) =
h 2
f ( x 0 ) − 2 f ( x 0 + h ) +
2
f ( x 0 + 2 h ) 3 f (ξ 2 ).
+
2
f ' ( x0 ) =
1
[− 3 f ( x0 ) + 4 f ( x0 + h) − f ( x0 + 2h)] + h f ( 3) (ξ0 ),
2h 3
2
f ' ( x0 ) =
1
[− f ( x0 − h) + f ( x0 + h )] − h f ( 3) (ξ1 ), y
2h 6
2
f ' ( x0 ) =
1
[ f ( x0 − 2h) − 4 f ( x0 − h ) + 3 f ( x0 )] + h f (3) (ξ 2 )
2h 3
Finalmente nótese que, como podemos obtener la última ecuación a partir de la primera
con sólo reemplazar h con -h, en realidad tenemos sólo dos fórmulas:
2
(4) f ' ( x0 ) =
1
[− 3 f ( x0 ) + 4 f ( x0 + h) − f ( x0 + 2h)] + h f ( 3) (ξ0 ),
2h 3
donde ξ0 se encuentra entre x0 y x0 + 2h y
2
(5) f ' ( x0 ) =
1
[ f ( x0 + h) − f ( x0 − h)] − h f ( 3) (ξ1 ),
2h 6
4
(6) f ' ( x0 ) =
1
[ f ( x0 − 2h) − 8 f ( x0 + h ) + 8 f ( x0 + h) − f ( x0 + 2h)] + h f (5) (ξ ).
12h 30
Otra fórmula de cinco puntos de gran utilidad, sobre todo en lo relacionado con
la interpolación de splines cúbicos, es la siguiente:
f ' ( x0 ) =
1
[− 25 f ( x0 ) + 48 f ( x0 + h) − 36 f ( x0 + 2h) + 16 f ( x0 + 3h) − 3 f ( x0 + 4h)]
12h
h 4 ( 5)
+ f (ξ ) (7)
5
Principio :
2 f i + 3 − 9 f i + 2 + 18 f i +1 − 11 f i
f 'i =
6h
Medio :
− f i + 2 + 8 f i + 1 − 8 f i −1 + f i − 2
f 'i =
12h
Fin :
11 f i − 18 f i −1 + 9 f i − 2 − 2 f i − 3
f 'i =
6h
Principio :
− f i + 3 + 4 f i + 2 − 5 f i +1 + 2 f i
f ' 'i =
h2
Medio :
− f i + 2 + 16 f i +1 − 30 f i + 16 f i −1 − f i − 2
f ' 'i =
12h 2
Fin :
2 f i − 5 f i −1 + 4 f i − 2 − f i − 3
f ' 'i =
h2
{(xo,f(xo)), (x1,f(x1)),...,(xn,f(xn))}
posible.
Vamos a estudiar la aproximación por medio de polinomios fragmentarios que
no requieren información sobre la derivada, salvo, quizá, en los extremos del intervalo
donde se aproxima la función.
El tipo más simple de función de polinomio fragmentario diferenciable en un
intervalo entero [x0, xn] es la función obtenida al ajustar un polinomio cuadrático entre
cada par consecutivo de nodos. Esto se hace construyendo una cuadrática en [x0, x1] que
concuerde con la función en xo y en x1 otra cuadrática en [x1, x2] que concuerde con la
función en x1 y en x2 y así sucesivamente. Un polinomio cuadrático general tiene tres
constantes arbitrarias —el término constante, el coeficiente de x y el coeficiente de x2—
y únicamente se requieren dos condiciones para ajustar los datos en los extremos de
cada intervalo, por ello, existe una flexibilidad que permite seleccionar la cuadrática de
modo que la interpolante tenga una derivada continua en [x0, xn]. El problema de este
procedimiento se presenta cuando hay que especificar las condiciones referentes a la
derivada de la interpolante en los extremos x0 y xn. No hay constantes suficientes para
cerciorarse de que se satisfagan las condiciones.
La aproximación polinómica fragmentaria más común utiliza polinomios entre
cada par consecutivo de nodos y recibe el nombre de interpolación de splines cúbicos.
Un polinomio cúbico general contiene cuatro constantes; así pues, el procedimiento del
trazador cúbico ofrece suficiente flexibilidad para garantizar que el interpolante no sólo
sea continuamente diferenciable en el intervalo, sino que además tenga una segunda
derivada continua en el intervalo. Sin embargo, en la construcción del trazador cúbico
no se supone que las derivadas del interpolante concuerdan con las de la función, ni
siquiera en los nodos.
Dada una función f definida en [a, b] y un conjunto de nodos a = x0 < x1 < ... xn =
b un interpolante de trazador cúbico S para f es una función que cumple con las
condiciones siguientes:
Aunque los splines cúbicos se definen con otras condicione s de frontera, las
condiciones anteriores son suficientes en este caso. Cuando se presentan las condiciones
de frontera libre, el trazador recibe el nombre de trazador natural, y su gráfica se
aproxima a la forma que adoptaría una varilla larga y flexible si la hiciéramos pasar por
los puntos de datos {(xo,f(xo)),(x1,f(x1)),...,(xn,f(xn))}.
Sj(xj) = aj = f(xj),
Puesto que los términos (xj+1 - xj) se utilizarán varias veces en este desarrollo, conviene
introducir la notación más simple
hj = xj+1 - xj
Al definir cn = S”(xn)/2 y al aplicar la condición (e), se obtiene otra relación entre los
coeficientes de S,. En este caso,
Al resolver d~ en la ecuación (3) y al sustituir este valor en las ecuaciones (1) y (2), se
obtienen las ecuaciones
h 2j
(4) a j +1 = a j + b j h j + (2c j + c j +1 )
3
y
(6) bj =
1
(a j +1 − a j )− h j (2c j + c j+1 )
hj 3
b j −1 =
1
(a j − a j −1 )− h j−1 (2c j−1 + c j )
h j −1 3
h j −1c j −1 + 2(h j −1 + h j )c j + h j c j +1 = (a j +1 − a j )− 3 (a j + a j −1 ),
3
(7)
hj h j −1
para cada j = 1, 2,..., n - 1. Este sistema contiene sólo {c j }j =0 como incógnitas, ya que
n
valores de f en éstos.
Nótese que una vez que se conocen los valores de {c j }j =0 , encontrar el resto de las
n
(7) y, de ser así, si estos valores son únicos. El siguiente teorema indica que esto es
posible cuando se establece una de las dos condiciones de frontera de la parte (f) de la
definición.
Demostración :
En este caso, las condiciones de frontera significan que cn = S”(xn)/2 = 0 y que
así que c0 = 0.
Las dos ecuaciones c0 = 0 y cn = 0 junto con las ecuaciones de (7) producen un sistema
lineal descrito por la ecuación vectorial Ax = b, donde A es la matriz de (n + 1) por
(n+1)
La solución del problema de los splines cúbicos con las condiciones de frontera S”(xo)
= S”(x0) = 0 puede obtenerse por medio del algoritmo.
αj =
3
(ai +1 − ai ) − 3 (ai + ai +1 )
hj hi −1
Paso 3 Tome l0 = 1; (Pasos 3,4,5, y parte del paso 6 resuelven un sistema lineal
tridiagonal
utilizando el método descrito en el algoritmo 6.7.)
µ = 0;
zo = 0.
Paso5 Tome ln = 1;
zn = 0;
cn = 0.
PARE.
Teorema
Si f está definida en a = x0 <x1 < ... <xn = b, y si es diferenciable en a y en b, entonces f
tendrá un interpolante de trazador sujeto único en los nodos x0, x1l,..., xn, es decir, un
interpolante de trazador que cumple las condiciones de frontera S’(a) = f’(a) y S’(b) =
f’(b).
Demostración
Al aplicar el hecho de que S’(a) = f’(x0) = b0, podemos ver que la ecuación (3.21) con j
= 0 implica que
a1 − a0 h0
f ' (a ) = − ( 2c0 + c1 )
h0 3
En consecuencia,
3
2h0c0 + h0c1 + (a1 − a0 ) − 3 f ' (a )
h0
De manera semejante,
an − an −1 hn −1
f ' (b) = − (2cn −1 + cn ) + hn −1 (cn −1 + cn )
hn −1 3
a − an −1 hn −1
= n − ( cn −1 + 2cn ),
hn −1 3
y que
3
hn −1cn −1 + 2hn −1cn = 3 f ' (b) − ( a1 − an −1 ).
hn −1
3
2h0c0 = h0c1 = (a1 − a0 ) − 3 f ' ( a )
h0
3
hn −1cn −1 + 2hn −1cn = 3 f ' (b) − ( an − an −1 )
hn −1
EJEMPLO
La figura muestra a un joven pato en pleno vuelo. Para aproximar el perfil de la parte
superior del pato, seleccionamos algunos puntos a lo largo de la curva por donde
queremos que pase la curva de aproximación.
X 0.9 1.3 1.9 2.1 2.6 3.0 3.9 4.4 4.7 5.0 6.0 7.0 8.0 9.2 10.5 11.3 11.6 12.0 12.6 13.0 13.3
F(x) 1.3 1.5 1.85 2.1 2.6 2.7 2.4 2.15 2.05 2.1 2.25 2.3 2.25 1.95 1.4 0.9 0.7 0.6 0.5 0.4 0.25
Al utilizar el algoritmo para generar el trazador cúbico libre con estos datos, se
obtienen los coeficientes que aparecen en la tabla. Esta curva de trazador es casi
idéntica al perfil, como se observa en la figura siguiente.
j xj aj bj cj dj
0 0.9 1.3 5.40 0.00 -0.25
1 1.3 1.5 0.42 -0.30 0.95
2 1.9 1.85 1.09 1.41 -2.96
3 2.1 2.1 1.29 -0.37 -0.45
4 2.6 2.6 0.59 -1.04 0.45
5 3.0 2.7 -0.02 -0.50 0.17
6 3.9 2.4 -0.50 -0.03 0.08
7 4.4 2.15 -0.48 0.08 1.31
8 4.7 2.05 -0.07 1.27 -1.58
9 5.0 2.1 0.26 -0.16 0.04
10 6.0 2.25 0.08 -0.03 0.00
11 7.0 2.3 0.01 -0.04 -0.02
12 8.0 2.25 -0.14 -0.11 0.02
13 9.2 1.95 -0.34 -0.05 -0.01
14 10.5 1.4 -0.53 -0.10 -0.02
15 11.3 0.9 -0.73 -0.15 1.21
16 11.6 0.7 -0.49 0.94 -0.84
17 12.0 0.6 -0.14 -0.06 0.04
18 12.6 0.5 -0.18 0.00 -0.45
19 13.0 0.4 -0.39 -0.54 0.60
20 13.3 0.25
En esta parte, voy a explicar la estructura del programa que permite calcular las
velocidades.
No serán presentadas las declaraciones de las variables y algunos módulos que están
particulares.
No será presentada la parte que permite calcular las aceleraciones ya que está muy
parecida con la parte que permite calcular las velocidades.
Sin embargo, es posible ver el programa completo (partes para calcular las velocidades
y aceleraciones) en los anexos.
call tocarbarra(elemento,ordenbarra,punto1,punto2,acabar)
do j=1,num_barras
if ((nudos(barras(j,1),1).eq.punto2%wx).and.(nudos(barras(j,1),2).eq.punto2%wy)) then
if ((nudos(barras(j,2),1).eq.punto1%wx)
.and.(nudos(barras(j,2),2).eq.punto1%wy)) then
bar_diag=j
end if
end if
end do
do num_posicion=1,control(1)
xa=pto_coord(barras(bar_ent,1))%x(num_posicion)
ya=pto_coord(barras(bar_ent,1))%y(num_posicion)
xb=pto_coord(barras(bar_ent,2))%x(num_posicion)
yb=pto_coord(barras(bar_ent,2))%y(num_posicion)
call calcular_angulo(xa,ya,xb,yb,ang)
ang_ent(num_posicion)=ang
end do
do i=1,control(1)
if (ang_ent(i).gt.ang_maxi) then
ang_maxi=ang_ent(i)
end if
if (ang_ent(i).lt.ang_mini) then
ang_mini=ang_ent(i)
end if
end do
call calcular_angulo2(xa,ya,xb,yb,ang)
dϕ
dθ
h=0
do i=2,control(1)-1
if (ang_ent(i+1)-ang_ent(i).GT.(ang_ent(i)-ang_ent(i-1))*1.2
.OR. (ang_ent(i+1)-ang_ent(i))*1.2.LT.ang_ent(i)-ang_ent(i-1)) then
h=1
end if
end do
if (h.EQ.0) then
do num_posicion=1,2
call fctini(num_posicion)
end do
do num_posicion=control(1)-1,control(1)
call fctfin(num_posicion)
end do
do num_posicion=3,control(1)-2
call fctmed(num_posicion)
end do
else
do num_posicion=1,2
call fctini(num_posicion)
end do
do num_posicion=3,h-2
call fctmed(num_posicion)
end do
do num_posicion=h-1,h
call fctfin(num_posicion)
end do
call fctini(h+1)
do num_posicion=h+2,control(1)-2
call fctmed(num_posicion)
end do
do num_posicion=control(1)-1,control(1)
call fctfin(num_posicion)
end do
end if
subroutine fctfin(num_posicion)
h=ang_ent(num_posicion)-ang_ent(num_posicion-1)
vel_barra(num_posicion)=(11*ang_barra(num_posicion)
-18*ang_barra(num_posicion-1)+9*ang_barra(num_posicion-2)
-2*ang_barra(num_posicion-3))/(6*h)
end subroutine fctfin
subroutine fctmed(num_posicion)
h=(ang_ent(num_posicion+2)-ang_ent(num_posicion-2))/4
vel_barra(num_posicion)=(-ang_barra(num_posicion+2)
+8*ang_barra(num_posicion+1)-8*ang_barra(num_posicion-1)
+ang_barra(num_posicion-2))/(12*h)
end subroutine fctmed
retlog=dlginit(eleg_mov,dial)
retlog=dlgset(dial,w,.true.)
retlog=dlgset(dial,A,.false.)
result=dlgmodal(dial)
retlog=dlgget(dial,w,chequeador)
call dlguninit(dial)
if (chequeador) then
retlog=dlginit(cond_ini2,dial2)
retlog=dlgset(dial2,veloc,"1")
result=dlgmodal(dial2)
retlog=dlgget(dial2,veloc,in)
call dlguninit(dial2)
read(in,*) var_ent
var_ent=abs(var_ent)
movt=2
else
retlog=dlginit(cond_ini1,dial1)
retlog=dlgset(dial1,acel,"1")
result=dlgmodal(dial1)
retlog=dlgget(dial1,acel,in)
call dlguninit(dial1)
read(in,*) var_ent
var_ent=abs(var_ent)
movt=1
end if
El programa llama ventanas creadas con la función “dialog box” donde saca valores
introducidas por el usuario y que serán utilizadas luego. Aquí siguen estas ventanas.
El coeficiente de influencia es :
dϕ dϕ dt
= ⋅
dθ dt dθ
Se calcula :
dθ
dt
dϕ
dt
do i=1,control(1)
if (vit(i).gt.vmax) then
vmax=vit(i)
end if
if (vit(i).lt.vmin) then
vmin=vit(i)
end if
end do
do i=1, n
x(i) = ang_ent(i)
a(i) = vit(i)
end do
do i=1, n-1
h(i) = x(i+1) - x(i)
end do
do i=2, n-1
alpha(i) = 3 / h(i) * (a(i+1) - a(i)) - 3 / h(i-1) * (a(i) - a(i-1))
end do
l(1) = 1
nu(1) = 0
z(1) = 0
do i=2, n-1
l(i) = 2 * (x(i+1) - x(i-1)) - h(i-1) * nu(i-1)
nu(i) = h(i) / l(i)
z(i) = (alpha(i) - h(i-1) * z(i-1)) / l(i)
end do
l(n) = 1
z(n) = 0
c(n) = 0
do j=n-1, 1, -1
c(j) = z(j) - nu(j) * c(j+1)
b(j) = (a(j+1) - a(j)) / h(j) - h(j) * (c(j+1) + 2 * c(j)) / 3
d(j) = (c(j+1) - c(j)) / (3 * h(j))
end do
do i=1,nb_pts-1
ptx(i)=ang_mini+(ang_maxi-ang_mini)*(i-1)/(nb_pts-1)
s=1
do j=2,control(1)-1
if (ptx(i).gt.ang_ent(j).and.ptx(i).le.ang_ent(j+1)) then
s=j
end if
end do
pty(i)=a(s)+b(s)*(ptx(i)-x(s))+c(s)*(ptx(i)-x(s))**2+d(s)*(ptx(i)-x(s))**3
end do
s=control(1)-1
ptx(nb_pts)=ang_maxi
pty(nb_pts)=a(s)+b(s)*(ptx(i)-x(s))+c(s)*(ptx(i)-x(s))**2+d(s)*(ptx(i)-x(s))**3
Open(Unit=15,File='User',Title='diagrama de velocidades')
config15.numxpixels=(configfw.numxpixels*0.7)
config15.numypixels=(configfw.numypixels*0.7)
10 ifun=focusqq(15)!la traigo delante y pinto en ella
status=SETWINDOWCONFIG(config15)
If(.NOT.status) Goto 10
winfo15.x=0
winfo15.y=0
estado=SETWSIZEQQ(15,winfo15)
if (vmax.gt.0.AND.vmin.gt.0) then
vmin=0
end if
if (vmax.lt.0.AND.vmin.lt.0) then
vmax=0
end if
los ejes,
las flechas,
los títulos de los ejes,
los valores extremos,
los colores...
wx1=ang_mini-.1*(ang_maxi-ang_mini)
wy1=vmax+.3*abs(vmax-vmin)
wx2=ang_maxi+.25*(ang_maxi-ang_mini)
wy2=vmin-.2*abs(vmax-vmin)
dibuja=SETCOLORRGB(#ffffff)
call moveto_w(ang_mini,cero,wxy )
ifun=lineto_w(ang_maxi+.05*(ang_maxi-ang_mini),cero)
ifun=lineto_w(ang_maxi+.03*(ang_maxi-ang_mini),.03*abs(vmax-vmin))
call moveto_w(ang_maxi+.05*(ang_maxi-ang_mini),cero,wxy)
ifun=lineto_w(ang_maxi+.03*(ang_maxi-ang_mini),-.03*abs(vmax-vmin))
call moveto_w(ang_mini,vmin,wxy)
ifun=lineto_w(ang_mini,vmax+.1*abs(vmax-vmin))
ifun=lineto_w(ang_mini-.015*(ang_maxi-ang_mini),vmax+.05*abs(vmax-vmin))
call moveto_w(ang_mini,vmax+.1*abs(vmax-vmin),wxy)
ifun=lineto_w(ang_mini+.015*(ang_maxi-ang_mini),vmax+.05*abs(vmax-vmin))
ifun=focusqq(15)
res=setactiveqq(15)
numfonts=initializefonts()
fontnum=setfont('t''Arial''h14w8')
ifun=setcolor(15)
call moveto_w(ang_mini-.06*(ang_maxi-ang_mini),vmax+.18*abs(vmax-vmin),wxwy)
call outgtext('Velocidad')
call moveto_w(ang_maxi+.065*(ang_maxi-ang_mini),.11*abs(vmax-vmin),wxwy)
call outgtext('angulo')
call moveto_w(ang_maxi+.07*(ang_maxi-ang_mini),.04*abs(vmax-vmin),wxwy)
call outgtext('barra')
call moveto_w(ang_maxi+.06*(ang_maxi-ang_mini),-.03*abs(vmax-vmin),wxwy)
call outgtext('entrada')
call moveto_w (ang_mini-.09*(ang_maxi-ang_mini),vmax+.03*abs(vmax-vmin),wxwy)
write (y1,'(f5.2)')vmax
call outgtext (y1)
Hay que notar que el eje de las abscisas es graduado con valores crecientes de la
izquierda hasta la derecha y que el eje de las ordenadas es graduado con valores
crecientes de abajo arriba.
ifun=setcolor(10)
call moveto_w(ptx(1),pty(1),wxy)
if (control(1).gt.1) then
do i=2,nb_pts
result=lineto_w(ptx(i),pty(i))
call moveto_w(ptx(i),pty(i),wxy)
end do
end if
2. Seleccionar :
/ File / New...
Se abre una ventana,
3. Seleccionar :
Project Workspace
OK,
Se abre una ventana,
6. Seleccionar :
/ Insert / Files into Project...
Se abre una ventana,
8. Seleccionar :
/ Build / Build nombre.exe
9. Seleccionar :
/ Build / Execute nombre.exe
6. Empezar el análisis :
Seleccionar / Análisis / velocidades,
o / Análisis / aceleraciones.
OK.
9. Datos :
Aquí se introduce el módulo de la velocidad o de la aceleración de la barra de
entrada.
Hay que saber que este módulo es siempre positivo porque el sentido fue dado
elogiando el incremento positivo o negativo al principio (/ Problemas de Posición /
Posiciones sucesivas). Si el usuario introduce un valor negativo, sólo será considerado
el módulo.
OK.
10. Gráfico :
Se abre una ventana con el gráfico de la velocidad o de la aceleración de la barra
estudiada en función del ángulo de la barra de entrada.
Dos ejes :
Cuatro valores :
Para leer bien el gráfico, hay que saber que el ángulo de la barra de entrada tiene
valores crecientes de la izquierda hasta la derecha. Así, aun cuando el ángulo tome
valores decrecientes respecto a la horizontal en el tiempo, los ángulos se representan por
valores crecientes de la izquierda hasta la derecha.
Incremento : -1
Velocidad constante
Hay que notar que los valores calculados con el método de los coeficientes de influencia
son los valores antes de la interpolación con los splines cúbicos (que sale demasiados
puntos para comparar bien).
Por eso, los dos métodos son factibles. Para elegir uno de los dos, hay que saber
cual es el más sencillo para el desarrollo futuro del programa.
10. LIMITACIONES
Para utilizar bien el programa y mejorarlo en el futuro, hay que conocer los
límites.
El programa permite analizar una barra cada vez que esta ejecutado.
11. CONCLUSIÓN
programación.
Para mi, este proyecto fue muy interesante. Me permití aprender un lenguaje
informático, hacer un trabajo en grupo (ya que muchos alumnos trabajaban en diferentes
partes del programa) y pasar el obstáculo del idioma.
12. BIBLIOGRAFÍA
Aquí siguen referencias de libros y revistas para familiarizarse con varios temas
o ahondarlos.
Fortran :
Programmer en Fortran 90
Claude Delannoy
Eyrolles
Mechanics of Machines
Samuel Doughty
Wiley
Numerical Analysis
Richard L Burden
J Douglas Faires
13. ANEXOS
!*********************************************************************
*************!
!*********************************************************************
*************!
! Subrutina vitesses
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine vitesses(bar_diag)
use tipos
use msimsl
use msflib
use influencia
type(element) elemento
type(wxycoord) punto1,punto2
real*8 xa,ya,xb,yb,ang
real*8, allocatable::tempo1(:),tempo2(:),tempo3(:),t(:)
integer(4)
h,bar_diag,num_posicion,i,ordenbarra,ierror,num_nudos,num_apoyos,num_p
arp,apoyos(200)
logical acabar
allocate(vel_barra(control(1)),ang_ent(control(1)),ang_barra(con
trol(1)),tempo1(control(1)),tempo2(control(1)),tempo3(control(1)),t(co
ntrol(1)),vit(control(1)),stat=ierror)
if(ierror.ne.0)then
deallocate(vel_barra,ang_ent,ang_barra,tempo1,tempo2,tempo3,t,vi
t,stat=ierror)
allocate
(vel_barra(control(1)),ang_ent(control(1)),tempo1(control(1)),tempo2(c
ontrol(1)),tempo3(control(1)),ang_barra(control(1)),t(control(1)),vit(
control(1)),stat=ierror)
end if
!
!
! Cual es el numero de la barra seleccionada
!
!
!
call
transformacion(num_barras,num_nudos,num_apoyos,num_parp,nudos,barras,a
poyos)
write(10,*)'PARA FINALIZAR PULSE EL BOTÓN DERECHO DEL
RATÓN'
call tocarbarra(elemento,ordenbarra,punto1,punto2,acabar)
!
!
! Numero de la barra seleccionada
!
!
!
bar_diag=0
do i=1,num_barras
if
((nudos(barras(i,1),1).eq.punto1%wx).and.(nudos(barras(i,1),2).eq.punt
o1%wy)) then
if
((nudos(barras(i,2),1).eq.punto2%wx).and.(nudos(barras(i,2),2).eq.punt
o2%wy)) then
bar_diag=i
end if
end if
end do
do j=1,num_barras
if
((nudos(barras(j,1),1).eq.punto2%wx).and.(nudos(barras(j,1),2).eq.punt
o2%wy)) then
if
((nudos(barras(j,2),1).eq.punto1%wx).and.(nudos(barras(j,2),2).eq.punt
o1%wy)) then
bar_diag=j
end if
end if
end do
!
!
! ¿Cual es la barra de entrada?
!
!
!
bar_ent=entradas(1)%barra
!
!
! Calculo del ángulo de la barra de entrada en cada
posición !
!
!
do num_posicion=1,control(1)
xa=pto_coord(barras(bar_ent,1))%x(num_posicion)
ya=pto_coord(barras(bar_ent,1))%y(num_posicion)
xb=pto_coord(barras(bar_ent,2))%x(num_posicion)
yb=pto_coord(barras(bar_ent,2))%y(num_posicion)
call calcular_angulo(xa,ya,xb,yb,ang)
! Llamada de la función que transforme las coordenadas
!
! de las extremidades de la barra en un ángulo respecto a la
horizontal !
ang_ent(num_posicion)=ang
end do
!
!
! Cálculo de los angulos extremos de la barra de entrada
!
!
!
ang_maxi=ang_ent(1)
ang_mini=ang_ent(1)
do i=1,control(1)
if (ang_ent(i).gt.ang_maxi) then
ang_maxi=ang_ent(i)
end if
if (ang_ent(i).lt.ang_mini) then
ang_mini=ang_ent(i)
end if
end do
!
!
! Cálculo del ángulo de la barra seleccionada en cada
posición !
!
!
do num_posicion=1,control(1)
xa=pto_coord(barras(bar_diag,1))%x(num_posicion)
ya=pto_coord(barras(bar_diag,1))%y(num_posicion)
xb=pto_coord(barras(bar_diag,2))%x(num_posicion)
yb=pto_coord(barras(bar_diag,2))%y(num_posicion)
call calcular_angulo2(xa,ya,xb,yb,ang)
ang_barra(num_posicion)=ang
end do
!
!
! Arreglo en orden creciente de los ángulos
!
! en función de la barra de entrada
!
!
!
if (entradas(num_entradas)%incremento.LT.0) then
do i=1,control(1)
tempo1(i)=ang_ent(control(1)+1-i)
tempo2(i)=ang_barra(control(1)+1-i)
end do
do i=1,control(1)
ang_ent(i)=tempo1(i)
ang_barra(i)=tempo2(i)
end do
end if
!
!
! Cálculo de los coeficientes de influencia de las
velocidades !
!
!
h=0
do i=2,control(1)-1
if (ang_ent(i+1)-ang_ent(i).GT.(ang_ent(i)-ang_ent(i-1))*1.2
.OR. (ang_ent(i+1)-ang_ent(i))*1.2.LT.ang_ent(i)-ang_ent(i-1)) then
h=1
end if
end do
if (h.EQ.0) then
do num_posicion=1,2
call fctini(num_posicion)
end do
do num_posicion=control(1)-1,control(1)
call fctfin(num_posicion)
end do
do num_posicion=3,control(1)-2
call fctmed(num_posicion)
end do
else
do num_posicion=1,2
call fctini(num_posicion)
end do
do num_posicion=3,h-2
call fctmed(num_posicion)
end do
do num_posicion=h-1,h
call fctfin(num_posicion)
end do
call fctini(h+1)
do num_posicion=h+2,control(1)-2
call fctmed(num_posicion)
end do
do num_posicion=control(1)-1,control(1)
call fctfin(num_posicion)
end do
end if
!
!
! Se pide la ley de entrada desde una pantallita
!
!
!
call ley_entrada(movt,var_ent)
!
!
! Cálculo de las velocidades
!
!
!
if (movt.eq.1) then
do i=1,control(1)
t(i)=abs(sqrt(2*(ang_ent(i)-ang_ent(1))/var_ent))
end do
if (entradas(num_entradas)%incremento.lt.0) then
do i=1,control(1)
tempo3(i)=t(control(1)+1-i)
end do
do i=1,control(1)
t(i)=tempo3(i)
end do
end if
do i=1,control(1)
vit(i)=vel_barra(i)*var_ent*t(i)
if (entradas(num_entradas)%incremento.lt.0) then
vit(i)=-vit(i)
end if
end do
else
do i=1,control(1)
vit(i)=vel_barra(i)*var_ent
if (entradas(num_entradas)%incremento.lt.0) then
vit(i)=-vit(i)
end if
end do
end if
!
!
! Calculo de las velocidades extremas de la barra estudiada
!
!
!
vmax=vit(1)
vmin=vit(1)
do i=1,control(1)
if (vit(i).gt.vmax) then
vmax=vit(i)
end if
if (vit(i).lt.vmin) then
vmin=vit(i)
end if
end do
!
!
! Se llama la subrutina de interpolación
!
!
!
call interpolacion()
!*********************************************************************
*************!
!*********************************************************************
*************!
! SUBRUTINA PARA DIBUJAR EL DIAGRAMA DE VELOCIDADES
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine diag_vit()
use tipos
use msimsl
use msflib
use influencia
type(windowconfig) config15,configfw
type(qwinfo)winfo15,winfofw
type(wxycoord) wxy
logical status,estado
Real*8 wx1,wy1,wx2,wy2
integer(4) i,bar_diag,result
real*8 :: cero=0
!
!
! Se llama la subrutina vitesses
!
!
!
call vitesses(bar_diag)
!
!
! Características de la ventana donde se dibuja el
gráfico !
!
!
estado=GETWSIZEQQ(QWIN$FRAMEWINDOW,QWIN$SIZEMAX,winfofw)
status=GETWINDOWCONFIG(configfw)
Open(Unit=15,File='User',Title='diagrama de velocidades')
config15.numxpixels=(configfw.numxpixels*0.7)
config15.numypixels=(configfw.numypixels*0.7)
10 ifun=focusqq(15) !la traigo delante y pinto en
ella
status=SETWINDOWCONFIG(config15)
If(.NOT.status) Goto 10
winfo15.x=0
winfo15.y=0
estado=SETWSIZEQQ(15,winfo15)
!
!
! Características del gráfico
!
!
!
if (vmax.gt.0.AND.vmin.gt.0) then
vmin=0
end if
if (vmax.lt.0.AND.vmin.lt.0) then
vmax=0
end if
wx1=ang_mini-.1*(ang_maxi-ang_mini)
wy1=vmax+.3*abs(vmax-vmin)
wx2=ang_maxi+.25*(ang_maxi-ang_mini)
wy2=vmin-.2*abs(vmax-vmin)
ifun=focusqq(15)
status=SETWINDOW(.TRUE.,(wx1),(wy1),(wx2),(wy2))
!
!
! dibujo los ejes
!
!
!
dibuja=SETCOLORRGB(#ffffff)
call moveto_w(ang_mini,cero,wxy )
ifun=lineto_w(ang_maxi+.05*(ang_maxi-ang_mini),cero)
ifun=lineto_w(ang_maxi+.03*(ang_maxi-ang_mini),.03*abs(vmax-
vmin))
call moveto_w(ang_maxi+.05*(ang_maxi-ang_mini),cero,wxy)
ifun=lineto_w(ang_maxi+.03*(ang_maxi-ang_mini),-.03*abs(vmax-
vmin))
call moveto_w(ang_mini,vmin,wxy)
ifun=lineto_w(ang_mini,vmax+.1*abs(vmax-vmin))
ifun=lineto_w(ang_mini-.015*(ang_maxi-
ang_mini),vmax+.05*abs(vmax-vmin))
call moveto_w(ang_mini,vmax+.1*abs(vmax-vmin),wxy)
ifun=lineto_w(ang_mini+.015*(ang_maxi-
ang_mini),vmax+.05*abs(vmax-vmin))
!
!
! Se llama la subrutina que permite escribir en la ventana
!
!
!
call escribir
!
!
! Trazado de la curva
!
!
!
ifun=setcolor(10)
call moveto_w(ptx(1),pty(1),wxy)
if (control(1).gt.1) then
do i=2,nb_pts
result=lineto_w(ptx(i),pty(i))
call moveto_w(ptx(i),pty(i),wxy)
end do
end if
call espera()
!*********************************************************************
*************!
!*********************************************************************
*************!
! subroutina escribir
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine escribir
use influencia
use tipos
use msflib
type (wxycoord) wxwy
integer(2) numfonts,fontnum
integer(4) res
character (25) y1,y2,x1,x2
ifun=focusqq(15)
res=setactiveqq(15)
numfonts=initializefonts()
fontnum=setfont('t''Arial''h14w8')
ifun=setcolor(15)
call moveto_w(ang_mini-.06*(ang_maxi-
ang_mini),vmax+.18*abs(vmax-vmin),wxwy)
call outgtext('Velocidad')
call moveto_w(ang_maxi+.065*(ang_maxi-
ang_mini),.11*abs(vmax-vmin),wxwy)
call outgtext('angulo')
call moveto_w(ang_maxi+.07*(ang_maxi-
ang_mini),.04*abs(vmax-vmin),wxwy)
call outgtext('barra')
call moveto_w(ang_maxi+.06*(ang_maxi-ang_mini),-
.03*abs(vmax-vmin),wxwy)
call outgtext('entrada')
call moveto_w (ang_mini-.09*(ang_maxi-
ang_mini),vmax+.03*abs(vmax-vmin),wxwy)
write (y1,'(f7.2)')vmax
call outgtext (y1)
call moveto_w (ang_mini-.09*(ang_maxi-
ang_mini),vmin+.03*abs(vmax-vmin),wxwy)
write (y2,'(f7.2)')vmin
call outgtext (y2)
call moveto_w (ang_mini-.04*(ang_maxi-ang_mini),-
.04*abs(vmax-vmin),wxwy)
write (x1,'(f7.2)')ang_mini
call outgtext (x1)
call moveto_w (ang_maxi-.04*(ang_maxi-ang_mini),-
.04*abs(vmax-vmin),wxwy)
write (x2,'(f7.2)')ang_maxi
call outgtext (x2)
!*********************************************************************
*************!
!*********************************************************************
*************!
! Interpolación con el método de los trazadores
cúbicos !
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine interpolacion ()
use tipos
use msimsl
use msflib
use influencia
integer(4) i,n,j,s,ierror
real*8, dimension (1:control(1)) :: l, z, x, c, h , nu, alpha, a, b, d
allocate(ptx(nb_pts),pty(nb_pts),stat=ierror)
if(ierror.ne.0)then
deallocate(ptx,pty)
allocate (ptx(nb_pts),pty(nb_pts),stat=ierror)
end if
n=control(1)
do i=1, n
x(i) = ang_ent(i)
a(i) = vit(i)
end do
do i=1, n-1
h(i) = x(i+1) - x(i)
end do
do i=2, n-1
alpha(i) = 3 / h(i) * (a(i+1) - a(i)) - 3 / h(i-1) * (a(i) -
a(i-1))
end do
l(1) = 1
nu(1) = 0
z(1) = 0
do i=2, n-1
l(i) = 2 * (x(i+1) - x(i-1)) - h(i-1) * nu(i-1)
nu(i) = h(i) / l(i)
z(i) = (alpha(i) - h(i-1) * z(i-1)) / l(i)
end do
l(n) = 1
z(n) = 0
c(n) = 0
do j=n-1, 1, -1
c(j) = z(j) - nu(j) * c(j+1)
b(j) = (a(j+1) - a(j)) / h(j) - h(j) * (c(j+1) + 2 * c(j)) / 3
d(j) = (c(j+1) - c(j)) / (3 * h(j))
end do
do i=1,nb_pts-1
ptx(i)=ang_mini+(ang_maxi-ang_mini)*(i-1)/(nb_pts-1)
s=1
do j=2,control(1)-1
if (ptx(i).gt.ang_ent(j).and.ptx(i).le.ang_ent(j+1)) then
s=j
end if
end do
pty(i)=a(s)+b(s)*(ptx(i)-x(s))+c(s)*(ptx(i)-
x(s))**2+d(s)*(ptx(i)-x(s))**3
end do
s=control(1)-1
ptx(nb_pts)=ang_maxi
pty(nb_pts)=a(s)+b(s)*(ptx(i)-x(s))+c(s)*(ptx(i)-
x(s))**2+d(s)*(ptx(i)-x(s))**3
!
!
! Función para diferenciar los puntos 1 y 2
!
!
!
subroutine fctini(num_posicion)
use influencia
real*8 h
h=ang_ent(num_posicion+1)-ang_ent(num_posicion)
vel_barra(num_posicion)=(2*ang_barra(num_posicion+3)-
9*ang_barra(num_posicion+2)+18*ang_barra(num_posicion+1)-
11*ang_barra(num_posicion))/(6*h)
end subroutine fctini
!
! Función para diferenciar los puntos 3 a n-2
!
subroutine fctfin(num_posicion)
use influencia
real*8 h
h=ang_ent(num_posicion)-ang_ent(num_posicion-1)
vel_barra(num_posicion)=(11*ang_barra(num_posicion)-
18*ang_barra(num_posicion-1)+9*ang_barra(num_posicion-2)-
2*ang_barra(num_posicion-3))/(6*h)
end subroutine fctfin
!
! Función para diferenciar los puntos n-1 y n
subroutine fctmed(num_posicion)
use influencia
real*8 h
h=(ang_ent(num_posicion+2)-ang_ent(num_posicion-2))/4
vel_barra(num_posicion)=(-
ang_barra(num_posicion+2)+8*ang_barra(num_posicion+1)-
8*ang_barra(num_posicion-1)+ang_barra(num_posicion-2))/(12*h)
end subroutine fctmed
!*********************************************************************
*************!
!*********************************************************************
*************!
! SUBRUTINA PARA LA LEY DE ENTRADA
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine ley_entrada(movt,var_ent)
use dialogm
use tipos
include 'resource.fd'
type(dialog) dial,dial1,dial2
real*8 var_ent
logical chequeador
character*25 in
retlog=dlginit(eleg_mov,dial)
retlog=dlgset(dial,w,.true.)
retlog=dlgset(dial,A,.false.)
result=dlgmodal(dial)
retlog=dlgget(dial,w,chequeador)
call dlguninit(dial)
if (chequeador) then
retlog=dlginit(cond_ini2,dial2)
retlog=dlgset(dial2,veloc,"1")
result=dlgmodal(dial2)
retlog=dlgget(dial2,veloc,in)
call dlguninit(dial2)
read(in,*) var_ent
var_ent=abs(var_ent)
movt=2 ! movt=2 significa velocidad constante
else
retlog=dlginit(cond_ini1,dial1)
retlog=dlgset(dial1,acel,"1")
result=dlgmodal(dial1)
retlog=dlgget(dial1,acel,in)
call dlguninit(dial1)
read(in,*) var_ent
var_ent=abs(var_ent)
movt=1 ! movt=1 significa aceleracion constante
end if
!*********************************************************************
*************!
!*********************************************************************
*************!
! Subrutina vitesses
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine acceleration(bar_diag)
use tipos
use msimsl
use msflib
use influencia
type(element) elemento
type(wxycoord) punto1,punto2
real*8 xa,ya,xb,yb,ang
real*8, allocatable::tempo1(:),tempo2(:),tempo3(:),t(:)
integer(4)
h,bar_diag,num_posicion,i,ordenbarra,ierror,num_nudos,num_apoyos,num_p
arp,apoyos(200)
logical acabar
allocate(acel_barra(control(1)),ang_ent(control(1)),ang_barra(co
ntrol(1)),tempo1(control(1)),tempo2(control(1)),tempo3(control(1)),t(c
ontrol(1)),accel(control(1)),stat=ierror)
if(ierror.ne.0)then
deallocate(acel_barra,ang_ent,ang_barra,tempo1,tempo2,tempo3,t,a
ccel,stat=ierror)
allocate
(acel_barra(control(1)),ang_ent(control(1)),tempo1(control(1)),tempo2(
control(1)),tempo3(control(1)),ang_barra(control(1)),t(control(1)),acc
el(control(1)),stat=ierror)
end if
!
!
! Cual es el numero de la barra seleccionada
!
!
!
call
transformacion(num_barras,num_nudos,num_apoyos,num_parp,nudos,barras,a
poyos)
write(10,*)'PARA FINALIZAR PULSE EL BOTÓN DERECHO DEL
RATÓN'
call tocarbarra(elemento,ordenbarra,punto1,punto2,acabar)
!
!
! Numero de la barra seleccionada
!
!
!
bar_diag=0
do i=1,num_barras
if
((nudos(barras(i,1),1).eq.punto1%wx).and.(nudos(barras(i,1),2).eq.punt
o1%wy)) then
if
((nudos(barras(i,2),1).eq.punto2%wx).and.(nudos(barras(i,2),2).eq.punt
o2%wy)) then
bar_diag=i
end if
end if
end do
do j=1,num_barras
if
((nudos(barras(j,1),1).eq.punto2%wx).and.(nudos(barras(j,1),2).eq.punt
o2%wy)) then
if
((nudos(barras(j,2),1).eq.punto1%wx).and.(nudos(barras(j,2),2).eq.punt
o1%wy)) then
bar_diag=j
end if
end if
end do
!
!
! ¿Cual es la barra de entrada?
!
!
!
bar_ent=entradas(1)%barra
!
!
! Calculo del ángulo de la barra de entrada en cada
posición !
!
!
do num_posicion=1,control(1)
xa=pto_coord(barras(bar_ent,1))%x(num_posicion)
ya=pto_coord(barras(bar_ent,1))%y(num_posicion)
xb=pto_coord(barras(bar_ent,2))%x(num_posicion)
yb=pto_coord(barras(bar_ent,2))%y(num_posicion)
call calcular_angulo(xa,ya,xb,yb,ang)
ang_ent(num_posicion)=ang
end do
!
!
! Cálculo de los angulos extremos de la barra de entrada
!
!
!
ang_maxi=ang_ent(1)
ang_mini=ang_ent(1)
do i=1,control(1)
if (ang_ent(i).gt.ang_maxi) then
ang_maxi=ang_ent(i)
end if
if (ang_ent(i).lt.ang_mini) then
ang_mini=ang_ent(i)
end if
end do
!
!
! Cálculo del ángulo de la barra seleccionada en cada
posición !
!
!
do num_posicion=1,control(1)
xa=pto_coord(barras(bar_diag,1))%x(num_posicion)
ya=pto_coord(barras(bar_diag,1))%y(num_posicion)
xb=pto_coord(barras(bar_diag,2))%x(num_posicion)
yb=pto_coord(barras(bar_diag,2))%y(num_posicion)
call calcular_angulo2(xa,ya,xb,yb,ang)
ang_barra(num_posicion)=ang
end do
!
!
! Arreglo en orden creciente de los ángulos
!
! en función de la barra de entrada
!
!
!
if (entradas(num_entradas)%incremento.LT.0) then
do i=1,control(1)
tempo1(i)=ang_ent(control(1)+1-i)
tempo2(i)=ang_barra(control(1)+1-i)
end do
do i=1,control(1)
ang_ent(i)=tempo1(i)
ang_barra(i)=tempo2(i)
end do
end if
!
!
! Cálculo de los coeficientes de influencia de las
velocidades !
!
!
h=0
do i=2,control(1)-1
if (ang_ent(i+1)-ang_ent(i).GT.(ang_ent(i)-ang_ent(i-1))*1.2
.OR. (ang_ent(i+1)-ang_ent(i))*1.2.LT.ang_ent(i)-ang_ent(i-1)) then
h=1
end if
end do
if (h.EQ.0) then
do num_posicion=1,2
call fctini2(num_posicion)
end do
do num_posicion=control(1)-1,control(1)
call fctfin2(num_posicion)
end do
do num_posicion=3,control(1)-2
call fctmed2(num_posicion)
end do
else
do num_posicion=1,2
call fctini2(num_posicion)
end do
do num_posicion=3,h-2
call fctmed2(num_posicion)
end do
do num_posicion=h-1,h
call fctfin2(num_posicion)
end do
call fctini2(h+1)
do num_posicion=h+2,control(1)-2
call fctmed2(num_posicion)
end do
do num_posicion=control(1)-1,control(1)
call fctfin2(num_posicion)
end do
end if
!
!
! Se pide la ley de entrada desde una pantallita
!
!
!
call ley_entrada(movt,var_ent)
!
!
! Cálculo de las velocidades
!
!
!
if (movt.eq.1) then
do i=1,control(1)
accel(i)=acel_barra(i)*var_ent
if (entradas(num_entradas)%incremento.lt.0) then
accel(i)=-accel(i)
end if
end do
else
do i=1,control(1)
accel(i)=0
end do
end if
!
!
! Calculo de las velocidades extremas de la barra estudiada
!
!
!
amax=accel(1)
amin=accel(1)
do i=1,control(1)
if (accel(i).gt.amax) then
amax=accel(i)
end if
if (accel(i).lt.amin) then
amin=accel(i)
end if
end do
!
!
! Se llama la subrutina de interpolación
!
!
!
call interpolacion2()
!*********************************************************************
*************!
!*********************************************************************
*************!
! SUBRUTINA PARA DIBUJAR EL DIAGRAMA DE VELOCIDADES
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine diag_acel()
use tipos
use msimsl
use msflib
use influencia
type(windowconfig) config15,configfw
type(qwinfo)winfo15,winfofw
type(wxycoord) wxy
logical status,estado
Real*8 wx1,wy1,wx2,wy2
integer(4) i,bar_diag,result
real*8 :: cero=0
!
!
! Se llama la subrutina vitesses
!
!
!
call acceleration(bar_diag)
!
!
! Características de la ventana donde se dibuja el
gráfico !
!
!
estado=GETWSIZEQQ(QWIN$FRAMEWINDOW,QWIN$SIZEMAX,winfofw)
status=GETWINDOWCONFIG(configfw)
Open(Unit=15,File='User',Title='diagrama de aceleraciones')
config15.numxpixels=(configfw.numxpixels*0.7)
config15.numypixels=(configfw.numypixels*0.7)
10 ifun=focusqq(15) !la traigo delante y pinto en
ella
status=SETWINDOWCONFIG(config15)
If(.NOT.status) Goto 10
winfo15.x=0
winfo15.y=0
estado=SETWSIZEQQ(15,winfo15)
!
!
! Características del gráfico
!
!
!
if (amax.gt.0.AND.amin.gt.0) then
amin=0
end if
if (amax.lt.0.AND.amin.lt.0) then
amax=0
end if
wx1=ang_mini-.1*(ang_maxi-ang_mini)
wy1=amax+.3*abs(amax-amin)
wx2=ang_maxi+.25*(ang_maxi-ang_mini)
wy2=amin-.2*abs(amax-amin)
ifun=focusqq(15)
status=SETWINDOW(.TRUE.,(wx1),(wy1),(wx2),(wy2))
!
!
! dibujo los ejes
!
!
!
dibuja=SETCOLORRGB(#ffffff)
call moveto_w(ang_mini,cero,wxy )
ifun=lineto_w(ang_maxi+.05*(ang_maxi-ang_mini),cero)
ifun=lineto_w(ang_maxi+.03*(ang_maxi-ang_mini),.03*abs(amax-
amin))
call moveto_w(ang_maxi+.05*(ang_maxi-ang_mini),cero,wxy)
ifun=lineto_w(ang_maxi+.03*(ang_maxi-ang_mini),-.03*abs(amax-
amin))
call moveto_w(ang_mini,amin,wxy)
ifun=lineto_w(ang_mini,amax+.1*abs(amax-amin))
ifun=lineto_w(ang_mini-.015*(ang_maxi-
ang_mini),amax+.05*abs(amax-amin))
call moveto_w(ang_mini,amax+.1*abs(amax-amin),wxy)
ifun=lineto_w(ang_mini+.015*(ang_maxi-
ang_mini),amax+.05*abs(amax-amin))
!
!
! Se llama la subrutina que permite escribir en la ventana
!
!
!
call escribir2
!
!
! Trazado de la curva
!
!
!
ifun=setcolor(10)
call moveto_w(ptx(1),pty(1),wxy)
if (control(1).gt.1) then
do i=2,nb_pts
result=lineto_w(ptx(i),pty(i))
call moveto_w(ptx(i),pty(i),wxy)
end do
end if
call espera()
!*********************************************************************
*************!
!*********************************************************************
*************!
! subroutina escribir2
!
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine escribir2
use influencia
use tipos
use msflib
type (wxycoord) wxwy
integer(2) numfonts,fontnum
integer(4) res
character (25) y1,y2,x1,x2
ifun=focusqq(15)
res=setactiveqq(15)
numfonts=initializefonts()
fontnum=setfont('t''Arial''h14w8')
ifun=setcolor(15)
call moveto_w(ang_mini-.06*(ang_maxi-
ang_mini),amax+.18*abs(amax-amin),wxwy)
call outgtext('Aceleracion')
call moveto_w(ang_maxi+.065*(ang_maxi-
ang_mini),.11*abs(amax-amin),wxwy)
call outgtext('angulo')
call moveto_w(ang_maxi+.07*(ang_maxi-
ang_mini),.04*abs(amax-amin),wxwy)
call outgtext('barra')
call moveto_w(ang_maxi+.06*(ang_maxi-ang_mini),-
.03*abs(amax-amin),wxwy)
call outgtext('entrada')
call moveto_w (ang_mini-.09*(ang_maxi-
ang_mini),amax+.03*abs(amax-amin),wxwy)
write (y1,'(f7.2)')amax
call outgtext (y1)
call moveto_w (ang_mini-.09*(ang_maxi-
ang_mini),amin+.03*abs(amax-amin),wxwy)
write (y2,'(f7.2)')amin
call outgtext (y2)
call moveto_w (ang_mini-.04*(ang_maxi-ang_mini),-
.04*abs(amax-amin),wxwy)
write (x1,'(f7.2)')ang_mini
call outgtext (x1)
call moveto_w (ang_maxi-.04*(ang_maxi-ang_mini),-
.04*abs(amax-amin),wxwy)
write (x2,'(f7.2)')ang_maxi
call outgtext (x2)
!*********************************************************************
*************!
!*********************************************************************
*************!
! Interpolación con el método de los trazadores
cúbicos !
!*********************************************************************
*************!
!*********************************************************************
*************!
subroutine interpolacion2 ()
use tipos
use msimsl
use msflib
use influencia
integer(4) i,n,j,s,ierror
real*8, dimension (1:control(1)) :: l, z, x, c, h , nu, alpha, a, b, d
allocate(ptx(nb_pts),pty(nb_pts),stat=ierror)
if(ierror.ne.0)then
deallocate(ptx,pty)
allocate (ptx(nb_pts),pty(nb_pts),stat=ierror)
end if
n=control(1)
do i=1, n
x(i) = ang_ent(i)
a(i) = accel(i)
end do
do i=1, n-1
h(i) = x(i+1) - x(i)
end do
do i=2, n-1
alpha(i) = 3 / h(i) * (a(i+1) - a(i)) - 3 / h(i-1) * (a(i) -
a(i-1))
end do
l(1) = 1
nu(1) = 0
z(1) = 0
do i=2, n-1
l(i) = 2 * (x(i+1) - x(i-1)) - h(i-1) * nu(i-1)
nu(i) = h(i) / l(i)
z(i) = (alpha(i) - h(i-1) * z(i-1)) / l(i)
end do
l(n) = 1
z(n) = 0
c(n) = 0
do j=n-1, 1, -1
c(j) = z(j) - nu(j) * c(j+1)
b(j) = (a(j+1) - a(j)) / h(j) - h(j) * (c(j+1) + 2 * c(j)) / 3
d(j) = (c(j+1) - c(j)) / (3 * h(j))
end do
!
! Tenemos la ecuación de la curva :
!
! Sj(x) = aj+ bj * (x - xj) + cj * (x - xj)^2 + dj * (x-xj)^3
!
! con j=1,...,n-1
do i=1,nb_pts-1
ptx(i)=ang_mini+(ang_maxi-ang_mini)*(i-1)/(nb_pts-1)
s=1
do j=2,control(1)-1
if (ptx(i).gt.ang_ent(j).and.ptx(i).le.ang_ent(j+1)) then
s=j
end if
end do
pty(i)=a(s)+b(s)*(ptx(i)-x(s))+c(s)*(ptx(i)-
x(s))**2+d(s)*(ptx(i)-x(s))**3
end do
s=control(1)-1
ptx(nb_pts)=ang_maxi
pty(nb_pts)=a(s)+b(s)*(ptx(i)-x(s))+c(s)*(ptx(i)-
x(s))**2+d(s)*(ptx(i)-x(s))**3
!*********************************************************************
*************!
!*********************************************************************
*************!
! functiones de diferencias numérica
!
!*********************************************************************
*************!
!*********************************************************************
*************!
!
! Función para diferenciar los puntos 1 y 2
subroutine fctini2(num_posicion)
use influencia
real*8 h
h=ang_ent(num_posicion+1)-ang_ent(num_posicion)
acel_barra(num_posicion)=(-
ang_barra(num_posicion+3)+4*ang_barra(num_posicion+2)-
5*ang_barra(num_posicion+1)+2*ang_barra(num_posicion))/(h**2)
end subroutine fctini2
!
! Función para diferenciar los puntos 3 a n-2
!
subroutine fctfin2(num_posicion)
use influencia
real*8 h
h=ang_ent(num_posicion)-ang_ent(num_posicion-1)
acel_barra(num_posicion)=(2*ang_barra(num_posicion)-
5*ang_barra(num_posicion-1)+4*ang_barra(num_posicion-2)-
ang_barra(num_posicion-3))/(h**2)
end subroutine fctfin2
!
! Función para diferenciar los puntos n-1 y n
subroutine fctmed2(num_posicion)
use influencia
real*8 h
h=(ang_ent(num_posicion+2)-ang_ent(num_posicion-2))/4
acel_barra(num_posicion)=(-
ang_barra(num_posicion+2)+16*ang_barra(num_posicion+1)-
30*ang_barra(num_posicion)+16*ang_barra(num_posicion-1)-
ang_barra(num_posicion-2))/(12*h**2)
end subroutine fctmed2