Blame view

src/idl_extern/CMTotal_for_Dustemwrap/srvadd.pro 5.62 KB
517b8f98   Annie Hughes   first commit
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
174
175
176
177
178
179
;+
; NAME:
;   SRVADD
;
; AUTHOR:
;   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
;   craigm@lheamail.gsfc.nasa.gov
;   UPDATED VERSIONs can be found on my WEB PAGE: 
;      http://cow.physics.wisc.edu/~craigm/idl/idl.html
;
; PURPOSE:
;   Add velocity 3-vectors according to special relativity
;
; MAJOR TOPICS:
;   Physics, Geometry
;
; CALLING SEQUENCE:
;   U0 = SRVADD(U1, V)
;
; DESCRIPTION:
;
;  The function SRVADD performs addition of velocity 3-vectors
;  according to special relativity.
;
;  Consider two inertial coordinate frames.  Frame "0" is a "lab" or
;  rest frame.  Frame "1" is a "rocket" or moving frame, moving at
;  velocity V with respect to the lab frame.  The velocity V is
;  allowed to be an arbitrary 3-vector.
;
;    * An observer in the rocket frame sees a body moving at velocity U1.
;
;    * An observer in the lab frame sees the same body moving at
;      velocity U0.
;
;    * This function solves for U0 in terms of V and U1.
;
;  U1 and V are allowed to be 3xN arrays, which means more than one
;  vector can be computed in a single call.  If the dimensions of
;  either U1 or V are 3x1, then it will be expanded to match the
;  dimensions of the other vector.  This simulates addition by a
;  "scalar" vector.  Because V can be a 3xN array, this means that
;  multiple "rocket" frames can be computed at one time.
;
;  NOTE: Velocities passed to SRVADD are measured as a *fraction of
;        the speed of light*.  Therefore, if the velocities are
;        measured in some physical units, and CLIGHT is the speed of
;        light in those same units, then the following statement:
;
;           U0 = SRVADD(U1/CLIGHT, V/CLIGHT)*CLIGHT
;
;        will compute the velocity U0, also in the same units.
;
;
;  The formula for computing the velocity in the lab frame is:
;
;         ( (1-1/GAMMA)*(U1 . VUNIT)*VUNIT + U1/GAMMA + V )
;    U0 = -------------------------------------------------
;                           (1 - U1 . V)
;
;  where 
;    GAMMA is the Lorentz factor = 1/SQRT(1 - |V|^2)
;    VUNIT is the unit vector in the direction of V, = V/|V|
;    "." is the vector dot product
;
;  [ IDL notation is not strictly adhered to in this formula, for
;  clarity of presentation. ]
;
;
; INPUTS:
;
;   U1 - 3-vector or 3xN array, the velocity of a body as seen in the
;        rocket frame (frame 1).  The velocity is normalized such that
;        the speed of light is 1.
;
;
;   V - 3-vector or 3xN array, the velocity of the rocket frame as
;       seen by an observer in the lab.  The velocity is normalized
;       such that the speed of light is 1.
;
; RETURNS:
;
;   A 3xN array, containing the velocity of the body as seen in the
;   lab frame.  The velocity is normalized such that the speed of
;   light is 1.
;
; KEYWORD PARAMETERS:
;
;   CLASSICAL - if set, then classical velocity addition is performed,
;               and the relativistic form is disabled.
;               Default: not set (i.e., relativity is applied)
;
; EXAMPLE:
;
;   IDL> print, srvadd([0.1d,0,0],   [0.5d,0,0])
;         0.56504883       0.0000000       0.0000000
;
;   Adds velocities of 0.1 and 0.5 times the speed of light.  The
;   result is slightly less than the arithmetic sum.
;
;
;   IDL> print, srvadd([0.,0.1,0],[0.5d,0,0])
;         0.50000000     0.086602542       0.0000000
;
;   Adds velocities in two orthogonal directions.  Demonstrates the
;   relativistic aberration of velocities (i.e., velocities in the
;   perpendicular direction are affected).
;
;
; MODIFICATION HISTORY:
;   Written, 28 Jan 2002, CM
;   More documentation, 29 Jan 2002, CM
;   Add CLASSICAL keyword, 29 Jul 2002, CM
;
;  $Id: srvadd.pro,v 1.3 2002/07/29 23:16:47 craigm Exp $
;
;-
; Copyright (C) 2002, Craig Markwardt
; This software is provided as is without any warranty whatsoever.
; Permission to use, copy, modify, and distribute modified or
; unmodified copies is granted, provided this copyright and disclaimer
; are included unchanged.
;-

function srvadd, u, v, classical=classical

  nu = n_elements(u)/3
  nv = n_elements(v)/3

  if nu EQ 0 OR nv EQ 0 then begin
      message, 'USAGE: U0 = SRVADD(U1, V)', /info
      message, '   U1 = vel. of body in rocket frame; V is velocity of rocket in lab', $
        /info
      message, '   U0 = vel. of body in lab frame', /info
      return, -1d
  endif

  if nu NE nv AND nu NE 1 AND nv NE 1 then begin
      message, 'ERROR: U and V must have the same number of vectors'
  endif else if nu EQ 1 then begin
      v1 = v
      u1 = v*0
      u1(0,*) = u(0) & u1(1,*) = u(1) & u1(2,*) = u(2)
  endif else if nv EQ 1 then begin
      u1 = u
      v1 = u*0
      v1(0,*) = v(0) & v1(1,*) = v(1) & v1(2,*) = v(2)
  endif else begin
      u1 = u
      v1 = v
  endelse

  if keyword_set(classical) then begin
      return, u1+v1
  endif

  ;; Compute unit vector v, along with 1/gamma and 1 - 1/gamma
  vunit = v1
  vnorm = total(vunit^2,1)        ;; Momentarily = |V|^2

  oogamma = sqrt(1 - vnorm)       ;; 1/gamma
  omoogamma = 1 - oogamma         ;; 1 - 1/gamma
  vnorm = sqrt(temporary(vnorm))  ;; Now vnorm = |V|
  wh = where(vnorm EQ 0, ct)      ;; Avoid overflow
  if ct GT 0 then vnorm(wh) = 1

  ;; Normalize the unit vector
  if ct GT 0 then $
    for i = 0, 2 do vunit(i,*) = vunit(i,*) / vnorm

  ;; Compute elements of numerator and denominator
  udv  = total(u1*v1,1)        ;; Dot product U1 . V
  denom = 1/(1 + udv)          ;; Denominator of expression
  udvu = temporary(udv)/vnorm  ;; Dot product U1 . VUNIT
  uu = [1,1,1]                 ;; Used to expand N-vector to 3xN array
  
  ;; U0 = ( (1-1/GAMMA)*(U1 . VUNIT)*VUNIT + U1/GAMMA + V ) / (1 - U1 . V)
  return, ((uu#(omoogamma*udvu))*vunit + (uu#oogamma)*u1 + v1)*(uu#denom)

end