forked from geodynamics/hc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hc_propagator.c
173 lines (142 loc) · 4.32 KB
/
hc_propagator.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
propagator generation routines for hc_polsol part of HC code
$Id: hc_propagator.c,v 1.1 2004/07/01 23:52:23 becker Exp $
*/
#include "hc.h"
void hc_evalpa(int l,HC_HIGH_PREC r1,HC_HIGH_PREC r2,HC_HIGH_PREC visc, HC_HIGH_PREC *p)
{
//
// ****************************************************************
// * THIS SUBROUTINE CALCULATES THE 4X4 PROPAGATOR MATRIX THROUGH *
// * USE OF AN ALGEBRAI//FORM (IE: ALL MATRIX MULTIPLICATIONS *
// * PERFORMED ALGEBRAICLY, THE RESULT BEING CODED HEREIN). THIS *
// * CODE IS A REVISION OF M. RICHARDS' SUBROUTINE, DESIGNED TO *
// * INTERFACE WITH THE EXISTING PROGRAMS. *
// ****************************************************************
//
HC_HIGH_PREC den1,den2,f[4],r,rlm1,rlp1,rmlm2,rml,v2,rs;
long int np[4][4][4];
long int lp1,lp2,lp3,lm1,lm2,lpp,lmm,l2p3,l2p1,l2m1,lltp1,lltp2;
long int i,j,k,os1,os2;
//fprintf(stderr,"hc_evalpa: %i %g %g %g\n",l,r1,r2,visc);
//
// PASSED PARAMETERS: L: DEGREE,
// R1,R2: PROPAGATE FROM R1 TO R2 (RADII),
// VISC: VISCOSITY
// P: THE PROPAGATOR [4*4]
//
// OTHER VARIABLES:
// NP: INTEGER FACTORS (FUNCTIONS OF L) IN THE EXPRESSIONS
// FOR THE ELEMENTS OF P,
// F: HC_HIGH_PREC PRECISION FACTORS (FUNCTIONS OF R AND L) FOR P,
// R IS THE RADIUS RATIO R/R0 (HC_HIGH_PREC PRECISION).
//
r = r2 / r1;
lp1 = l + 1;
lp2 = l + 2;
lp3 = l + 3;
lm1 = l - 1;
lm2 = l - 2;
lpp = l * lp3 - 1;
lmm = l * l - lp3;
lltp1 = l * lp1;
lltp2 = l * lp2;
l2p3 = lp3 + l;
l2p1 = lp1 + l;
l2m1 = lm1 + l;
v2 = visc * 2.0;
rs = r * r;
rlm1 = pow(r,(HC_HIGH_PREC)lm1);
rlp1 = rlm1 * rs;
rmlm2 = pow(r,(HC_HIGH_PREC)(-lp2));
rml = rmlm2 * rs;
den1 = (HC_HIGH_PREC)(l2p1 * l2p3);
den2 = (HC_HIGH_PREC)(l2p1 * l2m1);
f[0] = rlp1 / den1;
f[1] = rlm1 / den2;
f[2] = rml / den2;
f[3] = rmlm2/ den1;
// DO INTEGER MULTIPLIES
// FIRST, SET UP 16 'REFERENCE' ELEMENTS
np[0][2][0] = -lltp1;
np[0][2][1] = -np[0][2][0];
np[0][2][2] = np[0][2][0];
np[0][2][3] = np[0][2][1];
np[1][2][0] = -lp3;
np[1][2][1] = lp1;
np[1][2][2] = lm2;
np[1][2][3] = -l;
np[2][2][0] = - lp1 * lmm;
np[2][2][1] = lltp1 * lm1;
np[2][2][2] = l * lpp;
np[2][2][3] = -lltp1 * lp2;
np[3][2][0] = -lltp2;
np[3][2][1] = lm1 * lp1;
np[3][2][2] = -np[3][2][1];
np[3][2][3] = -np[3][2][0];
//generate other elements
for(i=0;i < 4;i++){
np[i][0][0] = np[i][2][0] * lp2;
np[i][1][0] = -np[i][0][0] * l;
np[i][3][0] = -np[i][2][0] * l;
np[i][0][1] = (np[i][2][1] * lpp) / lp1;
np[i][1][1] = -np[i][2][1] * lp1 * lm1;
np[i][3][1] = -np[i][2][1] * lm2;
np[i][0][2] = -np[i][2][2] * lm1;
np[i][1][2] = np[i][0][2] * lp1;
np[i][3][2] = np[i][2][2] * lp1;
np[i][0][3] =(-np[i][2][3] * lmm) / l;
np[i][1][3] = -np[i][2][3] * lltp2;
np[i][3][3] = np[i][2][3] * lp3;
}
//put IN COMMON FACTORS
for(os1=i=0;i < 4;i++,os1+=4){
for(j=0;j<4;j++){
os2 = os1 + j;
p[os2] = 0.0;
for(k=0;k < 4;k++)
p[os2] += ((HC_HIGH_PREC)(np[i][j][k])) * f[k];
}
}
// PUT IN VISCOSITIES
p[0*4+2] /= v2;
p[0*4+3] /= v2;
p[1*4+2] /= v2;
p[1*4+3] /= v2;
p[2*4+0] *= v2;
p[2*4+1] *= v2;
p[3*4+0] *= v2;
p[3*4+1] *= v2;
}
void
hc_evppot (l, ratio, ppot)
int l;
HC_HIGH_PREC ratio;
HC_HIGH_PREC *ppot;
{
// ********************************************
// * THIS SUBROUTINE OBTAINS THE POTENTIALS *
// * PROPAGATOR FROM R1 TO R2 AT L, WHERE *
// * RATIO = R1/R2. *
// ********************************************
//
HC_HIGH_PREC c,expf1,expf2,x,xp1;
// PASSED PARAMETERS: L: DEGREE,
// RATIO: R1 / R2 (R2>R1),
// PPOT: THE POTENTIALS PROPAGATOR [4]
//
// HC_HIGH_PREC PRECISION: C: COEFFICIENT MULTIPLYING PROPAGATOR,
// EXPF1: RATIO**L, EXPONENTIAL FACTOR IN PPOT,
// EXPF2: (1/RATIO)**(L+1), EXP. FACTOR IN PPOT,
// X: DEGREE (L),
// XP1: X+1.
x = (HC_HIGH_PREC)l;
c = 1.0 / (2.0 * x + 1.0);
xp1 = x + 1.0;
expf1 = pow(ratio,x);
expf2 = 1.0 / (expf1*ratio);
ppot[0] = c * (x * expf1 + xp1 * expf2);
ppot[1] = c * (expf2 - expf1);
ppot[2] = x * xp1 * ppot[1];
ppot[3] = ppot[0] - ppot[1];
}