aboutsummaryrefslogtreecommitdiff
path: root/Tools/CodeGen/ConservationCalculation.m
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CodeGen/ConservationCalculation.m')
-rw-r--r--Tools/CodeGen/ConservationCalculation.m223
1 files changed, 223 insertions, 0 deletions
diff --git a/Tools/CodeGen/ConservationCalculation.m b/Tools/CodeGen/ConservationCalculation.m
new file mode 100644
index 0000000..66fc7f3
--- /dev/null
+++ b/Tools/CodeGen/ConservationCalculation.m
@@ -0,0 +1,223 @@
+
+(* Copyright 2010 Ian Hinder
+
+ This file is part of Kranc.
+
+ Kranc is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kranc is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Kranc; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*)
+
+BeginPackage["ConservationCalculation`", {"Errors`", "Helpers`", "Kranc`",
+ "MapLookup`", "KrancGroups`", "CalculationFunction`", "Differencing`"}];
+
+ProcessConservationCalculation;
+ConservationDifferencingOperators;
+DiffPlus;
+DiffMinus;
+ShiftMinus;
+PDplus;
+ConservationCalculationDeclaredGroups;
+ConservationDifferencingRealParameters;
+hlleAlpha;
+PrimitiveEquations;
+ConservedEquations;
+
+Begin["`Private`"];
+
+ConservationDifferencingOperators[] :=
+{
+ DiffPlus[i_] -> DiffPlusOp[i],
+ DiffMinus[i_] -> DiffMinusOp[i],
+ ShiftMinus[i_] -> 1/shift[i],
+ PDplus[i_] -> DPlus[i]
+};
+
+ConservationDifferencingRealParameters[] :=
+{
+ hlleAlpha
+};
+
+zeroRHSCalc[calc_] :=
+{
+ Name -> lookup[calc,Name] <> "_zero_rhs",
+ Schedule -> {"in MoL_CalcRHS"},
+ Equations ->
+ (Map[First, lookup[calc, Equations]] /. {flux[v_, rest___] :> (dot[v] -> 0)})
+};
+
+minmodVar[v_, i_, vLeft_, vRight_] :=
+{
+ slopeL -> DiffMinus[v, i],
+ slopeR -> DiffPlus[v, i],
+ slope -> MinMod[slopeL, slopeR],
+ vLeft -> v - 0.5 slope,
+ vRight -> v + 0.5 slope
+}
+
+vanLeerVar[v_, i_, vLeft_, vRight_] :=
+{
+ slopeL -> DiffMinus[v, i],
+ slopeR -> DiffPlus[v, i],
+ slope -> VanLeer[slopeL, slopeR],
+ vLeft -> v - 0.5 slope,
+ vRight -> v + 0.5 slope
+}
+
+leftSymbol[v_] :=
+ Symbol["Global`" <> ToString[v] <> "Left"];
+
+rightSymbol[v_] :=
+ Symbol["Global`" <> ToString[v] <> "Right"];
+
+fluxSymbol[v_] :=
+ Symbol["Global`" <> ToString[v] <> "Flux"];
+
+(* Return the list of conserved variables in a calculation *)
+consVars[calc_] :=
+ Union[(Map[First, lookup[calc, Equations]] /. {flux[v_, rest___] :> v})]
+
+(* Return the list of variables to reconstruct in a calculation *)
+primitiveVars[calc_] :=
+ lookup[calc, Primitives];
+
+ (* Module[{allGFs, calcSyms, gfsUsed, conserved, primitive}, *)
+ (* allGFs = allGroupVariables[lookup[calc, Groups]]; *)
+ (* calcSyms = calculationSymbols[calc]; *)
+ (* gfsUsed = Intersection[allGFs, calcSyms]; *)
+ (* conserved = consVars[calc]; *)
+ (* primitive = Complement[gfsUsed, conserved]; *)
+ (* primitive]; *)
+
+(* Return the variables for which Left and Right GFs need to be created *)
+lrGFs[calc_] :=
+ Join[primitiveVars[calc], consVars[calc]];
+
+ (* Module[{allGFs, calcSyms, gfsUsed, conserved, primitive}, *)
+ (* allGFs = allGroupVariables[lookup[calc, Groups]]; *)
+ (* calcSyms = calculationSymbols[calc]; *)
+ (* gfsUsed = Intersection[allGFs, calcSyms]; *)
+ (* conserved = consVars[calc]; *)
+ (* primitive = Complement[gfsUsed, conserved]; *)
+ (* Join[primitive, conserved]]; *)
+
+reconstructCalc[calc_, i_] :=
+{
+ Name -> lookup[calc,Name] <> "_reconstruct_" <> ToString[i],
+ Where -> Interior,
+ Schedule -> {"in MoL_CalcRHS after " <>
+ If[i == 1, lookup[calc,Name] <> "_zero_rhs",
+ lookup[calc,Name] <> "_rhs_" <> ToString[i-1]]},
+ Shorthands -> {slopeL, slopeR, slope},
+ ApplyBCs -> True,
+ Equations ->
+ Flatten[Table[vanLeerVar[v,i, leftSymbol[v], rightSymbol[v]],
+ {v, primitiveVars[calc]}], 1]
+};
+
+replaceVars[x_, vars_, f_] :=
+ Module[{},
+ x /. Map[(# -> f[#])&, vars]];
+
+hlle[flux[q_, j_] -> frhs_, vars_] :=
+ Module[{},
+ {
+ leftSymbol[fluxSymbol[q]] -> replaceVars[frhs, vars, leftSymbol],
+ rightSymbol[fluxSymbol[q]] -> replaceVars[frhs, vars, Function[v,ShiftMinus[rightSymbol[v],j]]],
+ fluxSymbol[q] ->
+ 1/2(leftSymbol[fluxSymbol[q]] + rightSymbol[fluxSymbol[q]] +
+ hlleAlpha(ShiftMinus[rightSymbol[q],j] - leftSymbol[q]))
+ }];
+
+fluxCalc[calc_, i_] :=
+ Module[{fluxes = Select[lookup[calc, Equations], MatchQ[#, flux[_,i]->_] &]},
+ {
+ Name -> lookup[calc,Name] <> "_flux_" <> ToString[i],
+ ApplyBCs -> True,
+ Where -> Interior,
+ Schedule -> {"in MoL_CalcRHS after " <> lookup[calc,Name] <>
+ "_intercell_conserved_" <> ToString[i]},
+ Shorthands -> Join[Map[leftSymbol[fluxSymbol[#]]&, consVars[calc]],
+ Map[rightSymbol[fluxSymbol[#]]&, consVars[calc]]],
+ Equations ->
+ Flatten[Map[hlle[#,GridFunctionsInExpression[#[[2]], lookup[calc, Groups]]] &, fluxes],1]
+ }];
+
+rhs[calc_, i_] :=
+{
+ Name -> lookup[calc,Name] <> "_rhs_" <> ToString[i],
+ Schedule -> {"in MoL_CalcRHS after " <> lookup[calc,Name] <> "_flux_" <> ToString[i]},
+ Where -> Interior,
+ Equations ->
+ Table[dot[v] -> dot[v] - PDplus[fluxSymbol[v], i], {v, consVars[calc]}]
+};
+
+primitivesCalc[calc_, thornName_] :=
+{
+ Name -> lookup[calc, Name] <> "_primitives",
+ Schedule -> {"in MoL_PostStep after " <> thornName <>"_ApplyBCs"},
+ Equations -> lookup[calc, PrimitiveEquations],
+ Shorthands -> lookupDefault[calc, Shorthands, {}]
+};
+
+conservedCalc[calc_] :=
+{
+ Name -> lookup[calc, Name] <> "_conserved",
+ Schedule -> {"at POSTINITIAL"},
+ Equations -> lookup[calc, ConservedEquations],
+ Shorthands -> lookupDefault[calc, Shorthands, {}]
+};
+
+conservedIntercellCalc[calc_, i_] :=
+{
+ Name -> lookup[calc, Name] <> "_intercell_conserved_" <> ToString[i],
+ Schedule -> {"in MoL_CalcRHS after " <> lookup[calc, Name] <> "_reconstruct_" <> ToString[i]},
+
+ Shorthands -> lookupDefault[calc, Shorthands, {}],
+ Equations ->
+ Module[{vars = Join[primitiveVars[calc], consVars[calc]]},
+ Join[lookup[calc, ConservedEquations] /. (Map[# -> leftSymbol[#] &, vars]),
+ lookup[calc, ConservedEquations] /. (Map[# -> rightSymbol[#] &, vars])]]
+};
+
+(* Given a ConservationCalculation structure, return a list of
+ calculations which should be scheduled to solve that conservation
+ law. *)
+ProcessConservationCalculation[calc_, thornName_] :=
+ Module[{},
+ {
+ zeroRHSCalc[calc],
+ conservedCalc[calc],
+ primitivesCalc[calc, thornName],
+ Sequence@@Flatten[
+ Table[
+ {reconstructCalc[calc, i],
+ conservedIntercellCalc[calc, i],
+ fluxCalc[calc, i],
+ rhs[calc, i]}, {i, 1, 3}], 1]
+ }];
+
+(* Return all the new groups which need to be created for this
+ conservation calculation *)
+ConservationCalculationDeclaredGroups[calc_] :=
+ Module[{},
+ Map[CreateGroup[
+ ToString[#]<>"_lr_group",
+ {leftSymbol[#], rightSymbol[#]}, {}] &, lrGFs[calc]] ~Join~
+ Map[CreateGroup[
+ ToString[#]<>"_flux_group",
+ {fluxSymbol[#]}, {}] &, consVars[calc]]];
+
+End[];
+
+EndPackage[];