fide1.red 84 KB

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