aboutsummaryrefslogtreecommitdiff
path: root/Tools/CodeGen/Jacobian.m
diff options
context:
space:
mode:
authorIan Hinder <ian.hinder@aei.mpg.de>2011-05-30 19:31:12 +0200
committerIan Hinder <ian.hinder@aei.mpg.de>2011-06-09 16:44:11 +0200
commit66668c409754acc1f76ed50118d8831fc3992c59 (patch)
treef81a7003d35aba34e128ddb2f3359290dd4e722e /Tools/CodeGen/Jacobian.m
parentf880f0a6da11cfd2be1decd03851051d885f3eef (diff)
Jacobian.m: Insert Jacobian multiplications after any shorthands that are used in the derivatives
In order to multiply derivatives by the Jacobians, it is necessary to evaluate the derivative operators. If shorthands are required for this, they must be computed before the Jacobians are multiplied. With this commit, Kranc will compute the Jacobianised derivatives as early as possible in the calculation after all the shorthands used in them have been assigned, rather than computing them at the start of the calculation.
Diffstat (limited to 'Tools/CodeGen/Jacobian.m')
-rw-r--r--Tools/CodeGen/Jacobian.m36
1 files changed, 33 insertions, 3 deletions
diff --git a/Tools/CodeGen/Jacobian.m b/Tools/CodeGen/Jacobian.m
index 31f6b67..20f24df 100644
--- a/Tools/CodeGen/Jacobian.m
+++ b/Tools/CodeGen/Jacobian.m
@@ -62,21 +62,51 @@ derivToJacDeriv[deriv_[var_, i_]] :=
derivToJacDeriv[deriv_[var_, i_, j_]] :=
Symbol["Global`Jac"<>ToString[deriv]<>ToString[i]<>ToString[j]<>ToString[var]];
+shorthandsInDerivDef[def_, shorthands_] :=
+ Module[{allAtoms},
+ allAtoms = Union[Level[def, {-1}]];
+ Intersection[shorthands, allAtoms]];
+
+(* Insert a Jacobian shorthand definition into a list of equations
+ after all the shorthands that it uses *)
+insertDerivInEqs[deriv_, defs_, eqs_, shorthands_] :=
+ Module[{shortsUsed, lhss, positions, positions2, position, newShort, derivsInShort, defsUsed},
+ newShort = jacobianShorthand[deriv]; (* Definition expression for new shorthand *)
+ derivsInShort = GridFunctionDerivativesInExpression[defs, newShort]; (* Derivatives needed *)
+ defsUsed = Map[GridFunctionDerivativeToDef[#, defs] &, derivsInShort]; (* Definitions of those derivatives *)
+ shortsUsed = Union[Flatten[Map[shorthandsInDerivDef[#, shorthands] &, defsUsed],1]];
+ lhss = Map[First, eqs];
+ positions = Map[Position[lhss, #, {1}, 1] &, shortsUsed];
+ MapThread[If[Length[#2] === 0,
+ Throw["Shorthand " <> ToString[#1] <> " used in derivative " <> ToString[deriv] <>
+ " but not defined in calculation"]] &, {shortsUsed, positions}];
+ positions2 = Map[#[[1,1]] &, positions];
+ position = If[Length[positions2] === 0, 1, Max[positions2]+1];
+ Insert[eqs, newShort, position]
+ ];
+
(* Given a calculation containing partial derivatives, return a
version of the calculation with all the partial derivatives multiplied
by the Jacobian *)
Options[InsertJacobian] = ThornOptions;
InsertJacobian[calc_List, opts:OptionsPattern[]] :=
- Module[{pdDefs, derivs, newShortDefs, newShorts, combinedShorts, combinedEqs, combinedCalc, eqs, newEqs},
+ Module[{pdDefs, derivs, newShortDefs, newShorts, combinedShorts, combinedEqs, combinedCalc, eqs, newEqs,
+ shorts},
+ shorts = lookupDefault[calc, Shorthands, {}];
pdDefs = OptionValue[PartialDerivatives];
derivs = GridFunctionDerivativesInExpression[pdDefs, lookup[calc, Equations]];
If[Length[derivs] === 0, Return[calc]];
newShortDefs = Map[jacobianShorthand, derivs];
newShorts = Map[First, newShortDefs];
- combinedShorts = Join[lookupDefault[calc, Shorthands, {}], newShorts];
+ combinedShorts = Join[shorts, newShorts];
eqs = lookup[calc, Equations];
newEqs = eqs /. (x_?(MemberQ[derivs, #] &) :> derivToJacDeriv[x]);
- combinedEqs = Join[newShortDefs, newEqs];
+ combinedEqs = newEqs;
+
+ Do[
+ combinedEqs = insertDerivInEqs[derivs[[i]], pdDefs, combinedEqs, shorts],
+ {i, Length[derivs], 1, -1}];
+
combinedCalc = mapReplace[mapReplace[mapEnsureKey[calc, Shorthands, {}], Shorthands, combinedShorts], Equations, combinedEqs];
combinedCalc];