orthovec.red 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. module orthovec; % 3-D vector calculus package.
  2. create!-package('(orthovec),'(contrib avector));
  3. % %========================================%
  4. % % ORTHOVEC %
  5. % %========================================%
  6. % % A 3-D VECTOR CALCULUS PACKAGE %
  7. % % USING ORTHOGONAL CURVILINEAR %
  8. % % COORDINATES %
  9. % % %
  10. % % copyright James W Eastwood, %
  11. % % Culham Laboratory, %
  12. % % Abingdon, Oxon. %
  13. % % %
  14. % % February 1987 %
  15. % % %
  16. % % This new version differs from the %
  17. % % original version published in CPC, %
  18. % % 47(1987)139-147 in the following %
  19. % % respects: %
  20. % % %
  21. % % *.+.,etc replaced by +,-,*,/ %
  22. % % *unary vector +,-,/ introduced %
  23. % % *vector component selector _ %
  24. % % *general tidy up %
  25. % % *L'Hopitals rule in Taylor series %
  26. % % *extended division definition %
  27. % % *algebraic output of lisp vectors %
  28. % % *exponentiation of vectors %
  29. % % *vector extension of depend %
  30. % % %
  31. % % Version 2 %
  32. % % All rights reserved %
  33. % % copyright James W Eastwood %
  34. % % June 1990 %
  35. % % %
  36. % % This is a preliminary version of %
  37. % % the NEW VERSION of ORTHOVEC which %
  38. % % will be available from the Computer %
  39. % % Physics Communications Program %
  40. % % Library, Dept. of Applied Maths and %
  41. % % Theoretical Physics, The Queen's %
  42. % % University of Belfast, Belfast %
  43. % % BT7 1NN, Northern Ireland. %
  44. % % See any copy of CPC for further %
  45. % % details of the library services. %
  46. % % %
  47. % %========================================%
  48. % % REDUCE 3.4 is assumed %
  49. % %========================================%
  50. %
  51. %
  52. %
  53. %-------------------------------------------------------------------
  54. % INITIALISATION
  55. %%
  56. algebraic;
  57. %select coordinate system
  58. %========================
  59. procedure vstart0;
  60. begin scalar ctype;
  61. write "Select Coordinate System by number";
  62. write "1] cartesian";
  63. write "2] cylindrical";
  64. write "3] spherical";
  65. write "4] general";
  66. write "5] others";
  67. %remove previous settings
  68. clear u1,u2,u3,h1,h2,h3;
  69. depend h1,u1,u2,u3;
  70. depend h2,u1,u2,u3;
  71. depend h3,u1,u2,u3;
  72. nodepend h1,u1,u2,u3;
  73. nodepend h2,u1,u2,u3;
  74. nodepend h3,u1,u2,u3;
  75. %select coordinate system
  76. ctype := symbolic read();
  77. if ctype=1 then
  78. << u1:=x;u2:=y;u3:=z;h1:=1;h2:=1;h3:=1 >>
  79. else if ctype=2 then
  80. << u1:=r;u2:=th;u3:=z;h1:=1;h2:=r;h3:=1 >>
  81. else if ctype=3 then
  82. << u1:=r;u2:=th;u3:=ph;h1:=1;h2:=r;h3:=r*sin(th) >>
  83. else if ctype=4 then
  84. << depend h1,u1,u2,u3;depend h2,u1,u2,u3;depend h3,u1,u2,u3 >>
  85. else << write "To define another coordinate system, give values ";
  86. write "to components u1,u2,u3 and give functional form or";
  87. write "DEPEND for scale factors h1,h2 and h3. For example,";
  88. write "to set up paraboloidal coords u,v,w type in:-";
  89. write "u1:=u;u2:=v;u3:=w;h1:=sqrt(u**2+v**2);h2:=h1;h3:=u*v;">>;
  90. write "coordinate type = ",ctype;
  91. write "coordinates = ",u1,",",u2,",",u3;
  92. write "scale factors = ",h1,",",h2,",",h3;
  93. return
  94. end$
  95. let vstart=vstart0()$
  96. %give access to lisp vector procedures
  97. %=======================================
  98. symbolic operator putv,getv,mkvect;
  99. flag('(vectorp), 'direct);
  100. flag('(vectorp), 'boolean);
  101. %-------------------------------------------------------------------
  102. % INPUT-OUTPUT
  103. %
  104. %set a new vector
  105. %===================
  106. procedure svec(c1,c2,c3);
  107. begin scalar a;a:=mkvect(2);
  108. putv(a,0,c1);putv(a,1,c2);putv(a,2,c3);
  109. return a
  110. end$
  111. %output a vector
  112. %===============
  113. procedure vout(v);
  114. begin;
  115. if vectorp(v) then
  116. for j:=0:2 do write "[",j+1,"] ",getv(v,j)
  117. else write v;
  118. return v
  119. end$
  120. %-------------------------------------------------------------------
  121. % REDEFINITION OF SOME STANDARD PROCEDURES
  122. %
  123. % Vector extension of standard definitions of depend and nodepend.
  124. remflag('(depend nodepend),'lose); % We must use these definitions.
  125. symbolic procedure depend u;
  126. begin scalar v,w; v:= !*a2k car u;
  127. for each x in cdr u do
  128. if vectorp(v) then
  129. for ic:=0:upbv(v) do
  130. <<if atom(w:=getv(v,ic)) and not numberp(w) then depend1(w,x,t)>>
  131. else depend1(car u,x,t)
  132. end$
  133. symbolic procedure nodepend u;
  134. begin scalar v,w;
  135. rmsubs();
  136. v:= !*a2k car u;
  137. for each x in cdr u do
  138. if vectorp(v) then
  139. for ic:=0:upbv(v) do
  140. <<if atom(w:=getv(v,ic)) and not numberp(w) then depend1(w,x,nil)>>
  141. else depend1(car u,x,nil)
  142. end $
  143. %
  144. %-------------------------------------------------------------------
  145. % ALGEBRAIC OPERATIONS
  146. %
  147. %define symbols for vector algebra
  148. %=====================================
  149. newtok '(( !+ ) vectoradd);
  150. newtok '(( !- ) vectordifference);
  151. newtok '((!> !< ) vectorcross);
  152. newtok '(( !* ) vectortimes);
  153. newtok '(( !/ ) vectorquotient);
  154. newtok '(( !_ ) vectorcomponent);
  155. newtok '(( !^ ) vectorexpt);
  156. %
  157. %define operators
  158. %================
  159. operator vectorminus,vectorplus,vectorrecip;
  160. infix vectoradd,vectordifference,vectorcross,vectorexpt,
  161. vectorcomponent,vectortimes,vectorquotient,dotgrad;
  162. precedence vectoradd,<;
  163. precedence vectordifference,vectoradd;
  164. precedence dotgrad,vectordifference;
  165. precedence vectortimes,dotgrad;
  166. precedence vectorcross,vectortimes;
  167. precedence vectorquotient,vectorcross;
  168. precedence vectorexpt,vectorquotient;
  169. precedence vectorcomponent,vectorexpt;
  170. deflist( '(
  171. (vectordifference vectorminus)
  172. (vectoradd vectorplus)
  173. (vectorquotient vectorrecip)
  174. (vectorrecip vectorrecip)
  175. ), 'unary)$
  176. deflist('((vectorminus vectorplus) (vectorrecip vectortimes)),
  177. 'alt)$
  178. %extract component of a vector
  179. %=============================
  180. procedure vectorcomponent(v,ic);
  181. if vectorp(v) then
  182. if ic=1 or ic=2 or ic=3 then getv(v,ic-1)
  183. else rerror(orthovec,1,"Incorrect component number")
  184. else rerror(orthovec,2,"Not a vector")$
  185. %
  186. %add vector or scalar pair v1 and v2
  187. %===================================
  188. procedure vectoradd(v1,v2);
  189. begin scalar v3;
  190. if vectorp(v1) and vectorp(v2) then
  191. <<v3:=mkvect(2);
  192. for ic:=0:2 do putv(v3,ic,plus(getv(v1,ic),getv(v2,ic)))>>
  193. else
  194. if not(vectorp(v1)) and not(vectorp(v2)) then v3:=plus(v1, v2)
  195. else rerror(orthovec,3,"Incorrect args to vector add");
  196. return v3
  197. end$
  198. %unary plus
  199. %==========
  200. procedure vectorplus(v);v$
  201. %
  202. %negate vector or scalar v
  203. %=========================
  204. procedure vectorminus(v);
  205. begin scalar v3;
  206. if vectorp(v) then
  207. <<v3:=mkvect(2);
  208. for ic:=0:2 do putv(v3,ic,minus(getv(v,ic)))>>
  209. else v3:=minus(v);
  210. return v3
  211. end$
  212. %scalar or vector subtraction
  213. %============================
  214. procedure vectordifference(v1,v2);(v1 + vectorminus(v2))$
  215. %dot product or scalar times
  216. %===========================
  217. procedure vectortimes(v1,v2);
  218. begin scalar v3;
  219. if vectorp(v1) and vectorp(v2) then
  220. v3:= for ic:=0:2 sum times(getv(v1,ic),getv(v2,ic))
  221. else
  222. if not(vectorp(v1)) and not(vectorp(v2)) then
  223. v3:=times(v1 , v2 )
  224. else if vectorp(v1) and not(vectorp(v2)) then
  225. <<v3:=mkvect(2);
  226. for ic:=0:2 do putv(v3,ic,times(getv(v1,ic),v2)) >>
  227. else
  228. <<v3:=mkvect(2);
  229. for ic:=0:2 do putv(v3,ic,times(getv(v2,ic),v1)) >>;
  230. return v3
  231. end$
  232. %vector cross product
  233. %====================
  234. procedure vectorcross(v1,v2);
  235. begin scalar v3;
  236. if vectorp(v1) and vectorp(v2) then
  237. <<v3:=mkvect(2);
  238. putv(v3,0,getv(v1,1)*getv(v2,2)-getv(v1,2)*getv(v2,1));
  239. putv(v3,1,getv(v1,2)*getv(v2,0)-getv(v1,0)*getv(v2,2));
  240. putv(v3,2,getv(v1,0)*getv(v2,1)-getv(v1,1)*getv(v2,0))>>
  241. else rerror(orthovec,4,"Incorrect args to vector cross product");
  242. return v3
  243. end$
  244. %vector division
  245. %===============
  246. procedure vectorquotient(v1,v2);
  247. if vectorp(v1) then
  248. if vectorp(v2) then
  249. quotient (v1*v2,v2*v2)
  250. else v1*recip(v2)
  251. else if vectorp(v2) then
  252. v1*v2*recip(v2*v2)
  253. else quotient(v1,v2)$
  254. procedure vectorrecip(v);
  255. if vectorp(v) then
  256. v*recip(v*v)
  257. else recip(v)$
  258. %length of vector
  259. %================
  260. procedure vmod(v);sqrt(v * v)$
  261. %vector exponentiation
  262. %=====================
  263. procedure vectorexpt(v,n);
  264. if vectorp(v) then expt(vmod(v),n) else expt(v,n)$
  265. %-------------------------------------------------------------------
  266. % DIFFERENTIAL OPERATIONS
  267. %
  268. %div
  269. %===
  270. procedure div(v);
  271. if vectorp(v) then
  272. (df(h2*h3*getv(v,0),u1)+df(h3*h1*getv(v,1),u2)
  273. +df(h1*h2*getv(v,2),u3))/h1/h2/h3
  274. else rerror(orthovec,5,"Incorrect arguments to div")$
  275. %grad
  276. %====
  277. procedure grad(s);
  278. begin scalar v;
  279. v:=mkvect(2);
  280. if vectorp(s) then
  281. rerror(orthovec,6,"Incorrect argument to grad")
  282. else << putv(v,0,df(s,u1)/h1);
  283. putv(v,1,df(s,u2)/h2);
  284. putv(v,2,df(s,u3)/h3) >>;
  285. return v
  286. end$
  287. %curl
  288. %====
  289. procedure curl(v);
  290. begin scalar v1;
  291. v1:=mkvect(2);
  292. if vectorp(v) then
  293. << putv(v1,0,(df(h3*getv(v,2),u2)-df(h2*getv(v,1),u3))/h2/h3);
  294. putv(v1,1,(df(h1*getv(v,0),u3)-df(h3*getv(v,2),u1))/h3/h1);
  295. putv(v1,2,(df(h2*getv(v,1),u1)-df(h1*getv(v,0),u2))/h1/h2) >>
  296. else rerror(orthovec,7,"Incorrect argument to curl");
  297. return v1
  298. end$
  299. %laplacian
  300. %=========
  301. procedure delsq(v);
  302. if vectorp(v) then (grad(div(v)) - curl(curl(v))) else div(grad(v))$
  303. %differentiation
  304. %===============
  305. procedure vdf(v,x);
  306. begin scalar v1;
  307. if vectorp(x) then
  308. rerror(orthovec,8,"Second argument to VDF must be scalar")
  309. else if vectorp(v) then
  310. <<v1:=mkvect(2);for ic:=0:2 do putv(v1,ic,vdf(getv(v,ic),x)) >>
  311. else v1:=df(v,x);
  312. return v1
  313. end$
  314. %v1.grad(v2)
  315. %===========
  316. procedure dotgrad(v1,v2);
  317. if vectorp(v1) then
  318. if vectorp(v2) then
  319. (1/2)*(grad(v1 * v2) + v1 * div(v2) - div(v1) * v2
  320. - (curl(v1 >< v2) + v1 >< curl(v2) - curl(v1) >< v2 ))
  321. else v1 * grad(v2)
  322. else rerror(orthovec,9,"Incorrect arguments to dotgrad")$
  323. %3-D Vector Taylor Expansion about vector point
  324. %==============================================
  325. procedure vtaylor(vex,vx,vpt,vorder);
  326. %note: expression vex, variable vx, point vpt and order vorder
  327. % are any legal mixture of vectors and scalars
  328. begin scalar vseries;
  329. if vectorp(vex) then
  330. <<vseries:=mkvect(2);
  331. for ic:=0:2 do putv(vseries,ic,vptaylor(getv(vex,ic),vx,vpt,vorder))>>
  332. else vseries:=vptaylor(vex,vx,vpt,vorder);
  333. return vseries
  334. end$
  335. %Scalar Taylor expansion about vector point
  336. %==========================================
  337. procedure vptaylor(sex,vx,vpt,vorder);
  338. %vector variable
  339. if vectorp(vx) then
  340. if vectorp(vpt) then
  341. %vector order
  342. if vectorp(vorder) then
  343. taylor( taylor( taylor( sex,
  344. getv(vx,0), getv(vpt,0), getv(vorder,0) ),
  345. getv(vx,1), getv(vpt,1), getv(vorder,1) ),
  346. getv(vx,2), getv(vpt,2), getv(vorder,2) )
  347. else
  348. taylor( taylor( taylor( sex,
  349. getv(vx,0), getv(vpt,0), vorder),
  350. getv(vx,1), getv(vpt,1), vorder),
  351. getv(vx,2), getv(vpt,2), vorder)
  352. else rerror(orthovec,10,"VTAYLOR: vector VX mismatches scalar VPT")
  353. %scalar variable
  354. else if vectorp(vpt) then
  355. rerror(orthovec,11,"VTAYLOR: scalar VX mismatches vector VPT")
  356. else if vectorp(vorder) then
  357. rerror(orthovec,12,"VTAYLOR: scalar VX mismatches vector VORDER")
  358. else taylor(sex,vx,vpt,vorder)$
  359. %Scalar Taylor expansion of ex wrt x about point pt to order n
  360. %=============================================================
  361. procedure taylor(ex,x,pt,n);
  362. begin scalar term,series,dx,mfac;
  363. if numberp n then <<
  364. mfac:=1;dx:=x-pt;term:=ex;
  365. series:= limit(ex,x,pt) +
  366. for k:=1:n sum limit((term:=df(term,x)),x,pt)*(mfac:=mfac*dx/k) >>
  367. else rerror(orthovec,13,
  368. "Truncation orders of Taylor series must be integers");
  369. return series
  370. end$
  371. %
  372. %limiting value of exression ex as x tends to pt
  373. %===============================================
  374. procedure limit(ex,x,pt);
  375. begin scalar lim,denex,numex;
  376. %polynomial
  377. lim:=if (denex:=den(ex))=1 then sub(x=pt,ex)
  378. else
  379. %zero denom rational
  380. if sub(x=pt,denex)=0 then
  381. %l'hopital's rule
  382. << if sub(x=pt,(numex:=num(ex)))=0 then
  383. limit(df(numex,x)/df(denex,x),x,pt)
  384. %singular
  385. else rerror(orthovec,14,"Singular coefficient found by LIMIT")>>
  386. %nonzero denom rational
  387. else sub(x=pt,ex);
  388. return lim
  389. end$
  390. %
  391. %-------------------------------------------------------------------
  392. % INTEGRAL OPERATIONS
  393. %
  394. % Vector Integral
  395. %================
  396. procedure vint(v,x);
  397. begin scalar v1;
  398. if vectorp(x) then
  399. rerror(orthovec,15,"Second argument to VINT must be scalar")
  400. else if vectorp(v) then
  401. <<v1:=mkvect(2);for ic:=0:2 do putv(v1,ic,int(getv(v,ic),x)) >>
  402. else v1:=int(v,x);
  403. return v1
  404. end$
  405. %Definite Vector Integral
  406. %========================
  407. procedure dvint(v,x,xlb,xub);
  408. begin scalar integr,intval;
  409. if vectorp(xlb) or vectorp(xub)
  410. then rerror(orthovec,16,"Limits to DVINT must be scalar")
  411. else if vectorp(v) then
  412. <<intval:=mkvect(2);
  413. for ic:=0:2 do <<integr:=int(getv(v,ic),x);
  414. putv(intval,ic,sub(x=xub,integr)-sub(x=xlb,integr)) >> >>
  415. else
  416. <<integr:=int(v,x);intval:=sub(x=xub,integr)-sub(x=xlb,integr)>>;
  417. return intval
  418. end$
  419. %Volume Integral
  420. %===============
  421. procedure volint(v);
  422. begin scalar v1;
  423. if vectorp(v) then
  424. <<v1:=mkvect(2);for ic:=0:2 do putv(v1,ic,volint(getv(v,ic))) >>
  425. else v1:= int( int( int(v*h1*h2*h3,u1),u2),u3);
  426. return v1
  427. end$
  428. %Definite Volume Integral
  429. %========================
  430. procedure dvolint(v,vlb,vub,n);
  431. begin scalar v1,intgrnd;
  432. if vectorp(vlb) and vectorp(vub) then
  433. <<intgrnd:= (h1*h2*h3) * v;
  434. v1:= if n=1 then
  435. dvint(dvint(dvint(intgrnd,
  436. u1,getv(vlb,0),getv(vub,0)),
  437. u2,getv(vlb,1),getv(vub,1)),
  438. u3,getv(vlb,2),getv(vub,2) )
  439. else if n=2 then
  440. dvint(dvint(dvint(intgrnd,
  441. u3,getv(vlb,2),getv(vub,2)),
  442. u1,getv(vlb,0),getv(vub,0)),
  443. u2,getv(vlb,1),getv(vub,1) )
  444. else if n=3 then
  445. dvint(dvint(dvint(intgrnd,
  446. u2,getv(vlb,1),getv(vub,1)),
  447. u3,getv(vlb,2),getv(vub,2)),
  448. u1,getv(vlb,0),getv(vub,0) )
  449. else if n=4 then
  450. dvint(dvint(dvint(intgrnd,
  451. u1,getv(vlb,0),getv(vub,0)),
  452. u3,getv(vlb,2),getv(vub,2)),
  453. u2,getv(vlb,1),getv(vub,1) )
  454. else if n=5 then
  455. dvint(dvint(dvint(intgrnd,
  456. u2,getv(vlb,1),getv(vub,1)),
  457. u1,getv(vlb,0),getv(vub,0)),
  458. u3,getv(vlb,2),getv(vub,2) )
  459. else
  460. dvint(dvint(dvint(intgrnd,
  461. u3,getv(vlb,2),getv(vub,2)),
  462. u2,getv(vlb,1),getv(vub,1)),
  463. u1,getv(vlb,0),getv(vub,0)) >>
  464. else rerror(orthovec,17,"Bounds to DVOLINT must be vectors");
  465. return v1
  466. end$
  467. %Scalar Line Integral
  468. %====================
  469. procedure lineint(v,vline,tt);
  470. if vectorp(v) and vectorp(vline) and not vectorp(tt) then
  471. int(sub( u1=getv(vline,0), u2=getv(vline,1), u3=getv(vline,2),
  472. getv(v,0) * df(getv(vline,0),tt) * h1 +
  473. getv(v,1) * df(getv(vline,1),tt) * h2 +
  474. getv(v,2) * df(getv(vline,2),tt) * h3 ) , tt)
  475. else rerror(orthovec,18,"Incorrect arguments to LINEINT")$
  476. %Definite Scalar Line Integral
  477. %=============================
  478. procedure dlineint(v,vline,tt,tlb,tub);
  479. begin scalar integr,intval;
  480. if vectorp(tlb) or vectorp(tub)
  481. then rerror(orthovec,19,"Limits to DLINEINT must be scalar")
  482. else <<integr:=lineint(v,vline,tt);
  483. intval:=sub(tt=tub,integr)-sub(tt=tlb,integr)>>;
  484. return intval
  485. end$
  486. %
  487. %-------------------------------------------------------------------
  488. % SET DEFAULT COORDINATES TO CARTESIAN
  489. %
  490. % write "Cartesian coordinates selected by default";
  491. % write "If you wish to change this then type VSTART";
  492. % write "and follow the instructions given.";
  493. % write "u1,u2,u3 are reserved for coordinate names";
  494. % write "h1,h2,h3 are reserved for scale factor names";
  495. ctype:=1$u1:=x$u2:=y$u3:=z$h1:=1$h2:=1$h3:=1$
  496. % write "coordinate type = ",ctype;
  497. % write "coordinates = ",u1,",",u2,",",u3;
  498. % write "scale factors = ",h1,",",h2,",",h3;
  499. %-------------------------------------------------------------------
  500. endmodule;
  501. end;