Preamble Sometimes I have to solve nonlinear PDEs using Comsol. Often these equations I already have in Mma, written in a Mma notations. For this reason I would like to be able to transform them so that I could copy-paste them directly into Comsol.

There is one more reason to do in such a way. The point is that the Comsol service is poor: the slot to type equations is narrow and short, as if it is created to force the user to make typing errors. In addition, if Comsol is not sure in syntax, it makes equations yellow. I simply do not see them afterwards.

In Mma, in contrast, one can type a well-visible equation, and then... what? One cannot copy-paste it, since Comsol has another syntax.

a) One needs to introduce dependent variables without their arguments. That is u[x] in Mma, but u in Comsol

b) In functions one needs to replace the square brackets by round ones and should not use the Capitals. That is, Sin[x] in Mma, but sin(x) in Comsol.

c) One has to use another expressions for the derivatives. That is D[u[x],x] and D[u[x],{x,2}] or u'[x]and u''[x]in Mma, but ux and uxx in Comsol.

Minor addition: if the differential equation is non-stationary, one does not need to take care of time derivatives, since Comsol has a special template for that purpose.

My question is: How to do it programmatically?

What I already do is as follows. Say, I need to transform an expression: expr = D[y[x, t], {x, 2}] + D[y[x, t], x] + Sin[x] + y[x, t] -y[x, t]^3. I do as follows:

    expr = D[y[x, t], {x, 2}] + D[y[x, t], x] + Sin[x] + y[x, t] -y[x, t]^3;

    expr /. y -> (u[#] &) /. {u[x]^n_ -> u^n, u[x] -> u} /. {u'[x] -> ux, u''[x] -> uxx}

In principle, it almost gives what I need. This expression can be copy-pasted into Comsol.

There is still a problem, however. The resulting expression contains spaces between some characters. For example, each sign +is flanked by the spaces. Comsol treats these as errors. Do you see any way to programmatically eliminate these spaces?

  • 2
    $\begingroup$ I assume something of the sort: // ToString // StringReplace[#, " " .. -> ""] & instead of TraditionalForm does not work? $\endgroup$ – gpap Nov 25 '14 at 10:59
  • $\begingroup$ Can't help. Copying & pasting the TraditionaForm output to Notepad from V.9 on Win 7 already yields an expression with no spaces, i.e. : -u^3+u+ux+uxx+sin(x) $\endgroup$ – Chris Degnen Nov 25 '14 at 11:20
  • $\begingroup$ @Cris Dengen, thank you, Cris. Based on your idea I built a function that works: toComsol[expr_, y_, u_] := Module[{n}, expr /. y -> (u[#] &) /. {u[x]^n_ -> u^n, u[x] -> u} /. {u'[x] -> ToExpression[ToString[u] <> "x"], u''[x] -> ToExpression[ToString[u] <> "xx"]} // InputForm // ToString // ToLowerCase // StringReplace[#, {" " .. -> "", "[" -> "(", "]" -> ")"}] &] . Why do not you give your idea as a regular answer? $\endgroup$ – Alexei Boulbitch Nov 25 '14 at 12:29

You could convert the expression to string after applying all your rules, and then replace any spaces using StringReplace:

expr = D[y[x, t], {x, 2}] + D[y[x, t], x] + Sin[x] + y[x, t] - y[x, t]^3;
rules = {y -> (u[#] &), u[x]^n_ -> u^n, u[x] -> u, u'[x] -> ux, u''[x] -> uxx};
postprocessing = ToLowerCase[ToString[InputForm[#]]] ~ StringReplace ~ 
    {" " .. -> "", "[" -> "(", "]" -> ")"} &;

I was reluctant to post an answer as I have no idea what sort of input comsol requires but it seems based on your comment that the following was what you wanted:

expr //. rules // postprocessing
(* u-u^3+ux+uxx+sin(x) *)
  • $\begingroup$ Sorry, right as it is written in your case it creates the expressions for derivatives that are not acceptable for Comsol. It can be, however, slightly transformed: rule1 = {y -> (u[#] &)}; then rule2 = {u[x]^n_ -> u^n, u[x] -> u}; , rule3 = {u'[x] -> ux, u''[x] -> uxx}; and postprocessing = ToLowerCase[ToString[InputForm[#]]]~ StringReplace~{" " .. -> "", "[" -> "(", "]" -> ")"} &; . After that one makes expr /. rule1 /. rule2 /. rule3 // postprocessing that works perfectly $\endgroup$ – Alexei Boulbitch Nov 25 '14 at 14:44
  • $\begingroup$ @AlexeiBoulbitch I can't see any difference between the output of your code and mine. Are you sure you are using replace repeated //. and not merely /. when applying my rules to expr? $\endgroup$ – gpap Nov 25 '14 at 16:04
  • $\begingroup$ You are probably right. Yesterday I tried your code and repeatedly obtained a result that differs from what I want vy the form in which the derivatives are represented. Today it is OK. Well, it must be something related to Mma have kept in memory, though it seems I cleaned everything. $\endgroup$ – Alexei Boulbitch Nov 26 '14 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.