Exit

<<xAct`xPert`;
<<xAct`xCoba`;

$CovDFormat="Prefix";
$DefInfoQ=False;
$CVVerbose=False;

DefManifold[M,4,{b,c,d,e,f,i,j,k}];
DefMetric[-1,g[-b,-c],CD,{";","∇"},WeightedWithBasis->AIndex];
PrintAs[RiemannCD]^="R";
PrintAs[RicciCD]^="R";
PrintAs[RicciScalarCD]^="R";
PrintAs[ChristoffelCD]^="Γ";
PrintAs[EinsteinCD]^="G";
PrintAs[Detg]^="g";

Definition of VarAction

PerturbAction[expr_,g_?MetricQ[a_?UpIndexQ,b_?UpIndexQ]|g_?MetricQ[a_?DownIndexQ,b_?DownIndexQ]]:=Module[{pertexpr,res,dgloc,(*dummyloc,*)hp},

(* We define the metric perturbation, if not defined already *)
dgloc=SymbolJoin["δ",g];

hp=Head@Perturbation[g[DownIndex@a,DownIndex@b]];

If[hp===Perturbation,DefMetricPerturbation[g,dgloc,SymbolJoin["ϵ",g]],dgloc=hp];


Block[{$DefInfoQ=False},

(* We perturb wrt to the metric and if it is the inverse metric we put a minus sign *)
pertexpr=(If[DownIndexQ[a],1,-1])*ToCanonical@ContractMetric@ExpandPerturbation@Perturbation[expr]/.Perturbation[tens_]:>0;

(*We then use VarD. It happens that some trivial Kronecker appear which need to be handle manually *)
res=ToCanonical[(SameDummies@ContractMetric@VarD[dgloc[LI[1],a,b],CovDOfMetric[g]][pertexpr])/.delta[-LI[n_],LI[m_]]:>KroneckerDelta[NoScalar[n],NoScalar[m]]];
];
res
]
PerturbAction[expr_,tensor_?xTensorQ,covd_]:=Module[{res,dummyloc,pertexpr,inds},
Block[{$DefInfoQ=False},

(* We use a dummy name for the variation of the tensor, and use it to replace the formal first order perturbation the tensor *)
(* So first we define this dummy tensor *)
dummyloc=SymbolJoin["Var",tensor];
inds=DummyIn/@SlotsOfTensor[tensor];
If[!xTensorQ[dummyloc],DefTensor[dummyloc@@inds,First@DependenciesOfTensor@tensor]];
SymmetryGroupOfTensor[dummyloc]^=SymmetryGroupOfTensor[tensor];

(* Then we perturb the action and replace Perturbation[Tensor[..]] by this dummy tensor *)
pertexpr=(ToCanonical@ContractMetric[ExpandPerturbation@Perturbation[expr]/.Perturbation[tens_?((#=!=tensor)&)[ar___]]:>0/.Perturbation[tensor[ind___]]:>dummyloc[ind]]);

(* With this simple head, VarD works correctly. Again we need to handel some trivial Kronecker *)
res=ToCanonical[(SameDummies@ContractMetric@VarD[dummyloc@@inds,covd][pertexpr])/.delta[-LI[n_],LI[m_]]:>KroneckerDelta[NoScalar[n],NoScalar[m]]];
];
res
]
PerturbAction[expr_,tensor_[inds___]]:=PerturbAction[expr,tensor[inds],CovDOfMetric@First@$Metrics]
PerturbAction[expr_,tensor_?xTensorQ[inds___],covd_]:=Module[{res,dummyloc,pertexpr},
Block[{$DefInfoQ=False},
dummyloc=SymbolJoin["Var",tensor];

If[!xTensorQ[dummyloc],DefTensor[dummyloc[inds],First@DependenciesOfTensor@tensor]];
SymmetryGroupOfTensor[dummyloc]^=SymmetryGroupOfTensor[tensor];

(* Perturbation with xPert*)
pertexpr=(ToCanonical@ContractMetric[ExpandPerturbation@Perturbation[expr]/.Perturbation[tens_?((#=!=tensor)&)[ar___]]:>0/.Perturbation[tensor[ind___]]:>dummyloc[ind]]);
(* VarD and removal of KroneckerDelta*)
res=ToCanonical[(SameDummies@ContractMetric@VarD[dummyloc[inds],covd][pertexpr])/.delta[-LI[n_],LI[m_]]:>KroneckerDelta[NoScalar[n],NoScalar[m]]];
];
res
]
VarAction[expr_,g_?MetricQ[as__?((UpIndexQ[#]||DownIndexQ[#])&)]]:=Module[{sqrtg},
sqrtg=Sqrt[SignDetOfMetric[g]Determinant[g][]];
ToCanonical[PerturbAction[expr,g[as]]+ReplaceDummies@expr*PerturbAction[sqrtg,g[as]]/sqrtg ]
]
VarAction[expr_,tensor_?((xTensorQ[#]&&Not[MetricQ[#]])&),g_?MetricQ]:=PerturbAction[expr,tensor,CovDOfMetric[g]]
VarAction[expr_,tensor_?((xTensorQ[#]&&Not[MetricQ[#]])&)]:=VarAction[expr,tensor,First@$Metrics];

VarAction[expr_,tensor_?((xTensorQ[#]&&Not[MetricQ[#]])&)[inds___],g_?MetricQ]:=PerturbAction[expr,tensor[inds],CovDOfMetric[g]]
VarAction[expr_,tensor_?((xTensorQ[#]&&Not[MetricQ[#]])&)[inds___]]:=VarAction[expr,tensor[inds],First@$Metrics];

Lagrangian

In my full notebook, I define a basis and a metric perturbation with a Schwarzschild background. I then write the Lagrangian for the Einstein-Hilbert action in terms of the components of the perturbation. I end up with an expression with around 200 terms. I want to apply a variation to this action with respect to the functions and that’s where I have problems. The InputForm of my terms in my Lagrangian are as shown below.

DefScalarFunction[p]

L=2f[r[]]+3Derivative[1][f[r[]]]-5 Derivative[2][f[r[]]]

VarAction[L,f[r[]]]

I can make a rule to change f(r) to a “scalar tensor”

DefTensor[fTensor[],M,PrintAs->"f"]

VarAction[L/.f[r[]]->fTensor[],fTensor[]]

However, this doesn’t take into account the other terms.