From 7ee56b2b76c33da3ac57fd695f1349dbf51a89d0 Mon Sep 17 00:00:00 2001 From: Diablo Date: Tue, 12 May 2026 16:20:42 +0200 Subject: [PATCH 1/3] Add heavyside and gauss function to tinyexpr.c, make a test of them, and add documentation in Inhomogenous_incoherent_process.comp --- .../Test_inhomogenous_process.instr | 31 ++++++++++++++++++- mcstas-comps/share/tinyexpr.c | 18 ++++++++++- .../Inhomogenous_incoherent_process.comp | 14 +++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr b/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr index cc075934c6..e85b24a1dd 100755 --- a/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr +++ b/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr @@ -51,6 +51,7 @@ * %Example: sample=inc_and_inho Detector: lin_det_I=0.017457 * %Example: -n 1e5 sample=phonon Detector: lin_det_I=0.0174609 * %Example: sample=inc_trans Detector: lin_det_I=0.081029 +* %Example: sample=gauss_heavy Detector: lin_det_I=0.081029 * %Example: sample=inho_trans Detector: lin_det_I=0.081040 * * @@ -83,6 +84,7 @@ DECLARE int activate_inc_linear; int activate_inc_and_inho_linear; int activate_phonon; + int activate_gauss; double rot_samples; %} @@ -123,6 +125,10 @@ INITIALIZE rot_samples = 90; activate_inho_linear = 1; width = 0.01; + } else if (!strcmp("gauss_heavy", sample)){ + rot_samples = 90; + activate_gauss = 1; + width = 0.01; } %} @@ -503,7 +509,7 @@ COMPONENT inho_and_inc_box = Union_box( xwidth=width, yheight = 0.03, zdepth = thick, - material_string = "Inho_lin", + material_string = "inc_and_inho", number_of_activations = activate_inc_and_inho_linear ) AT (0,0, 0) RELATIVE arm_sample ROTATED (0, 0, 0) RELATIVE arm_sample @@ -533,7 +539,30 @@ COMPONENT phonon_box = Union_box( ) AT (0,0, 0) RELATIVE arm_sample ROTATED (0, 0, 0) RELATIVE arm_sample +// ============================ Inhomogenous as a gaussian and heavy side +COMPONENT gauss = Inhomogenous_incoherent_process( + sigma_expr = "5.08 - gauss(0.01,0.001,z+0.0025) + hvs(z,0,5,0)", unit_cell_volume = 13.827, + // verbose=1, + number_of_sample_points = 10 +) +AT (0,0,0) RELATIVE arm_sample + +COMPONENT gauss_mat = Union_make_material( + my_absorption = 100 * 5.08 / 13.827, + process_string = "gauss" +) +AT (0,0,0) RELATIVE PREVIOUS + +COMPONENT gauss_box = Union_box( + priority = 163, + xwidth=width, + yheight = 0.03, + zdepth = thick, + material_string = "gauss_mat", + number_of_activations = activate_gauss +) AT (0,0, 0) RELATIVE arm_sample +ROTATED (0, 0, 0) RELATIVE arm_sample diff --git a/mcstas-comps/share/tinyexpr.c b/mcstas-comps/share/tinyexpr.c index 30bc63caf9..7f2e91694c 100644 --- a/mcstas-comps/share/tinyexpr.c +++ b/mcstas-comps/share/tinyexpr.c @@ -22,13 +22,16 @@ * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ +// THIS VERSION OF TINYEXPR HAS BEEN MODIFIED TO BETTER SUIT THE NEEDS +// OF THE MCSTAS SOFTWARE PACKAGE + /* COMPILE TIME OPTIONS */ /* Exponentiation associativity: For a^b^c = (a^b)^c and -a^b = (-a)^b do nothing. For a^b^c = a^(b^c) and -a^b = -(a^b) uncomment the next line.*/ -/* #define TE_POW_FROM_RIGHT */ +#define TE_POW_FROM_RIGHT /* Logarithms For log = base 10 log do nothing @@ -153,6 +156,17 @@ static double ncr(double n, double r) { return result; } static double npr(double n, double r) {return ncr(n, r) * fac(r);} +static double hvs(double x, double t, double a, double b) { + if (x>t){ + return a; + } + return b; +} +static double gauss(double A, double sig, double x){ + double inv_sqrt_2pi = 0.3989422804; + double result = A * inv_sqrt_2pi / sig * exp(-0.5 * (x * x) / (sig * sig)); + return result; +} #ifdef _MSC_VER #pragma function (ceil) @@ -175,6 +189,8 @@ static const te_variable functions[] = { {"exp", exp, TE_FUNCTION1 | TE_FLAG_PURE, 0}, {"fac", fac, TE_FUNCTION1 | TE_FLAG_PURE, 0}, {"floor", floor, TE_FUNCTION1 | TE_FLAG_PURE, 0}, + {"gauss", gauss, TE_FUNCTION3 | TE_FLAG_PURE, 0}, + {"hvs", hvs, TE_FUNCTION4 | TE_FLAG_PURE, 0}, {"ln", log, TE_FUNCTION1 | TE_FLAG_PURE, 0}, #ifdef TE_NAT_LOG {"log", log, TE_FUNCTION1 | TE_FLAG_PURE, 0}, diff --git a/mcstas-comps/union/Inhomogenous_incoherent_process.comp b/mcstas-comps/union/Inhomogenous_incoherent_process.comp index 3e581ff684..12a121da7e 100755 --- a/mcstas-comps/union/Inhomogenous_incoherent_process.comp +++ b/mcstas-comps/union/Inhomogenous_incoherent_process.comp @@ -83,6 +83,20 @@ * The velocities $vx, vy, vz$ * and the time $t$ * +* McStas uses a sligthly modified version of tiny expressions that evaluate +* exponentials from right to left instead of the standard left to right. +* Furthermore McStas has added two functions to tiny expressions. These are: +* A heavy side function +* hvs(variable, switch_point, large_val,small_val) which returns large val if +* variable > switch_point and small val otherwise. +* +* A gaussian distribution: +* +* gauss(A,sig,x), which evaluates to A*1/sqrt(2*PI)/sig*exp(-x^2/2/sig^2) +* +* An example using these can be found in the Test instrument for this component, +* called Test_inhomogenous_process.instr. Example #9 implements a gaussian and a +* heavyside function. * For more information on tiny expressions, see the link below. * * From 3542ca8fcb6a1ae799187c56bc8d8cd8f3b08c41 Mon Sep 17 00:00:00 2001 From: Diablo Date: Tue, 12 May 2026 16:54:08 +0200 Subject: [PATCH 2/3] Simplify phonon process with inhomogenous process test, to reduce test time --- .../Test_inhomogenous_process.instr | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr b/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr index e85b24a1dd..a30f400fad 100755 --- a/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr +++ b/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr @@ -49,9 +49,9 @@ * %Example: sample=inc_linear Detector: lin_det_I=0.017457 * %Example: sample=inho_linear Detector: lin_det_I=0.017457 * %Example: sample=inc_and_inho Detector: lin_det_I=0.017457 -* %Example: -n 1e5 sample=phonon Detector: lin_det_I=0.0174609 +* %Example: sample=phonon thick=0.001 Detector: lin_det_I=0.00505839 * %Example: sample=inc_trans Detector: lin_det_I=0.081029 -* %Example: sample=gauss_heavy Detector: lin_det_I=0.081029 +* %Example: sample=gauss_heavy Detector: lin_det_I=0.0985658 * %Example: sample=inho_trans Detector: lin_det_I=0.081040 * * @@ -116,6 +116,7 @@ INITIALIZE } else if (!strcmp("inc_and_inho", sample)){ activate_inc_and_inho_linear = 1; } else if (!strcmp("phonon", sample)){ + activate_phonon = 1; } else if (!strcmp("inc_trans", sample)) { rot_samples = 90; @@ -515,6 +516,14 @@ COMPONENT inho_and_inc_box = Union_box( ROTATED (0, 0, 0) RELATIVE arm_sample // ============================ Inhomogenous + homogenous + phononsimple process +COMPONENT inho_phonon_proc= Inhomogenous_incoherent_process( + sigma_expr = "9.58/2*((z+0.0045)*1000)", unit_cell_volume = 13.827, + // verbose=1, + number_of_sample_points = 2 +) +AT (0,0,0) RELATIVE arm_sample + + COMPONENT phonon_proc = PhononSimple_process( @@ -525,7 +534,7 @@ AT (0,0,0) RELATIVE arm_sample COMPONENT phonon_mat = Union_make_material( my_absorption = 100 * 5.08 / 13.827, - process_string = "only_inc_proc,only_inho_proc,phonon_proc" + process_string = "inho_phonon_proc,phonon_proc" ) AT (0,0,0) RELATIVE PREVIOUS From b2dceb3c8c4fee2cdb53b2a01f53ddef6df0cb4c Mon Sep 17 00:00:00 2001 From: Diablo Date: Tue, 12 May 2026 17:44:41 +0200 Subject: [PATCH 3/3] Add documentation in Inhomogenous process test for the gaussian/heavyside test --- .../Test_inhomogenous_process.instr | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr b/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr index a30f400fad..c2c75b27ba 100755 --- a/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr +++ b/mcstas-comps/examples/Tests_union/Test_inhomogenous_process/Test_inhomogenous_process.instr @@ -13,7 +13,7 @@ * and comparison to incoherent process, and incoherent component. * * %Description -* Test of 9 different setups. +* Test of different setups with the Inhomogenous_incoherent_process. * For all setups, the idea is the same. A source shines neutrons on the box, * and a detector placed right up on the side of the box, measures the * incoherently scattered neutrons. @@ -41,6 +41,10 @@ * nature of the two different processes, the one process curve becomes * continous (Inhomogenous_incoherent_process), * and the other discrete (Incoherent_process). +* +* The 10th example plays with some more complex tiny expressions using the +* gaussian function and the heavyside function. +* * * * %Example: sample=thin Detector: lin_det_I=0.007387 @@ -51,8 +55,8 @@ * %Example: sample=inc_and_inho Detector: lin_det_I=0.017457 * %Example: sample=phonon thick=0.001 Detector: lin_det_I=0.00505839 * %Example: sample=inc_trans Detector: lin_det_I=0.081029 -* %Example: sample=gauss_heavy Detector: lin_det_I=0.0985658 * %Example: sample=inho_trans Detector: lin_det_I=0.081040 +* %Example: sample=gauss_heavy Detector: lin_det_I=0.0985658 * * *