# Constructing a function that finds the fixed point of an expression

I have an issue regarding a function I'm trying to create, specially with how to aproppiately assign the variables. The code is the following, this is MWE of what I'm currently doing:

T1 = 300;
V1 = 200;
V2 = 100;

Press[P0_, V0_, V_, gam_] := P0*(V0/V)^gam
Temp[gam_] := T1*(V1/V2)^(gam - 1)
GamGas[T_] :=
1.4391 - 0.0416*Log[T - 273.15] + 0.0141*(Log[T - 273.15])^2 -
0.0015*(Log[T - 273.15])^3
meanGamGas[T1_, T2_] := Sqrt[GamGas[T1]*GamGas[T2]]

gamR = 1.35;
difgamR = 1;
While[
Abs[difgamR] > 0.0001,
gamR = meanGamGas[T1, Temp[gamR]];
difgamR = gamR - meanGamGas[T1, Temp[gamR]]
]
gamComp = gamR;

Manipulate[
Plot[
Press[P1, V1, v, gamComp], {v, V2, V1},
PlotRange -> {{V2, V1}, {0.8, 4}},
AxesLabel -> {"Volume [cm3]", "Pressure [atm]"},
PlotLabel -> "Compression Process"
],

{{P1, 1, "Initial Pressure"}, 0.8, 1.5,
Appearance -> "Labeled"},
{{T1, 300, "Initial Temperature"}, 300, 350,
Appearance -> "Labeled"}
]


Basically this plots the PV diagram of a compression process, and at the moment I give the code a value for T1, but I would like to be able to manipulate it and I'm not sure how to proceed.

I've tried the following: redefining my expressions to take into account the value of T1, but the section that gives the most trouble trying to understand how to solve this is the function While used to get the value for gamComp, maybe this is not the most adequate for this. In particular, the line

gamR = meanGamGas[T1, Temp[gamR]];


Where I could try to add T1 as a parameter of Temp[] and then gamR should be a function fo T1 also, but it doesn't make much sense given how Mathematica works.

I hope this is not a question too basic, I'm just recently working with this software, any comments on this are appreciated, I also tried looking for similar questions on this site but this in particular I think has a problem with how I'm defining the variables, which constrains me to work in way that won't get me anywhere.

Edit

I tried changing the following

Temp[gam_] := T1*(V1/V2)^(gam - 1)


to

Temp[gam_, T0_] := T0*(V1/V2)^(gam - 1)


And this

gamR = 1.35;
difgamR = 1;
While[
Abs[difgamR] > 0.0001,
gamR = meanGamGas[T1, Temp[gamR, T1]];
difgamR = gamR - meanGamGas[T1, Temp[gamR, T1]]
];
gamComp = gamR;


Into the manipulate enviroment and seems to work but the notebook starts to blink and the cpu works continuosly apparently as shown in this question Strange evaluating indication of output cells, I'm trying to use the answer given there but my question still remains as I think there must be a better way to solve this.

I find three issues with your code. There may be more, but the three I found were:

1. Temp must take a 2nd argument that provides a value for temperature, because I'm pretty sure you don't want to use the global value T1 = 300 at every evaluation.

2. Your While-loop iteration needs to be transformed into a function that returns a value of gamR with every call. It should not depend on global variables and it is better done with FixedPoint.

3. gamR is almost constant over the range 300 <= T1 <= 350, so in this range the T1 slider has no visible effect. I increased the range to 300 <= T1 <= 10000 to get some visible action.

I also decided to eliminate all global variables to avoid scoping issues with values set at top-level.

The resulting code looks like this:

With[{V1 = 200, V2 = 100},
Press[P0_, V0_, V_, gam_] := P0*(V0/V)^gam;
GamGas[T_] :=
1.4391 - 0.0416*Log[T - 273.15] + 0.0141*(Log[T - 273.15])^2 -
0.0015*(Log[T - 273.15])^3;
meanGamGas[T1_, T2_] := Sqrt[GamGas[T1]*GamGas[T2]];
Temp[gam_, T_] := T*(V1/V2)^(gam - 1);
With[{gamR0 = 1.35},
gamR[T1_] :=
FixedPoint[meanGamGas[T1, Temp[#, T1]] &, gamR0,
SameTest -> (Abs[#1 - #2] < 0.0001 &)]];
Manipulate[
Plot[Press[P1, V1, v, gamR[T1]], {v, V2, V1},
PlotRange -> {{V2, V1}, {0.8, 4}},
AxesLabel -> {"Volume [cm3]", "Pressure [atm]"},
PlotLabel -> "Compression Process"],
{{P1, 1, "Initial Pressure"}, 0.8, 1.5, .1, Appearance -> "Labeled"},
{{T1, 300, "Initial Temperature"}, 300, 10000, 100, Appearance -> "Labeled"}]]


and the manipulable plot looks like this • Thanks for this, it solves the problem in exactly the way I was trying. I also found another way, but it needs to define all the parameters that depend on T1 and P1 inside the Manipulate, so it gets a bit messy when adding more stages to the process. – Juan Pablo Rojas Olmedo Feb 23 '18 at 0:42