SDDSlib
Loading...
Searching...
No Matches
elliptic.c
Go to the documentation of this file.
1/**
2 * @file elliptic.c
3 * @brief Functions for evaluating complete elliptic integrals of the first and second kind (K and E),
4 * as well as their total derivatives with respect to the modulus k.
5 *
6 * @copyright
7 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
8 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
9 *
10 * @license
11 * This file is distributed under the terms of the Software License Agreement
12 * found in the file LICENSE included with this distribution.
13 *
14 * @author M. Borland, C. Saunders, R. Soliday
15 */
16
17#include "mdb.h"
18
19static double ceiAccuracy = 1e-14;
20
21void setCeiAccuracy(double newAccuracy) {
22 ceiAccuracy = newAccuracy;
23}
24
25/**
26 * @brief Compute the complete elliptic integral of the first kind, K(k).
27 *
28 * K(k) = ∫_0^(π/2) dθ / √(1 - k² sin² θ)
29 *
30 * @param[in] k The modulus of the elliptic integral.
31 * @return The value of K(k).
32 */
33double K_cei(double k) {
34 double a0, b0, c0, a1, b1;
35
36 a0 = 1;
37 b0 = sqrt(1 - sqr(k));
38 c0 = k;
39
40 do {
41 /* do two steps of recurrence per pass in the loop */
42 a1 = (a0 + b0) / 2;
43 b1 = sqrt(a0 * b0);
44 a0 = (a1 + b1) / 2;
45 b0 = sqrt(a1 * b1);
46 c0 = (a1 - b1) / 2;
47 } while (fabs(c0) > ceiAccuracy);
48 return PI / (2 * a0);
49}
50
51/**
52 * @brief Compute the complete elliptic integral of the second kind, E(k).
53 *
54 * E(k) = ∫_0^(π/2) √(1 - k² sin² θ) dθ
55 *
56 * @param[in] k The modulus of the elliptic integral.
57 * @return The value of E(k).
58 */
59double E_cei(double k) {
60 double a0, b0, c0, a1, b1, c1, K, sum, powerOf2;
61
62 a0 = 1;
63 b0 = sqrt(1 - sqr(k));
64 c0 = k;
65 sum = sqr(c0);
66 powerOf2 = 1;
67
68 do {
69 /* do two steps of recurrence per pass in the loop */
70 a1 = (a0 + b0) / 2;
71 b1 = sqrt(a0 * b0);
72 c1 = (a0 - b0) / 2;
73 sum += sqr(c1) * (powerOf2 *= 2);
74 ;
75
76 a0 = (a1 + b1) / 2;
77 b0 = sqrt(a1 * b1);
78 c0 = (a1 - b1) / 2;
79 sum += sqr(c0) * (powerOf2 *= 2);
80 } while (fabs(c0) > ceiAccuracy);
81
82 K = PI / (2 * a0);
83 return K * (1 - sum / 2);
84}
85
86double *KE_cei(double k, double *buffer) {
87 double a0, b0, c0, a1, b1, c1, K, sum, powerOf2;
88
89 if (!buffer)
90 buffer = tmalloc(sizeof(*buffer) * 2);
91
92 a0 = 1;
93 b0 = sqrt(1 - sqr(k));
94 c0 = k;
95 sum = sqr(c0);
96 powerOf2 = 1;
97
98 do {
99 /* do two steps of recurrence per pass in the loop */
100 a1 = (a0 + b0) / 2;
101 b1 = sqrt(a0 * b0);
102 c1 = (a0 - b0) / 2;
103 sum += sqr(c1) * (powerOf2 *= 2);
104 ;
105
106 a0 = (a1 + b1) / 2;
107 b0 = sqrt(a1 * b1);
108 c0 = (a1 - b1) / 2;
109 sum += sqr(c0) * (powerOf2 *= 2);
110 } while (fabs(c0) > ceiAccuracy);
111
112 buffer[0] = K = PI / (2 * a0);
113 buffer[1] = K * (1 - sum / 2);
114 return buffer;
115}
116
117/* These two functions rely on formulae quoted in Landau and Lifshitz,
118 ELECTRODYNAMICS OF CONTINUOUS MEDIA, pg 112.
119 */
120
121/**
122 * @brief Compute the total derivative dK/dk of the complete elliptic integral of the first kind.
123 *
124 * Uses K(k) and E(k) to determine the derivative with respect to k.
125 *
126 * @param[in] k The modulus of the elliptic integral.
127 * @return The value of dK/dk.
128 */
129double dK_cei(double k) {
130 double buffer[2];
131 KE_cei(k, buffer);
132 return (buffer[1] / (1 - k * k) - buffer[0]) / k;
133}
134
135/**
136 * @brief Compute the total derivative dE/dk of the complete elliptic integral of the second kind.
137 *
138 * Uses K(k) and E(k) to determine the derivative with respect to k.
139 *
140 * @param[in] k The modulus of the elliptic integral.
141 * @return The value of dE/dk.
142 */
143double dE_cei(k) double k;
144{
145 double buffer[2];
146 KE_cei(k, buffer);
147 return (buffer[1] - buffer[0]) / k;
148}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
double dK_cei(double k)
Compute the total derivative dK/dk of the complete elliptic integral of the first kind.
Definition elliptic.c:129
double E_cei(double k)
Compute the complete elliptic integral of the second kind, E(k).
Definition elliptic.c:59
double K_cei(double k)
Compute the complete elliptic integral of the first kind, K(k).
Definition elliptic.c:33
double dE_cei(double k)
Compute the total derivative dE/dk of the complete elliptic integral of the second kind.
Definition elliptic.c:143