conlaw2.red 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. % CONLAW version 2, to calculate conservation laws of systems
  2. % of PDEs by calculating characteristic functions
  3. % by Thomas Wolf, September 1997
  4. %----------------------------------------------------------------------
  5. symbolic fluid '(print_ logoprint_ potint_ facint_ adjust_fnc)$
  6. %symbolic fluid '(div_p)$
  7. %-------------
  8. symbolic procedure newil(il,mo,nx)$
  9. if (null il) or (length il<mo) then cons(1,il) else
  10. if car il<nx then cons(add1 car il,cdr il) else
  11. <<while il and (car il = nx) do il:=cdr il;
  12. if null il then nil
  13. else cons(add1 car il,cdr il)>>$
  14. %-------------
  15. symbolic procedure sortli(l)$
  16. % sort a list of numbers
  17. begin scalar l1,l2,l3,m,n$
  18. return
  19. if null l then nil
  20. else <<
  21. n:=car l$
  22. l2:=list car l$
  23. l:=cdr l$
  24. while l do <<
  25. m:=car l$
  26. if m>n then l1:=cons(car l,l1)
  27. else if m<n then l3:=cons(car l,l3)
  28. else l2:=cons(car l,l2)$
  29. l:=cdr l
  30. >>$
  31. append(sortli(l1),append(l2,sortli(l3)))
  32. >>
  33. end$
  34. %-------------
  35. %symbolic operator combi$
  36. symbolic procedure combi(ilist)$
  37. % ilist is a list of indexes (of variables of a partial derivative)
  38. % and returns length!/k1!/k2!../ki! where kj! is the multiplicity of j.
  39. begin
  40. integer n0,n1,n2,n3;
  41. n1:=1;
  42. % ilist:=cdr ilist;
  43. while ilist do
  44. <<n0:=n0+1;n1:=n1*n0;
  45. if car ilist = n2 then <<n3:=n3+1; n1:=n1/n3>>
  46. else <<n2:=car ilist; n3:=1>>;
  47. ilist:=cdr ilist>>;
  48. return n1
  49. end$
  50. %-------------
  51. symbolic procedure derili(il)$
  52. % make a derivative index list from a list of numbers
  53. if null il then nil else
  54. begin scalar h1,h2,h3$
  55. h1:=sortli(il);
  56. while h1 do <<
  57. h2:=reval algebraic mkid(!`,lisp car h1);
  58. h3:=if h3 then mkid(h2,h3)
  59. else h2;
  60. h1:=cdr h1
  61. >>;
  62. return h3
  63. end$
  64. %-------------
  65. symbolic operator intcurrent1$
  66. symbolic procedure intcurrent1(divp,ulist,xlist,dulist,
  67. nx,nde,eqord,densord)$
  68. % computes a list in reverse order from which the conserved
  69. % current is computed through integration
  70. begin scalar ii,il,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,contrace,u,
  71. nega,pii,mo,pl$
  72. %contrace:=t;
  73. ulist:=cdr ulist;
  74. xlist:=cdr xlist;
  75. mo:=if eqord>densord then eqord-1
  76. else densord-1$
  77. pl:=for ii:=1:nx collect << % the components W^i
  78. il:=nil;
  79. pii:=nil;
  80. repeat <<
  81. h11:=cons(ii,il);
  82. h1:=derili(h11);
  83. h11:=combi(sortli(h11));
  84. if contrace then
  85. <<write"==== ii=",ii," il=",il," h1=",h1," h11=",h11;terpri()>>;
  86. h2:=il;
  87. h3:=nil;
  88. if null h2 then h4:=list(nil . nil)
  89. else <<
  90. h4:=list(car h2 . nil);
  91. while h2 do <<
  92. h3:=cons(car h2,h3);h2:=cdr h2;
  93. h4:=cons((if h2 then car h2
  94. else nil ) . derili(h3),h4)$
  95. >>;
  96. >>;
  97. if contrace then <<write"h3=",h3," h4=",h4;terpri()>>;
  98. for e1:=1:nde do << % for each function u
  99. u:=nth(ulist,e1);
  100. h5:=mkid(u,h1);
  101. if contrace then <<write"h5=",h5;terpri()>>;
  102. h6:=nil;
  103. if contrace then <<write"h6-1=", list('DF,divp,h5);
  104. terpri()>>;
  105. h6:=cons(reval list('QUOTIENT,list('DF,divp,h5),h11), h6);
  106. if nde=1 then h6:=car h6
  107. else h6:=cons('PLUS,h6);
  108. if contrace then <<write"h6=",h6;terpri()>>;
  109. nega:=nil;
  110. h7:=h4;
  111. % h7 is in such an order that the first term is always positive
  112. while h7 and not zerop h6 do <<
  113. h8:=car h7; h7:=cdr h7;
  114. h9:=car h8; h8:=cdr h8;
  115. if contrace then <<write if nega then "--" else "++",
  116. " h8=",h8," h9=",h9;terpri()>>;
  117. if contrace then <<write"h9-2=",h9;terpri()>>;
  118. if h9 then h6:=totdif(h6,nth(xlist,h9),h9,dulist);
  119. if contrace then <<write"h6-3=",h6;terpri()>>;
  120. h10:=if h8 then mkid(u,h8)
  121. else u;
  122. if contrace then <<write"h10=",h10;terpri()>>;
  123. h10:=list('TIMES,h6,h10);
  124. if nega then h10:=list('MINUS,h10);
  125. if contrace then algebraic write">>>> h10=",h10;
  126. pii:=cons(h10,pii)$
  127. nega:=not nega;
  128. >>
  129. >>; % for each function u
  130. il:=newil(il,mo,nx);
  131. >> until null il;
  132. pii:=reval if length pii=1 then car pii
  133. else cons('PLUS,pii);
  134. if contrace then algebraic write"pii-end=",pii;
  135. pii
  136. >>; % for all ii
  137. return cons('LIST,pl)
  138. end$ % of intcurrent1
  139. %-------------
  140. symbolic operator intcurrent2$
  141. symbolic procedure intcurrent2(divp,ulist,xlist,nondiv)$
  142. % computes the conserved current P_i from the divergence through
  143. % partial integration
  144. begin scalar h2,h3,h4,h5,h6,h7,h8,e2,e3;
  145. % repeated partial integration to compute P_i
  146. ulist :=cdr reval ulist;
  147. xlist :=cdr reval xlist;
  148. h4:=list xlist;
  149. % dequ is here a list containing only the conserved density
  150. % and flux to drop commen factors
  151. repeat <<
  152. e3:=divp;
  153. h3:=car h4; % h3 is the list of variables is a spec. order
  154. h4:=cdr h4;
  155. h5:=for e2:=1:length h3 collect 0;
  156. % h5 is old list of the conserved quantities
  157. h8:=0; % h8 counts integrations wrt. all variables
  158. repeat << % integrate several times wrt. all variables
  159. h8:=h8+1;
  160. h2:=h3; % h2 is a copy of h3
  161. h6:=nil; % h6 is new list of the conserved quantities
  162. h7:=nil; % h7 is true if any integration was possible
  163. while h2 neq nil do << % integrating wrt. each variable
  164. e2:=intpde(e3,ulist,h3,car h2,t);
  165. e3:=cadr e2;
  166. if not zerop e2 then h7:=t;
  167. h6:=cons(list('PLUS,car e2,car h5),h6);
  168. h5:=cdr h5;
  169. h2:=cdr h2
  170. >>;
  171. h5:=reverse h6;
  172. >> until (h7=nil) % no integration wrt. no variable was possible
  173. or (e3=0) % complete integration
  174. or (h8=10); % max. 10 integrations wrt. all variables
  175. >> until (e3=0) or (h4=nil);
  176. return if e3=0 then cons('LIST, h5)
  177. else nondiv
  178. % end of the computation of the conserved current P
  179. % result is a list of P_i
  180. end$ % of intcurrent2
  181. %-------------
  182. algebraic procedure conlaw2(problem,runmode)$
  183. begin
  184. scalar contrace,eqlist,ulist,xlist,dequ,cllist,divlist,
  185. sb,densord,flist,eqord,maxord,dulist,revdulist,vl,expl,
  186. deplist,e1,e2,e3,n,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,
  187. condi,soln,adjust_old,potold,adjustold,udens,gensepold,
  188. inequ0,inequ,logoold,treqlist,fl,facold,u,lhslist,cpu,
  189. gc,cpustart,gcstart,nontriv,cf0,rtnlist,paralist,solns,
  190. found,clcopy,extraline,nondiv,nx,nde,nonconstc,
  191. mindensord,mindensord0,maxdensord,rules$
  192. lisp <<adjustold:=adjust_fnc; adjust_fnc:=t;
  193. logoold:=logoprint_; logoprint_:=t;
  194. potold:=potint_; potint_:=t;
  195. facold:=facint_; facint_:=1000>>;
  196. cpustart:=lisp time()$ gcstart:=lisp gctime()$
  197. % contrace:=t;
  198. %--- extracting input data
  199. eqlist:= maklist first problem;
  200. ulist := maklist second problem;
  201. xlist := maklist third problem;
  202. nx:=length xlist;
  203. nde:=length eqlist;
  204. if contrace then write"eqlist=",eqlist,
  205. " ulist=",ulist," xlist=",xlist;
  206. mindensord:=part(runmode,1)$
  207. maxdensord:=part(runmode,2)$
  208. expl :=part(runmode,3)$
  209. flist :=part(runmode,4)$
  210. inequ0 :=part(runmode,5)$
  211. problem:=runmode:=0;
  212. %--- initial printout
  213. lisp(if logoprint_ then <<terpri()$
  214. write "--------------------------------------------------",
  215. "------------------------"$ terpri()$terpri()$
  216. write "This is CONLAW2 - a program for calculating conservation",
  217. " laws of DEs"; terpri()
  218. >> else terpri());
  219. if nde = 1
  220. then write "The DE under investigation is :"
  221. else write "The DEs under investigation are :";
  222. for each e1 in eqlist do write e1;
  223. write "for the function(s): ",ulist;
  224. write"======================================================"$
  225. %--- lhslist is the list of derivatives to substitute
  226. %--- is needed in order not to let the Q depend on them and their deriv.
  227. eqlist:=reverse eqlist;
  228. lhslist:={};
  229. for each h1 in eqlist do lhslist:=cons(lhs h1,lhslist);
  230. %--- bringing eqlist and ulist in line
  231. h1:={}; h2:={};
  232. if nde neq length ulist then n:=t else
  233. for each e1 in eqlist do <<
  234. e2:=part(lhs e1,1);
  235. if freeof(ulist,e2) then n:=t
  236. else h1:=cons(e2,h1);
  237. h2:=cons(lhs e1 - rhs e1, h2)
  238. >>;
  239. if n then
  240. rederr("The lists of equations and functions are not consistent!")
  241. else <<ulist:=h1; eqlist:=h2>>;
  242. if contrace then write"ulist=",ulist," eqlist=",eqlist;
  243. %--- initializations to be done only once
  244. rtnlist:={};
  245. nondiv:=lisp gensym(); % as a marker if p-computation was not succ.
  246. %------ the list of parameters of the equation to be determined
  247. paralist:={};
  248. for each e1 in flist do
  249. if not freeof(eqlist,e1) then paralist:=cons(e1,paralist);
  250. %------ determination of the order of the input equations
  251. eqord:=0;
  252. mindensord0:=mindensord;
  253. for each e1 in eqlist do
  254. for each e2 in ulist do <<
  255. h1:=totdeg(e1,e2);
  256. if h1>eqord then eqord:=h1
  257. >>;
  258. for n:=1:nde do <<
  259. h1:=mkid(q_,n);
  260. if not lisp(null get(mkid('q_,n),'avalue)) then <<
  261. for each e2 in ulist do <<
  262. h2:=totdeg(h1,e2);
  263. if h2>eqord then eqord:=h2;
  264. if h2>mindensord then mindensord:=h2
  265. >>;
  266. cf0:=t;
  267. >>
  268. >>;
  269. if contrace then write"eqord=",eqord;
  270. if maxdensord<mindensord then maxdensord:=mindensord;
  271. %------ all transformations into jet-space
  272. sb:=subdif1(xlist,ulist,eqord)$
  273. if contrace then write"sb=",sb;
  274. treqlist:=eqlist;
  275. for each e1 in sb do treqlist:=sub(e1,treqlist);
  276. for each e1 in sb do lhslist:=sub(e1, lhslist);
  277. if contrace then write"treqlist=",treqlist,
  278. " lhslist=",lhslist;
  279. if cf0 then
  280. for n:=1:nde do <<
  281. h1:=mkid(q_,n);
  282. if not lisp(null get(mkid('q_,n),'avalue)) then <<
  283. for each e1 in sb do h1:=sub(e1,h1);
  284. lisp(mkid('q_,n)):=h1;
  285. >>
  286. >>;
  287. for each e1 in sb do inequ0:=sub(e1,inequ0);
  288. %--- investigate conservation laws of increasing order
  289. for densord:=mindensord:maxdensord do <<
  290. nodepnd(ulist);
  291. cpu:=lisp time()$ gc:=lisp gctime()$
  292. if cf0 then
  293. lisp<<write"A special ansatz of order ",densord,
  294. " for the characteristic"$terpri()$
  295. write"function(s) is investigated.";terpri()
  296. >> else
  297. lisp<<
  298. write"Currently conservation laws with characteristic";
  299. terpri();
  300. write"function(s) of order ",densord," are determined";
  301. terpri();
  302. write"======================================================"$
  303. >>;
  304. %--- repeated initializations
  305. %--- maxord is maximal derivative in condition
  306. maxord:=eqord % from the total derivatives
  307. + 1 % for safety
  308. + if eqord>densord then eqord
  309. else densord$
  310. %######## possibly to be increased due to substitutions
  311. if contrace then write"maxord=",maxord;
  312. if {}=fargs first ulist then
  313. for each e1 in ulist do depnd(e1,{xlist});
  314. sb:=subdif1(xlist,ulist,maxord)$
  315. nodepnd ulist;
  316. if contrace then write"sb=",sb;
  317. dulist:=ulist . reverse for each e1 in sb collect
  318. for each e2 in e1 collect rhs e2;
  319. sb:=0;
  320. revdulist:=reverse dulist; % dulist with decreasing order
  321. udens:=part(dulist,densord+1); % derivatives of order densord
  322. vl:=for each e1 in dulist join e1;
  323. if contrace then write"vl=",vl," udens=",udens;
  324. if not flist then fl:={}
  325. else fl:=flist;
  326. %--- initializing characteristic functions cf, the list of functions fl
  327. deplist:=ulist . for n:=1:densord collect
  328. listdifdif2(lhslist,part(dulist,n+1));
  329. if expl then deplist:=xlist . deplist;
  330. deplist:=reverse deplist;
  331. cf:={};
  332. for n:=1:nde do <<
  333. h1:=mkid(q_,n);
  334. if lisp(null get(mkid('q_,n),'avalue)) then <<
  335. nodepnd({h1});
  336. depnd(h1, deplist);
  337. fl:=cons(h1,fl);
  338. >>;
  339. cf:=cons(h1,cf);
  340. >>;
  341. cf:=reverse cf;
  342. if contrace then write"fl=",fl;
  343. if contrace then lisp (write" depl*=",depl!*);
  344. %--- generation of the conditions
  345. condi:={};
  346. for each u in ulist do <<
  347. if contrace then write"function=",u;
  348. h1:=treqlist;
  349. h2:=cf;
  350. h3:=0;
  351. while h1 neq {} do << % sum over all equations
  352. if contrace then write"equation :",first h1;
  353. for each e1 in vl do % sum over u and all its derivatives
  354. if lisp(reval algebraic(u) =
  355. car combidif algebraic(e1)) then
  356. << % for u and all its derivatives
  357. e2:=df(first h1, e1);
  358. if e2 neq 0 then <<
  359. if contrace then write"e1=",e1;
  360. dequ:=first h2 * e2;
  361. e2:=1;
  362. for each e3 in lisp
  363. cons('LIST,cdr combidif(algebraic e1)) do
  364. <<dequ:=totdif(dequ,part(xlist,e3),e3,dulist)$
  365. e2:=-e2;
  366. if contrace then write"dequ=",dequ," e3=",e3>>;
  367. h3:=h3+e2*dequ;
  368. if contrace then write"h3=",h3;
  369. >>;
  370. >>;
  371. h1:=rest h1;h2:=rest h2
  372. >>;
  373. condi:=cons(h3,condi)
  374. >>;
  375. if contrace then write"condi=",condi;
  376. %--- generating a substitution list
  377. %--- at first using the equations themselves
  378. sb:={};
  379. rules:={};
  380. h1:=treqlist;
  381. h2:=lhslist;
  382. h4:=nil; % h4 is list of undifferentiated substitutions
  383. while h1 neq {} do <<
  384. h3:=first h2;
  385. h5:=h3-first h1;
  386. rules:=cons(h3 => h5,rules)$
  387. lisp(e3:=combidif h3);
  388. % extracts the list of derivatives: u`1`1`2 --> (u, 1, 1, 2)
  389. lisp(h4:=cons(list(car e3, cdr e3, h5), h4))$
  390. % function name of h3, derivative list of h3, value of h3
  391. h1:=rest h1;
  392. h2:=rest h2;
  393. >>;
  394. %--- then their derivatives
  395. for each e1 in vl do lisp <<
  396. e1:=reval e1;
  397. % is e1 a derivative of any of the undifferentiated substitutions?
  398. h1:=h4;
  399. while h1 neq nil do <<
  400. h3:=comparedif2(caar h1, cadar h1, e1);
  401. if (h3 neq nil) and (h3 neq 0) then algebraic <<
  402. h3:=lisp(cons('LIST,h3));
  403. dequ:=lisp caddar h1; % rhs which is to be differentiated
  404. for each n in h3 do dequ:=totdif(dequ,part(xlist,n),n,dulist);
  405. % new highest derivatives should be added to vl afterwards
  406. % if lower derivatives are substituted by higher derivatives
  407. rules:=cons(e1 => dequ,rules)$
  408. lisp(h1:=nil)
  409. >> else lisp(h1:=cdr h1);
  410. >>
  411. >>;
  412. if contrace then write"rules=",rules;
  413. let rules;
  414. condi:=condi;
  415. clearrules rules$
  416. if contrace then write"condi=",condi;
  417. vl:=append(xlist,vl); % now the full list
  418. inequ:=inequ0;
  419. %--- inequ is to stop crack if order of cf is too low
  420. if (densord neq 0) and
  421. ((cf0=nil) or (mindensord0 neq 0)) then <<
  422. % investigation should stop if
  423. % cf is independent of highest order derivatives
  424. dequ:=0;
  425. for each e1 in cf do <<
  426. h1:=udens;
  427. while h1 neq {} do <<
  428. dequ:=dequ+df(e1,first h1)*(lisp gensym());
  429. h1:=rest h1
  430. >>;
  431. >>;
  432. inequ:=cons(dequ,inequ)
  433. >>;
  434. let rules;
  435. inequ:=inequ;
  436. clearrules rules$
  437. rules:=0;
  438. if contrace then write"inequ=",inequ;
  439. %--- freeing some space
  440. sb:=revdulist:=deplist:=e1:=e2:=e3:=
  441. n:=h1:=h2:=h3:=soln:=u:=dequ:=0;
  442. %--- the real calculation
  443. if lisp(!*time) then
  444. write "time to formulate condition: ", lisp time() - cpu,
  445. " ms GC time : ", lisp gctime() - gc," ms"$
  446. solns:=crack(condi,inequ,fl,vl);
  447. %--- postprocessing
  448. lisp terpri()$
  449. found:=nil;
  450. while solns neq {} do <<
  451. divlist:={};
  452. cllist:={};
  453. soln:=first solns;
  454. solns:=rest solns;
  455. condi:=first soln;
  456. cfcopy:=sub(second soln,cf);
  457. h1:=third soln;
  458. if contrace then <<
  459. write"cfcopy=",cfcopy;
  460. write"soln=",soln;
  461. write"third soln=",h1;
  462. >>;
  463. fl:={};
  464. h2:={};
  465. for each e1 in h1 do <<
  466. if not freeof(condi,e1) then fl:=cons(e1,fl);
  467. % fl to output remaining conditions later
  468. if freeof(paralist,e1) then h2:=cons(e1,h2)
  469. >>;
  470. h1:=parti_fn(h2,condi)$
  471. if contrace then write"h1(partitioned)=",h1;
  472. extraline:=nil;
  473. nonconstc:={};
  474. while h1 neq {} do <<
  475. e1:=first h1;h1:=rest h1;
  476. for each h4 in e1 do
  477. if fargs h4 neq {} then <<
  478. nonconstc:=cons(h4,nonconstc);
  479. lisp <<
  480. write"The function "$
  481. fctprint list reval h4$
  482. write" is not constant!";
  483. extraline:=t;
  484. terpri()
  485. >>
  486. >>;
  487. dequ:=0; % to compute rhs
  488. h2:=treqlist; % "
  489. if paralist then h2:=sub(second soln,h2); % "
  490. if contrace then write"h2=",h2; % "
  491. nontriv:=nil;
  492. h3:=for each e2 in cfcopy collect <<
  493. e3:=for each h4 in e1 sum fdepterms(e2,h4);
  494. dequ:=dequ+e3*first h2; h2:=rest h2; % computes rhs
  495. if e3 neq 0 then nontriv:=t;
  496. e3
  497. >>;
  498. if nontriv then <<
  499. found:=t;
  500. cllist:=cons(<<if contrace then write"h3-1=",h3," dequ=",dequ;
  501. sb:=absorbconst(h3,e1)$
  502. if (sb neq nil) and (sb neq 0) then <<
  503. h3:=sub(sb,h3);
  504. dequ:=sub(sb,dequ)
  505. >>;
  506. if contrace then write"h3-2=",h3," dequ=",dequ;
  507. if (length(e1)=1) and (fargs first e1 = {}) then <<
  508. h4:=first e1;
  509. dequ:=sub(h4=1,dequ);
  510. sub(h4=1,h3)
  511. >> else h3
  512. >>,
  513. cllist);
  514. divlist:=cons(dequ,divlist)
  515. >>
  516. >>;
  517. if contrace then <<
  518. write"characteristic functions found so far:";
  519. write cllist;
  520. >>$
  521. if condi neq {} then <<
  522. write"There are remaining conditions: ",
  523. condi;
  524. lisp <<
  525. write"for the functions: ";
  526. fctprint cdr reval algebraic fl;terpri();
  527. write"Corresponding CLs might not be shown below as they";
  528. terpri()$write"could be of too low order.";terpri()>>;
  529. extraline:=t;
  530. >>;
  531. if extraline then lisp <<
  532. write"======================================================"$
  533. terpri()
  534. >>;
  535. %--- Dropping conservation laws of too low order
  536. if (densord > 0) and
  537. ((cf0=nil) or (mindensord0 neq 0)) then <<
  538. h1:={};
  539. h2:={};
  540. for each e1 in cllist do <<
  541. h5:=udens;
  542. while (h5 neq {}) and
  543. freeof(e1,first h5) do h5:=rest h5;
  544. if h5 neq {} then <<
  545. h1:=cons(e1,h1);
  546. h2:=cons(first divlist,h2)
  547. >>;
  548. divlist:=rest divlist;
  549. >>;
  550. cllist:=h1;
  551. divlist:=h2
  552. >>;
  553. if contrace then write"cllist=",cllist;
  554. if cllist neq {} then <<
  555. %--- Below h1 is the list of W^i in the Anco/Bluman formula
  556. h1:=for e1:=1:(length cllist) collect
  557. intcurrent1(part(divlist,e1),ulist,xlist,dulist,nx,nde,
  558. eqord,densord);
  559. %--- Backsubstitution of e.g. u`1`1 --> df(u,x,2)
  560. for each e1 in ulist do depnd(e1,{xlist});
  561. on evallhseqp;
  562. sb:=subdif1(xlist,ulist,maxord)$
  563. sb:=for each e1 in sb join
  564. for each e2 in e1 collect(rhs e2 = lhs e2);
  565. off evallhseqp;
  566. cllist:=sub(sb,cllist);
  567. h1:=sub(sb,h1);
  568. %--- lambda integration of h1 to compute P_i
  569. h2:=lisp gensym()$
  570. for each e1 in ulist do
  571. h1:=sub(e1=h2*e1,h1);
  572. if not lisp(freeof(h1,'SUB)) then h1:={}
  573. else
  574. h1:=for each e1 in h1 collect << % i.e. for each cl
  575. h10:=sub(sb,first divlist); divlist:=rest divlist;
  576. % at first try direct integration to compute p
  577. h9:=intcurrent2(h10,append(nonconstc,ulist),xlist,nondiv);
  578. % if no success use lambda-integration
  579. if h9=nondiv then <<
  580. h8:=t; % whether intcurrent1 is still ok
  581. %--- at first the term h10 = T^i/x^i in conca.tex
  582. for each e2 in ulist do <<
  583. if h8 then h10:=err_catch_sub(e2,0,h10);
  584. if h10 eq nil then h8:=nil
  585. >>$
  586. if contrace then write"h10-1=",h10$
  587. if h8 and (h10 neq 0) then <<
  588. for each e2 in xlist do <<
  589. if h8 then h10:=err_catch_sub(e2,h2*e2,h10);
  590. if h10 eq nil then h8:=nil
  591. >>$
  592. if h8 then <<
  593. if contrace then write"h10-2=",h10$
  594. h10:=int(h10*h2**(nx-1),h2);
  595. if contrace then write"h10-3=",h10$
  596. %--- the following is to catch errors in:
  597. %--- sub(h2=1,h10)-sub(h2=0,h10)
  598. h6:=err_catch_sub(h2,1,h10);
  599. if contrace then write"h6=",h6$
  600. if h6 eq nil then h7:=nil
  601. else h7:=err_catch_sub(h2,0,h10);
  602. if contrace then write"h7=",h7$
  603. if h7 eq nil then h8:=nil
  604. else h10:=h6-h7
  605. >>
  606. >>$
  607. if contrace then write"h10-4=",h10$
  608. h4:={}; % h4 becomes the inverse list of P^i
  609. h11:=0;
  610. while h8 and (e1 neq {}) do <<
  611. h11:=h11+1;
  612. e2:=first e1;
  613. e1:=rest e1;
  614. if contrace then write"e2=",e2$
  615. h3:=int(e2/h2,h2);
  616. if contrace then write"h3-1=",h3$
  617. %--- the following is to catch errors in:
  618. %--- sub(h2=1,h3)-sub(h2=0,h3)
  619. h6:=err_catch_sub(h2,1,h3);
  620. if h6 eq nil then h7:=nil
  621. else h7:=err_catch_sub(h2,0,h3);
  622. if h7 eq nil then h8:=nil
  623. else h4:=cons(h6-h7+h10*part(xlist,h11),h4)
  624. >>;
  625. if h8 then h9:=reverse h4
  626. >>;
  627. h9
  628. >>;
  629. if contrace then write"h1-1=",h1$
  630. if h1={} then <<
  631. lisp <<
  632. write"The conserved quantities could not be found."$
  633. terpri()
  634. >>$
  635. if condi neq {} then lisp <<
  636. write"For that the remaining conditions should be solved.";
  637. terpri()
  638. >>;
  639. lisp <<
  640. write"The adjoined symmetries are:"$terpri()
  641. >>$
  642. for each e1 in cllist do write e1$
  643. >>$
  644. if contrace then <<
  645. write"h1=",h1;write"cllist=",cllist;write"eqlist=",eqlist
  646. >>;
  647. while h1 neq {} do <<
  648. h2:=first h1;
  649. h3:=first cllist;
  650. rtnlist:=cons({h3,h2},rtnlist);
  651. %--- conditions on parameters
  652. if paralist neq {} then
  653. for each e2 in second soln do
  654. if not freeof(paralist,lhs e2) then
  655. <<write e2,",";lisp(terpri())>>$
  656. %--- the conservation laws
  657. %--- Test whether actually only an adjoint symmetry has been
  658. %--- computed and not a conservation law
  659. h4:=eqlist;
  660. if paralist neq {} then h4:=sub(second soln,h4);
  661. h8:=0;
  662. if h2 neq nondiv then <<
  663. h5:=h4;
  664. for each e1 in h3 do <<
  665. h8:=h8 + e1*(first h5)$
  666. h5:=rest h5
  667. >>$
  668. for e1:=1:nx do <<
  669. h8:=h8-df(part(h2,e1),part(xlist,e1))$ % for test purposes
  670. >>;
  671. if h8 neq 0 then h2:=nondiv
  672. >>;
  673. if h2=nondiv then write"Adjoint symmetry:"
  674. else write"Conservation law:";
  675. while h3 neq {} do <<
  676. if length h3 < length first cllist then write "+"$
  677. write"(",first h3,") * (",first h4,")"$
  678. h3:=rest h3; h4:=rest h4
  679. >>$
  680. if h2=nondiv then <<
  681. lisp <<
  682. write"could not be written as a divergence but solves the"$
  683. terpri()$
  684. write"adjoint symmetry condition and therefore represents"$
  685. terpri()$
  686. write"an adjoint symmetry."$ terpri()$
  687. >>$
  688. if (h8 neq 0) and (condi neq {}) then <<
  689. write"Please check: if the remaining conditions guarantee "$
  690. write" 0 = ",h8$
  691. write"then the conservation law is"$
  692. write" 0 = "$
  693. for e1:=1:nx do <<
  694. write"df( ",part(h2,e1),", ",part(xlist,e1)," )"$
  695. if e1<nx then write "+"$
  696. >>
  697. >>$
  698. >> else <<
  699. write"= "$
  700. for e1:=1:nx do <<
  701. write"df( ",part(h2,e1),", ",part(xlist,e1)," )"$
  702. if e1<nx then write "+"$
  703. >>
  704. >>;
  705. h1:=rest h1;
  706. cllist:=rest cllist;
  707. write"======================================================"$
  708. >>$
  709. >>; % if cllist neq {} then <<
  710. nodepnd(ulist);
  711. >>; % while solns neq {} do <<
  712. if found=nil then <<
  713. write"There is no conservation law of this order.";
  714. write"======================================================"$
  715. >>
  716. >>; % for densord:=mindensord:maxdensord
  717. if fargs first ulist = {} then
  718. for each e1 in ulist do depnd(e1,{xlist});
  719. if lisp(!*time) then
  720. write "time to run conlaw2: ", lisp time() - cpustart,
  721. " ms GC time : ", lisp gctime() - gcstart," ms"$
  722. lisp <<adjust_fnc:=adjustold;
  723. logoprint_:=logoold;
  724. %gensep_:=gensepold;
  725. potint_:=potold;
  726. facint_:=facold>>;
  727. return rtnlist
  728. end$ % of conlaw2
  729. end$