Skip to content
Snippets Groups Projects
CustomFormFactor.py 3.06 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/env python3
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    from bornagain import ba_plot as bp, deg, angstrom, nm
    
    import matplotlib.pyplot as plt
    
    class CustomFormfactor:
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        The particle is a prism of height H,
        with a base in form of a Greek cross ("plus" sign) with side length L.
    
            """ arguments and initialization for the formfactor """
    
    
            # parameters describing the form factor
            self.L = L
    
        def formfactor(self, q:'C3'):
            """ main scattering function """
    
            qzhH = 0.5 * q.z() * self.H
            qxhL = 0.5 * q.x() * self.L
            qyhL = 0.5 * q.y() * self.L
            return (0.5 * self.H * self.L**2
                    * cmath.exp(complex(0., 1.) * qzhH) * sinc(qzhH)
                    * (sinc(0.5 * qyhL) * (sinc(qxhL) - 0.5 * sinc(0.5 * qxhL))
                       + sinc(0.5 * qxhL) * sinc(qyhL)))
    
        def spanZ(self, rotation):
    
            """ upper and lower z-positions of a custom shape """
    
    
            return ba.Span(0, self.H)
    
        Sample with particles, having a custom formfactor, on a substrate.
    
        vacuum = ba.RefractiveMaterial("Vacuum", 0, 0)
    
        material_substrate = ba.RefractiveMaterial("Substrate", 6e-6, 2e-8)
        material_particle = ba.RefractiveMaterial("Particle", 6e-4, 2e-8)
    
        ff = CustomFormfactor(20*nm, 15*nm)
    
        particle = ba.Particle(material_particle, ff)
    
        particle_layout.addParticle(particle)
    
        vacuum_layer = ba.Layer(vacuum)
    
        vacuum_layer.addLayout(particle_layout)
    
        substrate_layer = ba.Layer(material_substrate)
    
        """ NOTE:
        Slicing of custom formfactor is not possible.
        all layers must have number of slices equal to 1.
        It is a default situation; otherwise use
        ```
        my_layer.setNumberOfSlices(1)
        ```
    
        Furthermore, a custom particle should not cross layer boundaries;
        that is, the z-span should be within a single layer
        """
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
        sample = ba.Sample()
    
        sample.addLayer(vacuum_layer)
        sample.addLayer(substrate_layer)
        return sample
    
    def get_simulation(sample):
    
        beam = ba.Beam(1e9, 1*angstrom, 0.2*deg)
    
        n = <%= test_mode ? 11 : 100 %>
    
        det = ba.SphericalDetector(n, -1*deg, 1*deg, n, 0, 2*deg)
    
        simulation = ba.ScatteringSimulation(beam, sample, det)
    
    
        # Deactivate multithreading:
        # Currently BornAgain cannot access the Python interpreter
        # from a multi-threaded C++ function
        simulation.options().setNumberOfThreads(1)
    
    
        sample = get_sample()
    
        simulation = get_simulation(sample)
    
        result = simulation.simulate()
    
    AlQuemist's avatar
    AlQuemist committed
        <%- if test_mode or figure_mode -%>
    
        plotargs = bp.parse_commandline()
        bp.plot_simulation_result(result, **plotargs)
        bp.export(**plotargs)
        <%- else -%>
    
        bp.plot_simulation_result(result)