conlaw2.red 22 KB

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