Advertisement
Thomas_Lillieskold

Natrural Cubic Spline

Dec 6th, 2022
729
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. !Este Programa fue realizado por Lillieskold, Thomas Enrique
  2. !Instituto Universitario Aeronautico - 2022
  3. !Docentes: Giovacchini, Juan Pablo; Weht, German
  4. !Asignatura: Computacion e Introduccion al Calculo Numerico
  5. !-------------------------------------------------------------------------------
  6.  
  7. !--------------------------DECLARACION DEL MODULO-------------------------------
  8. MODULE Datos
  9. !-----------------------------DATOS DE ENTRADA----------------------------------
  10.     INTEGER,PARAMETER::N_Puntos=26
  11.     INTEGER,PARAMETER::N_Nodos=N_Puntos-1
  12.  
  13. !------------------------VARIABLES DEL PROGRAMA---------------------------------
  14.  
  15.     REAL(8),DIMENSION(4*N_Nodos,4*N_Nodos)::Mat_Coef
  16.     REAL(8),DIMENSION(4*N_Nodos)::Mat_Indep
  17.     REAL(8),DIMENSION(4*N_Nodos)::Coeficiente
  18.     REAL(8),DIMENSION(2,4)::Mat_Inf
  19.     REAL(8),DIMENSION(2,4)::Mat_Sup
  20.     REAL(8),DIMENSION(4,8)::Mat_Int
  21.     REAL(8),DIMENSION(4)::Mat_Int_indep
  22.     REAL(8),DIMENSION(N_Puntos)::Xpoint
  23.     REAL(8),DIMENSION(N_Puntos)::Ypoint
  24.  
  25. !-------------------------------------------------------------------------------
  26. !PROCEDO A DECLARAR VARIABLES PARA ELIMINACION GAUSSIANA
  27.  
  28.     REAL(8),DIMENSION(4*N_Nodos,4*N_Nodos)::A
  29.     REAL(8),DIMENSION(4*N_Nodos)::B
  30.     REAL(8),DIMENSION(4*N_Nodos)::X
  31.     INTEGER N_Filas, N_Columnas
  32.  
  33. END MODULE
  34.  
  35. PROGRAM Spline_Cubico_Normal
  36.     USE DATOS
  37.     IMPLICIT NONE
  38.  
  39.     CALL Lectura_Datos_Par_Puntos
  40.     CALL Burbuja_Mejorado(Xpoint,Ypoint)
  41.     CALL Matrices_Externas
  42.     CALL Matriz_Coef_Indep
  43.     CALL Eliminacion_Gaussiana
  44.     CALL Dots_Graph
  45.     CALL Write_Outs
  46.  
  47. END PROGRAM
  48.  
  49. !SUBRUTINAS
  50.  
  51. !-------------------------------LECTURA DE DATOS--------------------------------
  52. Subroutine Lectura_Datos_Par_Puntos
  53.     USE Datos
  54.     IMPLICIT NONE
  55.     INTEGER I
  56.         OPEN (2,File="Coordenadas_Intrados.txt")
  57.         READ(2,*)
  58.         READ(2,*)
  59.         DO I=1,N_Puntos
  60.             READ(2,*)Xpoint(i),Ypoint(i)
  61.         END DO
  62. End Subroutine
  63. !-------------------------------------------------------------------------------
  64.  
  65. !--------------------------BURBUJA MEJORADO-------------------------------------
  66. SUBROUTINE Burbuja_Mejorado(Vector_x1,Vector_y1)
  67.     USE DATOS
  68.     IMPLICIT NONE
  69. REAL(8),DIMENSION(N_Puntos)::Vector_x1
  70. REAL(8),DIMENSION(N_Puntos)::Vector_y1
  71. REAL(8)Aux_x
  72. REAL(8)Aux_y
  73. LOGICAL ACCESO
  74. INTEGER I,J
  75.  
  76. Aux_x=0.d0
  77. Aux_y=0.d0
  78.  
  79. DO I=1,N_Puntos-1
  80.     ACCESO=.False.
  81.     DO J=1, N_Puntos-i
  82.         IF(Vector_x1(j)>Vector_x1(j+1))Then
  83.             !Pivoteo Vector x
  84.             Aux_x=Vector_x1(j)
  85.             Vector_x1(j)=Vector_x1(j+1)
  86.             Vector_x1(j+1)=Aux_x
  87.  
  88.             !Pivoteo Vector y
  89.             Aux_y=Vector_y1(j)
  90.             Vector_y1(j)=Vector_y1(j+1)
  91.             Vector_y1(j+1)=Aux_y
  92.  
  93.             Acceso=.True.
  94.         END IF
  95.     END DO
  96.         If(.not.(Acceso)) EXIT
  97. END DO
  98. END SUBROUTINE Burbuja_Mejorado
  99. !-------------------------------------------------------------------------------
  100.  
  101. !--------------------------MATRICES EXTERNAS------------------------------------
  102. SUBROUTINE Matrices_Externas
  103.     USE DATOS
  104.     IMPLICIT NONE
  105.     INTEGER J
  106.     Mat_Inf=0.d0
  107.     Mat_Sup=0.d0
  108.  
  109.     DO J=1,4
  110.         Mat_Inf(1,J)=Xpoint(1)**(4-j)
  111.         Mat_Sup(1,J)=Xpoint(N_Nodos+1)**(4-J)
  112.     END DO
  113.         Mat_Inf(2,1)=6.d0*Xpoint(1)
  114.         Mat_Sup(2,1)=6.d0*Xpoint(N_Nodos+1)
  115.         Mat_Inf(2,2)=2.d0
  116.         Mat_Sup(2,2)=2.d0
  117. END SUBROUTINE
  118. !-------------------------------------------------------------------------------
  119.  
  120. !-------------------------MATRIZ_COEF_INDEP-------------------------------------
  121. SUBROUTINE Matriz_Coef_Indep
  122.     USE DATOS
  123.     IMPLICIT NONE
  124.     INTEGER I,M                !Variables de control para la matriz de coeficientes
  125.  
  126.     Mat_Coef=0.d0
  127.     Mat_Indep=0.d0
  128.     M=1
  129.  
  130.     Mat_Coef(1:2,1:4)=Mat_Inf
  131.     Mat_Indep(1)=Ypoint(1)
  132.     Mat_Coef(4*N_Nodos-1:4*N_Nodos,4*N_Nodos-3:4*N_Nodos)=Mat_Sup
  133.     Mat_Indep(4*N_Nodos - 1)=Ypoint(N_Nodos+1)
  134.  
  135.     DO I=3, (4*N_Nodos)-2,4
  136.         M=M+1
  137.         CALL Matriz(Mat_Int,Mat_Int_indep,M)
  138.         Mat_Indep(i:i+3)=Mat_int_indep
  139.         Mat_Coef(i:i+3,i-2:i+5)=Mat_Int
  140.     END DO
  141. END SUBROUTINE
  142. !-------------------------------------------------------------------------------
  143.  
  144. !------------------------------MATRIZ_INTERNA-----------------------------------
  145. SUBROUTINE Matriz(Mat,Vec,M)
  146.     USE DATOS
  147.     IMPLICIT NONE
  148.     REAL(8),DIMENSION(4,8)::Mat
  149.     REAL(8),DIMENSION(4)::Vec
  150.     INTEGER J,M
  151.  
  152.     Mat=0.d0
  153.     Vec=0.d0
  154.  
  155.         DO J=1,4
  156.             Mat(1,J)=Xpoint(M)**(4-J)
  157.         END DO
  158.  
  159.         DO J=5,8
  160.             Mat(2,J)=Xpoint(M)**(8-J)
  161.         END DO
  162.  
  163.             Mat(3,1)=3*Xpoint(M)**2
  164.             Mat(3,2)=2*Xpoint(M)
  165.             Mat(3,3)=1.d0
  166.             Mat(3,5)= -Mat_Int(3,1)
  167.             Mat(3,6)= -Mat_Int(3,2)
  168.             Mat(3,7)= -Mat_Int(3,3)
  169.             Mat(4,1)=6*Xpoint(M)
  170.             Mat(4,2)=2.d0
  171.             Mat(4,5)= -Mat_Int(4,1)
  172.             Mat(4,6)= -Mat_Int(4,2)
  173.  
  174.             Vec(1)=Ypoint(m)
  175.             Vec(2)=Ypoint(m)
  176.  
  177. END SUBROUTINE
  178. !-------------------------------------------------------------------------------
  179.  
  180. !------------------------ELIMINACION_GAUSSIANA----------------------------------
  181. SUBROUTINE Eliminacion_Gaussiana
  182.     USE DATOS
  183.     IMPLICIT NONE
  184.  
  185.     !PROCEDO A ASIGNAR VALORES A LAS VARIABLES PARA ELIMINACION GAUSSIANA
  186.  
  187.     A=Mat_Coef
  188.     B=Mat_Indep
  189.     X=Coeficiente
  190.     N_Filas=4*N_Nodos
  191.     N_Columnas=4*N_Nodos
  192.  
  193.  
  194.     CALL Triangular_sup
  195.     CALL Retrosustitucion
  196.  
  197.  
  198.     Coeficiente=X
  199.  
  200. END SUBROUTINE
  201.  
  202. SUBROUTINE Triangular_sup
  203.     USE DATOS
  204.     IMPLICIT NONE
  205.     REAL(8)Multiplicador
  206.     INTEGER i,j,k
  207.     DO i= 1 , N_Filas-1
  208.         CALL PIVOTEO (i)
  209.         DO j= i+1 , N_Filas
  210.             Multiplicador= A(j,i)/A(i,i)
  211.             A(j,i)=0                        !Con esto me aseguro que las componentes a la izquierda de la diagonal sean cero
  212.             B(j)=B(j)-Multiplicador*B(i)
  213.             DO K= i+1 , N_Filas
  214.                 A(j,k)= A(j,k)-Multiplicador*A(i,k)
  215.             END DO
  216.         END DO
  217.     END DO
  218. END SUBROUTINE Triangular_sup
  219.  
  220. SUBROUTINE Pivoteo(Ref_Columna)
  221.     USE DATOS
  222.     IMPLICIT NONE
  223. REAL(8),DIMENSION(N_Columnas)::Aux
  224. REAL(8) Ref_Coef, Aux_B
  225. INTEGER Ref_Fila,Ref_Columna
  226. INTEGER j,k
  227.  
  228.     Ref_Coef=A(Ref_Columna,Ref_Columna)                     !Coeficiente de referencia -> DIAGONAL PRINCIPAL
  229.     Ref_Fila=Ref_Columna                                    !Variable que guarda la fila del coeficiente de referencia
  230.     DO j= Ref_Columna+1,N_Filas                               !Recorre el subvector -> El valor es i+1 debido a que me interesan los valores por debajo de la diagonal principal
  231.         IF (ABS(Ref_Coef)<ABS(A(j,Ref_Columna)))THEN
  232.             Ref_Coef=A(j,Ref_Columna)                      !Hago que el valor de referencia para la comparacion sea el mayor
  233.             Ref_Fila=j                                     !Fila en la cual esta el elemento de referencia
  234.         END IF
  235.     END DO                      !Cuando termina este bucle tengo en Ref_Fila la fila en la que se encuentra el valor maximo
  236.  
  237.     DO k=1,N_Columnas
  238.     Aux(k)= A(Ref_Columna,k)            !Guardo la fila de referencia inicial completa - !Uso Ref_Columna debido a que es igual a la fila que me interesa
  239.     END DO
  240.  
  241.     DO k=1,N_Columnas
  242.     A(Ref_Columna,k)=A(Ref_Fila,k)           !Reemplazo la fila de referencia inicial por la que tiene el coeficiente de valor mas elevado
  243.     END DO
  244.  
  245.     DO k=1,N_Columnas
  246.     A(Ref_Fila,k)=Aux(k)      !Reescribo la fila de referencia inicial en la posicion de la que tenia el coeficiente de valor mas elevado
  247.     END DO
  248.  
  249.     Aux_B=B(Ref_Fila)
  250.     B(Ref_Fila)=B(Ref_Columna)
  251.     B(Ref_Columna)=Aux_B
  252. END SUBROUTINE Pivoteo
  253.  
  254. SUBROUTINE Retrosustitucion
  255.     USE DATOS
  256.     IMPLICIT NONE
  257.     REAL(8)Producto
  258.     INTEGER I,J
  259.     DO i= N_Filas , 1 , -1
  260.     Producto=0.d0
  261.     DO j= i+1 , N_Filas
  262.         Producto= Producto + (A(i,j)*X(j))
  263.     END DO
  264.     X(i)=(B(i)-Producto)/A(i,i)
  265. END DO
  266. END SUBROUTINE
  267. !-------------------------------------------------------------------------------
  268.  
  269. !-------------------------------DOTS GRAPH--------------------------------------
  270. Subroutine Dots_Graph
  271.     USE Datos
  272.     IMPLICIT NONE
  273.     REAL(8) Func
  274.     REAL(8)X_Point
  275.     REAL(8)dx_Point
  276.     INTEGER N_PointToPlot, Point_I
  277.  
  278.     N_PointToPlot=100
  279.     dx_Point=(Maxval(Xpoint)-Minval(Xpoint))/(N_PointToPlot-1)
  280.     Do Point_I=1,N_PointToPlot
  281.         X_point= Minval(XPoint)+(Point_I-1)*dx_Point
  282.     WRITE(50,*)X_Point,Func(X_point)
  283.     End do
  284. End Subroutine
  285. !-------------------------------------------------------------------------------
  286.  
  287. REAL(8)FUNCTION Func(X_int)
  288.     USE DATOS
  289.     IMPLICIT NONE
  290.     REAL(8)X_int
  291.     REAL(8)a_i,b_i,c_i,d_i
  292.     INTEGER I
  293.  
  294.     DO I=1,N_Nodos
  295.         IF(X_int>Xpoint(i) .and. X_Int<Xpoint(i+1))THEN
  296.             !Estoy en P_i
  297.             a_i=Coeficiente(4*i-3)
  298.             b_i=Coeficiente(4*i-2)
  299.             c_i=Coeficiente(4*i-1)
  300.             d_i=Coeficiente(4*i)
  301.         END IF
  302.         FUNC=a_i*X_int**3+b_i*X_int**2+c_i*X_int+d_i
  303.     END DO
  304. END FUNCTION
  305.  
  306.  
  307. !--------------------------------WRITE OUTS-------------------------------------
  308. SUBROUTINE Write_Outs
  309.     USE DATOS
  310.     IMPLICIT NONE
  311.     INTEGER I,K,J
  312.     OPEN(3,File="Write_Outs_Ejercicio_1_Final.txt")
  313.     k=1
  314.     J=0
  315.         DO I=1,4*N_Nodos,4
  316.             J=J+1
  317.                 Print*,"Coeficientes de P_",J, "[",(Coeficiente(I+K-1),K=1,4),"]"
  318.                 PRINT*, "--------------------------------------------------------------"
  319.                 WRITE(3,*) "Coeficientes de P_",J, "[",(Coeficiente(I+K-1),K=1,4),"]"
  320.                 WRITE(3,*)"-------------------------------------------------------------"
  321.         END DO
  322. END SUBROUTINE
  323.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement