fide1.red 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958
  1. COMMENT ***** NOTE *****;
  2. % For fastloading of this package please follow these steps:
  3. % faslout fide1;
  4. % in "fide1.red";
  5. % faslend;
  6. % load "fide1","gentran";
  7. % faslout fide;
  8. % in "fide.red"$
  9. % faslend;
  10. % For running this package the matrix, gentran, fide1 and fide packages
  11. % have to be loaded. However, loading fide is enough to make this
  12. % happen, since matrix, gentran and fide1 are automatically loaded.
  13. % Version 1.1.1 of the FIDE package is the result of porting the FIDE
  14. % package version 1.1.0 to REDUCE 3.5.
  15. off echo$
  16. load!-package 'matrix;
  17. %***********************************************************************
  18. %***** *****
  19. %***** P a c k a g e F I D E Ver. 1.1.1 November 2, 1993 *****
  20. %***** *****
  21. %***********************************************************************
  22. %** **
  23. %**FInite difference method for partial Differential Equation systems **
  24. %** **
  25. %***********************************************************************
  26. %** (C) 1991, Richard Liska **
  27. %** Faculty of Nuclear Science and Physical Engineering **
  28. %** Technical University of Prague **
  29. %** Brehova 7 **
  30. %** 115 19 Prague 1 **
  31. %** Czech Republic **
  32. %** Email: Richard Liska <tjerl@cspuni12.bitnet> **
  33. %** <tjerl@aci.cvut.cz> **
  34. %** This package can be distributed through REDUCE Network Library. **
  35. %***********************************************************************
  36. % The FIDE package consists of the following modules:
  37. %
  38. % EXPRES for transforming PDES into any orthogonal coordinate system.
  39. % IIMET for discretization of PDES by integro-interpolation method.
  40. % APPROX for determining the order of approximation of difference
  41. % scheme
  42. % CHARPOL for calculation of amplification matrix and characteristic
  43. % polynomial of difference scheme, which are needed in Fourier
  44. % stability analysis.
  45. % HURWP for polynomial roots locating necessary in verifying the von
  46. % Neumann stability condition.
  47. % LINBAND for generating the block of FORTRAN code, which solves a
  48. % system of linear algebraic equations with band matrix
  49. % appearing quite often in difference schemes.
  50. %
  51. % Changes since version 1.1:
  52. % Patches in SIMPINTERPOL and SIMPINTT 13/06/91
  53. % Patch in TDIFPAIR 08/07/91
  54. % Two FEXPR routines F2VAL, FPLUS changed to MACROs 17/03/92
  55. % Patches in IIM1, AMPMAT, HURW, CHARPOL for 3.5 01/11/93
  56. %***********************************************************************
  57. %***** *****
  58. %***** M O D U L E E X P R E S *****
  59. %***** *****
  60. %***********************************************************************
  61. module expres$
  62. % Author: R. Liska
  63. % Program EXPRES, Version REDUCE 3.4 05/1991
  64. symbolic$
  65. global '(!*outp)$ % declarations for 3.4
  66. fluid '(!*wrchri orig!* posn!*)$
  67. %global '(!*outp orig!* posn!*)$ % declarations for 3.3
  68. %fluid '(!*wrchri)$
  69. switch wrchri$
  70. global '(olddimension!* dimension!* coordindx!* cyclic1!* cyclic2!*
  71. sfprod!* nscal!*)$
  72. flag('(share),'eval)$ % So that SHARE recognized by FASL.
  73. share olddimension!*,dimension!*,coordindx!*,cyclic1!*,cyclic2!*,
  74. sfprod!*,nscal!*$
  75. nscal!*:=0$
  76. put('tensor,'tag,'tens)$
  77. put('tensor,'fn,'tensfn)$
  78. put('tensor,'evfn,'expres)$
  79. put('tens,'prifn,'tenspri)$
  80. flag('(tensor),'sprifn)$
  81. put('tens,'setprifn,'settenspri)$
  82. put('tensor,'typeletfn,'tenslet)$
  83. symbolic procedure ptensor x$
  84. 'tensor$
  85. symbolic procedure poptensor u$
  86. if null u then 'tensor else nil$
  87. deflist('((tensor ptensor)
  88. (tensop poptensor)
  89. (df getrtypecar)
  90. (diff getrtypecar)
  91. (!& ptensor)
  92. (!# ptensor)
  93. (!? ptensor)
  94. (grad ptensor)
  95. (div ptensor)
  96. (lapl ptensor)
  97. (curl ptensor)
  98. (vect ptensor)
  99. (dyad ptensor)
  100. (dirdf ptensor)),'rtypefn)$
  101. put('cons,'rtypefn,'getrtypecons)$
  102. put('rcons,'evfn,'evrcons)$
  103. remprop('cons,'psopfn)$
  104. symbolic procedure getrtypecons u$
  105. if getrtypecar u eq 'tensor then 'tensor
  106. else 'rcons$
  107. symbolic procedure evrcons(u,v)$
  108. rcons cdr u$
  109. symbolic procedure tensor u$
  110. for each a in u do
  111. <<put(a,'rtype,'tensop)$
  112. put(a,'avalue,list('tensor,mktensor(0 , (0 . 1)))) >>$
  113. deflist('((tensor rlis)),'stat)$
  114. symbolic procedure tenslet(u,v,typu,b,typv)$
  115. if not atom u then lprie list(" Non atom tensor variable ",u)
  116. else if b then
  117. <<if not eqcar(v,'tensor) then v:= mktensor(0,
  118. if eqcar(v,'!*sq) then cadr v else simp!* v)$
  119. rmsubs()$
  120. put(u,'rtype,'tensop)$
  121. put(u,'avalue,list('tensor,v)) >>
  122. else
  123. <<remprop(u,'rtype)$
  124. remprop(u,'avalue) >>$
  125. %======================================================================
  126. % Data structure for tensor quantities
  127. % ====================================
  128. % (tensor nr rnk val car !*sqvar!*)
  129. % nr - integer, should be equal to actual nscal!*, otherwise
  130. % the quantity has been defined in previous coor. system
  131. % number of coordinate system
  132. % rnk - integer, 0,1,2
  133. % rank of the tensor
  134. % 0 - scalar
  135. % 1 - vertor
  136. % 2 - dyad (matrix)
  137. % val - value
  138. % s.q. for rnk = 0
  139. % list of s.q.s for rnk = 1
  140. % list of lists of s.q.s for rnk = 2
  141. % !*sqvar!* used in resimplification routine
  142. %======================================================================
  143. % Smacro definitions for access of data structure subparts
  144. %======================================================================
  145. smacro procedure tensrnk u$
  146. % determines rank from cddr of datastructure
  147. car u$
  148. smacro procedure tensval u$
  149. % determines value from cddr of datastructure
  150. cadr u$
  151. symbolic procedure mktensor(rnk,u)$
  152. 'tensor . nscal!* . rnk . u . if !*resubs then !*sqvar!* else list nil$
  153. symbolic procedure settenspri(u,v)$
  154. if not atom u then lprie list(" Non-atom tensor variable ",u)
  155. else <<prin2!* u$
  156. prin2!* get('setq,'prtch)$
  157. tenspri v >>$
  158. symbolic procedure tenspri u$
  159. begin
  160. scalar rnk$
  161. u:=cddr u$
  162. rnk:=car u$
  163. u:=cadr u$
  164. if rnk=0 then
  165. <<pmaprin u$
  166. terpri!* t >>
  167. else if rnk=1 then
  168. <<tenspri1 u$
  169. orig!*:=0$
  170. terpri!* t >>
  171. else if rnk=2 then
  172. <<prin2!* " ( "$
  173. tenspri1 car u$
  174. for each i in cdr u do
  175. <<prin2!* " , "$
  176. terpri!* t$
  177. tenspri1 i >>$
  178. prin2!* " ) "$
  179. orig!*:=0$
  180. terpri!* t >>
  181. else lprie list(" Can't print tensor ",u," with rank ",rnk)
  182. end$
  183. symbolic procedure tenspri1 u$
  184. <<prin2!* " ( "$
  185. orig!*:=posn!*$
  186. pmaprin car u$
  187. for each i in cdr u do
  188. <<prin2!* " , "$
  189. terpri!* t$
  190. pmaprin i >>$
  191. orig!*:=orig!* - 3$
  192. prin2!* " ) " >>$
  193. symbolic procedure pmaprin u$
  194. maprin(!*outp:=prepsq!* u)$
  195. symbolic procedure updatedimen()$
  196. if olddimension!* = dimension!* then t
  197. else
  198. <<if dimension!* =2 then <<coordindx!* :='(2 1)$
  199. cyclic1!* :='(1 2)$
  200. cyclic2!* :='(2 1) >>
  201. else if dimension!* =3 then
  202. <<coordindx!* :='(3 2 1)$
  203. cyclic1!* :='(2 3 1)$
  204. cyclic2!* :='(3 1 2) >>
  205. else lprie list(" Can't handle dimension = ",dimension!*)$
  206. olddimension!* := dimension!* >>$
  207. symbolic procedure expres(expn,v)$
  208. express expn$
  209. symbolic procedure resimptens u$
  210. mktensor(caddr u,if caddr u=0 then resimp cadddr u
  211. else if caddr u=1 then for each a in cadddr u collect
  212. resimp a
  213. else if caddr u=2 then
  214. for each a in cadddr u collect
  215. for each b in a collect resimp b
  216. else lprie list("Can't handle tensor ",u,
  217. " with rank ",caddr u))$
  218. symbolic procedure express expn$
  219. begin
  220. scalar lst,matrx,rnk,opexpress$
  221. if not atom expn then go to op$
  222. if get(expn,'rtype) eq 'tensop and (rnk:=get(expn,'avalue)) and
  223. car rnk memq '(tensor tensop) and (rnk:=cadr rnk) then return
  224. if cadr rnk=nscal!* then
  225. if car cddddr rnk then rnk
  226. else resimptens rnk
  227. else lprie list(" You must rebind tensor ",expn,
  228. " in the new coordinate system")$
  229. return mktensor(0,simp!* expn)$
  230. op:if car expn = 'vect then return mktensor
  231. (1,testdim1 mapcar(cdr expn,function simp!*))
  232. else if car expn = 'dyad then return mktensor
  233. (2,testdim2 mapcar(cdr expn,function (lambda a$
  234. mapcar(a,function simp!*))))
  235. else if car expn eq 'tensor then return
  236. if cadr expn=nscal!* then
  237. if car cddddr expn then expn
  238. else resimptens expn
  239. else lprie list(" You must rebind tensor ",expn,
  240. " in the new coordinate system")$
  241. lst:=mapcar(cdr expn,function (lambda a$ cddr express a))$
  242. if (opexpress:=get(car expn,'express)) then
  243. <<rnk:=eval(opexpress . list mkquote lst)$
  244. return mktensor(car rnk,cadr rnk)>>$
  245. if get(car expn,'simpfn) then return mktensor(0,simp(
  246. car expn . mapcar(lst,function(lambda a$
  247. if car a=0 then list('!*sq,cdr a,nil)
  248. else typerr(expn," well formed scalar "))) ))$
  249. lst:=mapcar(lst,function(lambda a$
  250. if car a=0 then prepsq cdr a
  251. else typerr(expn," well formed tensor")))$
  252. return mktensor(0,!*k2q(car expn.lst))
  253. end$
  254. procedure testdim1 u$
  255. if length u=dimension!* then u
  256. else <<lprie "Bad number of vector components"$u>>$
  257. procedure testdim2 u$
  258. begin
  259. scalar x$
  260. if length u = dimension!* then t
  261. else go to er$
  262. x:=u$
  263. a:if length car u = dimension!* then t
  264. else go to er$
  265. x:=cdr x$
  266. if x then go to a$
  267. return u$
  268. er:lprie "Bad number of dyad components"$
  269. return u
  270. end$
  271. %======================================================================
  272. % Procedures in EXPRESS properties of operators are returning
  273. % (rnk val), their argument is list of (rnk val)
  274. symbolic procedure vectors arglist$
  275. for each i in arglist do
  276. <<put(i,'rtype,'tensop)$
  277. put(i,'simpfn,'simpiden)$
  278. put(i,'avalue,list('tensop,
  279. mktensor(1,reverse
  280. for each a in coordindx!* collect
  281. simp list(i,a) )) )>>$
  282. deflist('((vectors rlis)),'stat)$
  283. symbolic procedure dyads arglist$
  284. for each i in arglist do
  285. <<put(i,'rtype,'tensop)$
  286. put(i,'simpfn,'simpiden)$
  287. put(i,'avalue,list('tensop,
  288. mktensor(2,reverse
  289. for each a in coordindx!* collect
  290. reverse
  291. for each b in coordindx!* collect
  292. simp list(i,a,b)))) >>$
  293. deflist('((dyads rlis)),'stat)$
  294. symbolic procedure plusexpress u$
  295. begin
  296. scalar z$
  297. z:=car u$
  298. a:u:=cdr u$
  299. if null u then return z$
  300. z:=plus2ex(z,car u)$
  301. go to a
  302. end$
  303. put('plus,'express,'plusexpress)$
  304. symbolic procedure plus2ex(x,y)$
  305. begin
  306. scalar mtx,mty,slx,sly,rnk,ans,ans1$
  307. rnk:=tensrnk x$
  308. if not(rnk=tensrnk y) then lprie "Tensor mishmash"$
  309. if rnk=0 then return list(rnk,addsq(cadr x,cadr y))
  310. else if rnk=1 then
  311. <<slx:=tensval x$
  312. sly:=tensval y$
  313. while slx do
  314. <<ans:=addsq(car slx,car sly) . ans$
  315. slx:=cdr slx$
  316. sly:=cdr sly>>$
  317. ans:= list(1,reverse ans) >>
  318. else if rnk=2 then
  319. <<mtx:=tensval x$
  320. mty:=tensval y$
  321. while mtx do
  322. <<slx:=car mtx$
  323. sly:=car mty$
  324. ans1:=nil$
  325. while slx do
  326. <<ans1:=addsq(car slx,car sly) . ans1$
  327. slx:=cdr slx$
  328. sly:=cdr sly>>$
  329. ans:=reverse ans1 . ans$
  330. mtx:=cdr mtx$
  331. mty:=cdr mty>>$
  332. ans:=list(2,reverse ans) >>$
  333. return ans
  334. end$
  335. symbolic procedure timesexpress u$
  336. begin
  337. scalar z$
  338. z:=car u$
  339. a:u:=cdr u$
  340. if null u then return z$
  341. z:=times2ex(z,car u)$
  342. go to a
  343. end$
  344. put('times,'express,'timesexpress)$
  345. symbolic procedure times2ex(x,y)$
  346. begin
  347. scalar rnkx,rnky$
  348. rnkx:=tensrnk x$
  349. rnky:=tensrnk y$
  350. return
  351. if rnkx=0 then list(rnky,times0ex(tensval x,tensval y,rnky))
  352. else if rnky=0 then list(rnkx,times0ex(tensval y,tensval x,rnkx))
  353. else lprie " Tensor mishmash "
  354. end$
  355. symbolic procedure times0ex(x,y,rnk)$
  356. if rnk=0 then multsq(x,y)
  357. else if rnk=1 then
  358. for each a in y collect multsq(x,a)
  359. else if rnk=2 then
  360. for each a in y collect
  361. for each b in a collect multsq(x,b)
  362. else lprie " Tensor mishmash "$
  363. symbolic procedure minusexpress expn$
  364. timesexpress list(list(0,cons(-1,1)),car expn)$
  365. put('minus,'express,'minusexpress)$
  366. symbolic procedure differenceexpress expn$
  367. plusexpress list(car expn,minusexpress list cadr expn)$
  368. put('difference,'express,'differenceexpress)$
  369. symbolic procedure quotientexpress expn$
  370. if tensrnk cadr expn = 0 then
  371. times2ex(list(0,simp!* list('recip,prepsq tensval cadr expn)),
  372. car expn)
  373. else lprie " Tensor mishmash "$
  374. put('quotient,'express,'quotientexpress)$
  375. symbolic procedure exptexpress expn$
  376. if tensrnk car expn=0 and tensrnk cadr expn = 0 then
  377. list(0,simp!* list('expt,
  378. prepsq tensval car expn,
  379. prepsq tensval cadr expn))
  380. else lprie " Tensor mishmash "$
  381. put('expt,'express,'exptexpress)$
  382. symbolic procedure recipexpress expn$
  383. if tensrnk car expn = 0 then
  384. list(0,simp!* list('recip,
  385. prepsq tensval car expn))
  386. else lprie " Tensor mishmash "$
  387. put('recip,'express,'recipexpress)$
  388. symbolic procedure inprodexpress expn$
  389. begin
  390. scalar arg1,arg2,rnk1,rnk2$
  391. arg1:=tensval car expn$
  392. arg2:=tensval cadr expn$
  393. rnk1:=tensrnk car expn$
  394. rnk2:=tensrnk cadr expn$
  395. return
  396. if rnk1=1 then inprod1ex(arg1,arg2,rnk2)
  397. else if rnk1=2 then inprod2ex(arg1,arg2,rnk2)
  398. else lprie " Tensor mishmash "
  399. end$
  400. put('cons,'express,'inprodexpress)$
  401. symbolic procedure inprod1ex(x,y,rnk)$
  402. begin
  403. scalar lstx,lsty,mty,z,zz$
  404. lstx:=x$
  405. lsty:=y$
  406. if rnk=1 then
  407. <<z:=nil . 1$
  408. while lstx do
  409. <<z:=addsq(z,multsq(car lstx,car lsty))$
  410. lstx:=cdr lstx$
  411. lsty:=cdr lsty>>$
  412. z:=list(0,z)>>
  413. else if rnk=2 then
  414. <<z:=nil$
  415. lsty:=mty:=copy2(y,t)$
  416. while car mty do
  417. <<lstx:=x$
  418. lsty:=mty$
  419. zz:=nil . 1$
  420. while lstx do
  421. <<zz:=addsq(zz,multsq(car lstx,caar lsty))$
  422. rplaca(lsty,cdar lsty)$
  423. lsty:=cdr lsty$
  424. lstx:=cdr lstx>>$
  425. z:=nconc(z,list zz) >>$
  426. z:=list(1,z)>>
  427. else lprie " Tensor mishmash "$
  428. return z
  429. end$
  430. symbolic procedure inprod2ex(x,y,rnk)$
  431. begin
  432. scalar lstx,lsty,mtx,z,zz$
  433. mtx:=x$
  434. if rnk=1 then
  435. while mtx do
  436. <<z:=nconc(z,cdr inprod1ex(car mtx,y,1))$
  437. mtx:=cdr mtx>>
  438. else if rnk=2 then
  439. while mtx do
  440. <<z:=nconc(z,cdr inprod1ex(car mtx,copy2(y,t),2))$
  441. mtx:=cdr mtx>>
  442. else lprie " Tensor mishmash "$
  443. return list(rnk,z)
  444. end$
  445. symbolic procedure outexpress expn$
  446. begin
  447. scalar x,y,z$
  448. x:=tensval car expn$
  449. y:=tensval cadr expn$
  450. if tensrnk car expn=1 and tensrnk cadr expn=1 and null cddr expn then
  451. for each i in x do z:=mapcar(y,function(lambda a$
  452. multsq(a,i))) . z
  453. else lprie list(" Outer product of ",expn)$
  454. return list(2,reverse z)
  455. end$
  456. put('!&,'express,'outexpress)$
  457. flag('(!&),'tensfn)$
  458. symbolic procedure copy2(x,p)$
  459. if null x then nil else
  460. if p then copy2(car x,nil) . copy2(cdr x,t)
  461. else car x . copy2(cdr x,nil)$
  462. symbolic procedure listar(arg,j)$
  463. if j=1 then car arg
  464. else if j=2 then cadr arg
  465. else if j=3 then caddr arg
  466. else lprie list(" LISTAR ",arg,j)$
  467. symbolic procedure listarsq(arg,j)$
  468. prepsq listar(arg,j)$
  469. symbolic procedure dinprod expn$
  470. begin
  471. scalar x,y,z,xx,yy$
  472. x:=tensval car expn$
  473. y:=copy2(tensval cadr expn,t)$
  474. z:=nil . 1$
  475. if not(tensrnk car expn=2 and tensrnk cadr expn=2 and null cddr expn)
  476. then lprie list(" D-scalar product of ",expn)$
  477. a:if null x and null y then go to d
  478. else if null x or null y then go to er$
  479. xx:=car x$
  480. yy:=car y$
  481. b:if null xx and null yy then go to c
  482. else if null xx or null yy then go to er$
  483. z:=addsq(z,multsq(car xx,car yy))$
  484. xx:=cdr xx$
  485. yy:=cdr yy$
  486. go to b$
  487. c:x:=cdr x$
  488. y:=cdr y$
  489. go to a$
  490. d:return list(0,z)$
  491. er:lprie list(" EXPRESS error ",expn," D-S dyads of dif. size")
  492. end$
  493. put('!#,'express,'dinprod)$
  494. put('hash,'express,'dinprod)$
  495. put('hash,'rtypefn,'ptensor)$
  496. symbolic procedure antisymsum(u,v)$
  497. if dimension!* = 2 then difmul(car u,cadr u,cadr v,car v)
  498. else if dimension!* = 3 then list
  499. (difmul(cadr u,caddr u,caddr v,cadr v),
  500. difmul(caddr u,car u,car v,caddr v),
  501. difmul(car u,cadr u,cadr v,car v))
  502. else lprie list(" ANTISYMSUM ",u,v)$
  503. symbolic procedure difmul(a,b,c,d)$
  504. % A*C-B*D$
  505. addsq(multsq(a,c),negsq multsq(b,d))$
  506. symbolic procedure vectprod expn$
  507. begin
  508. scalar x,y,rnx,rny$
  509. x:=tensval car expn$
  510. y:=tensval cadr expn$
  511. rnx:=tensrnk car expn$
  512. rny:=tensrnk cadr expn$
  513. if rnx=1 and rny=1 then return
  514. list(dimension!* - 2,antisymsum(x,y))
  515. else if rnx=2 and rny=1 then return
  516. list(dimension!* - 1,mapcar(x,function(lambda a$
  517. antisymsum(a,y))))
  518. else if rnx=1 and rny=2 then return
  519. list(dimension!* - 1,
  520. if dimension!*=3 then
  521. tp1 copy2(mapcar(tp1 copy2(y,t),
  522. function(lambda a$ antisymsum(x,a))),t)
  523. else mapcar(tp1 copy2(y,t),
  524. function(lambda a$ antisymsum(x,a)) ))
  525. else lprie list(" VECTPROD of ",expn)
  526. end$
  527. put('!?,'express,'vectprod)$
  528. algebraic operator diff$
  529. symbolic procedure gradexpress expn$
  530. begin
  531. scalar arg,vt,ans,row,z$
  532. arg:=tensval car expn$
  533. vt:=tensrnk car expn$
  534. if vt=0 then
  535. for each i in coordindx!* do
  536. ans:=simp!* list('quotient,
  537. list('diff,
  538. list('!*sq,arg,nil),
  539. getel list('coordinats,i)),
  540. getel list('sf,i)) . ans
  541. else if vt=1 then
  542. for each i in coordindx!* do
  543. <<row:=nil$
  544. for each j in coordindx!* do
  545. <<z:=list('diff,
  546. listarsq(arg,j),
  547. getel list('coordinats,i))$
  548. z:=list list('quotient,
  549. z,
  550. getel list('sf,i))$
  551. for each k in coordindx!* do
  552. z:=list('times,
  553. getel list('christoffel,i,j,k),
  554. listarsq(arg,k)) . z$
  555. row:=simp!*('plus.z) . row>>$
  556. ans:=row . ans>>
  557. else lprie list(" GRAD of ",expn)$
  558. return list(vt+1,ans)
  559. end$
  560. put('grad,'express,'gradexpress)$
  561. symbolic procedure divexpress expn$
  562. begin
  563. scalar arg,vt,ans,z$
  564. arg:=tensval car expn$
  565. vt:=tensrnk car expn$
  566. if vt=1 then
  567. <<for each i in coordindx!* do
  568. z:=list('diff,
  569. list('times,
  570. sfprod!*,
  571. listarsq(arg,i),
  572. list('recip,
  573. getel list('sf,i))),
  574. getel list('coordinats,i)) . z$
  575. z:='plus . z$
  576. z:=list('quotient,
  577. z,
  578. sfprod!*)$
  579. ans:=simp!* z>>
  580. else if vt=2 then
  581. for each i in coordindx!* do
  582. <<z:=nil$
  583. for j:=1:dimension!* do
  584. <<z:=list('quotient,
  585. list('diff,
  586. list('times,
  587. listarsq(listar(arg,j),i),
  588. sfprod!*,
  589. list('recip,
  590. getel list('sf,j))),
  591. getel list('coordinats,j)),
  592. sfprod!*) . z$
  593. for l:=1:dimension!* do
  594. z:=list('times,
  595. listarsq(listar(arg,j),l),
  596. getel list('christoffel,j,i,l)) . z>>$
  597. ans:=simp!*('plus.z) . ans>>
  598. else lprie list(" DIV of ",expn)$
  599. return list(vt-1,ans)
  600. end$
  601. put('div,'express,'divexpress)$
  602. symbolic procedure laplexpress expn$
  603. begin
  604. scalar arg,vt,ans$
  605. arg:=tensval car expn$
  606. vt:=tensrnk car expn$
  607. if vt=0 then
  608. <<for i:=1:dimension!* do
  609. ans:=list('diff,
  610. list('times,
  611. sfprod!*,
  612. list('expt,
  613. getel list('sf,i),
  614. -2),
  615. list('diff,
  616. list('!*sq,arg,nil),
  617. getel list('coordinats,i))),
  618. getel list('coordinats,i)).ans$
  619. ans:=list(0,simp!* list('quotient,
  620. 'plus . ans,
  621. sfprod!*))>>
  622. else if vt=1 then
  623. ans:=divexpress list gradexpress expn
  624. else lprie list(" LAPLACIAN of ",expn)$
  625. return ans
  626. end$
  627. put('lapl,'express,'laplexpress)$
  628. symbolic procedure curlexpress expn$
  629. begin
  630. scalar arg,vt,ans,ic1,ic2$
  631. arg:=tensval car expn$
  632. vt:=tensrnk car expn$
  633. if vt=1 then
  634. for each i in (if dimension!* = 3 then coordindx!*
  635. else '(1) ) do
  636. <<ic1:=listar(cyclic1!*,i)$
  637. ic2:=listar(cyclic2!*,i)$
  638. ans:=simp!* list('times,
  639. getel list('sf,i),
  640. list('recip,sfprod!*),
  641. list('difference,
  642. list('diff,
  643. list('times,
  644. getel list('sf,ic2),
  645. listarsq(arg,ic2)),
  646. getel list('coordinats,ic1)),
  647. list('diff,
  648. list('times,
  649. getel list('sf,ic1),
  650. listarsq(arg,ic1)),
  651. getel list('coordinats,ic2))))
  652. . ans>>
  653. else lprie list(" CURL of ",expn)$
  654. return (if dimension!* = 3 then list(1,ans)
  655. else list(0,car ans))
  656. end$
  657. put('curl,'express,'curlexpress)$
  658. flag('(cons grad div lapl curl tens vect dyad dirdf !& !# !?)
  659. ,'tensfn)$
  660. symbolic procedure exscalval u$
  661. begin
  662. scalar fce,args$
  663. fce:=car u$
  664. args:=mapcar(cdr u,function(lambda a$cddr express a))$
  665. fce:=eval(get(fce,'express) . list mkquote args)$
  666. if car fce=0 then return cadr fce
  667. else typerr(u," is not scalar ")$
  668. return (nil . 1)
  669. end$
  670. algebraic$
  671. infix #,?,&$
  672. precedence .,**$
  673. precedence #,.$
  674. precedence ?,#$
  675. precedence &,?$
  676. symbolic flag('(cons !# !? div lapl curl dirdf),'full)$
  677. symbolic for each a in '(cons !# !? div lapl curl dirdf)
  678. do put(a,'simpfn,'exscalval)$
  679. symbolic procedure scalefactors transf$
  680. begin
  681. scalar var$
  682. dimension!*:=car transf$
  683. transf:=cdr transf$
  684. if dimension!*=2 then
  685. <<var:=cddr transf$
  686. transf:=list( car transf,cadr transf)>>
  687. else if dimension!*:=3 then
  688. <<var:=cdddr transf$
  689. transf:=list(car transf,cadr transf,caddr transf)>>
  690. else lprie list(" Can't handle dimension = ",dimension!*)$
  691. if dimension!*=length var then t
  692. else lprie list(" Transformation ",transf,var)$
  693. for i:=1:dimension!* do
  694. setel(list('coordinats,i),listar(var,i))$
  695. for row:=1:dimension!* do
  696. for col:=1:dimension!* do
  697. setel(list('jacobian,row,col),
  698. aeval list('df,
  699. listar(transf,col),
  700. getel list('coordinats ,row)))$
  701. updatedimen()$
  702. rscale()
  703. end$
  704. deflist('((scalefactors rlis)),'stat)$
  705. array jacobian(3,3),coordinats (3),sf(3),christoffel(3,3,3)$
  706. procedure rscale()$
  707. begin
  708. sfprod!*:=1$
  709. nscal!*:=nscal!* + 1$
  710. for row:=1:dimension!* do
  711. <<for col:=1:(row-1) do
  712. <<sf(row):=gcov(row,col)$
  713. if sf(row)=0 then nil
  714. else write " WARNING: Coordinate system is nonorthogonal"
  715. ," unless following simplifies to zero: ",
  716. sf(row) >>$
  717. write sf(row):=sqrt gcov(row,row)$
  718. sfprod!*:=sfprod!* *sf(row)>>$
  719. on nero$
  720. for i:=1:dimension!* do for j:=1:dimension!* do
  721. for k:=1:dimension!* do begin christoffel(i,j,k):=
  722. ((if i=j then df(sf(j),coordinats (k)) else 0)
  723. -(if i=k then df(sf(k),coordinats (j)) else 0))
  724. /(sf(j)*sf(k))$
  725. if wrchri(a)=0 then write christoffel(i,j,k):=
  726. christoffel(i,j,k) end$
  727. off nero
  728. end$
  729. procedure gcov(j,k)$
  730. for l:=1:dimension!* sum jacobian(j,l)*jacobian(k,l)$
  731. symbolic$
  732. symbolic procedure simpwrchri u$
  733. if !*wrchri then nil . 1
  734. else 1 . 1$
  735. put('wrchri,'simpfn,'simpwrchri)$
  736. symbolic procedure rmat$
  737. 'dyad . cdr matstat()$
  738. symbolic procedure formdyad(u,v,m)$
  739. 'list . mkquote 'dyad . cddr formmat(u,v,m)$
  740. put('dyad,'stat,'rmat)$
  741. put('dyad,'formfn,'formdyad)$
  742. symbolic procedure dirdfexpress expn$
  743. begin
  744. scalar arg,vt,direc,ans,z,dj,di,argj,sfj,sfi,cooj$
  745. arg:=cadr expn$
  746. vt:=tensrnk arg$
  747. direc:=car expn$
  748. if not (tensrnk direc=1) then return
  749. lprie list (" Direction in DIRDF is not a vector ",expn)$
  750. if vt=0 then return inprodexpress list (direc,
  751. gradexpress list arg)$
  752. arg:=tensval arg$
  753. direc:=tensval direc$
  754. if not vt=1 then return
  755. lprie list (" Argument of DIRDF is dyadic ",expn)$
  756. for each i in coordindx!* do
  757. <<z:=nil$
  758. di:=listarsq(direc,i)$
  759. sfi:=getel list('sf,i)$
  760. for j:=1:dimension!* do
  761. <<dj:=listarsq(direc,j)$
  762. argj:=listarsq(arg,j)$
  763. sfj:=getel list('sf,j)$
  764. cooj:=getel list('coordinats,j)$
  765. z:=list('times,
  766. dj,
  767. list('recip,sfj),
  768. list('diff,
  769. listarsq(arg,i),
  770. cooj)) . z$
  771. z:=list('times,
  772. di,
  773. argj,
  774. list('recip,sfi),
  775. list('recip,sfj),
  776. list('df,sfi,cooj)) . z$
  777. z:=list('minus,
  778. list('times,
  779. dj,
  780. argj,
  781. list('recip,sfi),
  782. list('recip,sfj),
  783. list('df,
  784. sfj,
  785. getel list('coordinats,i)))) . z>>$
  786. z:='plus . z$
  787. z:=simp!* z$
  788. ans:=z . ans >>$
  789. return list(1,ans)
  790. end$
  791. put('dirdf,'express,'dirdfexpress)$
  792. symbolic procedure dfexpress expn$
  793. begin
  794. scalar arg,vt,rest$
  795. arg:=tensval car expn$
  796. vt:=tensrnk car expn$
  797. rest:=cdr expn$
  798. rest:=mapcar(rest,function(lambda a$
  799. if tensrnk a=0 then
  800. if atom tensval a then tensval a
  801. else if cdr tensval a=1 and
  802. numberp car tensval a then
  803. car tensval a
  804. else !*q2k tensval a
  805. else lprie list(" Bad arg of DF ",
  806. expn)))$
  807. if vt=0 then return list(0,simpdf(list('!*sq,arg,t) . rest))
  808. else if vt=1 then return list(1,mapcar(arg,function(
  809. lambda a$simpdf(list('!*sq,a,t) . rest))) )
  810. else if vt=2 then return list(2,mapcar(arg,function(
  811. lambda a$mapcar(a,function(
  812. lambda b$simpdf(list('!*sq,b,t) . rest))) )))
  813. else lprie list(" Bad tensor in DF ",expn)
  814. end$
  815. put('df,'express,'dfexpress)$
  816. symbolic procedure diffexpress expn$
  817. begin
  818. scalar arg,vt,rest$
  819. arg:=tensval car expn$
  820. vt:=tensrnk car expn$
  821. rest:=cdr expn$
  822. rest:=mapcar(rest,function(lambda a$
  823. if tensrnk a=0 then
  824. if atom tensval a then tensval a
  825. else if cdr tensval a=1 and
  826. numberp car tensval a then
  827. car tensval a
  828. else !*q2k tensval a
  829. else lprie list(" Bad arg of DIFF ",
  830. expn)))$
  831. if vt=0 then return list(0,simp('diff . (prepsq arg . rest)))
  832. else if vt=1 then return list(1,mapcar(arg,function(
  833. lambda a$simp('diff . (prepsq a . rest))) ))
  834. else if vt=2 then return list(2,mapcar(arg,function(
  835. lambda a$mapcar(a,function(
  836. lambda b$simp('diff . (prepsq b . rest))) ))))
  837. else lprie list(" Bad tensor in DIFF ",expn)
  838. end$
  839. put('diff,'express,'diffexpress)$
  840. algebraic$
  841. scalefactors 3,x,y,z,x,y,z$
  842. endmodule$
  843. %***********************************************************************
  844. %***** *****
  845. %***** M O D U L E I I M E T *****
  846. %***** *****
  847. %***********************************************************************
  848. module iimet$
  849. % Author: R. Liska
  850. % Program IIMET, Version REDUCE 3.4 05/1991$
  851. symbolic$
  852. global '(cursym!* !*val dimension!*)$
  853. fluid '(!*exp alglist!*)$
  854. symbolic procedure array u$
  855. begin
  856. scalar msg,erfg$
  857. msg:=!*msg$
  858. !*msg:=nil$
  859. erfg:=erfg!*$
  860. erfg!*:=nil$
  861. arrayfn('symbolic,
  862. mapcar (u,function(lambda a$car a . sub1lis cdr a)))$
  863. erfg!*:=erfg$
  864. !*msg:=msg
  865. end$
  866. symbolic procedure sub1lis u$
  867. if null u then nil else ((car u - 1) . sub1lis cdr u)$
  868. sfprod!*:=1$
  869. global'(date!*!*)$
  870. date!*!*:= "IIMET Ver 1.1 17/05/91"$
  871. put('version,'stat,'rlis)$
  872. put('diff,'simpfn,'simpiden)$
  873. global '(coords!* icoords!* dvars!* grids!* given!* same!*
  874. difml!* iobjs!* !*twogrid !*eqfu !*fulleq !*centergrid)$
  875. switch twogrid,eqfu,fulleq,centergrid$
  876. !*twogrid:=t$ % Given functions can be on both grids.
  877. !*eqfu:=nil$ % During pattern matching the given and
  878. % looked for functions are different.
  879. !*fulleq:=t$ % Optimalization is performed on both sides of PDE.
  880. !*centergrid:=t$ % Centers of grid cells are in points I
  881. % (otherwise in I+1/2).
  882. icoords!*:='(i j k l m n i1 j1 k1 l1 m1 n1)$
  883. % Indices which are given implicit.
  884. procedure coordfn$
  885. % Stat procedure of the COORDINATES statement, which defines indexes
  886. % of coordinates.
  887. begin
  888. scalar cor,icor$
  889. flag('(into),'delim)$
  890. cor:=remcomma xread nil$
  891. remflag('(into),'delim)$
  892. if cursym!* eq 'into then
  893. icor:=remcomma xread nil
  894. else if cursym!* eq '!*semicol!* then
  895. icor:=icoords!*
  896. else return symerr('coordfn,t)$
  897. return list('putcor,
  898. mkquote cor,
  899. mkquote icor)
  900. end$
  901. put('coordinates,'stat,'coordfn)$
  902. flag('(putcor),'nochange)$
  903. procedure putcor(u,v)$
  904. begin
  905. scalar j$
  906. j:=1$
  907. coords!*:=u$
  908. while u do
  909. <<if not idp car u then msgpri
  910. (" Coordinate ",car u," must be identifier",nil,'hold)$
  911. if not(idp car v or fixp car v) then msgpri
  912. (" Index ",car v," must be identifier or integer",nil,'hold)$
  913. put(car u,'index,list car v)$
  914. put(car v,'coord,list car u)$
  915. put(car u,'ngrid,j)$
  916. j:=j+1$
  917. put(car u,'simpfn,'simpiden)$
  918. u:=cdr u$
  919. v:=cdr v >>
  920. end$
  921. procedure tcar u$
  922. if pairp u then car u
  923. else u$
  924. procedure grid u$
  925. % Procedure definning the statement GRID.
  926. eval list(get(car u,'grid),
  927. mkquote cdr u)$
  928. put('grid,'stat,'rlis)$
  929. put('uniform,'grid,'gridunif)$
  930. procedure gridunif u$
  931. flag(u,'uniform)$
  932. procedure dependence u$
  933. % Procedure definning the statemnt DEPENDENCE.
  934. begin
  935. scalar x,y,z,gg,l,te,yy,y1,yl$
  936. if null coords!* then rederr
  937. " Coordinates have not been defined yet"$
  938. gg:=explode '!*grid$
  939. l:=list(length coords!* + 1)$
  940. a:x:=car u$
  941. y:=car x$
  942. if idp y then if not y memq dvars!* then dvars!*:=y . dvars!*
  943. else nil
  944. else return msgpri(" Variable ",y," must be identifier",nil,
  945. 'hold)$
  946. z:=cdr x$
  947. x:=car z$
  948. if not numberp x then go to b$
  949. if x=1 then apply('vectors,list y)
  950. else if x=2 then apply('dyads,list y)
  951. else if x=0 then t
  952. else return errpri2(car u,'hold)$
  953. z:=cdr z$
  954. b:yl:=nil$
  955. yy:=explode y$
  956. te:=aeval y$
  957. if eqcar(te,'tensor) then te:=caddr te
  958. else te:=nil$
  959. if te=1 then
  960. for i:=1:dimension!* do
  961. <<y1:=intern compress append(yy,explode i)$
  962. yl:=y1 . yl$
  963. setk1(list(y,i),y1,t)$
  964. x:=intern compress append(explode y1,gg)$
  965. % The name of an array filled with grids of Y(I)
  966. put(y1,'grid,x)$
  967. eval list('array,mkquote list(x . l)) >>
  968. else if te=2 then
  969. for i:=1:dimension!* do
  970. for j:=1:dimension!* do
  971. <<y1:=intern compress append(yy,append(explode i,
  972. explode j))$
  973. yl:=y1 . yl$
  974. setk1(list(y,i,j),y1,t)$
  975. x:=intern compress append(explode y1,gg)$
  976. % The name of an array filled with grids of Y(I)
  977. put(y1,'grid,x)$
  978. eval list('array,mkquote list(x . l)) >>
  979. else
  980. <<yl:=y . yl$
  981. x:=intern compress append(yy,gg)$
  982. put(y,'grid,x)$
  983. eval list('array,mkquote list(x . l)) >>$
  984. for each a in yl do put(a,'simpfn, 'simpiden)$
  985. put(y,'names,reverse yl)$
  986. if te member '(1 2) then
  987. <<put(y,'kkvalue,get(y,'kvalue))$
  988. remprop(y,'kvalue) >>$
  989. for each v in z do
  990. if v memq coords!* then
  991. for each w in yl do depend1(w,v,t)
  992. else msgpri(" Identifier ",v," is not coordinate",nil,'hold)$
  993. u:=cdr u$
  994. if u then go to a$
  995. return nil
  996. end$
  997. put('dependence,'stat,'rlis)$
  998. procedure given u$
  999. begin
  1000. scalar x,xnam$
  1001. a:x:=car u$
  1002. xnam:=get(x,'names)$
  1003. if not idp x then msgpri
  1004. (" Variable ",x," must be identifier",nil,'hold)
  1005. else if xnam then given!* := union(xnam,given!*)
  1006. else msgpri
  1007. (" Identifier ",x," is not variable",nil,'hold)$
  1008. u:=cdr u$
  1009. if u then go to a$
  1010. return nil
  1011. end$
  1012. put('given,'stat,'rlis)$
  1013. procedure cleargiven$
  1014. <<remflag(given!*,'noeq)$
  1015. given!*:=nil >>$
  1016. put('cleargiven,'stat,'endstat)$
  1017. flag('(cleargiven),'eval)$
  1018. newtok'(( !. !. ) isgr)$
  1019. algebraic infix ..$
  1020. grids!* := '(one half)$
  1021. procedure trlis$
  1022. % Stat procedure of the statement ISGRID.
  1023. begin
  1024. scalar x$
  1025. put('!*,'newnam,'tims)$
  1026. x:=rlis()$
  1027. remprop('!*,'newnam)$
  1028. return x
  1029. end$
  1030. procedure formtr(u,vars,mode)$
  1031. list('isgrid,mkquote cdr u)$
  1032. procedure isgrid u$
  1033. % Proceudre definning the statement ISGRID.
  1034. begin
  1035. scalar x,y,z,z1,te,gd,lz,lz1$
  1036. a:x:=car u$
  1037. y:=car x$
  1038. x:=cdr x$
  1039. if not(y memq dvars!*) then return msgpri
  1040. (" Identifier ",y," is not variable",nil,'hold)$
  1041. if null x then go to er$
  1042. te:=aeval y$
  1043. te:=if eqcar(te,'tensor) then caddr te
  1044. else nil$
  1045. if (te=1 and null atom x and indexp car x and gridp cdr x) or
  1046. (te=2 and null atom x and indexp car x and null atom cdr x
  1047. and indexp cadr x and gridp cddr x) or
  1048. ((te=0 or null te) and null atom x and gridp x) then t
  1049. else go to er$
  1050. if te=1 then
  1051. <<z:=car x$
  1052. x:=cdr x$
  1053. lz:=nil$
  1054. if numberp z then lz:=z . lz
  1055. else for i:=1:dimension!* do lz:=i . lz$
  1056. for each a in lz do mapc(x,function(lambda b$
  1057. setel(list(get(cadr assoc(list(y,a),
  1058. get(y,'kkvalue)),
  1059. 'grid),
  1060. car b),
  1061. cadr b . nil))) >>
  1062. else if te=2 then
  1063. <<z:=car x$
  1064. z1:=cadr x$
  1065. x:=cddr x$
  1066. lz:=lz1:=nil$
  1067. if numberp z then lz:=z . lz
  1068. else for i:=1:dimension!* do lz:=i . lz$
  1069. if numberp z1 then lz1:=z1 . lz1
  1070. else for i:=1:dimension!* do lz1:=i . lz1$
  1071. for each a in lz do for each b in lz1 do
  1072. mapc(x,function(lambda c$
  1073. setel(list(get(cadr assoc(list(y,a,b),
  1074. get(y,'kkvalue)),
  1075. 'grid),
  1076. car c),
  1077. cadr c . nil))) >>
  1078. else mapc(x,function(lambda c$
  1079. setel(list(get(y,'grid),car c),cadr c . nil)))$
  1080. u:=cdr u$
  1081. if u then go to a$
  1082. return nil$
  1083. er:errpri2(car u,'hold)
  1084. end$
  1085. put('isgrid,'stat,'trlis)$
  1086. put('isgrid,'formfn,'formtr)$
  1087. procedure indexp u$
  1088. u eq 'tims or (numberp u and 0<u and u<dimension!*)$
  1089. procedure gridp u$
  1090. null atom u and
  1091. begin
  1092. scalar x$
  1093. a:x:=car u$
  1094. if null atom x and car x eq 'isgr and null atom cdr x
  1095. and cadr x memq coords!* and null atom cddr x and
  1096. caddr x memq grids!* then rplaca(u,cdr x)
  1097. else return nil$
  1098. x:=car u$
  1099. rplaca(x,get(car x,'ngrid))$
  1100. u:=cdr u$
  1101. if u then go to a$
  1102. return t
  1103. end$
  1104. procedure grideq u$
  1105. begin
  1106. scalar x,y,z$
  1107. x:=u$
  1108. a:y:=car x$
  1109. if not car y memq dvars!* then return msgpri(
  1110. "Identifier ",car y," is not variable",nil,'hold)$
  1111. z:=cdr y$
  1112. b:if not atom car z and caar z eq 'isgr and cadar z memq coords!* and
  1113. caddar z memq grids!* then put(car y,cadar z,caddar z)
  1114. else return errpri2(u,'hold)$
  1115. z:=cdr z$
  1116. if z then go to b$
  1117. x:=cdr x$
  1118. if x then go to a$
  1119. return nil
  1120. end$
  1121. put('grideq,'stat,'rlis)$
  1122. fluid '(coord unvars sunvars interpolp novars ncor nvar intp icor gvar
  1123. hi hip1 hip2 him1 him2 lhs rhs lsun lun xxgrid resar)$
  1124. % GVAR - grid on which is actual equation integrated
  1125. % NVAR - number of actual equation in IIM21
  1126. % NCOR - number of actual coordinate
  1127. % UNVARS - list of looked for functions
  1128. % NOVARS - list of functions controlled by the SAME statement
  1129. % SUNVARS - list of looked for functions, which are not controlled by
  1130. % SAME, and of given functions, which are not controlled by
  1131. % SAME and which can be only on one grid (if OFF TWOGRID)
  1132. % in case ON TWOGRID given functions are not in SUNVARS
  1133. % distinguishing of given functions defined in ISGRID is done
  1134. % in procedures TWOGRIDP and GETGRID
  1135. % LSUN - length of SUNVARS-1
  1136. % INTERPOLP-flag for MATCHLINEAR (for OFF EXP), has value T for calling
  1137. % from INTERPOL and NIL for calling from SIMPINTT - for
  1138. % NGETVAR in SIMPINTT
  1139. % RESAR - the name of an array which will be filled by the result
  1140. procedure zero u$
  1141. nil . 1$
  1142. procedure ngetvar(u,v)$
  1143. if atom u then get(u,v)
  1144. else if atom car u then get(car u,v)
  1145. else nil$
  1146. procedure ngrid u$
  1147. if u eq 'one then 'none
  1148. else if u eq 'half then 'nhalf
  1149. else nil$
  1150. procedure gnot u$
  1151. % Procedure inverts denotation of half-integer and integer grid
  1152. if u='one then 'half
  1153. else if u='half then 'one
  1154. else nil$
  1155. procedure same u$
  1156. begin
  1157. scalar x,y,z,bo$
  1158. if null same!* then <<same!*:=list u$
  1159. return nil >>$
  1160. x:=same!*$
  1161. a:y:=car x$
  1162. z:=u$
  1163. bo:=nil$
  1164. while z and not bo do
  1165. <<if car z memq y then bo:=t$
  1166. z:=cdr z >>$
  1167. if bo then go to b$
  1168. x:=cdr x$
  1169. if x then go to a$
  1170. same!*:= u . same!*$
  1171. return nil$
  1172. b:rplaca(x,union(y,u))$
  1173. return nil
  1174. end$
  1175. put('same,'stat,'rlis)$
  1176. procedure clearsame$
  1177. same!*:=nil$
  1178. put('clearsame,'stat,'endstat)$
  1179. flag('(clearsame),'eval)$
  1180. procedure mksame$
  1181. begin
  1182. scalar x,y,z,yy,bo$
  1183. x:=expndsame()$
  1184. a:y:=car x$
  1185. yy:=y$
  1186. while yy and not(car yy memq unvars) do yy:=cdr yy$
  1187. if null yy then
  1188. <<msgpri
  1189. (" Same declaration ",nil,list(y,
  1190. " doesn't contain unknown variable"),nil,'hold)$
  1191. go to b >>$
  1192. if y neq yy then
  1193. <<z:=car y$ % The looked for function on the first place
  1194. rplaca(y,car yy)$
  1195. rplaca(yy,z) >>$
  1196. z:=car y$
  1197. yy:=cdr y$
  1198. put(z,'sames,yy)$
  1199. novars:=union(novars,yy)$
  1200. for each a in cdr y do
  1201. % Testing if A has appeared in the statement DEPENDENCE
  1202. if not get(a,'grid) then msgpri
  1203. (" Identifier ",a," is not variable",nil,'hold)
  1204. else put(a,'same,z)$
  1205. for i:=1:length coords!* do
  1206. <<yy:=y$
  1207. bo:=nil$
  1208. while yy and not bo do % Test on ISGRID
  1209. <<bo:=getel list(get(car yy,'grid),i)$
  1210. yy:=cdr yy >>$
  1211. if bo then filgrid(y,bo,i) >>$
  1212. b:x:=cdr x$
  1213. if x then go to a$
  1214. sunvars:=setdiff(unvars,novars)$
  1215. return unvars
  1216. end$
  1217. procedure filgrid(y,bo,i)$
  1218. % Filling up after finding ISGRID according to SAME
  1219. begin
  1220. scalar yy,bg$
  1221. yy:=y$
  1222. while yy do
  1223. <<bg:=getel list(get(car yy,'grid),i)$
  1224. if null bg then setel(list(get(car yy,'grid),i),bo)
  1225. else if bg eq bo then t
  1226. else msgpri
  1227. (" Same declaration ",nil,list(y,
  1228. " doesn't correspond to isgrid declarations"),nil,'hold)$
  1229. yy:=cdr yy>>
  1230. end$
  1231. procedure expndsame$
  1232. % Extending SAME!* by new identifiers for vectors and tensors
  1233. begin
  1234. scalar x,y,sam$
  1235. x:=same!*$
  1236. a:y:=mapcan(car x,function(lambda a$copy1 get(a,'names)))$
  1237. sam:=y . sam$
  1238. x:=cdr x$
  1239. if x then go to a$
  1240. return sam
  1241. end$
  1242. procedure copy1 u$
  1243. if null u then nil
  1244. else if atom u then u
  1245. else car u . copy1 cdr u$
  1246. procedure nrsame$
  1247. % Changing the numbering of variables according to SAME
  1248. for each a in sunvars do
  1249. begin
  1250. scalar x,nx$
  1251. x:=get(a,'sames)$
  1252. if x then
  1253. <<nx:=get(a,'nrvar)$
  1254. for each b in x do put(b,'nrvar,nx) >>$
  1255. return nil
  1256. end$
  1257. procedure iim u$
  1258. % Procedure defines the statement IIM
  1259. begin
  1260. scalar xx,xxx,be,beb1,val,twogr$
  1261. iim1 u$
  1262. iobjs!*:=append(unvars,append(coords!*,given!*))$
  1263. val:=!*val$
  1264. !*val:=nil$
  1265. novars:=sunvars:=nil$
  1266. if same!* then mksame() else sunvars:=unvars$
  1267. twogr:=!*twogrid$
  1268. xxx:=setdiff(given!*,novars)$
  1269. if !*twogrid then
  1270. if null xxx then !*twogrid:=nil
  1271. else flag(xxx,'twogrid)
  1272. else sunvars:=union(sunvars,xxx)$
  1273. flag(given!*,'noeq)$
  1274. xxx:=0$ % Numbering of variables and equation
  1275. for each a in sunvars do
  1276. <<put(a,'nrvar,xxx)$
  1277. xxx:=xxx+1 >>$
  1278. if same!* then nrsame()$
  1279. xxx:=0$
  1280. for each a in unvars do
  1281. <<put(a,'nreq,xxx)$
  1282. xxx:=xxx+1 >>$
  1283. lun:=length unvars-1$
  1284. lsun:=length sunvars-1$
  1285. eval list('array,mkquote list('!*f2 . add1lis list(lun,lsun,1)))$
  1286. xxx:=coords!*$
  1287. d:coord:=car xxx$
  1288. icor:=tcar get(coord,'index)$
  1289. difml!*:=nil$
  1290. for i:=0:10 do difml!*:=append(difml!*,
  1291. for each a in getel list('difm!*,i) collect
  1292. if (xx:=atsoc(coord,cdr a)) then car a . cdr xx
  1293. else if (xx:=atsoc('all,cdr a)) then car a . cdr xx
  1294. else nil )$
  1295. difml!*:=mapcon(difml!*,function(lambda a$if null car a then nil
  1296. else list car a ))$
  1297. if !*twogrid then difml!*:=
  1298. for each a in difml!* collect
  1299. if (xx:=caadr a) and (!*eqfu or memq(caar xx,'(f g))) then
  1300. (car a . extdif(cdr a,nil))
  1301. else a$
  1302. be:=iim2 ()$
  1303. iim21 be$
  1304. if car be then beb1:=iim22 be
  1305. else beb1:=list(car be,cadr be,car be)$
  1306. if not fixp intp then msgpri(" INTP after heuristic search ",
  1307. nil,list("is not a number, INTP=",intp),nil,nil)$
  1308. if not(intp=0) then iim3 beb1$
  1309. iim4 ()$
  1310. xxx:=cdr xxx$
  1311. if xxx then go to d$
  1312. iim5 ()$
  1313. for each a in '(rtype avalue dimension) do remprop('!*f2,a)$
  1314. !*val:=val$ !*twogrid:=twogr$
  1315. return nil
  1316. end$
  1317. procedure extdif(x,lg)$
  1318. % Performs corrections of diff. schemes for given functions on
  1319. % two grids - everytime chooses the scheme with minimal penalty.
  1320. % LG - list of all terms from (U V W F G), which has been in X
  1321. % already changed and choosen.
  1322. begin
  1323. scalar olds,news,y,gy,xx,lgrid,gg,g1$
  1324. lgrid:=get('difm!*,'grids)$
  1325. gy:=caar x$
  1326. gg:=gy$
  1327. for each a in lg do gg:=delete(atsoc(a,gg),gg)$
  1328. if gg then gg:=caar gg
  1329. else return x$
  1330. x:=mapcar(x,function(lambda a$a))$
  1331. a:xx:=x$
  1332. y:=car x$
  1333. gy:=car y$
  1334. g1:=atsoc(gg,gy)$
  1335. gy:=(gg . gnot cdr g1) . delete(g1,gy)$
  1336. gy:=acmemb(gy,lgrid)$
  1337. while cdr xx and not eqcar(cadr xx,gy) do xx:=cdr xx$
  1338. if cdr xx then
  1339. <<olds:=y . (cadr xx . olds)$
  1340. y:=if cadr y > cadadr xx
  1341. or (cadr y=cadadr xx
  1342. and sublength caddr y > sublength car cddadr xx)
  1343. then cadr xx
  1344. else y$
  1345. rplacd(xx,cddr xx) >>
  1346. else olds:=y . olds$
  1347. gy:=car y$
  1348. g1:=atsoc(gg,gy)$
  1349. gy:=delete(g1,gy)$
  1350. if null gy then t
  1351. else if (xx:=acmemb(gy,lgrid)) then gy:=xx
  1352. else nconc(lgrid, list gy)$
  1353. y:=gy . cdr y$
  1354. news:=y . news$
  1355. x:=cdr x$
  1356. if x then go to a$
  1357. if(xx:=caar news) and (!*eqfu or memq(caar xx,'(f g))) then
  1358. <<olds:=extdif(olds,gg . lg)$
  1359. news:=extdif(news,lg) >>$
  1360. return nconc(olds,news)
  1361. end$
  1362. procedure sublength u$
  1363. if atom u then 0
  1364. else length u + sublengthca u$
  1365. procedure sublengthca u$
  1366. if null u then 0
  1367. else sublength car u + sublengthca cdr u$
  1368. procedure iim1 u$
  1369. % Checks the syntax of the IIM statement, calculates scalar PDEs,
  1370. % vector and tensor equations are expanded to scalar components.
  1371. begin
  1372. scalar x,xx,e,te,exp$
  1373. terpri()$
  1374. prin2t"*****************************"$
  1375. prin2 "***** Program ***** "$
  1376. prin2t date!*!*$
  1377. prin2t"*****************************"$
  1378. exp:=!*exp$
  1379. !*exp:=t$
  1380. rhs:=lhs:=unvars:=nil$
  1381. if null coords!* then return lprie " Coordinates defined not yet"$
  1382. if null dvars!* then return lprie " Variables defined not yet"$
  1383. for each v in dvars!* do
  1384. if eqcar((te:=aeval v),'tensor) and caddr te member '(1 2) then
  1385. <<put(v,'kvalue,get(v,'kkvalue))$
  1386. rmsubs()>>$
  1387. if atom u or not idp car u then return errpri2(u,'hold)$
  1388. resar:=car u$
  1389. u:=cdr u$
  1390. a:if atom u or atom cdr u then return errpri2(u,'hold)$
  1391. x:=car u$
  1392. if not idp x then return msgpri
  1393. (" Parameter ",x," must be identifier",nil,'hold)
  1394. else if not(x memq dvars!*) then return msgpri
  1395. (" Identifier ",x," is not variable",nil,'hold)
  1396. else if x memq unvars then return msgpri
  1397. (" Variable ",x," has second appearance",nil,'hold)
  1398. else if x memq given!* then return msgpri
  1399. (" Variable ",x," cannot be declared given",nil,'hold)
  1400. else unvars:=x . unvars$
  1401. e:=cadr u$
  1402. if not eqexpr e then return msgpri
  1403. (" Parameter ",e," must be equation",nil,'hold)
  1404. else e:=aeval list('times,
  1405. list('difference,cadr e,caddr e),
  1406. sfprod!*)$
  1407. if atom e then return msgpri
  1408. (" Equation ",e," must be P.D.E.",nil,'hold)$
  1409. te:=aeval x$
  1410. te:=if eqcar(te,'tensor) then caddr te
  1411. else nil$
  1412. if(te=1 and car e eq 'tensor and caddr e=1) or
  1413. (te=2 and car e eq 'tensor and caddr e=2) or
  1414. (null te and car e eq 'tensor and caddr e=0) then
  1415. e:=cadddr e % Necessary to carrect after change in EXPRESS
  1416. else if null te and car e eq '!*sq then e:=cadr e
  1417. else return msgpri
  1418. (" Tensor order of",x," does not correspond to order of ",e,
  1419. 'hold)$
  1420. lhs:=e . lhs$
  1421. u:=cddr u$
  1422. if u then go to a$
  1423. for each v in dvars!* do
  1424. if eqcar((te:=aeval v),'tensor) and caddr te member '(1 2) then
  1425. remprop(v,'kvalue)$
  1426. b:x:=car unvars$
  1427. e:=car lhs$ % Transformation of vectors and tensor into components
  1428. te:=aeval x$
  1429. te:=if eqcar(te,'tensor) then caddr te
  1430. else nil$
  1431. if te=1 then rhs:=append(e,rhs)
  1432. else if te=2 then for each a in reverse e do
  1433. rhs:=append(a,rhs)
  1434. else rhs:=e . rhs$
  1435. xx:=append(get(x,'names),xx)$ % Add the checking if given equation
  1436. unvars:=cdr unvars$ % solves given variable (tensor var.)
  1437. lhs:=cdr lhs$
  1438. if unvars then go to b$
  1439. unvars:=xx$
  1440. lhs:=rhs$
  1441. put('diff,'simpfn,'zero)$ % Splitting left and right hand side
  1442. alglist!*:=nil . nil$ % All derivatives go to left h.s.
  1443. rhs:=mapcar(rhs,function resimp)$
  1444. put('diff,'simpfn,'simpiden)$
  1445. alglist!*:=nil . nil$
  1446. x:=lhs$
  1447. xx:=rhs$
  1448. terpri()$
  1449. prin2t " Partial Differential Equations"$
  1450. prin2t " =============================="$
  1451. terpri()$
  1452. c:rplaca(xx,negsq car xx)$
  1453. rplaca(x,prepsq!* addsq(car x,car xx))$
  1454. rplaca(xx,prepsq!* car xx)$
  1455. maprin car x$
  1456. prin2!* " = "$
  1457. maprin car xx$
  1458. terpri!* t$
  1459. rplaca(x,prepsq simp car x)$
  1460. rplaca(xx,prepsq simp car xx)$
  1461. x:=cdr x$
  1462. xx:=cdr xx$
  1463. if x then go to c$
  1464. terpri()$
  1465. x:=length lhs-1$
  1466. if x=0 then eval list('array, mkquote list(resar . add1lis list(1)))
  1467. else eval list('array,mkquote list(resar . add1lis list(x,1)))$
  1468. !*exp:=exp$
  1469. return nil
  1470. end$
  1471. procedure iim2$
  1472. % Defines the steps of the grid, splits variables to free and predefined
  1473. % grid in actual coordinate.
  1474. begin
  1475. scalar b,e,xx,dihalf,dione,dihalfc$
  1476. e:=append(explode 'h,explode coord)$
  1477. e:=intern compress e$
  1478. if flagp(coord,'uniform) then hi:=hip1:=him1:=him2:=e
  1479. else <<put(e,'simpfn,'simpiden)$
  1480. xx:=tcar get(coord,'index)$
  1481. him1:=list(e,list('difference,xx,1))$
  1482. him2:=list(e,list('difference,xx,2))$
  1483. hi:=list(e,xx)$
  1484. hip2:=list(e,list('plus,xx,2))$
  1485. hip1:=list(e,list('plus,xx,1)) >>$
  1486. dihalf:=list(
  1487. 'di . list('quotient,
  1488. list('plus,him1,hi),
  1489. 2),
  1490. 'dim1 . him1,
  1491. 'dip1 . hi,
  1492. 'dim2 . list('quotient,
  1493. list('plus,him2,him1),
  1494. 2),
  1495. 'dip2 . list('quotient,
  1496. list('plus,hi,hip1),
  1497. 2))$
  1498. dihalfc:=list(
  1499. 'di . list('quotient,
  1500. list('plus,hip1,hi),
  1501. 2),
  1502. 'dim1 . hi,
  1503. 'dip1 . hip1,
  1504. 'dim2 . list('quotient,
  1505. list('plus,hi,him1),
  1506. 2),
  1507. 'dip2 . list('quotient,
  1508. list('plus,hip2,hip1),
  1509. 2))$
  1510. dione:=list(
  1511. 'di . hi,
  1512. 'dim1 . list('quotient,
  1513. list('plus,him1,hi),
  1514. 2),
  1515. 'dip1 . list('quotient,
  1516. list('plus,hi,hip1),
  1517. 2),
  1518. 'dim2 . him1,
  1519. 'dip2 . hip1)$
  1520. put('steps,'one,
  1521. ('i . icor) . (if !*centergrid then dione else dihalf))$
  1522. put('steps,'half,
  1523. ('i . list('plus,
  1524. icor,
  1525. '(quotient 1 2))) . (if !*centergrid then dihalfc
  1526. else dione))$
  1527. ncor:=get(coord,'ngrid)$ % Number of the COODR coordinate
  1528. e:=nil$
  1529. for each a in sunvars do % Splitting of variables with predefined
  1530. % grid.
  1531. if (xx:=getel list(get(a,'grid),ncor))
  1532. and car xx then e:=a . e$
  1533. b:=setdiff(sunvars,e)$
  1534. return list(b,e)
  1535. end$
  1536. procedure filfree(var,vgrid,freelst,pgr,peq)$
  1537. begin
  1538. scalar x,nx,grn,nv,ng,ngrn,g1,g2,saml,bsam,asam,egrid$
  1539. x:=ngetvar (var,'nrvar)$
  1540. c:put(var,pgr,vgrid)$
  1541. egrid:=vgrid$
  1542. if flagp(var,'noeq) then go to d$
  1543. nx:=ngetvar (var,'nreq)$
  1544. % calulating in which point will be the euation for VAR integrated
  1545. if egrid:=get(var,coord) then go to a
  1546. else egrid:=vgrid$
  1547. put('f2val,'free,'f2vzero)$
  1548. if (g1:=f2eval(nx,x,0)) > (g2:=f2eval(nx,x,1)) then
  1549. egrid:=gnot vgrid$
  1550. if not g1=g2 then go to a$
  1551. put('f2val,'free,'f2vmin)$
  1552. if(g1:=f2eval(nx,x,0)) > (g2:=f2eval(nx,x,1)) then
  1553. egrid:=gnot vgrid$
  1554. if not g1=g2 then go to a$
  1555. put('f2val,'free,'f2vmax)$
  1556. if (g1:=f2eval(nx,x,0)) > (g2:=f2eval(nx,x,1)) then
  1557. egrid:=gnot vgrid$
  1558. a:put(var,peq,egrid)$
  1559. % Penalties for free variables in the equation for VAR
  1560. grn:=gnot egrid$
  1561. ng:=ngrid egrid$
  1562. ngrn:=ngrid grn$
  1563. for each a in freelst do
  1564. <<nv:=ngetvar (a,'nrvar)$
  1565. asam:=a . get(a,'sames)$
  1566. for each aa in asam do put(aa,pgr,egrid)$
  1567. put(a,ng,cfplus2(get(a,ng),getel list('!*f2,nx,nv,0)))$
  1568. for each aa in asam do put(aa,pgr,grn)$
  1569. put(a,ngrn,cfplus2(get(a,ngrn),getel list('!*f2,nx,nv,1)))$
  1570. for each aa in asam do remprop(aa,pgr) >>$
  1571. if bsam then go to d$
  1572. saml:=get(var,'sames)$
  1573. bsam:=t$
  1574. d:if null saml then go to b$
  1575. var:=car saml$
  1576. saml:=cdr saml$
  1577. go to c$
  1578. b:return egrid
  1579. end$
  1580. procedure f2eval(i,j,k)$
  1581. eval getel list('!*f2,i,j,k)$
  1582. procedure f2plus(i,j,k,l)$
  1583. % Procedure fills F2(I,J,K) with the number F2(I,J,K)+L$
  1584. begin
  1585. scalar ma,x,y$
  1586. if pairp l then
  1587. if length car l=2 and cadr l=caddr l then l:=cadr l
  1588. else if length l=3 and cadr l=caddr l and cadr l=cadddr l and
  1589. cadr l=car cddddr l then l:=cadr l$
  1590. ma:=list('!*f2,i,j,k)$
  1591. x:=getel ma$
  1592. if numberp l then
  1593. if numberp x then setel(ma,x+l)
  1594. else rplaca(x,car x+l)
  1595. else
  1596. if numberp x then setel(ma,list(x,l))
  1597. else if (y:=assoc(car l,cdr x)) then
  1598. <<rplaca(cdr y,cadr y+cadr l)$
  1599. rplaca(cddr y,caddr y+caddr l)$
  1600. if cddar l then
  1601. <<rplaca(cdddr y,cadddr y + cadddr l)$
  1602. rplaca(cddddr y,car cddddr y+car cddddr l)>>>>
  1603. else rplacd(x,(l . cdr x))
  1604. end$
  1605. procedure f2var u$
  1606. % Forms the elements of array !*F2 into the form
  1607. % (FPLUS <CISLO> {(F2VAL U V N1 N2)})
  1608. if numberp u then u
  1609. else ('fplus .
  1610. car u . mapcar(cdr u,function(lambda a$
  1611. list('f2val,car a,cdr a))))$
  1612. macro procedure f2val x$
  1613. % Evaluates the expression (F2VAL ...)
  1614. begin
  1615. scalar us,ns,u,v,w,n1,n2,n3,n4,gu,gv,gw$
  1616. x:=cdr x;
  1617. us:=car x$
  1618. ns:=cadr x$
  1619. u:=car us$
  1620. v:=cadr us$
  1621. n1:=car ns$
  1622. n2:= cadr ns$
  1623. gu:=get(u,xxgrid)$
  1624. gv:=get(v,xxgrid)$
  1625. if cddr us then
  1626. <<w:=caddr us$
  1627. gw:=get(w,xxgrid)$
  1628. n3:=caddr ns$
  1629. n4:=cadddr ns>>$
  1630. return mkquote
  1631. if w then
  1632. if gu and gv and gw then
  1633. if gu eq gv and gu eq gw then n1
  1634. else if gu eq gv then n2
  1635. else if gu eq gw then n3
  1636. else if gv eq gw then n4
  1637. else apply(get('f2val,'free),list(us,ns))
  1638. else if gu and gv then
  1639. if gu eq gv then aplf2val(u,w,n1,n2)
  1640. else aplf2val(u,w,n3,n4)
  1641. else if gu and gw then
  1642. if gu eq gw then aplf2val(u,v,n1,n3)
  1643. else aplf2val(u,v,n2,n4)
  1644. else if gv and gw then
  1645. if gv eq gw then aplf2val(u,v,n1,n4)
  1646. else aplf2val(u,v,n2,n3)
  1647. else apply(get('f2val,'free),list(us,ns))
  1648. else if gu and gv then
  1649. if gu eq gv then n1
  1650. else n2
  1651. else apply(get('f2val,'free),list(us,ns))
  1652. end$
  1653. procedure aplf2val(u,v,n1,n2)$
  1654. apply(get('f2val,'free),list(list(u,v),list(n1,n2)))$
  1655. macro procedure fplus u$
  1656. % Evaluates the expression (FPLUS ...)
  1657. begin
  1658. scalar x,y,z$
  1659. u:=cdr u;
  1660. y:=car u$
  1661. a:u:=cdr u$
  1662. z:=eval car u$
  1663. if numberp z then y:=y+z
  1664. else x:=z . x$
  1665. if cdr u then go to a$
  1666. return mkquote
  1667. if x then ('fplus . y . x)
  1668. else y
  1669. end$
  1670. procedure cfplus2(u,v)$
  1671. % Adds the expressions of type (FPLUS ...).
  1672. % Destroys U, does not destroy V.
  1673. begin
  1674. scalar f2v$
  1675. f2v:=get('f2val,'free)$
  1676. put('f2val,'free,'f2vunchange)$
  1677. if not fixp u then u:=eval u$
  1678. if not fixp v then v:=eval v$
  1679. put('f2val,'free,f2v)$
  1680. return
  1681. if fixp u then
  1682. if fixp v then (u + v)
  1683. else ('fplus . (cadr v+u) . cddr v)
  1684. else if numberp v then <<rplaca(cdr u,cadr u+v)$ u>>
  1685. else <<rplaca(cdr u,cadr u+cadr v)$
  1686. nconc(u,cddr v) >>
  1687. end$
  1688. procedure f2vunchange(us,ns)$
  1689. list('f2val,us,ns)$
  1690. procedure f2vzero(us,ns)$
  1691. 0$
  1692. procedure f2vplus(us,ns)$
  1693. eval('plus . ns)$
  1694. procedure f2vmax(us,ns)$
  1695. eval('max . ns)$
  1696. procedure f2vmin(us,ns)$
  1697. eval('min . ns)$
  1698. put('f2val,'fselect,'f2vplus)$
  1699. put('f2val,'fgrid,'f2vmin)$
  1700. procedure iim21 u$
  1701. % Fills the array !*F2 according to the system of PDE and penalties
  1702. % given.
  1703. % Fills the properties NONE,NHALF (FONE,FHALF) of free variables.
  1704. % According to predefined variables filles the properties XGRID and EQ
  1705. % of predefined variables.
  1706. begin
  1707. scalar b,e,lh,lhe,xx,rh,bdef$
  1708. b:=car u$ % Free vars
  1709. e:=cadr u$ % Predefined vars
  1710. for i:=0:lun do
  1711. for j:=0:lsun do % Filling the array F2
  1712. <<setel(list('!*f2,i,j,0),0)$
  1713. setel(list('!*f2,i,j,1),0) >>$
  1714. nvar:=0$ % Number of actual variable
  1715. lh:=lhs$
  1716. rh:=rhs$
  1717. interpolp:=nil$
  1718. put('intt,'simpfn,'simpiden)$
  1719. a:lhe:=car lh$ % Actual equation
  1720. lhe:=formlnr list('intt,lhe,coord)$
  1721. rplaca(lh,lhe)$
  1722. bdef:=t$
  1723. for each var in sunvars do
  1724. if get(var,coord) then t
  1725. else bdef:=nil$
  1726. if null b and bdef then go to c$
  1727. % If there are no free variables it is not necessary to fill
  1728. % the array F2 - no optimalization is necessary -> To use this
  1729. % statement, we have to test if we know in which point (over
  1730. % which interval) will all equation be integrated (discretized).
  1731. put('intt,'simpfn,'simpintt)$
  1732. alglist!*:=nil . nil$
  1733. simp lhe$
  1734. put('intt,'simpfn,'simpiden)$
  1735. if !*fulleq then % Optimalizatioon is performed for both sides of
  1736. <<lhe:=car rh$ % equations, otherwise only for left hand side.
  1737. lhe:=formlnr list('intt,lhe,coord)$
  1738. put('intt,'simpfn,'simpintt)$
  1739. simp lhe$
  1740. alglist!*:=nil . nil$
  1741. put('intt,'simpfn,'simpiden)$
  1742. rh:=cdr rh >>$
  1743. c:nvar:=nvar+1$
  1744. lh:=cdr lh$
  1745. if lh then go to a$
  1746. for i:=0:lun do
  1747. for j:=0:lsun do
  1748. for k:=0:1 do
  1749. setel(list('!*f2,i,j,k),f2var getel list('!*f2,i,j,k))$
  1750. xxgrid:='xgrid$
  1751. for each a in b do
  1752. <<put(a,'none,0)$
  1753. put(a,'nhalf,0) >>$
  1754. for each a in e do % Predefined variables
  1755. filfree(a,car getel list(get(a,'grid),ncor),b,'xgrid,'eq)$
  1756. % Predefined penalties
  1757. intp:=0$
  1758. for each a in e do
  1759. if a memq unvars then
  1760. <<xx:=ngetvar(a,'nreq)$
  1761. for each c in e do
  1762. if get(c,'xgrid) eq get(a,'eq) then intpfplus(xx,c,0)
  1763. else intpfplus(xx,c,1) >>$
  1764. for each a in b do
  1765. <<put(a,'fone,get(a,'none))$
  1766. put(a,'fhalf,get(a,'nhalf)) >>$
  1767. return nil
  1768. end$
  1769. procedure iim22 u$
  1770. begin
  1771. scalar b,e,bb,b1,b2,x,xx,x1,nv,g1,g2$
  1772. b:=car u$
  1773. e:=cadr u$
  1774. bb:=b$ % Heuristic determination of grids for
  1775. % variables from B
  1776. f:x:=car bb$ % Chose the next variable X
  1777. put('f2val,'free,get('f2val,'fselect))$
  1778. xx:=abs(eval get(x,'none)-eval get(x,'nhalf))$
  1779. b2:=cdr bb$
  1780. while b2 do
  1781. if xx<(x1:=abs(eval get(car b2,'none)-eval get(car b2,'nhalf)))
  1782. then <<x:=car b2$
  1783. xx:=x1$
  1784. b2:=cdr b2 >>
  1785. else b2:=cdr b2$
  1786. b1:=x . b1$ % List of variables subsequently choosen from B
  1787. bb:=delete(x,bb)$ % List of variables remaining in B
  1788. put('f2val,'free,get('f2val,'fgrid))$
  1789. put(x,'xgrid,'one)$
  1790. g1:=eval get(x,'none)$
  1791. put(x,'xgrid,'half)$
  1792. g2:=eval get(x,'nhalf)$
  1793. if g1>g2 then xx:='half
  1794. else xx:='one$
  1795. filfree(x,xx,bb,'xgrid,'eq)$
  1796. intpgplus(x,xx)$
  1797. for each ax in (x . get(x,'sames)) do
  1798. if ax memq unvars then
  1799. <<x1:=ngetvar(ax,'nreq)$
  1800. for each a in append(b1,e) do
  1801. if get(a,'xgrid)=get(ax,'eq) then intpfplus(x1,a,0)
  1802. else intpfplus(x1,a,1) >>$
  1803. if bb then go to f$
  1804. return list(b,e,b1)
  1805. end$
  1806. procedure intpfplus(nx1,a,n)$
  1807. intp:=cfplus2(intp,getel list('!*f2,nx1,ngetvar(a,'nrvar),n))$
  1808. procedure intpgplus(a,ga)$
  1809. intp:=cfplus2(intp,get(a,ngrid ga))$
  1810. procedure iim3 u$
  1811. begin
  1812. scalar b,e,b1,bb$
  1813. prin2t" Backtracking needed in grid optimalization"$
  1814. b:=car u$ % Free vars
  1815. e:=cadr u$ % Predefined vars
  1816. b1:=caddr u$
  1817. for each a in b do % Full search - bactracking
  1818. <<put(a,'none,get(a,'fone))$
  1819. put(a,'nhalf,get(a,'fhalf)) >>$
  1820. xxgrid:='bxgrid$
  1821. nbxgrid(e,'bxgrid,'beq,'xgrid,'eq)$
  1822. put('f2val,'free,'f2vunchange)$
  1823. varyback(b1,nil)$
  1824. for each a in union(unvars,given!*) do
  1825. <<remprop(a,'bxgrid)$
  1826. remprop(a,'beq) >>$
  1827. return nil
  1828. end$
  1829. procedure nbxgrid(u,ng,ne,og,oe)$
  1830. for each a in u do
  1831. for each b in (a . get(a,'sames)) do
  1832. <<put(b,ng,get(b,og))$
  1833. put(b,ne,get(b,oe)) >>$
  1834. procedure varyback(bb,b1)$
  1835. % Performs full search of BB. B1 is B-BB. N is the number of
  1836. % interpolations performed up to now.
  1837. if null bb then
  1838. begin
  1839. scalar none,nhalf,n,eqg,i,j$
  1840. n:=0$
  1841. for each a in unvars do
  1842. <<none:=nhalf:=0$
  1843. i:=get(a,'nreq)$
  1844. for each b in sunvars do
  1845. <<j:=get(b,'nrvar)$
  1846. none:=none + if get(b,'bxgrid) eq 'one then f2eval(i,j,0)
  1847. else f2eval(i,j,1)$
  1848. nhalf:=nhalf + if get(b,'bxgrid) eq 'half
  1849. then f2eval(i,j,0)
  1850. else f2eval(i,j,1) >>$
  1851. put(a,'beq,if (eqg:=get(a,coord)) then eqg
  1852. else if none<=nhalf then 'one
  1853. else 'half)$
  1854. n:=n + if eqg then
  1855. if eqg eq 'one then none
  1856. else if eqg eq 'half then nhalf
  1857. else <<msgpri("VARYBACK ",eqg,nil,nil,'hold)$ 0>>
  1858. else if none<=nhalf then none
  1859. else nhalf >>$
  1860. if n<intp then
  1861. <<nbxgrid(b1,'xgrid,'eq,'bxgrid,'beq)$
  1862. for each a in unvars do put(a,'eq,get(a,'beq))$
  1863. intp:=n >>
  1864. end
  1865. else if intp=0 then t
  1866. else <<varb(bb,b1,'one)$
  1867. varb(bb,b1,'half) >>$
  1868. procedure varb(bb,b1,xx)$
  1869. % Subprocedure of VARYBACK procedure
  1870. % In BB are temporary free variables
  1871. % In B1 are temporary predefined variables (over BXGRID property)
  1872. begin
  1873. scalar x$
  1874. x:=car bb$
  1875. for each a in (x . get(x,'sames)) do
  1876. put(a,'bxgrid,xx)$
  1877. return varyback(cdr bb,x . b1)
  1878. end$
  1879. procedure iim4$
  1880. begin
  1881. scalar lh,rh,x,lhe,var$
  1882. intp:=intp/6$
  1883. prin2 intp$
  1884. prin2 " interpolations are needed in "$
  1885. prin2 coord$
  1886. prin2t " coordinate"$
  1887. for each a in unvars do
  1888. <<prin2" Equation for "$
  1889. prin2 a$
  1890. prin2" variable is integrated in "$
  1891. prin2 get(a,'eq)$
  1892. prin2t" grid point" >>$
  1893. interpolp:=t$
  1894. put('intt,'simpfn,'simpinterpol)$
  1895. lh:=lhs$
  1896. rh:=rhs$
  1897. x:=unvars$
  1898. j:var:=car x$
  1899. gvar:=get(var,'eq)$
  1900. lhe:=car lh$
  1901. alglist!*:=nil . nil$
  1902. lhe:=prepsq simp lhe$
  1903. rplaca(lh,lhe)$
  1904. lhe:=car rh$
  1905. lhe:=formlnr list('intt,lhe,coord)$
  1906. lhe:=prepsq simp lhe$
  1907. rplaca(rh,lhe)$
  1908. x:=cdr x$
  1909. lh:=cdr lh$
  1910. rh:=cdr rh$
  1911. if x then go to j$
  1912. put('intt,'simpfn,'simpiden)$
  1913. return lhs
  1914. end$
  1915. procedure iim5$
  1916. begin
  1917. scalar lh,rh,val,nreq,ar$
  1918. val:=!*val$
  1919. !*val:=nil$
  1920. for each a in union(union(unvars,sunvars),given!*) do
  1921. <<remprop(a,'xgrid)$
  1922. remprop(a,'eq)$
  1923. remprop(a,'nreq)$
  1924. remprop(a,'nrvar)$
  1925. remprop(a,'sames)$
  1926. remprop(a,'none)$
  1927. remprop(a,'nhalf)$
  1928. remprop(a,'fone)$
  1929. remprop(a,'fhalf) >>$
  1930. remflag(given!*,'twogrid)$
  1931. remflag(given!*,'noeq)$
  1932. terpri()$
  1933. prin2t " Equations after Discretization Using IIM :"$
  1934. prin2t " =========================================="$
  1935. terpri()$
  1936. lh:=lhs$
  1937. rh:=rhs$
  1938. nreq:=0$
  1939. k:rplaca(lh,prepsq!* simp!* car lh)$
  1940. maprin car lh$
  1941. prin2!* " = "$
  1942. rplaca(rh,prepsq!* simp!* car rh)$
  1943. maprin car rh$
  1944. terpri!* t$
  1945. terpri()$
  1946. ar:=if null cdr lhs then list(resar,0) else list(resar,nreq,0)$
  1947. setel(ar,car lh)$
  1948. ar:=if null cdr lhs then list(resar,1) else list(resar,nreq,1)$
  1949. setel(ar,car rh)$
  1950. lh:=cdr lh$
  1951. rh:=cdr rh$
  1952. nreq:=nreq+1$
  1953. if lh then go to k$
  1954. !*val:=val$
  1955. return nil
  1956. end$
  1957. put('iim,'stat,'rlis)$
  1958. array difm!*(10)$
  1959. procedure iscomposedof(x,objs,ops)$
  1960. if null x then nil
  1961. else if atom x then if idp x then memq(x,objs)
  1962. else if fixp x then t
  1963. else nil
  1964. else if idp car x and car x memq ops and cdr x then
  1965. iscompos(cdr x,objs,ops)
  1966. else nil$
  1967. procedure iscompos(x,objs,ops)$
  1968. if null x then t
  1969. else if idp car x then car x memq objs and iscompos(cdr x,objs,
  1970. ops)
  1971. else if numberp car x then iscompos(cdr x,objs,ops)
  1972. else if atom car x then nil
  1973. else if idp caar x then caar x memq ops and cdar x and
  1974. iscompos(cdar x,objs,ops) and iscompos(cdr x,objs,ops)
  1975. else nil$
  1976. global'(difconst!* diffuncs!*)$
  1977. difconst!* := '(i n di dim1 dip1 dim2 dip2)$
  1978. diffuncs!*:=nil$
  1979. procedure difconst u$
  1980. difconst!* := append(u,difconst!*)$
  1981. put('difconst,'stat,'rlis)$
  1982. procedure diffunc u$
  1983. <<diffuncs!*:=append(u,diffuncs!*)$
  1984. for each a in u do put(a,'matcheq,'matchdfunc) >>$
  1985. put('diffunc,'stat,'rlis)$
  1986. procedure matchdfunc(u,v)$
  1987. begin
  1988. scalar x,y$
  1989. return
  1990. if null u and null v then list t
  1991. else if null u or null v then nil
  1992. else if (x:=matcheq(car u,car v)) and (y:=matchdfunc(cdr u,cdr v))
  1993. then union(x,y)
  1994. else nil
  1995. end$
  1996. procedure difmatch u$
  1997. begin
  1998. scalar l,gds,gdsf,pl,x,dx,y,z,coor$
  1999. coor:=car u$
  2000. if not atom coor then go to er$
  2001. u:=cdr u$
  2002. x:=car u$
  2003. if not iscomposedof(x,'(u f x n v w g),
  2004. append(diffuncs!*,'(diff times expt quotient recip)))then
  2005. go to er$
  2006. x:=prepsq simp x$
  2007. l:=if atom x then 0 else length x$
  2008. x:=x . nil$
  2009. if null(y:=getel list('difm!*,l)) then setel(list('difm!*,l),list x)
  2010. else if (z:=assoc(car x,y)) then x:=z
  2011. else nconc(y,list x)$
  2012. y:=cdr u$
  2013. a:gds:=nil$
  2014. gdsf:=nil$
  2015. if not eqexpr car y then go to b$
  2016. a1:if not(cadar y memq '(u v w f g) and caddar y memq grids!*) then
  2017. go to er$
  2018. if cadar y memq '(f g) then gdsf:=(cadar y . caddar y) . gdsf
  2019. else gds:=(cadar y . caddar y) . gds$
  2020. y:=cdr y$
  2021. if null y then go to er$
  2022. if eqexpr car y then go to a1$
  2023. b:if not fixp car y then go to er$
  2024. pl:=car y$
  2025. y:=cdr y$
  2026. if null y then go to er$
  2027. if not iscomposedof(car y,difconst!*,append(diffuncs!*,'(u x f v w
  2028. g plus minus difference times quotient recip expt)))then go to er$
  2029. dx:=car y$
  2030. y:=cdr y$
  2031. gds:=nconc(gdsf,gds)$
  2032. defdfmatch(x,gds,pl,list dx,coor)$
  2033. if y then go to a$
  2034. return nil$
  2035. er:errpri2(y,'hold)
  2036. end$
  2037. procedure defdfmatch(x,gds,pl,dx,coor)$
  2038. begin
  2039. scalar y,z,yy$
  2040. y:=get('difm!*,'grids)$
  2041. if null y then put('difm!*,'grids,list gds)
  2042. else if null gds then t
  2043. else if (z:=acmemb(gds,y)) then gds:=z
  2044. else nconc(y,list gds)$
  2045. y:=cdr x$
  2046. if y then
  2047. if (yy:=atsoc(coor,y)) then
  2048. if (z:=assoc(gds,cdr yy)) then
  2049. <<rplacd(z,pl . dx)$
  2050. msgpri(" Difference scheme for ",car x," redefined ",
  2051. nil,nil) >>
  2052. else nconc(cdr yy,list(gds . (pl . dx)))
  2053. else nconc(y,list(coor . list(gds . (pl . dx))))
  2054. else rplacd(x,list(coor . list(gds . (pl . dx))))$
  2055. return y
  2056. end$
  2057. deflist('((difmatch rlis) (cleardifmatch endstat)),'stat)$
  2058. procedure cleardifmatch$
  2059. for i:=0:10 do difm!*(i):=nil$
  2060. flag('(cleardifmatch),'eval)$
  2061. procedure acmemb(u,v)$
  2062. if null v then nil
  2063. else if aceq(u,car v) then car v
  2064. else acmemb(u,cdr v)$
  2065. procedure aceq(u,v)$
  2066. if null u then null v
  2067. else if null v then nil
  2068. else if car u member v then aceq(cdr u,delete(car u,v))
  2069. else nil$
  2070. procedure matcheq(u,v)$
  2071. if null u or null v then nil
  2072. else if numberp u then if u=v then list t else nil
  2073. else if atom u then
  2074. begin
  2075. scalar x$
  2076. x:=eval list(get(u,'matcheq),mkquote u,mkquote
  2077. (if atom v then list v else v))$
  2078. return
  2079. if x then x
  2080. else if null !*exp and pairp v and car v memq
  2081. '(plus difference) then matchlinear(u,v)
  2082. else nil
  2083. end
  2084. else if atom v then nil
  2085. else if atom car u and car u eq car v then
  2086. eval list(get(car u,'matcheq),mkquote cdr u,mkquote cdr v)
  2087. else if null !*exp and car v memq'(plus difference)
  2088. and car u eq 'diff then
  2089. matchlinear(u,v)
  2090. else nil$
  2091. algebraic operator matchplus$
  2092. fluid'(uu vv)$
  2093. procedure matchlinear(u,v)$
  2094. % Construction for OFF EXP and second and next coordinates
  2095. begin
  2096. scalar x,uu,vv,alg$
  2097. if not atom u then return
  2098. if car u eq 'diff then matchlindf(u,v)
  2099. else if car u eq 'times then matchlintimes(u,v)
  2100. else nil$
  2101. uu:=u$
  2102. vv:='first$
  2103. x:=formlnr list('matchplus,v,coord)$
  2104. put('matchplus,'simpfn,'matchp)$
  2105. alg:=alglist!*$
  2106. alglist!*:=nil . nil$
  2107. simp x$
  2108. alglist!*:=alg$
  2109. put('matchplus,'simpfn,'simpiden)$
  2110. return
  2111. if vv then list(u . (if interpolp then v else vv))
  2112. else nil
  2113. end$
  2114. procedure matchp y$
  2115. begin
  2116. scalar x$
  2117. if null vv then return(nil . 1)$
  2118. x:=matcheq(uu,car y)$
  2119. if null x then return
  2120. begin
  2121. vv:=nil$
  2122. return(nil . 1)
  2123. end$
  2124. if vv eq 'first then return
  2125. begin
  2126. vv:=cdar x$
  2127. return (nil . 1)
  2128. end$
  2129. if mainvareq(vv,cdar x) then return (nil . 1)$
  2130. vv:=nil$
  2131. return(nil . 1)
  2132. end$
  2133. unfluid '(uu vv)$
  2134. procedure mainvareq(x,y)$
  2135. if atom x then eq(x,y)
  2136. else if car x memq iobjs!* then eq(car x,car y)
  2137. else if car x memq '(diff expt) then
  2138. (car y eq car x and mainvareq(cadr x,cadr y) and cddr x=cddr y)
  2139. else nil$
  2140. procedure tlist x$
  2141. if atom x then list x
  2142. else x$
  2143. procedure matchlindf(u,v)$
  2144. begin
  2145. scalar x,y,b$
  2146. x:=mapcar(cdr v,function fsamedf)$
  2147. y:=cdar x$
  2148. if null y then return nil$
  2149. x:=for each a in x collect if y=cdr a then car a
  2150. else b:=t$
  2151. if b then return nil$
  2152. x:=(car v . x) . y$
  2153. return matchdf(cdr u,x)
  2154. end$
  2155. procedure fsamedf u$
  2156. begin
  2157. scalar x$
  2158. return
  2159. if atom u then nil . nil
  2160. else if car u eq 'minus then
  2161. <<x:=fsamedf cadr u$
  2162. list('minus,car x) . cdr x >>
  2163. else if car u eq 'diff then cadr u . cddr u
  2164. else if car u eq 'times then
  2165. begin
  2166. scalar y,z$
  2167. x:=cdr u$
  2168. a:if null x or y=t then go to b$
  2169. if numberp car x then z:=car x . z
  2170. else if eqcar(car x,'diff) then
  2171. <<if y then y:=t
  2172. else y:=cddar x$
  2173. z:=cadar x . z >>
  2174. else if depends(car x,coord) then y:=t
  2175. else z:=car x . z$
  2176. x:=cdr x$
  2177. go to a$
  2178. b:return if y=t then nil . nil
  2179. else ('times . z) . y
  2180. end
  2181. else nil . nil
  2182. end$
  2183. procedure matchlintimes(u,v)$
  2184. begin
  2185. scalar x,y,z$
  2186. y:=cadr v$
  2187. if eqcar(y,'times) then y:=cdr y
  2188. else if eqcar(y,'minus) and eqcar(cadr y,'times)
  2189. then y:= (-1) . cdadr y
  2190. else return nil$
  2191. x:=for each a in cdr v collect
  2192. if eqcar(a,'times) then <<y:=intersect(y,cdr a)$
  2193. a>>
  2194. else if eqcar(a,'minus) and eqcar(cadr a,'times) then
  2195. <<y:=intersect(y,cdadr a)$
  2196. 'times . ((-1) . cdadr a) >>
  2197. else y:=nil$
  2198. if null y then return nil$
  2199. x:=for each a in x collect <<z:=setdiff(cdr a,y)$
  2200. if null cdr z then car z
  2201. else 'times . z >>$
  2202. x:=car v . x$
  2203. return matchtimes(cdr u,x . y)
  2204. end$
  2205. procedure intersect(u,v)$
  2206. if null u or null v then nil
  2207. else if member(car u,v) then car u . intersect(cdr u,v)
  2208. else intersect(cdr u,v)$
  2209. procedure matchu(u,v)$
  2210. if car v memq unvars or (!*eqfu and car v memq given!*) then list(u . v)
  2211. else if car v eq 'diff and not coord memq cddr v
  2212. and matcheq(u,tlist cadr v)
  2213. then list(u . (car v . (tlist cadr v . cddr v)))
  2214. else if car v eq 'times then
  2215. % Product can be inside brackets or in DIFF
  2216. begin
  2217. scalar x,b1,vv$
  2218. x:=for each a in cdr v collect a$ % To allow RPLACA
  2219. vv:=car v . x$
  2220. b1:=0$
  2221. while x and b1<2 do
  2222. <<if depends(car x,coord) then
  2223. <<b1:=b1+1$
  2224. if atom car x then rplaca(x,list car x) >>$
  2225. x:=cdr x >>$
  2226. return if b1=0 or b1>1 then nil
  2227. else (u . vv)
  2228. end
  2229. else nil$
  2230. put('u,'matcheq,'matchu)$
  2231. put('v,'matcheq,'matchu)$
  2232. put('w,'matcheq,'matchu)$
  2233. procedure matchf(u,v)$
  2234. if car v memq given!* then list(u . v)
  2235. else if car v eq 'diff and not coord memq cddr v
  2236. and matchf(u,tlist cadr v)
  2237. then list(u . (car v . (tlist cadr v . cddr v)))
  2238. else nil$
  2239. put('f,'matcheq,'matchf)$
  2240. put('g,'matcheq,'matchf)$
  2241. procedure matchx(u,v)$
  2242. if car v eq coord then list t
  2243. else nil$
  2244. put('x,'matcheq,'matchx)$
  2245. procedure matchtimes(u,v)$
  2246. begin
  2247. scalar bool,bo,x,y,y1,asl$
  2248. x:=u$
  2249. a:y:=t . v$
  2250. d:bool:=nil$
  2251. while not bool and cdr y do
  2252. <<y:=cdr y$
  2253. bool:=matcheq(car x,car y)>>$
  2254. if null bool then go to b$
  2255. bo:=bool$
  2256. c: if not atom bo and not atom car bo then y1:=atsoc(caar bo,asl)
  2257. else y1 := nil$
  2258. if y1 and not y1=car bo then go to d$
  2259. bo:=cdr bo$
  2260. if bo then go to c$
  2261. v:=delete(car y,v)$
  2262. x:=cdr x$
  2263. asl:=union(bool,asl)$
  2264. if x then go to a$
  2265. if v then return nil$
  2266. return asl$
  2267. b:return if null cdr v and cdr x then
  2268. if y:=matcheq('times . x,car v) then union(asl,y)
  2269. else nil
  2270. else nil
  2271. end$
  2272. put('times,'matcheq,'matchtimes)$
  2273. procedure matchexpt(u,v)$
  2274. if fixp cadr u then
  2275. if cadr u=cadr v then matcheq(car u,car v)
  2276. else nil
  2277. else if cadr u='n then
  2278. begin
  2279. scalar x$
  2280. x:=matcheq(car u,car v)$
  2281. return if x then (('n . cadr v) . x)
  2282. else nil
  2283. end
  2284. else nil$
  2285. put('expt,'matcheq,'matchexpt)$
  2286. procedure matchquot(u,v)$
  2287. begin
  2288. scalar man,mad$
  2289. return if(man:=matcheq(car u,car v))
  2290. and (mad:=matcheq(cadr u,cadr v)) then
  2291. union(man,mad)
  2292. else nil
  2293. end$
  2294. put('quotient,'matcheq,'matchquot)$
  2295. procedure matchrecip(u,v)$
  2296. matcheq(car u,car v)$
  2297. put('recip,'matcheq,'matchrecip)$
  2298. procedure matchdf(u,v)$
  2299. begin
  2300. scalar x,asl,y$
  2301. asl:=matcheq(car u,car v)$
  2302. if null asl then return nil$
  2303. y:=x:=append(cdr v,nil)$
  2304. while x and car x neq coord do x:=cdr x$
  2305. if null x then return nil
  2306. else if null cddr u then
  2307. if null cdr x or idp cadr x then go to df1
  2308. else return nil
  2309. else if cdr x and caddr u=cadr x then t
  2310. else return nil$
  2311. rplacd(x,cddr x)$
  2312. df1:y:=delete(coord,y)$
  2313. if null y or null interpolp then return asl
  2314. % !!! Be aware !!! in mixed derivations of product
  2315. else return list(car u . ('diff . (cdar asl . y)))
  2316. end$
  2317. put('diff,'matcheq,'matchdf)$
  2318. procedure finddifm u$
  2319. begin
  2320. scalar x,v,asl,eqfu,b,bfntwo,bftwo1$
  2321. eqfu:=!*eqfu$
  2322. if eqfu then !*eqfu:=nil$
  2323. a:x:=t . difml!*$
  2324. bftwo1:=bfntwo$
  2325. bfntwo:=nil$
  2326. if !*eqfu then b:=t$
  2327. while cdr x and not asl do
  2328. <<x:=cdr x$
  2329. asl:=matcheq(caar x,u)$
  2330. % Test for given variables of type F, which have to be on one grid,
  2331. % if choosed substitution from DIFMATCH contains definition of F
  2332. % on grids.
  2333. if asl then for each a in asl do
  2334. if not atom a and car a memq'(f g) and (cadr a memq novars or
  2335. (null !*twogrid and cadr a memq sunvars)) and
  2336. null atsoc(car a,caadar x) then bfntwo:=t$
  2337. if bfntwo then asl:=nil >>$
  2338. !*eqfu:=eqfu$
  2339. if null asl then
  2340. if null b and eqfu then go to a
  2341. else go to nm$
  2342. return list(('x . coord) . delete(t,asl),cdar x)$
  2343. nm:if eqcar(u,'times) and null !*exp then
  2344. <<!*exp:=t$
  2345. alglist!*:=nil . nil$
  2346. v:=prepsq simp u$
  2347. v:=formlnr list('intt,v,coord)$
  2348. !*exp:=nil$
  2349. if null atom v and car v memq'(plus difference) then
  2350. return ('special . simp v) >>$
  2351. msgpri(" Matching of ",u," term not find ",nil,'hold)$
  2352. if bfntwo or bftwo1 then
  2353. lprie(" Variable of type F not defined on grids in DIFMATCH")$
  2354. return nil
  2355. end$
  2356. procedure tdifpair x$
  2357. % From CDR ATSOC(.,ASL) makes an atom - free variable
  2358. <<if eqcar(x,'diff) then
  2359. if eqcar(cadr x,'times) then
  2360. <<x:=cdadr x$
  2361. while x and not depends(car x,coord) do x:=cdr x$
  2362. x:=tdifpair car x>> % patch
  2363. else x:=cadr x$
  2364. if pairp x then x:=car x$
  2365. x >>$
  2366. procedure simpintt u$
  2367. begin
  2368. scalar asl,agdsl,l,x,nv,y,x1,y1,nv1,n1,n2,nn1,nn2,
  2369. x2,y2,nv2,n3,n4,n5,n6,lgrids,gds$
  2370. u:=prepsq simp car u$
  2371. if u=1
  2372. then go to r$
  2373. asl:=finddifm u$
  2374. if null asl or eqcar(asl,'special) then go to r$
  2375. agdsl:=cadr asl$ % List from DIFML!*
  2376. asl:=car asl$ % ASOC. list of assignments
  2377. gds:=caar agdsl$
  2378. l:=length gds$
  2379. if l=0 then go to r$
  2380. a:y:=caar gds$
  2381. x:=atsoc(y,asl)$
  2382. if null x then go to er1$
  2383. x:=tdifpair cdr x$
  2384. if !*twogrid and flagp(x,'twogrid) then
  2385. if l=1 then go to r
  2386. else <<gds:=cdr gds$
  2387. l:=l-1$
  2388. go to a>>$
  2389. nv:=ngetvar(x,'nrvar)$
  2390. if l=1 then go to l1
  2391. else go to l2$
  2392. l1:x:=assoc(list(y . 'one),agdsl)$
  2393. if null x then go to er2$
  2394. f2plus(nvar,nv,0,6*cadr x)$
  2395. x:=assoc(list(y . 'half),agdsl)$
  2396. if null x then go to er2$
  2397. f2plus(nvar,nv,1,6*cadr x)$
  2398. go to r$
  2399. l2:y1:=caadr gds$
  2400. x1:=atsoc(y1,asl)$
  2401. if null x1 then go to er1$
  2402. x1:=tdifpair cdr x1$
  2403. if !*twogrid and flagp(x1,'twogrid) then
  2404. if l=2 then go to l1
  2405. else <<gds:=cdr gds$
  2406. l:=l-1$
  2407. go to l2 >>$
  2408. nv1:=ngetvar(x1,'nrvar)$
  2409. lgrids:=get('difm!*,'grids)$
  2410. if l=3 then go to l3
  2411. else if l>3 then go to er$
  2412. l20:n1:=atsoc(acmemb(list(y . 'one,y1 . 'one),lgrids),agdsl)$
  2413. n2:=atsoc(acmemb(list(y . 'one,y1 . 'half),lgrids),agdsl)$
  2414. nn1:=atsoc(acmemb(list(y . 'half,y1 . 'half),lgrids),agdsl)$
  2415. nn2:=atsoc(acmemb(list(y . 'half,y1 . 'one),lgrids),agdsl)$
  2416. if n1 and n2 and nn1 and nn2 then t
  2417. else go to er2$
  2418. n1:=cadr n1$
  2419. n2:=cadr n2$
  2420. nn1:=cadr nn1$
  2421. nn2:=cadr nn2$
  2422. l21:add2sint(nv,nv1,x,x1,n1,n2,nn1,nn2)$
  2423. go to r$
  2424. l3:y2:=caaddr gds$
  2425. x2:=atsoc(y2,asl)$
  2426. if null x2 then go to er1$
  2427. x2:=tdifpair cdr x2$
  2428. if !*twogrid and flagp(x2,'twogrid) then go to l20$
  2429. nv2:=ngetvar(x2,'nrvar)$
  2430. n1:=atsoc(acmemb(list(y . 'one,y1 . 'one,y2 . 'one),lgrids),agdsl)$
  2431. n2:=atsoc(acmemb(list(y . 'half,y1 . 'half,y2 . 'half),lgrids),agdsl)$
  2432. nn1:=atsoc(acmemb(list(y . 'one,y1 . 'one,y2 . 'half),lgrids),agdsl)$
  2433. nn2:=atsoc(acmemb(list(y . 'half,y1 . 'half,y2 . 'one),lgrids),agdsl)$
  2434. n3:=atsoc(acmemb(list(y . 'one,y1 . 'half,y2 . 'one),lgrids),agdsl)$
  2435. n4:=atsoc(acmemb(list(y . 'half,y1 . 'one,y2 . 'half),lgrids),agdsl)$
  2436. n5:=atsoc(acmemb(list(y . 'one,y1 . 'half,y2 . 'half),lgrids),agdsl)$
  2437. n6:=atsoc(acmemb(list(y . 'half,y1 . 'one,y2 . 'one),lgrids),agdsl)$
  2438. if n1 and n2 and nn1 and nn2 and n3 and n4 and n5 and n6 then t
  2439. else go to er2$
  2440. n1:=cadr n1$
  2441. n2:= cadr n2$
  2442. nn1:=cadr nn1$
  2443. nn2:=cadr nn2$
  2444. n3:=cadr n3$
  2445. n4:=cadr n4$
  2446. n5:=cadr n5$
  2447. n6:=cadr n6$
  2448. if n1=nn1 and n2=nn2 and n3=n5 and n4=n6 then
  2449. <<n2:=n3$
  2450. nn1:=nn2$
  2451. nn2:=n4$
  2452. go to l21 >>
  2453. else if n1=n3 and n2=n4 and nn1=n5 and nn2=n6 then
  2454. <<n2:=nn1$
  2455. nn1:=n4$
  2456. x1:=x2$
  2457. nv1:=nv2$
  2458. go to l21 >>
  2459. else if n1=n6 and n2=n5 and nn1=n4 and nn2=n3 then
  2460. <<n2:=nn2$
  2461. nn1:=n5:
  2462. nn2:=n4$
  2463. x:=x2$
  2464. nv:=nv2$
  2465. go to l21 >>$
  2466. add3sint(nv,nv1,nv2,x,x1,x2,n1,n2,n3,n4,n5,n6,nn1,nn2)$
  2467. r:return (nil . 1)$
  2468. er:msgpri(nil,l," Free vars not yet implemented ",nil,'hold)$
  2469. go to r$
  2470. er1:msgpri(" Failed matching of variables in ",
  2471. u,list(asl,agdsl),nil,'hold)$
  2472. go to r$
  2473. er2:msgpri(" All grids not given for term ",u,list(asl,agdsl),
  2474. nil,'hold)$
  2475. go to r
  2476. end$
  2477. procedure add2sint(nv,nv1,x,x1,n1,n2,nn1,nn2)$
  2478. begin
  2479. % Enhansment for symmetries, when only one variable influence
  2480. if n1=n2 and nn1=nn2 then
  2481. <<f2plus(nvar,nv,0,6*n1)$
  2482. f2plus(nvar,nv,1,6*nn1)$
  2483. return >>
  2484. else if n1=nn2 and n2=nn1 then
  2485. <<f2plus(nvar,nv1,0,6*n1)$
  2486. f2plus(nvar,nv1,1,6*n2)$
  2487. return >>$
  2488. n1:=3*n1$
  2489. n2:=3*n2$
  2490. nn1:=3*nn1$
  2491. nn2:=3*nn2$
  2492. x:=list(x,x1)$
  2493. f2plus(nvar,nv,0,list(x,n1,n2))$
  2494. f2plus(nvar,nv,1,list(x,nn1,nn2))$
  2495. x:=reverse x$
  2496. f2plus(nvar,nv1,0,list(x,n1,nn2))$
  2497. f2plus(nvar,nv1,1,list(x,nn1,n2))$
  2498. return
  2499. end$
  2500. procedure add3sint(nv,nv1,nv2,x,x1,x2,n1,n2,n3,n4,n5,n6,nn1,nn2)$
  2501. begin
  2502. n1:=2*n1$
  2503. n2:=2*n2$
  2504. nn1:=2*nn1$
  2505. nn2:=2*nn2$
  2506. n3:=2*n3$
  2507. n4:=2*n4$
  2508. n5:=2*n5$
  2509. n6:=2*n6$
  2510. x:=list(x,x1,x2)$
  2511. f2plus(nvar,nv,0,list(x,n1,nn1,n3,n5))$
  2512. f2plus(nvar,nv,1,list(x,n2,nn2,n4,n6))$
  2513. f2plus(nvar,nv1,0,list(x,n1,nn1,n4,n6))$
  2514. f2plus(nvar,nv1,1,list(x,n2,nn2,n3,n5))$
  2515. f2plus(nvar,nv2,0,list(x,n1,nn2,n3,n6))$
  2516. f2plus(nvar,nv2,1,list(x,n2,nn1,n4,n5))$
  2517. return
  2518. end$
  2519. procedure simpinterpol u$
  2520. begin
  2521. scalar asl,agdsl,gds,x,y,xx,a$
  2522. u:=prepsq simp car u$
  2523. if eqcar(u,'diff) and not coord memq cddr u then
  2524. % !!!! Be aware !!!! could not work for mixed derivatives
  2525. return <<asl:=!*exp$
  2526. !*exp:=t$
  2527. alglist!*:=nil . nil$ % added 13/06/91
  2528. u:= simp formlnr('diff . (prepsq simp formlnr
  2529. list('intt,cadr u,coord) . cddr u))$
  2530. !*exp:=asl$
  2531. u>>$
  2532. asl:=finddifm u$
  2533. if null asl then return (nil . 1)
  2534. else if eqcar(asl,'special) then return cdr asl$
  2535. agdsl:=cadr asl$ % Actual list from DIFML!*, contains definition
  2536. % of grid, penalty and diff. scheme
  2537. asl:=car asl$ % Assoc. list of assignments of variables X,U,V,W
  2538. % to actual variables
  2539. if not gvar memq grids!* then go to erg$
  2540. asl:=append(asl,get('steps,gvar))$ % Adding DIM1, DIP1 ... to assoc.
  2541. % list
  2542. if null caar agdsl then return simp sublap(asl,caddar agdsl)$ % For
  2543. a:=caar agdsl$ % DIFMATCH without def. grids
  2544. b:if null a then go to c$
  2545. y:=caar a$
  2546. x:=atsoc(y,asl)$
  2547. if null x then go to er1$ % GDS is assoc. list of actual
  2548. xx:=cdr x$ % assignments of grids to
  2549. x:=getgrid xx$ % variables U, V
  2550. if gvar eq 'half then x:=gnot x$
  2551. if !*twogrid and twogridp xx then t
  2552. else gds:=(y . x) . gds$
  2553. a:=cdr a$
  2554. go to b$
  2555. c:if null gds then go to a$ % For given functions which can be on
  2556. y:=get('difm!*,'grids)$ % both grids
  2557. x:=acmemb(gds,y)$ % Unique GDS
  2558. if null x then go to er1$
  2559. gds:=x$
  2560. a:x:=assoc(gds,agdsl)$
  2561. if null x then go to erg$
  2562. x:=caddr x$ % Actual difference scheme
  2563. return simp sublap(asl,x)$
  2564. er1:msgpri(" Failed matching of ",u,list(asl,agdsl,gds),nil,
  2565. 'hold)$
  2566. return (nil . 1)$
  2567. erg:msgpri(" Bad grids ",u,list(asl,agdsl,gds),nil,'hold)$
  2568. return (nil . 1)
  2569. end$
  2570. procedure twogridp u$
  2571. % Checks if prefix form U can be on both grids
  2572. begin
  2573. scalar x$
  2574. return
  2575. if atom u then
  2576. if flagp(u,'twogrid) then
  2577. if !*twogrid and u memq given!* and
  2578. getel list(get(u,'grid),ncor) then nil
  2579. else t
  2580. else nil
  2581. else if flagp(car u,'twogrid) then
  2582. if !*twogrid and car u memq given!* and
  2583. getel list(get(car u,'grid),ncor) then nil
  2584. else t
  2585. else if car u memq '(diff plus difference) then twogridp cadr u
  2586. else if car u eq 'times then twogridpti cdr u
  2587. else nil
  2588. end$
  2589. procedure twogridpti u$
  2590. begin
  2591. scalar x$
  2592. a:x:=twogridp car u$
  2593. if x then return x$
  2594. u:=cdr u$
  2595. if u then go to a$
  2596. return nil
  2597. end$
  2598. procedure getgrid u$
  2599. begin
  2600. scalar x$
  2601. return
  2602. if atom u then
  2603. if x:=get(u,'xgrid) then x
  2604. else if !*twogrid and u memq given!* and
  2605. (x:=getel list(get(u,'grid),ncor)) then car x
  2606. else nil
  2607. else if (x:=get(car u,'xgrid)) then x
  2608. else if !*twogrid and car u memq given!* and
  2609. (x:=getel list(get(car u,'grid),ncor)) then car x
  2610. else if car u eq 'diff then
  2611. if atom cadr u then getgrid cadr u
  2612. %else if caadr u eq 'times then % probably can
  2613. % if (x:=getgrid cadadr u) then x % be deleted
  2614. % else getgrid caddr cadr u % !!!!!"!!!
  2615. else getgrid cadr u
  2616. else if car u memq '(plus difference) then getgrid cadr u
  2617. else if car u eq 'times then getgti cdr u
  2618. else nil
  2619. end$
  2620. procedure getgti u$
  2621. begin
  2622. scalar x$
  2623. a:x:=getgrid car u$
  2624. if x then return x$
  2625. u:=cdr u$
  2626. if u then go to a$
  2627. return nil
  2628. end$
  2629. procedure sublap(u,v)$
  2630. % U is assoc. list, V is pattern diff. scheme
  2631. % Performs substitution of assod. list into the diff. scheme
  2632. begin
  2633. scalar x$
  2634. return
  2635. if null u or null v then v
  2636. else if atom v then
  2637. if numberp v then v
  2638. else if x:=atsoc(v,u) then cdr x
  2639. else v
  2640. else if flagp(car v,'app) then sublap1(u,v)
  2641. else (sublap(u,car v) . sublap(u,cdr v))
  2642. end$
  2643. flag('(u f v w x g),'app)$
  2644. procedure sublap1(u,v)$
  2645. begin
  2646. scalar x,y$
  2647. x:=atsoc(car v,u)$
  2648. if null x then return msgpri(" Substitution for ",v," not find",
  2649. nil,'hold)$
  2650. x:=cdr x$
  2651. y:=mapcar(cdr v,function(lambda a$irev sublap(u,a)))$
  2652. return
  2653. if eqcar(x,'diff) then ('diff . (subappend(cadr x,y) . cddr x))
  2654. else subappend(x,y)
  2655. end$
  2656. procedure subappend(x,y)$
  2657. if atom x then if x memq iobjs!* and depends(x,coord) then (x . y)
  2658. else x
  2659. else if car x memq iobjs!* and depends(car x,coord) then append(x,y)
  2660. else (car x . mapcar(cdr x,function(lambda a$
  2661. subappend(a,y))))$
  2662. procedure irev u$
  2663. begin
  2664. u:=simp u$
  2665. return
  2666. if cdaaar u=1 and cdaar u=cdr u and fixp cdar u then
  2667. if cdr u=1 then
  2668. if cdar u<0 then list('difference,
  2669. caaaar u,
  2670. -cdar u)
  2671. else list('plus,
  2672. caaaar u,
  2673. cdar u)
  2674. else if cdar u<0 then list('difference,
  2675. caaaar u,
  2676. list('quotient,
  2677. -cdar u,
  2678. cdr u))
  2679. else list('plus,
  2680. caaaar u,
  2681. list('quotient,
  2682. cdar u,
  2683. cdr u))
  2684. else prepsq u
  2685. end$
  2686. unfluid '(coord unvars sunvars interpolp novars ncor nvar intp icor gvar
  2687. hi hip1 hip2 him1 him2 lhs rhs lsun lun xxgrid resar)$
  2688. procedure gentempst$
  2689. list('gentemp,xread t)$
  2690. put('gentemp,'stat,'gentempst)$
  2691. put('gentemp,'formfn,'formgentran)$
  2692. put('outtemp,'stat,'endstat)$
  2693. flag('(outtemp),'eval)$
  2694. algebraic$
  2695. endmodule$
  2696. end$