We've encountered some situations in our own research lately that benefit substantially from simultaneous solution, e.g.,
would normally be solved with
eq_phi = TransientTerm() == DiffusionTerm(coeff=Dphiphi) + ... eq_T = TransientTerm() == ... + DiffusionTerm(coeff=DTT)
where the ... is ideally some ConvectionTerm, but which might be an explicit (DphiT * T.getFaceGrad()).getDivergence() and so on if w can't easily factor out the dependence of on .
It can be advantageous, though, to create a new master variable where and and to compose a master equation to simultaneously represent both the equation and the equation.
Daniel presently has a functional (but arguably brutish) implementation of this, but we've been brainstorming a way to make this more general and more elegant. The idea that we are currently playing with is to use the __call__() method of a Term to change it from a generic operator like it is now into an operator applied to a specific CellVariable, i.e. instead of .
- The current syntax will remain valid. DiffusionTerm(coeff=D) will continue to represent . You must call solve(var=phi) or sweep(var=phi) to apply the operator to the variable .
- If, instead, you write DiffusionTerm(coeff=D)(phi), this will represent . There will be no need to pass a variable to sweep() or solve(). In fact, it might be an error to do so.
In this new syntax, we would write
eq = (TransientTerm()(phi) + TransientTerm()(T) == (DiffusionTerm(coeff=Dphiphi)(phi) + DiffusionTerm(coeff=DphiT)(T) + DiffusionTerm(coeff=DTphi)(phi) + DiffusionTerm(coeff=DTT)(T)))
and then call solve(), either without a var argument, or perhaps with a var argument that must only contain a tuple of phi and T. I'm inclined to prohibit the var argument, because the list of solution variables is already implicitly determined by the Terms, so its value is proscribed.
It should also be possible (and maybe a bit clearer) to write
eq_phi = TransientTerm()(phi) == (DiffusionTerm(coeff=Dphiphi)(phi) + DiffusionTerm(coeff=DphiT)(T) eq_T = TransientTerm()(T) == DiffusionTerm(cofeff=DTphi)(phi) + DiffusionTerm(coeff=DTT)(T) eq = eq_phi + eq_T
We had originally talked about writing eq = eq_phi & eq_T, but as I write this up, I now don't think there's any reason to introduce this new syntax.
There remains an issue of what to do about boundary conditions.
- One option is to make boundary conditions also take a __call__() method, so FixedValue(...) would apply to whatever variable was passed to eq.solve(var=...), but FixedValue(...)(phi) would explicitly mean .
- Another option is to wait for our planned boundary condition reform and to require all boundary conditions to either be applied directly to CellVariables or to be incorporated as SourceTerms in the equation, as discussed in the new FAQ.
We welcome suggestions of how users would like this to look and behave.