From d735cd658c726728aae8224ddbd4f225f10cf0d6 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Fri, 31 Mar 2023 11:53:38 +0200 Subject: [PATCH 1/3] DpSim: + flags for partical beams, for amplitude modulus and phase --- Sim/Simulation/DepthprobeSimulation.cpp | 28 +++- Sim/Simulation/DepthprobeSimulation.h | 11 +- auto/Wrap/libBornAgainSim.py | 13 +- auto/Wrap/libBornAgainSim_wrap.cpp | 207 +++++++++++++++++++++++- 4 files changed, 249 insertions(+), 10 deletions(-) diff --git a/Sim/Simulation/DepthprobeSimulation.cpp b/Sim/Simulation/DepthprobeSimulation.cpp index f6584484838..7698ff4153f 100644 --- a/Sim/Simulation/DepthprobeSimulation.cpp +++ b/Sim/Simulation/DepthprobeSimulation.cpp @@ -32,11 +32,19 @@ #include <iostream> #include <valarray> +const int ZDirection_None = 0; +const int ZDirection_Reflected = 1; +const int ZDirection_Transmitted = 2; +const int WaveProperty_Intensity = 0; +const int WaveProperty_Modulus = 4; +const int WaveProperty_Phase = 8; + DepthprobeSimulation::DepthprobeSimulation(const IBeamScan& scan, const MultiLayer& sample, - const IAxis& zaxis) + const IAxis& zaxis, int flags) : ISimulation(sample) , m_scan(dynamic_cast<AlphaScan*>(scan.clone())) , m_z_axis(zaxis.clone()) + , m_flags(flags) { if (!m_scan) throw std::runtime_error("DepthprobeSimulation not implemented for non-alpha scan"); @@ -115,7 +123,23 @@ void DepthprobeSimulation::runComputation(const ReSample& re_sample, size_t i, d if (i_layer + 1 != n_layers && (*m_z_axis)[i_z] <= z_layer_bottom) break; const double z = (*m_z_axis)[i_z] - z_layer_top; - intensities[i_z] = std::norm(R * exp_I(kz_out * z) + T * exp_I(kz_in * z)); + complex_t psi; + if ((m_flags & 3) == ZDirection_None) + psi = R * exp_I(kz_out * z) + T * exp_I(kz_in * z); + else if (m_flags & ZDirection_Reflected) + psi = R * exp_I(kz_out * z); + else if (m_flags & ZDirection_Transmitted) + psi = T * exp_I(kz_in * z); + else + throw std::runtime_error("Invalid combination of ZDirection flags"); + if ((m_flags & 12) == WaveProperty_Intensity) + intensities[i_z] = std::norm(psi); + else if (m_flags & WaveProperty_Modulus) + intensities[i_z] = std::abs(psi); + else if (m_flags & WaveProperty_Phase) + intensities[i_z] = std::arg(psi); + else + throw std::runtime_error("Invalid combination of WaveProperty flags"); } start_z_ind = ip1_z; } diff --git a/Sim/Simulation/DepthprobeSimulation.h b/Sim/Simulation/DepthprobeSimulation.h index a92f16773db..fb750cfbc1a 100644 --- a/Sim/Simulation/DepthprobeSimulation.h +++ b/Sim/Simulation/DepthprobeSimulation.h @@ -22,6 +22,13 @@ class IAxis; class IBeamScan; class IFootprintFactor; +extern const int ZDirection_None; +extern const int ZDirection_Reflected; +extern const int ZDirection_Transmitted; +extern const int WaveProperty_Intensity; +extern const int WaveProperty_Modulus; +extern const int WaveProperty_Phase; + //! Simulation of radiation depth profile. //! //! Holds an instrument and sample model. @@ -31,7 +38,8 @@ class IFootprintFactor; class DepthprobeSimulation : public ISimulation { public: - DepthprobeSimulation(const IBeamScan& scan, const MultiLayer& sample, const IAxis& zaxis); + DepthprobeSimulation(const IBeamScan& scan, const MultiLayer& sample, const IAxis& zaxis, + int flags = 0); ~DepthprobeSimulation() override; std::string className() const final { return "DepthprobeSimulation"; } @@ -71,6 +79,7 @@ private: //... Model components: std::unique_ptr<AlphaScan> m_scan; std::unique_ptr<IAxis> m_z_axis; + const int m_flags; #endif // SWIG }; diff --git a/auto/Wrap/libBornAgainSim.py b/auto/Wrap/libBornAgainSim.py index fb632e0286b..f7ef1cb82c4 100644 --- a/auto/Wrap/libBornAgainSim.py +++ b/auto/Wrap/libBornAgainSim.py @@ -2725,9 +2725,9 @@ class DepthprobeSimulation(ISimulation): thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") __repr__ = _swig_repr - def __init__(self, scan, sample, zaxis): - r"""__init__(DepthprobeSimulation self, IBeamScan scan, MultiLayer const & sample, IAxis zaxis) -> DepthprobeSimulation""" - _libBornAgainSim.DepthprobeSimulation_swiginit(self, _libBornAgainSim.new_DepthprobeSimulation(scan, sample, zaxis)) + def __init__(self, scan, sample, zaxis, flags=0): + r"""__init__(DepthprobeSimulation self, IBeamScan scan, MultiLayer const & sample, IAxis zaxis, int flags=0) -> DepthprobeSimulation""" + _libBornAgainSim.DepthprobeSimulation_swiginit(self, _libBornAgainSim.new_DepthprobeSimulation(scan, sample, zaxis, flags)) __swig_destroy__ = _libBornAgainSim.delete_DepthprobeSimulation def className(self): @@ -2736,6 +2736,13 @@ class DepthprobeSimulation(ISimulation): # Register DepthprobeSimulation in _libBornAgainSim: _libBornAgainSim.DepthprobeSimulation_swigregister(DepthprobeSimulation) +ZDirection_None = cvar.ZDirection_None +ZDirection_Reflected = cvar.ZDirection_Reflected +ZDirection_Transmitted = cvar.ZDirection_Transmitted +WaveProperty_Intensity = cvar.WaveProperty_Intensity +WaveProperty_Modulus = cvar.WaveProperty_Modulus +WaveProperty_Phase = cvar.WaveProperty_Phase + class SpecularSimulation(ISimulation): r"""Proxy of C++ SpecularSimulation class.""" diff --git a/auto/Wrap/libBornAgainSim_wrap.cpp b/auto/Wrap/libBornAgainSim_wrap.cpp index 65662e37947..d78f0377b60 100644 --- a/auto/Wrap/libBornAgainSim_wrap.cpp +++ b/auto/Wrap/libBornAgainSim_wrap.cpp @@ -33395,7 +33395,145 @@ SWIGINTERN PyObject *ScatteringSimulation_swiginit(PyObject *SWIGUNUSEDPARM(self return SWIG_Python_InitShadowInstance(args); } -SWIGINTERN PyObject *_wrap_new_DepthprobeSimulation(PyObject *self, PyObject *args) { +SWIGINTERN int Swig_var_ZDirection_None_set(PyObject *) { + SWIG_Error(SWIG_AttributeError,"Variable ZDirection_None is read-only."); + return 1; +} + + +SWIGINTERN PyObject *Swig_var_ZDirection_None_get(void) { + PyObject *pyobj = 0; + + pyobj = SWIG_From_int(static_cast< int >(ZDirection_None)); + return pyobj; +} + + +SWIGINTERN int Swig_var_ZDirection_Reflected_set(PyObject *) { + SWIG_Error(SWIG_AttributeError,"Variable ZDirection_Reflected is read-only."); + return 1; +} + + +SWIGINTERN PyObject *Swig_var_ZDirection_Reflected_get(void) { + PyObject *pyobj = 0; + + pyobj = SWIG_From_int(static_cast< int >(ZDirection_Reflected)); + return pyobj; +} + + +SWIGINTERN int Swig_var_ZDirection_Transmitted_set(PyObject *) { + SWIG_Error(SWIG_AttributeError,"Variable ZDirection_Transmitted is read-only."); + return 1; +} + + +SWIGINTERN PyObject *Swig_var_ZDirection_Transmitted_get(void) { + PyObject *pyobj = 0; + + pyobj = SWIG_From_int(static_cast< int >(ZDirection_Transmitted)); + return pyobj; +} + + +SWIGINTERN int Swig_var_WaveProperty_Intensity_set(PyObject *) { + SWIG_Error(SWIG_AttributeError,"Variable WaveProperty_Intensity is read-only."); + return 1; +} + + +SWIGINTERN PyObject *Swig_var_WaveProperty_Intensity_get(void) { + PyObject *pyobj = 0; + + pyobj = SWIG_From_int(static_cast< int >(WaveProperty_Intensity)); + return pyobj; +} + + +SWIGINTERN int Swig_var_WaveProperty_Modulus_set(PyObject *) { + SWIG_Error(SWIG_AttributeError,"Variable WaveProperty_Modulus is read-only."); + return 1; +} + + +SWIGINTERN PyObject *Swig_var_WaveProperty_Modulus_get(void) { + PyObject *pyobj = 0; + + pyobj = SWIG_From_int(static_cast< int >(WaveProperty_Modulus)); + return pyobj; +} + + +SWIGINTERN int Swig_var_WaveProperty_Phase_set(PyObject *) { + SWIG_Error(SWIG_AttributeError,"Variable WaveProperty_Phase is read-only."); + return 1; +} + + +SWIGINTERN PyObject *Swig_var_WaveProperty_Phase_get(void) { + PyObject *pyobj = 0; + + pyobj = SWIG_From_int(static_cast< int >(WaveProperty_Phase)); + return pyobj; +} + + +SWIGINTERN PyObject *_wrap_new_DepthprobeSimulation__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + IBeamScan *arg1 = 0 ; + MultiLayer *arg2 = 0 ; + IAxis *arg3 = 0 ; + int arg4 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + int val4 ; + int ecode4 = 0 ; + DepthprobeSimulation *result = 0 ; + + if ((nobjs < 4) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_IBeamScan, 0 | 0); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DepthprobeSimulation" "', argument " "1"" of type '" "IBeamScan const &""'"); + } + if (!argp1) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DepthprobeSimulation" "', argument " "1"" of type '" "IBeamScan const &""'"); + } + arg1 = reinterpret_cast< IBeamScan * >(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_MultiLayer, 0 | 0); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_DepthprobeSimulation" "', argument " "2"" of type '" "MultiLayer const &""'"); + } + if (!argp2) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DepthprobeSimulation" "', argument " "2"" of type '" "MultiLayer const &""'"); + } + arg2 = reinterpret_cast< MultiLayer * >(argp2); + res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_IAxis, 0 | 0); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_DepthprobeSimulation" "', argument " "3"" of type '" "IAxis const &""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DepthprobeSimulation" "', argument " "3"" of type '" "IAxis const &""'"); + } + arg3 = reinterpret_cast< IAxis * >(argp3); + ecode4 = SWIG_AsVal_int(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_DepthprobeSimulation" "', argument " "4"" of type '" "int""'"); + } + arg4 = static_cast< int >(val4); + result = (DepthprobeSimulation *)new DepthprobeSimulation((IBeamScan const &)*arg1,(MultiLayer const &)*arg2,(IAxis const &)*arg3,arg4); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DepthprobeSimulation, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_DepthprobeSimulation__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { PyObject *resultobj = 0; IBeamScan *arg1 = 0 ; MultiLayer *arg2 = 0 ; @@ -33406,10 +33544,9 @@ SWIGINTERN PyObject *_wrap_new_DepthprobeSimulation(PyObject *self, PyObject *ar int res2 = 0 ; void *argp3 = 0 ; int res3 = 0 ; - PyObject *swig_obj[3] ; DepthprobeSimulation *result = 0 ; - if (!SWIG_Python_UnpackTuple(args, "new_DepthprobeSimulation", 3, 3, swig_obj)) SWIG_fail; + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_IBeamScan, 0 | 0); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DepthprobeSimulation" "', argument " "1"" of type '" "IBeamScan const &""'"); @@ -33442,6 +33579,62 @@ fail: } +SWIGINTERN PyObject *_wrap_new_DepthprobeSimulation(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[5] = { + 0 + }; + + if (!(argc = SWIG_Python_UnpackTuple(args, "new_DepthprobeSimulation", 0, 4, argv))) SWIG_fail; + --argc; + if (argc == 3) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_IBeamScan, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_MultiLayer, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_IAxis, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_new_DepthprobeSimulation__SWIG_1(self, argc, argv); + } + } + } + } + if (argc == 4) { + int _v = 0; + int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_IBeamScan, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_MultiLayer, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_IAxis, SWIG_POINTER_NO_NULL | 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_int(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_DepthprobeSimulation__SWIG_0(self, argc, argv); + } + } + } + } + } + +fail: + SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_DepthprobeSimulation'.\n" + " Possible C/C++ prototypes are:\n" + " DepthprobeSimulation::DepthprobeSimulation(IBeamScan const &,MultiLayer const &,IAxis const &,int)\n" + " DepthprobeSimulation::DepthprobeSimulation(IBeamScan const &,MultiLayer const &,IAxis const &)\n"); + return 0; +} + + SWIGINTERN PyObject *_wrap_delete_DepthprobeSimulation(PyObject *self, PyObject *args) { PyObject *resultobj = 0; DepthprobeSimulation *arg1 = (DepthprobeSimulation *) 0 ; @@ -36156,7 +36349,7 @@ static PyMethodDef SwigMethods[] = { { "ScatteringSimulation_detector", _wrap_ScatteringSimulation_detector, METH_O, "ScatteringSimulation_detector(ScatteringSimulation self) -> IDetector &"}, { "ScatteringSimulation_swigregister", ScatteringSimulation_swigregister, METH_O, NULL}, { "ScatteringSimulation_swiginit", ScatteringSimulation_swiginit, METH_VARARGS, NULL}, - { "new_DepthprobeSimulation", _wrap_new_DepthprobeSimulation, METH_VARARGS, "new_DepthprobeSimulation(IBeamScan scan, MultiLayer const & sample, IAxis zaxis) -> DepthprobeSimulation"}, + { "new_DepthprobeSimulation", _wrap_new_DepthprobeSimulation, METH_VARARGS, "DepthprobeSimulation(IBeamScan scan, MultiLayer const & sample, IAxis zaxis, int flags=0)"}, { "delete_DepthprobeSimulation", _wrap_delete_DepthprobeSimulation, METH_O, "delete_DepthprobeSimulation(DepthprobeSimulation self)"}, { "DepthprobeSimulation_className", _wrap_DepthprobeSimulation_className, METH_O, "DepthprobeSimulation_className(DepthprobeSimulation self) -> std::string"}, { "DepthprobeSimulation_swigregister", DepthprobeSimulation_swigregister, METH_O, NULL}, @@ -37200,6 +37393,12 @@ SWIG_init(void) { PyDict_SetItemString(md, "cvar", globals); SWIG_addvarlink(globals, "major_version_number", Swig_var_major_version_number_get, Swig_var_major_version_number_set); SWIG_addvarlink(globals, "minor_version_number", Swig_var_minor_version_number_get, Swig_var_minor_version_number_set); + SWIG_addvarlink(globals, "ZDirection_None", Swig_var_ZDirection_None_get, Swig_var_ZDirection_None_set); + SWIG_addvarlink(globals, "ZDirection_Reflected", Swig_var_ZDirection_Reflected_get, Swig_var_ZDirection_Reflected_set); + SWIG_addvarlink(globals, "ZDirection_Transmitted", Swig_var_ZDirection_Transmitted_get, Swig_var_ZDirection_Transmitted_set); + SWIG_addvarlink(globals, "WaveProperty_Intensity", Swig_var_WaveProperty_Intensity_get, Swig_var_WaveProperty_Intensity_set); + SWIG_addvarlink(globals, "WaveProperty_Modulus", Swig_var_WaveProperty_Modulus_get, Swig_var_WaveProperty_Modulus_set); + SWIG_addvarlink(globals, "WaveProperty_Phase", Swig_var_WaveProperty_Phase_get, Swig_var_WaveProperty_Phase_set); #if PY_VERSION_HEX >= 0x03000000 return m; #else -- GitLab From dbfcc62d18e640ac897d6c1cf57a35b8ecf61e6d Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Fri, 31 Mar 2023 13:38:21 +0200 Subject: [PATCH 2/3] DepthprobeSimulation can now return intensity, modulus, phase of total, reflected, transmitted field --- Examples/varia/Depthprobe1.py | 12 +++++++----- Examples/varia/TransmittedModulus.py | 11 +++++++++++ Sim/Simulation/DepthprobeSimulation.h | 2 +- Tests/Examples/CMakeLists.txt | 1 + .../varia/TransmittedModulus.int.gz | Bin 0 -> 11531 bytes 5 files changed, 20 insertions(+), 6 deletions(-) create mode 100755 Examples/varia/TransmittedModulus.py create mode 100644 Tests/ReferenceData/ExamplesMini/varia/TransmittedModulus.int.gz diff --git a/Examples/varia/Depthprobe1.py b/Examples/varia/Depthprobe1.py index a9531300399..af325d05308 100755 --- a/Examples/varia/Depthprobe1.py +++ b/Examples/varia/Depthprobe1.py @@ -22,21 +22,23 @@ def get_sample(): return sample -def get_simulation(sample): +def get_simulation(sample, flags): n = bp.simargs['n'] scan = ba.AlphaScan(n, 0*deg, 1*deg) scan.setWavelength(0.3*nm) z_axis = ba.FixedBinAxis("z", n, -130*nm, 30*nm) - simulation = ba.DepthprobeSimulation(scan, sample, z_axis) + simulation = ba.DepthprobeSimulation(scan, sample, z_axis, flags) return simulation - -if __name__ == '__main__': +def run_example(flags=0): bp.parse_args(sim_n=500, aspect='auto', intensity_max=1e2, intensity_min=1e-12) sample = get_sample() - simulation = get_simulation(sample) + simulation = get_simulation(sample, flags) result = simulation.simulate() bp.plot_simulation_result(result) + +if __name__ == '__main__': + run_example() diff --git a/Examples/varia/TransmittedModulus.py b/Examples/varia/TransmittedModulus.py new file mode 100755 index 00000000000..320b42d170c --- /dev/null +++ b/Examples/varia/TransmittedModulus.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +""" +Basic example of depth-probe simulation: +Computes intensity as function of incident angle alpha and depth z. +""" + +import bornagain as ba +import Depthprobe1 as dp1 + +if __name__ == '__main__': + dp1.run_example(ba.ZDirection_Transmitted | ba.WaveProperty_Modulus) diff --git a/Sim/Simulation/DepthprobeSimulation.h b/Sim/Simulation/DepthprobeSimulation.h index fb750cfbc1a..837ebc9eb91 100644 --- a/Sim/Simulation/DepthprobeSimulation.h +++ b/Sim/Simulation/DepthprobeSimulation.h @@ -39,7 +39,7 @@ extern const int WaveProperty_Phase; class DepthprobeSimulation : public ISimulation { public: DepthprobeSimulation(const IBeamScan& scan, const MultiLayer& sample, const IAxis& zaxis, - int flags = 0); + int flags = 0); ~DepthprobeSimulation() override; std::string className() const final { return "DepthprobeSimulation"; } diff --git a/Tests/Examples/CMakeLists.txt b/Tests/Examples/CMakeLists.txt index 2c45011d822..44ef32d6f71 100644 --- a/Tests/Examples/CMakeLists.txt +++ b/Tests/Examples/CMakeLists.txt @@ -218,6 +218,7 @@ run_example(specular/PolarizedSpinAsymmetry) run_example(specular/PolarizedSpinFlip) test_example1d(varia/Depthprobe1 2e-10) +test_example1d(varia/TransmittedModulus 2e-10) test_example1d(varia/Resonator 2e-10) test_example1d(varia/OffspecSimulation 2e-10) test_example1d(varia/AccessingSimulationResults 2e-10) diff --git a/Tests/ReferenceData/ExamplesMini/varia/TransmittedModulus.int.gz b/Tests/ReferenceData/ExamplesMini/varia/TransmittedModulus.int.gz new file mode 100644 index 0000000000000000000000000000000000000000..97fc66b6f1ee4b4202c017e7a1bb880104da00b5 GIT binary patch literal 11531 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 literal 0 HcmV?d00001 -- GitLab From 02c3e56d7cc03a86dd2d1176fbf00e41c05fbe55 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Fri, 31 Mar 2023 13:55:58 +0200 Subject: [PATCH 3/3] document transmitted modulus example --- CHANGELOG | 5 +++ Examples/varia/TransmittedModulus.py | 8 +++-- hugo/content/ex/sim/depthprobe/_index.md | 1 + .../ex/sim/depthprobe/transmitted_modulus.md | 18 ++++++++++ .../content/ref/sim/class/depthprobe/index.md | 33 +++++++++++++++++-- 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 hugo/content/ex/sim/depthprobe/transmitted_modulus.md diff --git a/CHANGELOG b/CHANGELOG index eb33b5bc087..dcc10ecc001 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +BornAgain-21.0, in preparation + > New functionality: + * DepthprobeSimulation can be parameterized through flags to return intensity, + modulus, or phase of the total, transmitted, or reflected wave field. + BornAgain-20.0, released 2023.03.27 > Contributors: * Current maintainers: Ammar Nejati, Mikhail Svechnikov, Joachim Wuttke diff --git a/Examples/varia/TransmittedModulus.py b/Examples/varia/TransmittedModulus.py index 320b42d170c..d2f578331e1 100755 --- a/Examples/varia/TransmittedModulus.py +++ b/Examples/varia/TransmittedModulus.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 """ -Basic example of depth-probe simulation: -Computes intensity as function of incident angle alpha and depth z. +Thin-film sample as in basic depth-probe example. +Computes modulus of amplitude of transmitted field +as function of of incident angle alpha and depth z. """ import bornagain as ba import Depthprobe1 as dp1 if __name__ == '__main__': - dp1.run_example(ba.ZDirection_Transmitted | ba.WaveProperty_Modulus) + flags = ba.ZDirection_Transmitted | ba.WaveProperty_Modulus + dp1.run_example(flags) diff --git a/hugo/content/ex/sim/depthprobe/_index.md b/hugo/content/ex/sim/depthprobe/_index.md index 5256aabe2ed..1a870257b87 100644 --- a/hugo/content/ex/sim/depthprobe/_index.md +++ b/hugo/content/ex/sim/depthprobe/_index.md @@ -12,4 +12,5 @@ Class reference: Examples - [Basic example: thin film on substrate](/ex/sim/depthprobe/depthprobe1) +- [Transmitted amplitude modulus](/ex/sim/depthprobe/transmitted_modulus) - [Resonator](/ex/sim/depthprobe/resonator) diff --git a/hugo/content/ex/sim/depthprobe/transmitted_modulus.md b/hugo/content/ex/sim/depthprobe/transmitted_modulus.md new file mode 100644 index 00000000000..fa63fcae36b --- /dev/null +++ b/hugo/content/ex/sim/depthprobe/transmitted_modulus.md @@ -0,0 +1,18 @@ ++++ +title = "Transmitted modulus" +weight = 10 ++++ + +## Transmitted modulus + +Modulus of the amplitude of the partial wave field propagating in +transmission direction, +as function of depth and incident angle $\alpha_i$. + +Same sample as in the previous [basic example](depthprobe1), +a thin film on a substrate. + + +{{< figscg src="/img/auto/varia/TransmittedModulus.png" width="500" class="center">}} + +{{< highlightfile file="Examples/varia/TransmittedModulus.py" >}} diff --git a/hugo/content/ref/sim/class/depthprobe/index.md b/hugo/content/ref/sim/class/depthprobe/index.md index 3e2e833a223..ba46d997704 100644 --- a/hugo/content/ref/sim/class/depthprobe/index.md +++ b/hugo/content/ref/sim/class/depthprobe/index.md @@ -9,7 +9,10 @@ Depth probe simulation is an auxiliary simulation type, which helps to visualize the total intensity in dependence on the beam incidence angle and the position in the sample. -To set up and run a simulation, use +#### Compute intensity + +To compute the total wave intensity as function of $\alpha_\text{i}$ and z, +use ```python import bornagain as ba scan = ... @@ -28,6 +31,32 @@ For optional settings, see [simulation options](/ref/sim/setup/options). For the return type of function `simulate()`, see [SimulationResult](/ref/sim/simulation-result). -Examples: +#### Partial waves, modulus, phase + +The constructor takes an optional `flags` argument +``` +simulation = ba.DepthprobeSimulation(scan, sample, z_axis, flags) +``` + +Flags may designate a partial beam +``` +ba.ZDirection_None # = 0, may be ommitted: total field +ba.ZDirection_Reflected # reflected beam only +ba.ZDirection_Transmitted # transmitted beam only +``` +or/and a property of the simulated wave field +``` +ba.WaveProperty_Intensity # = 0, may be ommitted: intensity, |psi|^2 +ba.WaveProperty_Modulus # modulus of wave amplitude, |psi| +ba.WaveProperty_Phase # phase of wave amplitude, arg(psi), in rad +``` +To combine flags from each of these groups, combine them with the "or" operator: +``` +flags = ba.ZDirection_Reflected | ba.WaveProperty_Modulus +``` + +#### Examples + - [Basic example: thin film on substrate](/ex/sim/depthprobe/depthprobe1) +- [Transmitted amplitude modulus](/ex/sim/depthprobe/transmitted_modulus) - [Resonator](/ex/sim/depthprobe/resonator) -- GitLab