-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnumerical_integration.c
108 lines (89 loc) · 2.83 KB
/
numerical_integration.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "header/numeric_integration.h"
#include "header/globals.h"
#include "header/v.h"
#include <math.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
#define SYS_DIM 2
/* -----------------------------------------------------------------------------
Funciones de ayuda
----------------------------------------------------------------------------- */
/** gnuplot:
gnuplot.exe -p plot.gnu
*/
/**
@brief Sistema de ecuaciones
@param t: tiempo
@param y: variables del sistema que permiten tener una ecuación de 1er orden
@param yp: derivadas del sistema: 1a, 2a, 3a...
@param params: parámetros para las ecuaciones
*/
int
funcSchw (double x,
const double y[],
double dydx[],
void* params)
{
struct schwarzschildParams *par = (struct schwarzschildParams *)params;
double w = (par->w);
double u = y[0];
double v = y[1];
dydx[0] = v;
dydx[1] = (V(x) - w*w)*u;
return GSL_SUCCESS;
}
/* -----------------------------------------------------------------------------
Funciones públicas
----------------------------------------------------------------------------- */
/**
@brief Integración ODE usando RK
NOTE: En realidad podría usar cualquiera de los métodos de GSL
@param x Posición inicial
@param ur Vector de resultados con la parte real
@param ui Vector de resultados con la parte imaginaria
@param qb Función 'q' calculada de la ecuación de Stum-Liouville
@param s Función 's' ídem
@param h Paso de integración
@param n Número de subintervalos
@param param Parámetros que tenga la ecuación
*/
int
backguardIntegrationRKSchwarzschild(double x,
double u,
double v,
double uu[],
double h,
double w)
{
int status = GSL_SUCCESS;
struct schwarzschildParams params = {w};
/* Vamos a integrar hacia atrás desde la parte de la onda transmitida, región
3. Dividiremos la integración en parte real e imaginaria */
double x0 = x;
double x1 = x + h;
double epsAbs = 1e-3; /* Parece que da error... será demasiado 1e-6 */
double epsRel = 0;
gsl_odeiv2_system sys = {funcSchw, NULL, SYS_DIM, ¶ms};
const gsl_odeiv2_step_type* T = gsl_odeiv2_step_rkf45;
gsl_odeiv2_driver* d = gsl_odeiv2_driver_alloc_y_new (&sys, T, h, epsAbs, epsRel);
double y[2] = {u, v};
int i;
for (i = 0; i < NODES; i++)
{
status = gsl_odeiv2_driver_apply(d, &x0, x1, y);
x0 = x1;
x1 = x0 + h;
if (status != GSL_SUCCESS)
{
printf ("k = %f -- error, return value = %d\n", w, status);
break;
}
/*
y[0] valor de la función
y[1] valor de la derivada de la función
*/
uu[i] = y[0];
}
gsl_odeiv2_driver_free(d);
return status;
}