# Construct a function whose definition depends on the values of its arguments and evaluates a Section

I have defined a function that returns different output according to the values of the axes of an ellipsoidal. If none of the Which statement cases is satisfied then the function evaluates the contents of a whole section within the same notebook (that actually contains several numerical integrations) and return as SMat the final output of this section. The function is defined based on the feedback I got from here and here.

Clear[S]
S[a1_, a2_, a3_] :=
Module[{b1 = a1, b2 = a2, b3 = a3},
Print["Ellipsoidal axes ", " a1: ", b1, ", a2: ", b2, ", a3: ", b3];
Which[(*sphere*)b1 == b2 == b3, Print["spherical inclusion"];
SMat = SSphere[a1, a2, a3];
Return[SMat],(*prolate spheroid*)(b1 == b2 && 1 < b3/b1 <= 1000),
Print["Prolate Spheroidal Inclusion"];
SMat = Chop@SProlateSpheroid[a1, a2, a3];
Return[SMat],(*oblate spheroid*)(b1 == b2 && b3/b1 <= 1),
Print["Oblate Spheroidal Inclusion"];
SMat = Chop@SOblateSpheroid[a1, a2, a3]; Return[SMat],
b3/b1 > 1000, Print["cylindrical inclusion"];
SMat = Chop@SCylinder[a1, a2, a3];
Return[SMat],(*generic ellipsoid spheroid with a3>a2>
a1*)(b3 > b2) && (b2 > b1),
Print["generic ellipsoid with a3>a2>a1"];
SMat = Chop[SEllipsoid[a1, a2, a3]];
Return[SMat],(*numerical evaluation in any other case*)True,
Print["generic ellipsoid; numerical evaluation"]; EvalSection]]


where

EvalSection :=
Block[{notebook, nb, thissection, result}, "find me 31415";
notebook = NotebookGet[EvaluationNotebook[]];
thissection =
Select[Cases[notebook, CellGroupData[a__],
Infinity], ! FreeQ[#1, "\"find me 31415\""] &];
nb = CreateDocument[];
NotebookWrite[nb, thissection];
result = NotebookEvaluate[nb, InsertResults -> True];
NotebookClose[nb]; result]


EDIT: Several lines of code unrelated to the problem were removed in order to make the post more readable Given the various definitions for the involved functions the function S[a1,a2,a3] works as desired for the cases with available closed form solutions. For instance

v = 0.3;
S[1, 2, 3]
(* Ellipsoidal axes  a1: 1, a2: 2, a3: 3*)
(*generic ellipsoid with a3>a2>a1*)
(* {{0.767827, 0.129931, 0.172969, 0, 0, 0}, {-0.00266515,
0.432612, 0.066196, 0, 0, 0}, {-0.00713551, 0.0186874, 0.278721, 0,
0, 0}, {0, 0, 0, 0.163429, 0, 0}, {0, 0, 0, 0, 0.292301, 0}, {0, 0,
0, 0, 0, 0.30469}}*)


The details of the section containing the various numerical integrations are ommited since the codes are not mine. Typing now, e.g.,

S[10,2,3]


will give the required result (EvalSection takes place) but the whole notebook is executed from the very beginning; not only the required section. How is it possibly to solve this issue (which increases drastically the time)?

Thank you very much.

• Oh! I forgot it! I edit the post right now! – Dimitris Oct 13 '15 at 10:37
• Ok, I want to modify the post to make it more readable in order to receive feedback. It's better to get rid of the n lines of code and concentrate on the problem? Btw, I must admit I do not have much experience with notebook manipulations. – Dimitris Oct 13 '15 at 10:56
• No worries, that's why we ask questions. And yes, the shorter the quesiton the more people will focus on it. – Kuba Oct 13 '15 at 10:58
• @Kuba. Thanks for the feedback. I removed various lines of unrelated code. I hope now the problem is more clear. – Dimitris Oct 13 '15 at 11:09

Ok, I found I workaround. Actually, it does not use the EvalSection command which was given as an answer to my previous relevant query here but utilize an advice I got as comment in the same post.

You can put that whole section into a Module, assign a name to it, like runSection := Module[{}, ...], and then add a last case to Which in the form of True, runSection. – Marius Ladegård Meyer.

As a minimal example...

EvalSection[a1_, a2_, a3_] :=
Module[{C11 = 1, C22 = 2},
Sm = (C22 - C11) Abs[(a3 - a2)/a1] NIntegrate[
BesselJ[0, x], {x, 0, \[Infinity]}]]

SEllipsoid[a1_, a2_, a3_] := "I am an generic ellipsoid with a1<a2<a3"
SProlateSpheroid[a1_, a2_,
a3_] := "I am a prolate spheroid with a1=a2<a3<1000"
SOblateSpheroid[a1_, a2_,
a3_] := "I am an oblate spheoroid with a1=a2>a3"
SSphere[a1_, a2_, a3_] := "I am a sphere with a1=a2=a3"
SCylinder[a1_, a2_, a3_] := "I am a cylinder with a1\[NotEqual]a2<a3"

S[a1_, a2_, a3_] :=
Module[{b1 = a1, b2 = a2, b3 = a3},
Print["Ellipsoidal axes ", " a1: ", b1, ", a2: ", b2, ", a3: ", b3];
Which[(*sphere*)b1 == b2 == b3, Print["spherical inclusion"];
SMat = SSphere[a1, a2, a3];
Return[SMat],(*prolate spheroid*)(b1 == b2 && 1 < b3/b1 <= 1000),
Print["Prolate Spheroidal Inclusion"];
SMat = Chop@SProlateSpheroid[a1, a2, a3];
Return[SMat],(*oblate spheroid*)(b1 == b2 && b3/b1 <= 1),
Print["Oblate Spheroidal Inclusion"];
SMat = Chop@SOblateSpheroid[a1, a2, a3]; Return[SMat],
b3/b1 > 1000, Print["cylindrical inclusion"];
SMat = Chop@SCylinder[a1, a2, a3];
Return[SMat],(*generic ellipsoid spheroid with a3>a2>
a1*)(b3 > b2) && (b2 > b1),
Print["generic ellipsoid with a3>a2>a1"];
SMat = Chop[SEllipsoid[a1, a2, a3]];
Return[SMat],(*numerical evaluation in any other case*)True,
Print["generic ellipsoid; numerical evaluation"];
EvalSection[a1, a2, a3]; Return[Sm]]]


so that

In:= S[1, 2, 3]
During evaluation of In:= Ellipsoidal axes  a1: 1, a2: 2, a3: 3
During evaluation of In:= generic ellipsoid with a3>a2>a1
Out= "I am an generic ellipsoid with a1<a2<a3"

In:= S[5, 5, 1]
During evaluation of In:= Ellipsoidal axes  a1: 5, a2: 5, a3: 1
During evaluation of In:= Oblate Spheroidal Inclusion
Out= "I am an oblate spheoroid with a1=a2>a3"

In:= S[1, 1, 1]
During evaluation of In:= Ellipsoidal axes  a1: 1, a2: 1, a3: 1
During evaluation of In:= spherical inclusion
Out= "I am a sphere with a1=a2=a3"

In:= S[1, 10, 3]
During evaluation of In:= Ellipsoidal axes  a1: 1, a2: 10, a3: 3
During evaluation of In:= generic ellipsoid; numerical evaluation
Out= 7.


as expected.

P.S. Of course I am still interested in how properly modifying the original EvalSection function.