From eabe6f33d8be10e726cf6499d7915c28a348051c Mon Sep 17 00:00:00 2001 From: astellhorn <93910032+astellhorn@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:07:31 +0100 Subject: [PATCH 01/22] parallelepiped chains based on MagneticOrientedChains have inserted the option for chains (taken form MagneticOrientedCHains) into the parallelepiped script from sasview --- sasmodels/models/ParallelepipedChain.c | 218 ++++++++++++++++++++++++ sasmodels/models/ParallelepipedChain.py | 92 ++++++++++ 2 files changed, 310 insertions(+) create mode 100644 sasmodels/models/ParallelepipedChain.c create mode 100644 sasmodels/models/ParallelepipedChain.py diff --git a/sasmodels/models/ParallelepipedChain.c b/sasmodels/models/ParallelepipedChain.c new file mode 100644 index 00000000..4676a024 --- /dev/null +++ b/sasmodels/models/ParallelepipedChain.c @@ -0,0 +1,218 @@ +static double +form_volume(double length_a, double length_b, double length_c) +{ + return length_a * length_b * length_c; +} + +static double +radius_from_excluded_volume(double length_a, double length_b, double length_c) +{ + double r_equiv, length; + double lengths[3] = {length_a, length_b, length_c}; + double lengthmax = fmax(lengths[0],fmax(lengths[1],lengths[2])); + double length_1 = lengthmax; + double length_2 = lengthmax; + double length_3 = lengthmax; + + for(int ilen=0; ilen<3; ilen++) { + if (lengths[ilen] < length_1) { + length_2 = length_1; + length_1 = lengths[ilen]; + } else { + if (lengths[ilen] < length_2) { + length_2 = lengths[ilen]; + } + } + } + if(length_2-length_1 > length_3-length_2) { + r_equiv = sqrt(length_2*length_3/M_PI); + length = length_1; + } else { + r_equiv = sqrt(length_1*length_2/M_PI); + length = length_3; + } + + return 0.5*cbrt(0.75*r_equiv*(2.0*r_equiv*length + (r_equiv + length)*(M_PI*r_equiv + length))); +} + +static double +radius_effective(int mode, double length_a, double length_b, double length_c) +{ + switch (mode) { + default: + case 1: // equivalent cylinder excluded volume + return radius_from_excluded_volume(length_a,length_b,length_c); + case 2: // equivalent volume sphere + return cbrt(length_a*length_b*length_c/M_4PI_3); + case 3: // half length_a + return 0.5 * length_a; + case 4: // half length_b + return 0.5 * length_b; + case 5: // half length_c + return 0.5 * length_c; + case 6: // equivalent circular cross-section + return sqrt(length_a*length_b/M_PI); + case 7: // half ab diagonal + return 0.5*sqrt(length_a*length_a + length_b*length_b); + case 8: // half diagonal + return 0.5*sqrt(length_a*length_a + length_b*length_b + length_c*length_c); + } +} + +static void +Fq(double q, + double *F1, + double *F2, + double sld, + double solvent_sld, + double length_a, + double length_b, + double length_c) +{ + const double mu = 0.5 * q * length_b; + + // Scale sides by B + const double a_scaled = length_a / length_b; + const double c_scaled = length_c / length_b; + + // outer integral (with gauss points), integration limits = 0, 1 + double outer_total_F1 = 0.0; //initialize integral + double outer_total_F2 = 0.0; //initialize integral + for( int i=0; i Date: Fri, 19 Jan 2024 17:43:06 +0100 Subject: [PATCH 02/22] model without magnetic sld --- sasmodels/models/ParallelepipedChain.c | 23 +---------------------- sasmodels/models/ParallelepipedChain.py | 4 +--- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/sasmodels/models/ParallelepipedChain.c b/sasmodels/models/ParallelepipedChain.c index 4676a024..c9ffbc0f 100644 --- a/sasmodels/models/ParallelepipedChain.c +++ b/sasmodels/models/ParallelepipedChain.c @@ -120,7 +120,6 @@ static double Iqabc(double qa, double qb, double qc, double sld, double solvent_sld, - double mag_sld, double length_a, double length_b, double length_c, @@ -131,9 +130,7 @@ Iqabc(double qa, double qb, double qc, const double siC = sas_sinx_x(0.5*length_c*qc); const double V = form_volume(length_a, length_b, length_c); const double drho = (sld - solvent_sld); - const double mrho = mag_sld const double Amp = V * drho * siA * siB * siC; - const double MAmp = V * mrho * siA * siB * siC; // adding several particles in the chain: double VolumeFraction = 1.0; @@ -147,15 +144,10 @@ Iqabc(double qa, double qb, double qc, // Just start parameters: double SingletIntensity = 0; - double MSingletIntensity = 0; double DimerIntensity = 0; - double MDimerIntensity = 0; double TrimerIntensity = 0; - double MTrimerIntensity = 0; double QuadramerIntensity = 0; - double MQuadramerIntensity = 0; double PentamerIntensity = 0; - double MPentamerIntensity = 0; // we take out: (i) polydispersity of chains (called "anglewt/sigma" before), (ii) orientation of chain (called "Viewing angle") // Now: chain only oriented along Qx @@ -172,8 +164,6 @@ Iqabc(double qa, double qb, double qc, double real_phase = 1.0; double img_phase = 0.0; - double mreal_phase = 1.0; - double mimg_phase = 0.0; for(int k=1; k<5; k++){ real_phase += cos(k*Length*(Q_X*ChainProjX + Q_Y*ChainProjY)); @@ -181,19 +171,15 @@ Iqabc(double qa, double qb, double qc, if(k==1){ DimerIntensity += pow(Amp*img_phase,2))/(2.0*Vol); - MDimerIntensity += pow(MAmp*mimg_phase,2))/(2.0*Vol); } if(k==2){ TrimerIntensity += pow(Amp*img_phase,2))/(3.0*Vol); - MTrimerIntensity += pow(MAmp*mimg_phase,2))/(3.0*Vol); } if(k==3){ QuadramerIntensity += pow(Amp*img_phase,2))/(4.0*Vol); - MQuadramerIntensity += pow(MAmp*mimg_phase,2))/(4.0*Vol); } if(k==4){ PentamerIntensity += pow(Amp*img_phase,2))/(5.0*Vol); - MPentamerIntensity += pow(MAmp*mimg_phase,2))/(5.0*Vol); } } //end k loop for dimers @@ -202,15 +188,8 @@ Iqabc(double qa, double qb, double qc, if(FractionScale == 0){FractionScale = 1.0;} double SIntensity = SingletFraction*SingletIntensity + DimerFraction*DimerIntensity + TrimerFraction*TrimerIntensity + QuadramerFraction*QuadramerIntensity + PentamerFraction*PentamerIntensity; - double MIntensity = 0.0; - if(MVar <= 1){ - MIntensity = MSingletIntensity*(SingletFraction + DimerFraction + TrimerFraction + QuadramerFraction + PentamerFraction); - } - else{ - MIntensity = SingletFraction*MSingletIntensity + DimerFraction*MDimerIntensity + TrimerFraction*MTrimerIntensity + QuadramerFraction*MQuadramerIntensity + PentamerFraction*MPentamerIntensity; - } - double Intensity = (SIntensity+MIntensity)*(1E4)/FractionScale; + double Intensity = (SIntensity)*(1E4)/FractionScale; return Intensity; diff --git a/sasmodels/models/ParallelepipedChain.py b/sasmodels/models/ParallelepipedChain.py index 48c07b47..f0220aa1 100644 --- a/sasmodels/models/ParallelepipedChain.py +++ b/sasmodels/models/ParallelepipedChain.py @@ -44,7 +44,7 @@ from numpy import inf name = "ParallelepipedChain" -title = "Base-script: Rectangular parallelepiped with uniform scattering length density. Add-on: Chain of parallelepipeds along x-direction, with uniform magnetic scattering length density (no applied magnetic field)" +title = "Base-script: Rectangular parallelepiped. Add-on: Chain of parallelepipeds along x-direction" description = """User model for chains of parallelepipeds oriented along X-axis""" category = "shape:parallelepiped" @@ -53,8 +53,6 @@ "Parallelepiped scattering length density"], ["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "sld", "Solvent scattering length density"], - ["mag_sld", "1e-6/Ang^2", 1, [-inf, inf], "sld", - "magnetic scattering length density"], ["length_a", "Ang", 35, [0, inf], "length", "Shorter side of the parallelepiped"], ["length_b", "Ang", 75, [0, inf], "length", From e4e317170a1f39b89b238beb89c1ab6728738d98 Mon Sep 17 00:00:00 2001 From: astellhorn <93910032+astellhorn@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:58:48 +0100 Subject: [PATCH 03/22] Have added the magnetic_functions.c, micromagnetic_FF_3D.c, and micromagnetic_FF_3D.py from the marketplace. Unsure how to insert the parameter descriptions given in micromagnetic_FF_3D.py to the GUI according to sasview issue #2784 --- sasmodels/models/magnetic_functions.c | 193 +++++++++++++++++++++++ sasmodels/models/micromagnetic_FF_3D.c | 200 ++++++++++++++++++++++++ sasmodels/models/micromagnetic_FF_3D.py | 194 +++++++++++++++++++++++ 3 files changed, 587 insertions(+) create mode 100644 sasmodels/models/magnetic_functions.c create mode 100644 sasmodels/models/micromagnetic_FF_3D.c create mode 100644 sasmodels/models/micromagnetic_FF_3D.py diff --git a/sasmodels/models/magnetic_functions.c b/sasmodels/models/magnetic_functions.c new file mode 100644 index 00000000..37eb6488 --- /dev/null +++ b/sasmodels/models/magnetic_functions.c @@ -0,0 +1,193 @@ +static double clipp(double value, double low, double high) //from kernel_iq.c +{ + return (value < low ? low : (value > high ? high : value)); +} + +static double length(double x, double y) +{ + return sqrt(x*x + y*y); +} + +static double fq_core_shell(double q, double sld_core, double radius, + double sld_solvent, double fp_n, double sld[], double thickness[]) +{ + const int n = (int)(fp_n+0.5); + double f, r, last_sld; + r = radius; + last_sld = sld_core; + f = 0.; + for (int i=0; i sld - D Pvector \cdot Mperp + sld[1] = +SCALAR_VEC(Pvector,Mperpimag); //dd.imag = nuc_img - SCALAR_VEC(Pvector,Mperpimg); nuc_img only exist for noncentrosymmetric nuclear structures; + sld[2] = nuc + SCALAR_VEC(Pvector,Mperpreal); // uu => sld + D Pvector \cdot Mperp + sld[3] = -SCALAR_VEC(Pvector,Mperpimag); //uu.imag + + sld[4] = SCALAR_VEC(perpy,Mperpreal)+SCALAR_VEC(perpx,Mperpimag); // du.real => real part along y + imaginary part along x + sld[5] = SCALAR_VEC(perpy,Mperpimag)-SCALAR_VEC(perpx,Mperpreal); // du.imag => imaginary component along y - i *real part along x + sld[6] = SCALAR_VEC(perpy,Mperpreal)-SCALAR_VEC(perpx,Mperpimag); // ud.real => real part along y - imaginary part along x + sld[7] = SCALAR_VEC(perpy,Mperpimag)+SCALAR_VEC(perpx,Mperpreal); // ud.imag => imaginary component along y + i * real part along x + + } \ No newline at end of file diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c new file mode 100644 index 00000000..892bd430 --- /dev/null +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -0,0 +1,200 @@ +//Core-shell form factor for anisotropy field (Hkx, Hky and Hkz), Nuc and lonitudinal magnetization Mz +static double +form_volume(double radius, double thickness) +{ + return M_4PI_3 * cube(radius + thickness); +} + +static double +radius_effective(int mode, double radius, double thickness) +{ + switch (mode) { + default: + case 1: // outer radius + return radius + thickness; + case 2: // core radius + return radius; + } +} + +static double fq(double q, double radius, + double thickness, double core_sld, double shell_sld, double solvent_sld) +{ + const double form = core_shell_fq(q, + radius, + thickness, + core_sld, + shell_sld, + solvent_sld); + return form; +} + + +static double reduced_field(double q, double Ms, double Hi, + double A) +{ + if( Hi > 1.0e-6 ) + return Ms / (Hi + 2.0 * A * 4.0 * M_PI / Ms * q * q * 10.0);//q in 10e10 m-1, A in 10e-12 J/m, mu0 in 1e-7 + else + return Ms / (1.0e-6 + 2.0 * A * 4.0 * M_PI / Ms * q * q * 10.0); + } + + static double DMI_length(double Ms, double D, double qval) + { + return 2.0 * D * 4.0 * M_PI / Ms / Ms * qval ; //q in 10e10 m-1, A in 10e-3 J/m^2, mu0 in 4 M_PI 1e-7 + } + +//Mz is defined as the longitudinal magnetisation component along the magnetic field. +//In the approach to saturation this component is (almost) constant with magnetic +//field and simplfy reflects the nanoscale variations in the saturation magnetisation +//value in the sample. The misalignment of the magnetisation due to perturbing +//magnetic anisotropy or dipolar magnetic fields in the sample enter Mx and My, +//the two transversal magnetisation components, reacting to a magnetic field. +//The micromagnetic solution for the magnetisation are from Michels et al. PRB 94, 054424 (2016). + +static double fqMxreal( double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +{ + const double q=MAG_VEC(x, y, z); + const double f = reduced_field(q, Ms, Hi, A)*(Hkx*(1.0+reduced_field(q, Ms, Hi, A)*y*y/q/q)-Ms*Mz*x*z/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hky*reduced_field(q, Ms, Hi, A)*x*y/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q-square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + return f; +} + +static double fqMximag(double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +{ + const double q=MAG_VEC(x, y, z); + const double f = -reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,y)+Hky*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + return f; +} + +static double fqMyreal( double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +{ + const double q=MAG_VEC(x, y, z); + const double f = reduced_field(q, Ms, Hi, A)*(Hky*(1.0+reduced_field(q, Ms, Hi, A)*x*x/q/q)-Ms*Mz*y*z/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hkx*reduced_field(q, Ms, Hi, A)*x*y/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + return f; +} + +static double fqMyimag( double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +{ + const double q=MAG_VEC(x, y, z); + const double f = reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,x)-Hkx*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + return f; +} + +//calculate 2D from _fq +static double +Iqxy(double qx, double qy, double radius, double thickness,double core_nuc, double shell_nuc, double solvent_nuc, double core_Ms, double shell_Ms, double solvent_Ms, double core_hk, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +{ + const double q=MAG_VEC(qx, qy, 0); + if (q > 1.0e-16 ) { + const double cos_theta=qx/q; + const double sin_theta=qy/q; + + double qrot[3]; + set_scatvec(qrot,q,cos_theta, sin_theta, alpha, beta); + // 0=dd.real, 1=dd.imag, 2=uu.real, 3=uu.imag, 4=du.real, 6=du.imag, 7=ud.real, 5=ud.imag + double weights[8]; + set_weights(up_i, up_f, weights); + + double mz=fq(q, radius, thickness, core_Ms, shell_Ms, solvent_Ms); + double nuc=fq(q, radius, thickness, core_nuc, shell_nuc, solvent_nuc); + + double cos_gamma, sin_gamma; + double sld[8]; + //loop over random anisotropy axis with isotropic orientation gamma for Hkx and Hky + //To be modified for textured material see also Weissmueller et al. PRB 63, 214414 (2001) + double total_F2 = 0.0; + for (int i=0; i 1.0e-8) { + // Since the cross section weight is significant, set the slds + // to the effective slds for this cross section, call the + // kernel, and add according to weight. + // loop over uu, ud real, du real, dd, ud imag, du imag + form += weights[xs]*sld[xs]*sld[xs]; + } + } + total_F2 += GAUSS_W[i] * form ; + } + return 0.5*1.0e-4*total_F2; + } +} + +static double +Iq(double q, double radius, double thickness,double core_nuc, double shell_nuc, double solvent_nuc, double core_Ms, double shell_Ms, double solvent_Ms, double core_hk, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +{ + // slots to hold sincos function output of the orientation on the detector plane + double sin_theta, cos_theta; + double total_F1D = 0.0; + for (int j=0; j 1.0e-8 ) { + // Since the cross section weight is significant, set the slds + // to the effective slds for this cross section, call the + // kernel, and add according to weight. + // loop over uu, ud real, du real, dd, ud imag, du imag + form += weights[xs]*sld[xs]*sld[xs]; + } + } + total_F2 += GAUSS_W[i] * form ; + } + total_F1D += GAUSS_W[j] * total_F2 ; + } + //convert from [1e-12 A-1] to [cm-1] + return 0.25*1.0e-4*total_F1D; +} + + + + + + diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py new file mode 100644 index 00000000..b31e44f1 --- /dev/null +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -0,0 +1,194 @@ +r""" +Definition +---------- +This model is a micromagnetic approach to analyse the SANS that arises from +nanoscale variations in the magnitude and orientation of the magnetization in +bulk ferromagnets in the approach to magnetic saturation (single domain state). +Typical materials are cold-worked elemental magnets, hard and soft magnetic +nanocomposites, amorphous alloys and precipitates in magnetic steel [#Michels2014]_. +The magnetic SANS depends on the magnetic interactions, the magnetic microstructure +(defect/particle size, magnetocrystalline anisotropy, saturation magnetisation) +and on the applied magnetic field. As shown in [#Michels2016]_ near magnetic +saturation the scattering cross-section can be evaluated by means of micromagnetic theory + +.. math:: + I(mathbf{Q}) = I_nuc +I_res+ I_mag(mathbf{Q},H), + +with the field-independent nuclear and magnetic residual SANS cross section (due +to nanoscale spatial variations of the saturation magnetisation) measured at +complete magnetic saturation. Commonly, a measurement at a high magnetic field +taken as reference and subtracted from the scattering cross-section at lower +field to obtain the so-called spin-misalignment scattering cross-section + +.. math:: + I_mag(mathbf{Q},H)= S_K(Q) R_K(mathbf{Q}, H_i) + S_M(Q) R_M(mathbf{Q}, H_i), + +with $H_i$ the internal field, i.e. the external magnetic field corrected for +demagnetizing effects and the influence of the magnetodipolar field and of the +magnetic anisotropy [#Bick2013]_. This purely magnetic scattering reflects the +sensitive response of the transversal magnetisation components with to an +externally applied magnetic field with a contribution $S_K imes R_K$ due to +perturbations around magnetic anisotropy fields and a term $S_M imes R_M$ +related to magnetostatic fields. The alignment of the magnetic moments along +the magnetic field is disturbed by perturbations in the microstructure. The +anisotropy-field function $S_K$ depends on the Fourier transform of the magnetic +anisotropy distribution (strength and orientation) in the material and the +scattering function of the longitudinal magnetisation $S_M$ reflects the +variations of the saturation magnetisation, e.g. jumps at the particle-matrix +interface. $R_K$ and $R_M$ denote the micromagnetic response functions that +describe the magnetisation distribution around a perturbation in magnetic +anisotropy and flucutations in the saturation magnetisation value. + +.. figure:: img/micromagnetic_FF.png + + Magnetisation distribution around (left) a particle with magnetic easy axis + in the vertical direction and (right) a precipitation with a magnetisation + that is higher than the matrix phase. + +The micromagnetic response functions depend on magnetic material parameters $M_S$: +average saturation magnetisation of the material, $H_i$: the internal magnetic +field, $A$ the average exchange-stiffness constant. In the vicinity of lattice +imperfection in ferromagnetic materials, antisymmetric Dzyaloshinskii–Moriya +interaction (DMI) can occur due to the local structural inversion symmetry +breaking [#Arrott1963]_. DMI with strength $D$ can give rise to nonuniform spin +textures resulting in a polarization-dependent asymmetric scattering term for +polycrystalline ferromagnetic with a centrosymmetric crystal structure [#Michels2016]_. +We assume (for simplicity) an isotropic microstructure (for $S_M$) and random +orientation of magnetic easy axes (additionally for $S_K$) such that the +contributions of the magnetic microstructure only depend on the magnitude of $q$. +Considerations for a microstructure with a prefered orientation (texture) can be +found in [#Weissmueller2001]_. In the code the averaging procedure over the random +anisotropy is explicitely performed. A specific orientation distribution can be +implemented. + +The magnetic field is oriented with an inclination of $alpha$ to the neutron beam +and rotated by $beta$. The model for the nuclear scattering amplitude, saturation +magnetisation is based on spherical particles with a core shell structure. For +simplicity, only the core has an effective anisotropy, that is varying randomly +in direction from particle to particle. The effect of different, more complex +spatial profiles of the anisotropy can be seen in Michels PRB 82, 024433 (2010). +The magnetic scattering length density (SLD) is defined as +$ ho_{mathrm{mag}}=b_H M_S$, where $b_H= 2.91*10^{8}A^{-1}m^{-1}$ and $M_S$ +is the saturation magnetisation (in $A/m$). + +The fraction of "upward" neutrons before ('up_frac_i') and after the sample +('up_frac_f') must range between 0 to 1, with 0.5 denoting an unpolarised beam. +Note that a fit may result in a negative magnetic SLD, and hence magnetisation, +when the polarisation state is inverted, i.e. if you have analysed for a $I_{00}$ + state wheras your data are $I_{11}$. The model allows to construct the 4 + spin-resolved cross sections (non-spin-flip I_{00}, I_{11} and spin-flip, here + I_{01}=I_{10}), half-polarised SANS (SANSpol, incoming polarised beam I_0 and + I_1, no analysis after sample 'up_frac_f'$=0.5$), and unpolarised beam + ('up_frac_i'$=$'up_frac_f'$=0.5$). Differences and other combinations between + polarised scattering cross section, e.g. to obtain the nuclear-magnetic + interference scattering, or subtraction of the residual scattering of the high + field reference state can be constructed with a custom model (Fitting> + Add/Multiply Model) and using approbriate scales. For dense systems, special + care has to be taken as the nculear structure factor (arrangement of particles) + does not need to be identical with the magnetic microstructure e.g. local + textures and correlations between easy axes (see [#Honecker2020]_ for further + details). The use of structure model is therefore strongly discouraged. Better + $I_nuc$, $S_K$ and $S_M$ are fit independent from each other in a model-free way. + + + +Validation +---------- + +The model needs testing and validation. Your feedback is kindly requested. + + + +References +---------- + +.. [#Arrott1963] A. Arrott, J. Appl. Phys. 34, 1108 (1963). +.. [#Weissmueller2001] J. Weissmueller et al., *Phys. Rev. B* 63, 214414 (2001). +.. [#Bick2013] J.-P. Bick et al., *Appl. Phys. Lett.* 102, 022415 (2013). +.. [#Michels2014] A. Michels, *J. Phys.: Condens. Matter* 26, 383201 (2014). +.. [#Michels2016] A. Michels et al., *Phys. Rev. B* 94, 054424 (2016). +.. [#Honecker2020] D. Honecker, L. Fernandez Barguin, and P. Bender, *Phys. Rev. B* 101, 134401 (2020). + + + +Authorship and Verification +---------------------------- + +* **Author: Dirk Honecker **Date:** January 14, 2021 +* **Last Modified by:** +* **Last Reviewed by:** + +""" + +import numpy as np +from numpy import pi, inf + +name = "spin_structure_ferromagnets_3D" +title = "Field-dependent magnetic microstructure around imperfections in bulk ferromagnets" +description = """ + I(q) = A (F_N^2(q)+ C F_N F_M + D F_M^2) +B(H) I_mag(q,H) + A: weighting function =1 for unpolarised beam and non-neutron-spin-flip scattering, zero for spin-flip scattering. The terms in the bracket are the residual scattering at perfectly saturating magnetic field. + B(H): weighting function for purely magnetic scattering I_mag(q,H) due to misaligned magnetic moments, different for the various possible spin-resolved scattering cross sections + C: weighting function for nuclear-magnetic interference scattering + F_N: nuclear form factor + F_M: magnetic form factor +The underlying defect can have a core-shell structure. +""" +category = "shape:sphere" + +# pylint: disable=bad-whitespace, line-too-long +# ["name", "units", default, [lower, upper], "type","description"], +parameters = [["radius", "Ang", 50., [0, inf], "volume", "Radius of the core"], + ["thickness", "Ang", 40., [0, inf], "volume", "Thickness of shell"], + ["nuc_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Core scattering length density"], + ["nuc_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Scattering length density of shell"], + ["nuc_sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "", "Solvent scattering length density"], + ["magnetic_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Magnetic scattering length density of core"], + ["magnetic_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Magnetic scattering length density of shell"], + ["magnetic_sld_solvent", "1e-6/Ang^2", 3.0, [-inf, inf], "", "Magnetic scattering length density of solvent"], + ["hk_core", "1e-6/Ang^2", 1.0, [0, inf], "", "anisotropy field of defect"], + ["Hi", "T", 2.0, [0, inf], "", "effective field inside the material"], + ["Ms", "T", 1.0, [0, inf], "", "volume averaged saturation magnetisation"], + ["A", "pJ/m", 10.0, [0, inf], "", "average exchange stiffness constant"], + ["D", "mJ/m^2", 0.0, [0, inf], "", "average DMI constant"], + ["up_i", "None", 0.5, [0, 1], "", "Polarisation incoming beam"], + ["up_f", "None", 0.5, [0, 1], "", "Polarisation outgoing beam"], + ["alpha", "None", 90, [0, 180], "", "inclination of field to neutron beam"], + ["beta", "None", 0, [0, 360], "", "rotation of field around neutron beam"], + ] +# pylint: enable=bad-whitespace, line-too-long + + + + +source = ["lib/sas_3j1x_x.c", "lib/core_shell.c", "lib/gauss76.c", "magnetic_functions.c", "micromagnetic_FF_3D.c"] +structure_factor = False +have_Fq = False +single=False + + +effective_radius_type = ["outer radius", "core radius"] + +def random(): + """Return a random parameter set for the model.""" + outer_radius = 10**np.random.uniform(1.3, 4.3) + # Use a distribution with a preference for thin shell or thin core + # Avoid core,shell radii < 1 + radius = np.random.beta(0.5, 0.5)*(outer_radius-2) + 1 + thickness = outer_radius - radius + pars = dict( + radius=radius, + thickness=thickness, + ) + return pars + + + + +# tests = [ + # [{'radius': 20.0, 'thickness': 10.0}, 0.1, None, None, 30.0, 4.*pi/3*30**3, 1.0], + + # # The SasView test result was 0.00169, with a background of 0.001 + # [{'radius': 60.0, 'thickness': 10.0, 'sld_core': 1.0, 'sld_shell': 2.0, + # 'sld_solvent': 3.0, 'background': 0.0}, 0.4, 0.000698838], +# ] From 600b1bf45e4627f7d5e351e539e8f8b0bf419567 Mon Sep 17 00:00:00 2001 From: dehoni Date: Mon, 8 Apr 2024 22:09:30 +0100 Subject: [PATCH 04/22] separate ParallelepipedChain into separate PR --- sasmodels/models/ParallelepipedChain.c | 197 ------------------------ sasmodels/models/ParallelepipedChain.py | 90 ----------- 2 files changed, 287 deletions(-) delete mode 100644 sasmodels/models/ParallelepipedChain.c delete mode 100644 sasmodels/models/ParallelepipedChain.py diff --git a/sasmodels/models/ParallelepipedChain.c b/sasmodels/models/ParallelepipedChain.c deleted file mode 100644 index c9ffbc0f..00000000 --- a/sasmodels/models/ParallelepipedChain.c +++ /dev/null @@ -1,197 +0,0 @@ -static double -form_volume(double length_a, double length_b, double length_c) -{ - return length_a * length_b * length_c; -} - -static double -radius_from_excluded_volume(double length_a, double length_b, double length_c) -{ - double r_equiv, length; - double lengths[3] = {length_a, length_b, length_c}; - double lengthmax = fmax(lengths[0],fmax(lengths[1],lengths[2])); - double length_1 = lengthmax; - double length_2 = lengthmax; - double length_3 = lengthmax; - - for(int ilen=0; ilen<3; ilen++) { - if (lengths[ilen] < length_1) { - length_2 = length_1; - length_1 = lengths[ilen]; - } else { - if (lengths[ilen] < length_2) { - length_2 = lengths[ilen]; - } - } - } - if(length_2-length_1 > length_3-length_2) { - r_equiv = sqrt(length_2*length_3/M_PI); - length = length_1; - } else { - r_equiv = sqrt(length_1*length_2/M_PI); - length = length_3; - } - - return 0.5*cbrt(0.75*r_equiv*(2.0*r_equiv*length + (r_equiv + length)*(M_PI*r_equiv + length))); -} - -static double -radius_effective(int mode, double length_a, double length_b, double length_c) -{ - switch (mode) { - default: - case 1: // equivalent cylinder excluded volume - return radius_from_excluded_volume(length_a,length_b,length_c); - case 2: // equivalent volume sphere - return cbrt(length_a*length_b*length_c/M_4PI_3); - case 3: // half length_a - return 0.5 * length_a; - case 4: // half length_b - return 0.5 * length_b; - case 5: // half length_c - return 0.5 * length_c; - case 6: // equivalent circular cross-section - return sqrt(length_a*length_b/M_PI); - case 7: // half ab diagonal - return 0.5*sqrt(length_a*length_a + length_b*length_b); - case 8: // half diagonal - return 0.5*sqrt(length_a*length_a + length_b*length_b + length_c*length_c); - } -} - -static void -Fq(double q, - double *F1, - double *F2, - double sld, - double solvent_sld, - double length_a, - double length_b, - double length_c) -{ - const double mu = 0.5 * q * length_b; - - // Scale sides by B - const double a_scaled = length_a / length_b; - const double c_scaled = length_c / length_b; - - // outer integral (with gauss points), integration limits = 0, 1 - double outer_total_F1 = 0.0; //initialize integral - double outer_total_F2 = 0.0; //initialize integral - for( int i=0; i Date: Mon, 29 Jan 2024 15:19:01 -0500 Subject: [PATCH 05/22] work around pocl problems (for now) --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ff0441e5..9d28b069 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,6 +57,8 @@ jobs: - name: check that the docs build (linux only) if: ${{ matrix.os == 'ubuntu-latest' }} + env: + SAS_OPENCL: none run: | make -j 4 -C doc SPHINXOPTS="-W --keep-going -n" html From 4e135a18c62fa53797439f7d3d6ab85a3bd006f6 Mon Sep 17 00:00:00 2001 From: Paul Kienzle Date: Mon, 29 Jan 2024 15:06:28 -0500 Subject: [PATCH 06/22] work around pocl problems (for now) --- .github/workflows/test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d28b069..9536dffd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,9 +45,14 @@ jobs: choco install opencl-intel-cpu-runtime python -m pip install --only-binary=pyopencl --find-links http://www.silx.org/pub/wheelhouse/ --trusted-host www.silx.org pyopencl +<<<<<<< HEAD - name: Test with pytest +======= + - name: Test with pytest (only on Windows for now since PoCL is failing on Ubuntu) +>>>>>>> 6b80a438 (work around pocl problems (for now)) env: PYOPENCL_COMPILER_OUTPUT: 1 + SAS_OPENCL: none run: | # other CI uses the following, but `setup.py test` is a deprecated way # of running tests From 108c0c2df0570f8d7a7808745c8893f2968b2600 Mon Sep 17 00:00:00 2001 From: Paul Kienzle Date: Mon, 29 Jan 2024 15:02:38 -0500 Subject: [PATCH 07/22] work around pocl problems (for now) --- .github/workflows/test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9536dffd..e194352d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,11 +45,8 @@ jobs: choco install opencl-intel-cpu-runtime python -m pip install --only-binary=pyopencl --find-links http://www.silx.org/pub/wheelhouse/ --trusted-host www.silx.org pyopencl -<<<<<<< HEAD - - name: Test with pytest -======= - name: Test with pytest (only on Windows for now since PoCL is failing on Ubuntu) ->>>>>>> 6b80a438 (work around pocl problems (for now)) + env: PYOPENCL_COMPILER_OUTPUT: 1 SAS_OPENCL: none From 062fbff89a8a6d753c7f4caf26102e7fa540b9fc Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 21 May 2024 17:09:58 +0100 Subject: [PATCH 08/22] add image and check model describtion --- sasmodels/models/img/micromagnetic_FF.png | Bin 0 -> 163495 bytes sasmodels/models/micromagnetic_FF_3D.py | 67 +++++++++++----------- 2 files changed, 34 insertions(+), 33 deletions(-) create mode 100644 sasmodels/models/img/micromagnetic_FF.png diff --git a/sasmodels/models/img/micromagnetic_FF.png b/sasmodels/models/img/micromagnetic_FF.png new file mode 100644 index 0000000000000000000000000000000000000000..b316ccb566bf8e1ef84daa93e0152f43df84c361 GIT binary patch literal 163495 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Ⓢv6-l@){`_r+2oOFZ#IL;U&E74kai)VmD5 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 YP~ym!y@B8`CWn9lv$VIUx$G7HZ@S#ZRsaA1 literal 0 HcmV?d00001 diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index b31e44f1..e4993d1b 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -12,23 +12,23 @@ saturation the scattering cross-section can be evaluated by means of micromagnetic theory .. math:: - I(mathbf{Q}) = I_nuc +I_res+ I_mag(mathbf{Q},H), + I(\mathbf{Q}) = I_{nuc} +I_{res}+ I_{mag}(\mathbf{Q},H), with the field-independent nuclear and magnetic residual SANS cross section (due to nanoscale spatial variations of the saturation magnetisation) measured at -complete magnetic saturation. Commonly, a measurement at a high magnetic field +complete magnetic saturation. Commonly, a measurement at a high magnetic field is taken as reference and subtracted from the scattering cross-section at lower field to obtain the so-called spin-misalignment scattering cross-section .. math:: - I_mag(mathbf{Q},H)= S_K(Q) R_K(mathbf{Q}, H_i) + S_M(Q) R_M(mathbf{Q}, H_i), + I_{mag}(\mathbf{Q},H)= S_K(Q) R_K(\mathbf{Q}, H_i) + S_M(Q) R_M(\mathbf{Q}, H_i), with $H_i$ the internal field, i.e. the external magnetic field corrected for demagnetizing effects and the influence of the magnetodipolar field and of the magnetic anisotropy [#Bick2013]_. This purely magnetic scattering reflects the -sensitive response of the transversal magnetisation components with to an -externally applied magnetic field with a contribution $S_K imes R_K$ due to -perturbations around magnetic anisotropy fields and a term $S_M imes R_M$ +response of the transversal magnetisation components with to an +externally applied magnetic field with a contribution $S_K \times R_K$ due to +perturbations around magnetic anisotropy fields and a term $S_M \times R_M$ related to magnetostatic fields. The alignment of the magnetic moments along the magnetic field is disturbed by perturbations in the microstructure. The anisotropy-field function $S_K$ depends on the Fourier transform of the magnetic @@ -48,7 +48,7 @@ The micromagnetic response functions depend on magnetic material parameters $M_S$: average saturation magnetisation of the material, $H_i$: the internal magnetic field, $A$ the average exchange-stiffness constant. In the vicinity of lattice -imperfection in ferromagnetic materials, antisymmetric Dzyaloshinskii–Moriya +imperfection in ferromagnetic materials, antisymmetric Dzyaloshinskii–Moriya interaction (DMI) can occur due to the local structural inversion symmetry breaking [#Arrott1963]_. DMI with strength $D$ can give rise to nonuniform spin textures resulting in a polarization-dependent asymmetric scattering term for @@ -59,36 +59,36 @@ Considerations for a microstructure with a prefered orientation (texture) can be found in [#Weissmueller2001]_. In the code the averaging procedure over the random anisotropy is explicitely performed. A specific orientation distribution can be -implemented. +implemented by rewriting the model. -The magnetic field is oriented with an inclination of $alpha$ to the neutron beam -and rotated by $beta$. The model for the nuclear scattering amplitude, saturation +The magnetic field is oriented with an inclination of $\alpha$ to the neutron beam +and rotated by $\beta$. The model for the nuclear scattering amplitude, saturation magnetisation is based on spherical particles with a core shell structure. For simplicity, only the core has an effective anisotropy, that is varying randomly in direction from particle to particle. The effect of different, more complex -spatial profiles of the anisotropy can be seen in Michels PRB 82, 024433 (2010). +spatial profiles of the anisotropy can be seen in [#Michels2010]_. The magnetic scattering length density (SLD) is defined as -$ ho_{mathrm{mag}}=b_H M_S$, where $b_H= 2.91*10^{8}A^{-1}m^{-1}$ and $M_S$ +$\rho_{\mathrm{mag}}=b_H M_S$, where $b_H= 2.91*10^{8}A^{-1}m^{-1}$ and $M_S$ is the saturation magnetisation (in $A/m$). The fraction of "upward" neutrons before ('up_frac_i') and after the sample ('up_frac_f') must range between 0 to 1, with 0.5 denoting an unpolarised beam. Note that a fit may result in a negative magnetic SLD, and hence magnetisation, when the polarisation state is inverted, i.e. if you have analysed for a $I_{00}$ - state wheras your data are $I_{11}$. The model allows to construct the 4 - spin-resolved cross sections (non-spin-flip I_{00}, I_{11} and spin-flip, here - I_{01}=I_{10}), half-polarised SANS (SANSpol, incoming polarised beam I_0 and - I_1, no analysis after sample 'up_frac_f'$=0.5$), and unpolarised beam - ('up_frac_i'$=$'up_frac_f'$=0.5$). Differences and other combinations between - polarised scattering cross section, e.g. to obtain the nuclear-magnetic - interference scattering, or subtraction of the residual scattering of the high - field reference state can be constructed with a custom model (Fitting> - Add/Multiply Model) and using approbriate scales. For dense systems, special - care has to be taken as the nculear structure factor (arrangement of particles) - does not need to be identical with the magnetic microstructure e.g. local - textures and correlations between easy axes (see [#Honecker2020]_ for further - details). The use of structure model is therefore strongly discouraged. Better - $I_nuc$, $S_K$ and $S_M$ are fit independent from each other in a model-free way. +state wheras your data are $I_{11}$. The model allows to construct the 4 +spin-resolved cross sections (non-spin-flip $I_{00}$, $I_{11}$ and spin-flip, here +$I_{01}=I_{10}$), half-polarised SANS (SANSpol, incoming polarised beam $I_0$ and +$I_1$, no analysis after sample 'up_frac_f'$=0.5$), and unpolarised beam +('up_frac_i'$=$'up_frac_f'$=0.5$). Differences and other combinations between +polarised scattering cross section, e.g. to obtain the nuclear-magnetic +interference scattering, or subtraction of the residual scattering of the high +field reference state can be constructed with a custom model (Fitting> +Add/Multiply Model) and using approbriate scales. For dense systems, special +care has to be taken as the nculear structure factor (arrangement of particles) +does not need to be identical with the magnetic microstructure e.g. local +textures and correlations between easy axes (see [#Honecker2020]_ for further +details). The use of structure model is therefore strongly discouraged. Better +$I_{nuc}$, $S_K$ and $S_M$ are fit independent from each other in a model-free way. @@ -105,6 +105,7 @@ .. [#Arrott1963] A. Arrott, J. Appl. Phys. 34, 1108 (1963). .. [#Weissmueller2001] J. Weissmueller et al., *Phys. Rev. B* 63, 214414 (2001). .. [#Bick2013] J.-P. Bick et al., *Appl. Phys. Lett.* 102, 022415 (2013). +.. [#Michels2010] A. Michels et al., *Phys. Rev. B* 82, 024433 (2010). .. [#Michels2014] A. Michels, *J. Phys.: Condens. Matter* 26, 383201 (2014). .. [#Michels2016] A. Michels et al., *Phys. Rev. B* 94, 054424 (2016). .. [#Honecker2020] D. Honecker, L. Fernandez Barguin, and P. Bender, *Phys. Rev. B* 101, 134401 (2020). @@ -146,15 +147,15 @@ ["magnetic_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Magnetic scattering length density of core"], ["magnetic_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Magnetic scattering length density of shell"], ["magnetic_sld_solvent", "1e-6/Ang^2", 3.0, [-inf, inf], "", "Magnetic scattering length density of solvent"], - ["hk_core", "1e-6/Ang^2", 1.0, [0, inf], "", "anisotropy field of defect"], - ["Hi", "T", 2.0, [0, inf], "", "effective field inside the material"], - ["Ms", "T", 1.0, [0, inf], "", "volume averaged saturation magnetisation"], - ["A", "pJ/m", 10.0, [0, inf], "", "average exchange stiffness constant"], - ["D", "mJ/m^2", 0.0, [0, inf], "", "average DMI constant"], + ["hk_core", "1e-6/Ang^2", 1.0, [0, inf], "", "Anisotropy field of defect"], + ["Hi", "T", 2.0, [0, inf], "", "Effective field inside the material"], + ["Ms", "T", 1.0, [0, inf], "", "Volume averaged saturation magnetisation"], + ["A", "pJ/m", 10.0, [0, inf], "", "Average exchange stiffness constant"], + ["D", "mJ/m^2", 0.0, [0, inf], "", "Average DMI constant"], ["up_i", "None", 0.5, [0, 1], "", "Polarisation incoming beam"], ["up_f", "None", 0.5, [0, 1], "", "Polarisation outgoing beam"], - ["alpha", "None", 90, [0, 180], "", "inclination of field to neutron beam"], - ["beta", "None", 0, [0, 360], "", "rotation of field around neutron beam"], + ["alpha", "None", 90, [0, 180], "", "Inclination of field to neutron beam"], + ["beta", "None", 0, [0, 360], "", "Rotation of field around neutron beam"], ] # pylint: enable=bad-whitespace, line-too-long From 8116f74f78e92132500dc14739e8e1f1f2c820e2 Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 30 Jul 2024 15:06:15 +0100 Subject: [PATCH 09/22] move magnetic_functions.c as library and align names --- sasmodels/models/{ => lib}/magnetic_functions.c | 0 sasmodels/models/micromagnetic_FF_3D.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename sasmodels/models/{ => lib}/magnetic_functions.c (100%) diff --git a/sasmodels/models/magnetic_functions.c b/sasmodels/models/lib/magnetic_functions.c similarity index 100% rename from sasmodels/models/magnetic_functions.c rename to sasmodels/models/lib/magnetic_functions.c diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index e4993d1b..9f5208d7 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -162,7 +162,7 @@ -source = ["lib/sas_3j1x_x.c", "lib/core_shell.c", "lib/gauss76.c", "magnetic_functions.c", "micromagnetic_FF_3D.c"] +source = ["lib/sas_3j1x_x.c", "lib/core_shell.c", "lib/gauss76.c", "lib/magnetic_functions.c", "micromagnetic_FF_3D.c"] structure_factor = False have_Fq = False single=False From d85cbcb8ccf3d4b5cc92f2c859cdf95bc8524a33 Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 30 Jul 2024 17:32:17 +0100 Subject: [PATCH 10/22] generalise models for varing structural, magnetic, and anisotropy structural sizes --- sasmodels/models/micromagnetic_FF_3D.c | 46 +++++++++++-------------- sasmodels/models/micromagnetic_FF_3D.py | 27 +++++++++------ 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c index 892bd430..e64d9334 100644 --- a/sasmodels/models/micromagnetic_FF_3D.c +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -1,22 +1,16 @@ //Core-shell form factor for anisotropy field (Hkx, Hky and Hkz), Nuc and lonitudinal magnetization Mz static double -form_volume(double radius, double thickness) +form_volume(double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius) { - return M_4PI_3 * cube(radius + thickness); -} + if( nuc_radius+nuc_thickness>mag_radius+ mag_thickness) + return M_4PI_3 * cube(nuc_radius + nuc_thickness); + else + return M_4PI_3 * cube(mag_radius + mag_thickness); -static double -radius_effective(int mode, double radius, double thickness) -{ - switch (mode) { - default: - case 1: // outer radius - return radius + thickness; - case 2: // core radius - return radius; - } } + + static double fq(double q, double radius, double thickness, double core_sld, double shell_sld, double solvent_sld) { @@ -80,9 +74,8 @@ static double fqMyimag( double x, double y, double z, double Mz, double Hkx, dou return f; } -//calculate 2D from _fq static double -Iqxy(double qx, double qy, double radius, double thickness,double core_nuc, double shell_nuc, double solvent_nuc, double core_Ms, double shell_Ms, double solvent_Ms, double core_hk, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +Iqxy(double qx, double qy, double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) { const double q=MAG_VEC(qx, qy, 0); if (q > 1.0e-16 ) { @@ -95,8 +88,9 @@ Iqxy(double qx, double qy, double radius, double thickness,double core_nuc, doub double weights[8]; set_weights(up_i, up_f, weights); - double mz=fq(q, radius, thickness, core_Ms, shell_Ms, solvent_Ms); - double nuc=fq(q, radius, thickness, core_nuc, shell_nuc, solvent_nuc); + double mz=fq(q, mag_radius, mag_thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); + double nuc=fq(q, nuc_radius, nuc_thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); + double cos_gamma, sin_gamma; double sld[8]; @@ -109,9 +103,9 @@ Iqxy(double qx, double qy, double radius, double thickness,double core_nuc, doub //Only the core of the defect/particle in the matrix has an effective //anisotropy (for simplicity), for the effect of different, more complex // spatial profile of the anisotropy see Michels PRB 82, 024433 (2010) - double Hkx= fq(q, radius, thickness, core_hk, 0, 0)*sin_gamma; - double Hky= fq(q, radius, thickness, core_hk, 0, 0)*cos_gamma; - + double Hkx= fq(q, hk_radius, 0, hk_sld_core, 0, 0)*sin_gamma; + double Hky= fq(q, hk_radius, 0, hk_sld_core, 0, 0)*cos_gamma; + double mxreal=fqMxreal(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); double mximag=fqMximag(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); double myreal=fqMyreal(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); @@ -134,8 +128,9 @@ Iqxy(double qx, double qy, double radius, double thickness,double core_nuc, doub } } + static double -Iq(double q, double radius, double thickness,double core_nuc, double shell_nuc, double solvent_nuc, double core_Ms, double shell_Ms, double solvent_Ms, double core_hk, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +Iq(double q, double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius,double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) { // slots to hold sincos function output of the orientation on the detector plane double sin_theta, cos_theta; @@ -151,8 +146,9 @@ Iq(double q, double radius, double thickness,double core_nuc, double shell_nuc, double weights[8]; set_weights(up_i, up_f, weights); - double mz=fq(q, radius, thickness, core_Ms, shell_Ms, solvent_Ms); - double nuc=fq(q, radius, thickness, core_nuc, shell_nuc, solvent_nuc); + double mz=fq(q, mag_radius, mag_thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); + double nuc=fq(q, nuc_radius, nuc_thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); + double cos_gamma, sin_gamma; double sld[8]; @@ -166,8 +162,8 @@ Iq(double q, double radius, double thickness,double core_nuc, double shell_nuc, //Only the core of the defect/particle in the matrix has an effective //anisotropy (for simplicity), for the effect of different, more complex //spatial profile of the anisotropy see Michels PRB 82, 024433 (2010). - double Hkx= fq(q, radius, thickness, core_hk, 0, 0)*sin_gamma; - double Hky= fq(q, radius, thickness, core_hk, 0, 0)*cos_gamma; + double Hkx= fq(q, hk_radius, 0, hk_sld_core, 0, 0)*sin_gamma; + double Hky= fq(q, hk_radius, 0, hk_sld_core, 0, 0)*cos_gamma; double mxreal=fqMxreal(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); double mximag=fqMximag(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index 9f5208d7..541f720e 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -124,7 +124,7 @@ import numpy as np from numpy import pi, inf -name = "spin_structure_ferromagnets_3D" +name = "micromagnetic_FF_3D" title = "Field-dependent magnetic microstructure around imperfections in bulk ferromagnets" description = """ I(q) = A (F_N^2(q)+ C F_N F_M + D F_M^2) +B(H) I_mag(q,H) @@ -139,15 +139,18 @@ # pylint: disable=bad-whitespace, line-too-long # ["name", "units", default, [lower, upper], "type","description"], -parameters = [["radius", "Ang", 50., [0, inf], "volume", "Radius of the core"], - ["thickness", "Ang", 40., [0, inf], "volume", "Thickness of shell"], +parameters = [["nuc_radius", "Ang", 50., [0, inf], "volume", "Structural radius of the core"], + ["nuc_thickness", "Ang", 40., [0, inf], "volume", "Structural thickness of shell"], + ["mag_radius", "Ang", 50., [0, inf], "volume", "Magnetic radius of the core"], + ["mag_thickness", "Ang", 40., [0, inf], "volume", "Magnetic thickness of shell"], + ["hk_radius", "Ang", 50., [0, inf], "volume", "Anisotropy radius of the core"], ["nuc_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Core scattering length density"], ["nuc_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Scattering length density of shell"], ["nuc_sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "", "Solvent scattering length density"], - ["magnetic_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Magnetic scattering length density of core"], - ["magnetic_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Magnetic scattering length density of shell"], - ["magnetic_sld_solvent", "1e-6/Ang^2", 3.0, [-inf, inf], "", "Magnetic scattering length density of solvent"], - ["hk_core", "1e-6/Ang^2", 1.0, [0, inf], "", "Anisotropy field of defect"], + ["mag_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Magnetic scattering length density of core"], + ["mag_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Magnetic scattering length density of shell"], + ["mag_sld_solvent", "1e-6/Ang^2", 3.0, [-inf, inf], "", "Magnetic scattering length density of solvent"], + ["hk_sld_core", "1e-6/Ang^2", 1.0, [0, inf], "", "Anisotropy field of defect"], ["Hi", "T", 2.0, [0, inf], "", "Effective field inside the material"], ["Ms", "T", 1.0, [0, inf], "", "Volume averaged saturation magnetisation"], ["A", "pJ/m", 10.0, [0, inf], "", "Average exchange stiffness constant"], @@ -168,8 +171,6 @@ single=False -effective_radius_type = ["outer radius", "core radius"] - def random(): """Return a random parameter set for the model.""" outer_radius = 10**np.random.uniform(1.3, 4.3) @@ -178,8 +179,12 @@ def random(): radius = np.random.beta(0.5, 0.5)*(outer_radius-2) + 1 thickness = outer_radius - radius pars = dict( - radius=radius, - thickness=thickness, + nuc_radius=radius, + nuc_thickness=thickness, + mag_radius=radius, + mag_thickness=thickness, + hk_radius=radius + ) return pars From f2405b37e47a56996ca08159d8c631008a3f7545 Mon Sep 17 00:00:00 2001 From: Paul Kienzle Date: Fri, 30 Aug 2024 11:52:50 -0400 Subject: [PATCH 11/22] add exploration for precision of the langevin function 1/tanh(x) + 1/x --- explore/precision.py | 54 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/explore/precision.py b/explore/precision.py index 47eb71a8..cb19ce72 100755 --- a/explore/precision.py +++ b/explore/precision.py @@ -190,13 +190,13 @@ def plotdiff(x, target, actual, label, diff): if diff == "relative": err = np.array([(abs((t-a)/t) if t != 0 else a) for t, a in zip(target, actual)], 'd') #err = np.clip(err, 0, 1) - pylab.loglog(x, err, '-', label=label) + pylab.loglog(x, err, '-', label=label, alpha=0.7) elif diff == "absolute": err = np.array([abs((t-a)) for t, a in zip(target, actual)], 'd') - pylab.loglog(x, err, '-', label=label) + pylab.loglog(x, err, '-', label=label, alpha=0.7) else: limits = np.min(target), np.max(target) - pylab.semilogx(x, np.clip(actual, *limits), '-', label=label) + pylab.semilogx(x, np.clip(actual, *limits), '-', label=label, alpha=0.7) def make_ocl(function, name, source=[]): class Kernel(object): @@ -412,6 +412,54 @@ def add_function(name, mp_function, np_function, ocl_function, np_function=lambda x: np.fmod(x, 2*np.pi), ocl_function=make_ocl("return fmod(q, 2*M_PI);", "sas_fmod"), ) + +def sas_langevin(x): + scalar = np.isscalar(x) + if scalar: + x = np.array([x]) # should inherit dtype for single if given single + f = np.empty_like(x) + cutoff = 0.1 if f.dtype == np.float64 else 1.0 + #cutoff *= 10 + index = x < cutoff + xp = x[index] + xpsq = xp*xp + f[index] = xp / (3. + xpsq / (5. + xpsq/(7. + xpsq/(9.)))) + # 4 terms gets to 1e-7 single, 1e-14 double. Can get to 1e-15 double by adding + # another 4 terms and setting cutoff at 1.0. Not worthwhile. Instead we would + # need an expansion about x somewhere between 1 and 10 for the interval [0.1, 100.] + #f[index] = xp / (3. + xpsq / (5. + xpsq/(7. + xpsq/(9. + xpsq/(11.0 + xpsq/(13. + xpsq/(15. + xpsq/17.))))))) + xp = x[~index] + f[~index] = 1/np.tanh(xp) - 1/xp + return f[0] if scalar else f + +def sas_langevin_x(x): + scalar = np.isscalar(x) + if scalar: + x = np.array([x]) # should inherit dtype for single if given single + f = np.empty_like(x) + cutoff = 0.1 if f.dtype == np.float64 else 1.0 + index = x < cutoff + xp = x[index] + xpsq = xp*xp + f[index] = 1. / (3. + xpsq / (5. + xpsq/(7. + xpsq/(9.)))) + xp = x[~index] + f[~index] = (1/np.tanh(xp) - 1/xp)/xp + return f[0] if scalar else f + +add_function( + name="langevin(x)", + mp_function=lambda x: (1/mp.tanh(x) - 1/x), + np_function=sas_langevin, + #ocl_function=make_ocl("return q < 0.7 ? q*(1./3. + q*q*(-1./45. + q*q*(2./945. + q*q*(-1./4725.) + q*q*(2./93555.)))) : 1/tanh(q) - 1/q;", "sas_langevin"), + ocl_function=make_ocl("return q < 1e-5 ? q/3. : 1/tanh(q) - 1/q;", "sas_langevin"), +) +add_function( + name="langevin(x)/x", + mp_function=lambda x: (1/mp.tanh(x) - 1/x)/x, + #np_function=lambda x: sas_langevin(x)/x, # Note: need to test for x=0 + np_function=sas_langevin_x, + ocl_function=make_ocl("return q < 1e-5 ? 1./3. : (1/tanh(q) - 1/q)/q;", "sas_langevin_x"), +) add_function( name="gauss_coil", mp_function=lambda x: 2*(mp.exp(-x**2) + x**2 - 1)/x**4, From 3023920a084e3cc346ff09fe90326987bca37bcd Mon Sep 17 00:00:00 2001 From: Paul Kienzle Date: Tue, 3 Sep 2024 15:50:35 -0400 Subject: [PATCH 12/22] Make clip() available to all models in the kernel header. --- doc/guide/plugin.rst | 2 ++ sasmodels/kernel_header.c | 5 +++++ sasmodels/kernel_iq.c | 6 ------ sasmodels/models/lib/magnetic_functions.c | 14 ++------------ sasmodels/models/sphere.py | 16 +++++++++++++++- sasmodels/special.py | 5 ++++- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/doc/guide/plugin.rst b/doc/guide/plugin.rst index e7c0ba4b..589d7872 100644 --- a/doc/guide/plugin.rst +++ b/doc/guide/plugin.rst @@ -851,6 +851,8 @@ Some non-standard constants and functions are also provided: $x^2$ cube(x): $x^3$ + clip(a, a_min, a_max): + $\min(\max(a, a_\text{min}), a_\text{max})$, or NaN if $a$ is NaN. sas_sinx_x(x): $\sin(x)/x$, with limit $\sin(0)/0 = 1$. powr(x, y): diff --git a/sasmodels/kernel_header.c b/sasmodels/kernel_header.c index f27584d5..19793041 100644 --- a/sasmodels/kernel_header.c +++ b/sasmodels/kernel_header.c @@ -187,6 +187,11 @@ #endif inline double square(double x) { return x*x; } inline double cube(double x) { return x*x*x; } +// clip() follows numpy.clip() semantics, returning (x < low ? low : x > high ? high : x) +// OpenCL/CUDA clamp() returns fmin(fmax(x, low), high) +// C++(17) clamp() matches numpy.clip() +// If x is NaN numpy.clip() returns NaN but OpenCL clamp() returns low. +inline double clip(double x, double low, double high) { return x < low ? low : x > high ? high : x; } inline double sas_sinx_x(double x) { return x==0 ? 1.0 : sin(x)/x; } // CRUFT: support old style models with orientation received qx, qy and angles diff --git a/sasmodels/kernel_iq.c b/sasmodels/kernel_iq.c index f7e73add..668b4128 100644 --- a/sasmodels/kernel_iq.c +++ b/sasmodels/kernel_iq.c @@ -111,12 +111,6 @@ void ORTH_VEC(double *result_vec, double *vec1, double *vec2) } -// Return value restricted between low and high -static double clip(double value, double low, double high) -{ - return (value < low ? low : (value > high ? high : value)); -} - // Compute spin cross sections given in_spin and out_spin // To convert spin cross sections to sld b: // uu * (sld - m_perp_x); diff --git a/sasmodels/models/lib/magnetic_functions.c b/sasmodels/models/lib/magnetic_functions.c index 37eb6488..1213cb72 100644 --- a/sasmodels/models/lib/magnetic_functions.c +++ b/sasmodels/models/lib/magnetic_functions.c @@ -1,13 +1,3 @@ -static double clipp(double value, double low, double high) //from kernel_iq.c -{ - return (value < low ? low : (value > high ? high : value)); -} - -static double length(double x, double y) -{ - return sqrt(x*x + y*y); -} - static double fq_core_shell(double q, double sld_core, double radius, double sld_solvent, double fp_n, double sld[], double thickness[]) { @@ -56,8 +46,8 @@ static void set_weights(double in_spin, double out_spin, double weight[8]) //fro double norm=out_spin; - in_spin = clipp(sqrt(square(in_spin)), 0.0, 1.0);//opencl has ambiguities for abs() - out_spin = clipp(sqrt(square(out_spin)), 0.0, 1.0); + in_spin = clip(sqrt(square(in_spin)), 0.0, 1.0);//opencl has ambiguities for abs() + out_spin = clip(sqrt(square(out_spin)), 0.0, 1.0); if (out_spin < 0.5){norm=1-out_spin;} diff --git a/sasmodels/models/sphere.py b/sasmodels/models/sphere.py index 1088e3e5..f6407077 100644 --- a/sasmodels/models/sphere.py +++ b/sasmodels/models/sphere.py @@ -75,7 +75,6 @@ have_Fq = True radius_effective_modes = ["radius"] #single = False - def random(): """Return a random parameter set for the model.""" radius = 10**np.random.uniform(1.3, 4) @@ -106,6 +105,21 @@ def random(): 0.1, 482.93824329, 29763977.79867414, 120.0, 8087664.122641933, 1.0], [{"radius": 120., "radius_pd": 0.2, "radius_pd_n": 45}, 0.2, 1.23330406, 1850806.1197361, 120.0, 8087664.122641933, 1.0], + + # For 2-D data use (qx, qy) pairs. Since sphere is radial, just need the + # correct |q| value for the test, so use 3-4-5 triangle. The test code + # looks for tuples to detect 2-D data, so can't use simple numpy cheats. + [{"scale": 1., "background": 0., "sld": 6., "sld_solvent": 1., + "radius": 120.}, + [(0.006, 0.008), (0.06,0.08), (0.12, 0.16)], + [1.34836265e+04, 6.20114062e+00, 1.04733914e-01]], + + # TODO: magnetism smoke test. Values not validated. + [dict(radius=120, sld_M0=4, sld_mphi=20, sld_mtheta=60, + up_frac_i=0.05, up_frac_f=0.1, up_theta=-15, up_phi=10), + [(0.0, 0.01), (0.0, 0.1), (0.0, 0.2)], + [20247.206006297125, 9.312720770235483, 0.15826993186001856]], + # But note P(Q) = F2/volume # F and F^2 are "unscaled", with for n S(q) or for beta approx # I(q) = n [ + (S(q) - 1)] diff --git a/sasmodels/special.py b/sasmodels/special.py index 1b8b3483..3b963270 100644 --- a/sasmodels/special.py +++ b/sasmodels/special.py @@ -58,6 +58,9 @@ cube(x): $x^3$ + clip(a, a_min, a_max): + $\min(\max(a, a_\text{min}), a_\text{max})$, or NaN if $a$ is NaN. + sas_sinx_x(x): $\sin(x)/x$, with limit $\sin(0)/0 = 1$. @@ -215,7 +218,7 @@ from numpy import sin, cos, tan, arcsin as asin, arccos as acos, arctan as atan from numpy import sinh, cosh, tanh, arcsinh as asinh, arccosh as acosh, arctanh as atanh from numpy import arctan2 as atan2 -from numpy import fabs, fmin, fmax, trunc, rint +from numpy import fabs, fmin, fmax, clip, trunc, rint from numpy import pi, nan, inf from scipy.special import gamma as sas_gamma from scipy.special import gammaln as sas_gammaln From d0f20391af2fc38e9a7063bb212f200b2aee561d Mon Sep 17 00:00:00 2001 From: Paul Kienzle Date: Tue, 3 Sep 2024 17:38:45 -0400 Subject: [PATCH 13/22] Remove compiler warnings for generic magnetic models --- sasmodels/kernel_iq.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sasmodels/kernel_iq.c b/sasmodels/kernel_iq.c index 668b4128..96684948 100644 --- a/sasmodels/kernel_iq.c +++ b/sasmodels/kernel_iq.c @@ -71,21 +71,21 @@ typedef union { // ===== Helper functions for magnetism ===== // vector algebra -void SET_VEC(double *vector, double v0, double v1, double v2) +static void SET_VEC(double *vector, double v0, double v1, double v2) { vector[0] = v0; vector[1] = v1; vector[2] = v2; } -void SCALE_VEC(double *vector, double a) +static void SCALE_VEC(double *vector, double a) { vector[0] = a*vector[0]; vector[1] = a*vector[1]; vector[2] = a*vector[2]; } -void ADD_VEC(double *result_vec, double *vec1, double *vec2) +static void ADD_VEC(double *result_vec, double *vec1, double *vec2) { result_vec[0] = vec1[0] + vec2[0]; result_vec[1] = vec1[1] + vec2[1]; @@ -102,7 +102,7 @@ static double MAG_VEC( double *vec) return sqrt(SCALAR_VEC(vec,vec)); } -void ORTH_VEC(double *result_vec, double *vec1, double *vec2) +static void ORTH_VEC(double *result_vec, double *vec1, double *vec2) { double scale = SCALAR_VEC(vec1,vec2) / SCALAR_VEC(vec2,vec2); result_vec[0] = vec1[0] - scale * vec2[0]; @@ -172,11 +172,10 @@ static double mag_sld( ) { double Mvector[3]; - double Pvector[3]; + double Pvector[3]; double qvector[3]; - double rhom[3]; double perpy[3]; - double perpz[3]; + double perpz[3]; double Mperp[3]; const double qsq = sqrt(qx*qx + qy*qy); From c1581a14769e89109b69959ad658b4296b00322f Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 10 Sep 2024 11:27:59 +0100 Subject: [PATCH 14/22] make vector calculations accessible for models --- sasmodels/kernel_header.c | 41 +++++++++++++++ sasmodels/kernel_iq.c | 38 -------------- sasmodels/models/lib/magnetic_functions.c | 63 ++--------------------- sasmodels/models/micromagnetic_FF_3D.c | 10 ++-- sasmodels/models/micromagnetic_FF_3D.py | 21 ++++---- 5 files changed, 60 insertions(+), 113 deletions(-) diff --git a/sasmodels/kernel_header.c b/sasmodels/kernel_header.c index 19793041..a65b1d7d 100644 --- a/sasmodels/kernel_header.c +++ b/sasmodels/kernel_header.c @@ -194,6 +194,47 @@ inline double cube(double x) { return x*x*x; } inline double clip(double x, double low, double high) { return x < low ? low : x > high ? high : x; } inline double sas_sinx_x(double x) { return x==0 ? 1.0 : sin(x)/x; } +// vector algebra +static void SET_VEC(double *vector, double v0, double v1, double v2) +{ + vector[0] = v0; + vector[1] = v1; + vector[2] = v2; +} + +static void SCALE_VEC(double *vector, double a) +{ + vector[0] = a*vector[0]; + vector[1] = a*vector[1]; + vector[2] = a*vector[2]; +} + +static void ADD_VEC(double *result_vec, double *vec1, double *vec2) +{ + result_vec[0] = vec1[0] + vec2[0]; + result_vec[1] = vec1[1] + vec2[1]; + result_vec[2] = vec1[2] + vec2[2]; +} + +static double SCALAR_VEC( double *vec1, double *vec2) +{ + return vec1[0] * vec2[0] + vec1[1] * vec2[1] + vec1[2] * vec2[2]; +} + +static double MAG_VEC( double *vec) +{ + return sqrt(SCALAR_VEC(vec,vec)); +} + + +static void ORTH_VEC(double *result_vec, double *vec1, double *vec2) +{ + double scale = SCALAR_VEC(vec1,vec2) / SCALAR_VEC(vec2,vec2); + result_vec[0] = vec1[0] - scale * vec2[0]; + result_vec[1] = vec1[1] - scale * vec2[1]; + result_vec[2] = vec1[2] - scale * vec2[2]; +} + // CRUFT: support old style models with orientation received qx, qy and angles // To rotate from the canonical position to theta, phi, psi, first rotate by diff --git a/sasmodels/kernel_iq.c b/sasmodels/kernel_iq.c index 96684948..b8e3394b 100644 --- a/sasmodels/kernel_iq.c +++ b/sasmodels/kernel_iq.c @@ -70,45 +70,7 @@ typedef union { #if defined(MAGNETIC) && NUM_MAGNETIC > 0 // ===== Helper functions for magnetism ===== -// vector algebra -static void SET_VEC(double *vector, double v0, double v1, double v2) -{ - vector[0] = v0; - vector[1] = v1; - vector[2] = v2; -} - -static void SCALE_VEC(double *vector, double a) -{ - vector[0] = a*vector[0]; - vector[1] = a*vector[1]; - vector[2] = a*vector[2]; -} - -static void ADD_VEC(double *result_vec, double *vec1, double *vec2) -{ - result_vec[0] = vec1[0] + vec2[0]; - result_vec[1] = vec1[1] + vec2[1]; - result_vec[2] = vec1[2] + vec2[2]; -} -static double SCALAR_VEC( double *vec1, double *vec2) -{ - return vec1[0] * vec2[0] + vec1[1] * vec2[1] + vec1[2] * vec2[2]; -} - -static double MAG_VEC( double *vec) -{ - return sqrt(SCALAR_VEC(vec,vec)); -} - -static void ORTH_VEC(double *result_vec, double *vec1, double *vec2) -{ - double scale = SCALAR_VEC(vec1,vec2) / SCALAR_VEC(vec2,vec2); - result_vec[0] = vec1[0] - scale * vec2[0]; - result_vec[1] = vec1[1] - scale * vec2[1]; - result_vec[2] = vec1[2] - scale * vec2[2]; -} // Compute spin cross sections given in_spin and out_spin diff --git a/sasmodels/models/lib/magnetic_functions.c b/sasmodels/models/lib/magnetic_functions.c index 1213cb72..7a87a26c 100644 --- a/sasmodels/models/lib/magnetic_functions.c +++ b/sasmodels/models/lib/magnetic_functions.c @@ -1,19 +1,6 @@ -static double fq_core_shell(double q, double sld_core, double radius, - double sld_solvent, double fp_n, double sld[], double thickness[]) -{ - const int n = (int)(fp_n+0.5); - double f, r, last_sld; - r = radius; - last_sld = sld_core; - f = 0.; - for (int i=0; i 1.0e-16 ) { const double cos_theta=qx/q; const double sin_theta=qy/q; diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index 541f720e..24575c06 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -12,27 +12,24 @@ saturation the scattering cross-section can be evaluated by means of micromagnetic theory .. math:: - I(\mathbf{Q}) = I_{nuc} +I_{res}+ I_{mag}(\mathbf{Q},H), + I(\mathbf{Q}) = I_{nuc} + I_{mag}(\mathbf{Q},H), -with the field-independent nuclear and magnetic residual SANS cross section (due -to nanoscale spatial variations of the saturation magnetisation) measured at -complete magnetic saturation. Commonly, a measurement at a high magnetic field is -taken as reference and subtracted from the scattering cross-section at lower -field to obtain the so-called spin-misalignment scattering cross-section +with the field-independent nuclear and magnetic SANS cross section (due +to nanoscale spatial variations of the magnetisation). .. math:: I_{mag}(\mathbf{Q},H)= S_K(Q) R_K(\mathbf{Q}, H_i) + S_M(Q) R_M(\mathbf{Q}, H_i), with $H_i$ the internal field, i.e. the external magnetic field corrected for demagnetizing effects and the influence of the magnetodipolar field and of the -magnetic anisotropy [#Bick2013]_. This purely magnetic scattering reflects the -response of the transversal magnetisation components with to an +magnetic anisotropy [#Bick2013]_. This magnetic field dependence of the scattering +reflects the increasing magnetisation misalignment with decreasing externally applied magnetic field with a contribution $S_K \times R_K$ due to perturbations around magnetic anisotropy fields and a term $S_M \times R_M$ -related to magnetostatic fields. The alignment of the magnetic moments along -the magnetic field is disturbed by perturbations in the microstructure. The -anisotropy-field function $S_K$ depends on the Fourier transform of the magnetic -anisotropy distribution (strength and orientation) in the material and the +related to magnetostatic fields. The magnetic moments decorate perturbations in the +microstructure (precipitates, grain boundaries etc). +The anisotropy-field function $S_K$ depends on the Fourier transform of the magnetic +anisotropy distribution (strength and orientation) in the material, and the scattering function of the longitudinal magnetisation $S_M$ reflects the variations of the saturation magnetisation, e.g. jumps at the particle-matrix interface. $R_K$ and $R_M$ denote the micromagnetic response functions that From a2a0a203addda130cd8d8f7b14cd8d94fc0dfd3b Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 10 Sep 2024 14:02:26 +0100 Subject: [PATCH 15/22] rename carthesian q components --- sasmodels/models/lib/magnetic_functions.c | 10 +++++----- sasmodels/models/micromagnetic_FF_3D.c | 24 +++++++++++------------ sasmodels/models/micromagnetic_FF_3D.py | 1 + 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/sasmodels/models/lib/magnetic_functions.c b/sasmodels/models/lib/magnetic_functions.c index 7a87a26c..c37b3f70 100644 --- a/sasmodels/models/lib/magnetic_functions.c +++ b/sasmodels/models/lib/magnetic_functions.c @@ -8,7 +8,7 @@ static double langevin( if (x < 0.00001) { // avoid dividing by zero - return 1.0/3.0*x; + return 1.0/3.0*x-1.0/45.0 * pow(x, 3) + 2.0/945.0 * pow(x, 5) - 1.0/4725.0 * pow(x, 7); } else { return 1.0/tanh(x)-1/x; } @@ -21,7 +21,7 @@ static double langevinoverx( if (x < 0.00001) { // avoid dividing by zero - return 1.0/3.0; + return 1.0/3.0-1.0/45.0 * pow(x, 2) + 2.0/945.0 * pow(x, 4) - 1.0/4725.0 * pow(x, 6); } else { return langevin(x)/x; } @@ -84,7 +84,7 @@ static void set_weights(double in_spin, double out_spin, double weight[8]) //fro //Evaluating the magnetic scattering vector (Halpern Johnson vector) for general orientation of q and collecting terms for the spin-resolved (POLARIS) cross sections. Mz is along the applied magnetic field direction, which is also the polarisation direction. static void mag_sld( // 0=dd.real, 1=dd.imag, 2=uu.real, 3=uu.imag, 4=du.real, 5=du.imag, 6=ud.real, 7=ud.imag - double x, double y, double z, + double qx, double qy, double qz, double mxreal, double mximag, double myreal, double myimag, double mzreal,double mzimag, double nuc, double sld[8]) { double vector[3]; @@ -100,8 +100,8 @@ static void mag_sld( double Mperpreal[3]; double Mperpimag[3]; - const double q = sqrt(x*x + y*y + z*z); - SET_VEC(vector, x/q, y/q, z/q); + const double q = sqrt(qx*qx + qy*qy + qz*qz); + SET_VEC(vector, qx/q, qy/q, qz/q); //Moon-Riste-Koehler notation choose z as pointing along field/polarisation axis //totally different to what is used in SASview (historical reasons) diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c index 3cd43a6e..64bd9a7c 100644 --- a/sasmodels/models/micromagnetic_FF_3D.c +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -46,31 +46,31 @@ static double reduced_field(double q, double Ms, double Hi, //the two transversal magnetisation components, reacting to a magnetic field. //The micromagnetic solution for the magnetisation are from Michels et al. PRB 94, 054424 (2016). -static double fqMxreal( double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +static double fqMxreal( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(x*x + y*y + z*z); - const double f = reduced_field(q, Ms, Hi, A)*(Hkx*(1.0+reduced_field(q, Ms, Hi, A)*y*y/q/q)-Ms*Mz*x*z/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hky*reduced_field(q, Ms, Hi, A)*x*y/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q-square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + const double q = sqrt(qx*qx + qy*qy + qz*qz); + const double f = reduced_field(q, Ms, Hi, A)*(Hkx*(1.0+reduced_field(q, Ms, Hi, A)*qy*qy/q/q)-Ms*Mz*qx*qz/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hky*reduced_field(q, Ms, Hi, A)*qx*qy/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q-square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); return f; } -static double fqMximag(double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +static double fqMximag(double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(x*x + y*y + z*z); - const double f = -reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,y)+Hky*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + const double q = sqrt(qx*qx + qy*qy + qz*qz); + const double f = -reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,qy)+Hky*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); return f; } -static double fqMyreal( double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +static double fqMyreal( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(x*x + y*y + z*z); - const double f = reduced_field(q, Ms, Hi, A)*(Hky*(1.0+reduced_field(q, Ms, Hi, A)*x*x/q/q)-Ms*Mz*y*z/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hkx*reduced_field(q, Ms, Hi, A)*x*y/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + const double q = sqrt(qx*qx + qy*qy + qz*qz); + const double f = reduced_field(q, Ms, Hi, A)*(Hky*(1.0+reduced_field(q, Ms, Hi, A)*qx*qx/q/q)-Ms*Mz*qy*qz/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hkx*reduced_field(q, Ms, Hi, A)*qx*qy/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); return f; } -static double fqMyimag( double x, double y, double z, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) +static double fqMyimag( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(x*x + y*y + z*z); - const double f = reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,x)-Hkx*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))/(1.0+reduced_field(q, Ms, Hi, A)*(x*x+y*y)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,z))); + const double q = sqrt(qx*qx + qy*qy + qz*qz); + const double f = reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,qx)-Hkx*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); return f; } diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index 24575c06..6db4220a 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -166,6 +166,7 @@ structure_factor = False have_Fq = False single=False +opencl = False def random(): From f9c7c5f23839820575e5728ac6ee2173629d396a Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 10 Sep 2024 14:37:08 +0100 Subject: [PATCH 16/22] simplifying magnetic form factors --- sasmodels/models/micromagnetic_FF_3D.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c index 64bd9a7c..4bac4a2b 100644 --- a/sasmodels/models/micromagnetic_FF_3D.c +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -48,36 +48,44 @@ static double reduced_field(double q, double Ms, double Hi, static double fqMxreal( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(qx*qx + qy*qy + qz*qz); - const double f = reduced_field(q, Ms, Hi, A)*(Hkx*(1.0+reduced_field(q, Ms, Hi, A)*qy*qy/q/q)-Ms*Mz*qx*qz/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hky*reduced_field(q, Ms, Hi, A)*qx*qy/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q-square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); + const double qsq = qx*qx + qy*qy + qz*qz; + const double q = sqrt(qsq); + const double Hr = reduced_field(q, Ms, Hi, A); + const double f = Hr*(Hkx*(qsq+Hr*qy*qy)-Ms*Mz*qx*qz*(1.0+Hr*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hky*Hr*qx*qy)/(qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI_length(Ms, D,qz)*q)); return f; } static double fqMximag(double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(qx*qx + qy*qy + qz*qz); - const double f = -reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,qy)+Hky*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); + const double qsq = qx*qx + qy*qy + qz*qz; + const double q = sqrt(qsq); + double Hr = reduced_field(q, Ms, Hi, A); + const double f = -Hr*qsq*(Ms*Mz*(1.0+Hr)*DMI_length(Ms, D,qy)+Hky*Hr*DMI_length(Ms, D,qz))/(qsq+Hr*(qx*qx+qy*qy) -square(Hr*DMI_length(Ms, D,qz)*q)); return f; } static double fqMyreal( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(qx*qx + qy*qy + qz*qz); - const double f = reduced_field(q, Ms, Hi, A)*(Hky*(1.0+reduced_field(q, Ms, Hi, A)*qx*qx/q/q)-Ms*Mz*qy*qz/q/q*(1.0+reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hkx*reduced_field(q, Ms, Hi, A)*qx*qy/q/q)/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); + const double qsq = qx*qx + qy*qy + qz*qz; + const double q = sqrt(qsq); + const double Hr = reduced_field(q, Ms, Hi, A); + const double f = Hr*(Hky*(qsq+Hr*qx*qx)-Ms*Mz*qy*qz*(1.0+Hr*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hkx*Hr*qx*qy)/(qsq+Hr*(qx*qx+qy*qy) -square(Hr*DMI_length(Ms, D,qz)*q)); return f; } static double fqMyimag( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double q = sqrt(qx*qx + qy*qy + qz*qz); - const double f = reduced_field(q, Ms, Hi, A)*(Ms*Mz*(1.0+reduced_field(q, Ms, Hi, A))*DMI_length(Ms, D,qx)-Hkx*reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))/(1.0+reduced_field(q, Ms, Hi, A)*(qx*qx+qy*qy)/q/q -square(reduced_field(q, Ms, Hi, A)*DMI_length(Ms, D,qz))); + const double qsq = qx*qx + qy*qy + qz*qz; + const double q = sqrt(qsq); + const double Hr = reduced_field(q, Ms, Hi, A); + const double f = Hr*qsq*(Ms*Mz*(1.0+Hr)*DMI_length(Ms, D,qx)-Hkx*Hr*DMI_length(Ms, D,qz))/(qsq+Hr*(qx*qx+qy*qy) -square(Hr*DMI_length(Ms, D,qz)*q)); return f; } static double Iqxy(double qx, double qy, double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) { - const double q = sqrt(qx*qx + qy*qy ); + const double q = sqrt(qx*qx + qy*qy); if (q > 1.0e-16 ) { const double cos_theta=qx/q; const double sin_theta=qy/q; From 5414c557099e65e48d156508305d0ee583737d19 Mon Sep 17 00:00:00 2001 From: dehoni Date: Tue, 10 Sep 2024 16:55:21 +0100 Subject: [PATCH 17/22] refactor model --- sasmodels/models/micromagnetic_FF_3D.c | 114 ++++++++++-------------- sasmodels/models/micromagnetic_FF_3D.py | 14 +-- 2 files changed, 50 insertions(+), 78 deletions(-) diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c index 4bac4a2b..8985b8ef 100644 --- a/sasmodels/models/micromagnetic_FF_3D.c +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -1,11 +1,11 @@ //Core-shell form factor for anisotropy field (Hkx, Hky and Hkz), Nuc and lonitudinal magnetization Mz static double -form_volume(double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius) +form_volume(double radius, double thickness) { - if( nuc_radius+nuc_thickness>mag_radius+ mag_thickness) - return M_4PI_3 * cube(nuc_radius + nuc_thickness); + if( radius+thickness>radius+ thickness) + return M_4PI_3 * cube(radius + thickness); else - return M_4PI_3 * cube(mag_radius + mag_thickness); + return M_4PI_3 * cube(radius + thickness); } @@ -27,10 +27,9 @@ static double fq(double q, double radius, static double reduced_field(double q, double Ms, double Hi, double A) { - if( Hi > 1.0e-6 ) - return Ms / (Hi + 2.0 * A * 4.0 * M_PI / Ms * q * q * 10.0);//q in 10e10 m-1, A in 10e-12 J/m, mu0 in 1e-7 - else - return Ms / (1.0e-6 + 2.0 * A * 4.0 * M_PI / Ms * q * q * 10.0); + // q in 10e10 m-1, A in 10e-12 J/m, mu0 in 1e-7 + return Ms / (fmax(Hi, 1.0e-6) + 2.0 * A * 4.0 * M_PI / Ms * q * q * 10.0); + } static double DMI_length(double Ms, double D, double qval) @@ -51,7 +50,9 @@ static double fqMxreal( double qx, double qy, double qz, double Mz, double Hkx, const double qsq = qx*qx + qy*qy + qz*qz; const double q = sqrt(qsq); const double Hr = reduced_field(q, Ms, Hi, A); - const double f = Hr*(Hkx*(qsq+Hr*qy*qy)-Ms*Mz*qx*qz*(1.0+Hr*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hky*Hr*qx*qy)/(qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI_length(Ms, D,qz)*q)); + const double DMI = DMI_length(Ms, D,q); + const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; + const double f = (Hkx*(qsq+Hr*qy*qy)-Ms*Mz*qx*qz*(1.0+Hr*square(DMI))-Hky*Hr*qx*qy)/denominator; return f; } @@ -60,7 +61,9 @@ static double fqMximag(double qx, double qy, double qz, double Mz, double Hkx, d const double qsq = qx*qx + qy*qy + qz*qz; const double q = sqrt(qsq); double Hr = reduced_field(q, Ms, Hi, A); - const double f = -Hr*qsq*(Ms*Mz*(1.0+Hr)*DMI_length(Ms, D,qy)+Hky*Hr*DMI_length(Ms, D,qz))/(qsq+Hr*(qx*qx+qy*qy) -square(Hr*DMI_length(Ms, D,qz)*q)); + const double DMI = DMI_length(Ms, D,q); + const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; + const double f = -qsq*(Ms*Mz*(1.0+Hr)*DMI+Hky*Hr*DMI)/denominator; return f; } @@ -69,7 +72,9 @@ static double fqMyreal( double qx, double qy, double qz, double Mz, double Hkx, const double qsq = qx*qx + qy*qy + qz*qz; const double q = sqrt(qsq); const double Hr = reduced_field(q, Ms, Hi, A); - const double f = Hr*(Hky*(qsq+Hr*qx*qx)-Ms*Mz*qy*qz*(1.0+Hr*DMI_length(Ms, D,q)*DMI_length(Ms, D,q))-Hkx*Hr*qx*qy)/(qsq+Hr*(qx*qx+qy*qy) -square(Hr*DMI_length(Ms, D,qz)*q)); + const double DMI = DMI_length(Ms, D,q); + const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; + const double f = (Hky*(qsq+Hr*qx*qx)-Ms*Mz*qy*qz*(1.0+Hr*square(DMI))-Hkx*Hr*qx*qy)/denominator; return f; } @@ -78,27 +83,24 @@ static double fqMyimag( double qx, double qy, double qz, double Mz, double Hkx, const double qsq = qx*qx + qy*qy + qz*qz; const double q = sqrt(qsq); const double Hr = reduced_field(q, Ms, Hi, A); - const double f = Hr*qsq*(Ms*Mz*(1.0+Hr)*DMI_length(Ms, D,qx)-Hkx*Hr*DMI_length(Ms, D,qz))/(qsq+Hr*(qx*qx+qy*qy) -square(Hr*DMI_length(Ms, D,qz)*q)); + const double DMI = DMI_length(Ms, D,q); + const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; + const double f = qsq*(Ms*Mz*(1.0+Hr)*DMI-Hkx*Hr*DMI)/denominator; return f; } static double -Iqxy(double qx, double qy, double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +Calculate_Scattering(double q, double cos_theta, double sin_theta, double radius, double thickness, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) { - const double q = sqrt(qx*qx + qy*qy); - if (q > 1.0e-16 ) { - const double cos_theta=qx/q; - const double sin_theta=qy/q; - double qrot[3]; set_scatvec(qrot,q,cos_theta, sin_theta, alpha, beta); // 0=dd.real, 1=dd.imag, 2=uu.real, 3=uu.imag, 4=du.real, 6=du.imag, 7=ud.real, 5=ud.imag double weights[8]; set_weights(up_i, up_f, weights); - double mz=fq(q, mag_radius, mag_thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); - double nuc=fq(q, nuc_radius, nuc_thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); - + double mz=fq(q, radius, thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); + double nuc=fq(q, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); + double hk=fq(q, radius, 0, hk_sld_core, 0, 0); double cos_gamma, sin_gamma; double sld[8]; @@ -111,9 +113,9 @@ Iqxy(double qx, double qy, double nuc_radius, double nuc_thickness, double mag_r //Only the core of the defect/particle in the matrix has an effective //anisotropy (for simplicity), for the effect of different, more complex // spatial profile of the anisotropy see Michels PRB 82, 024433 (2010) - double Hkx= fq(q, hk_radius, 0, hk_sld_core, 0, 0)*sin_gamma; - double Hky= fq(q, hk_radius, 0, hk_sld_core, 0, 0)*cos_gamma; - + double Hkx= hk*sin_gamma; + double Hky= hk*cos_gamma; + double mxreal=fqMxreal(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); double mximag=fqMximag(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); double myreal=fqMyreal(qrot[0], qrot[1], qrot[2], mz, Hkx, Hky, Hi, Ms, A, D); @@ -131,14 +133,32 @@ Iqxy(double qx, double qy, double nuc_radius, double nuc_thickness, double mag_r } } total_F2 += GAUSS_W[i] * form ; + return total_F2; } +} + + +static double +Iqxy(double qx, double qy, double radius, double thickness, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +{ + const double q = sqrt(qx*qx + qy*qy); + if (q > 1.0e-16 ) { + const double cos_theta=qx/q; + const double sin_theta=qy/q; + } else { + const double cos_theta=0.0; + const double sin_theta=0.0; + + double total_F2 = Calculate_Scattering(q, cos_theta, sin_theta, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent, mag_sld_core, mag_sld_shell, mag_sld_solvent, hk_sld_core, Hi, Ms, A, D, up_i, up_f, alpha, beta); + return 0.5*1.0e-4*total_F2; } } + static double -Iq(double q, double nuc_radius, double nuc_thickness, double mag_radius, double mag_thickness, double hk_radius,double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) +Iq(double q, double radius, double thickness, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) { // slots to hold sincos function output of the orientation on the detector plane double sin_theta, cos_theta; @@ -148,49 +168,7 @@ Iq(double q, double nuc_radius, double nuc_thickness, double mag_radius, double const double theta = M_PI * (GAUSS_Z[j] + 1.0); // 0 .. 2 pi SINCOS(theta, sin_theta, cos_theta); - double qrot[3]; - set_scatvec(qrot,q,cos_theta, sin_theta, alpha, beta); - // 0=dd.real, 1=dd.imag, 2=uu.real, 3=uu.imag, 4=du.real, 5=du.imag, 6=ud.real, 7=ud.imag - double weights[8]; - set_weights(up_i, up_f, weights); - - double mz=fq(q, mag_radius, mag_thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); - double nuc=fq(q, nuc_radius, nuc_thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); - - - double cos_gamma, sin_gamma; - double sld[8]; - - //loop over random anisotropy axis with isotropic orientation gamma for Hkx and Hky - //To be modified for textured material see also Weissmueller et al. PRB 63, 214414 (2001) - double total_F2 = 0.0; - for (int i=0; i 1.0e-8 ) { - // Since the cross section weight is significant, set the slds - // to the effective slds for this cross section, call the - // kernel, and add according to weight. - // loop over uu, ud real, du real, dd, ud imag, du imag - form += weights[xs]*sld[xs]*sld[xs]; - } - } - total_F2 += GAUSS_W[i] * form ; - } + double total_F2 = Calculate_Scattering(q, cos_theta, sin_theta, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent, mag_sld_core, mag_sld_shell, mag_sld_solvent, hk_sld_core, Hi, Ms, A, D, up_i, up_f, alpha, beta); total_F1D += GAUSS_W[j] * total_F2 ; } //convert from [1e-12 A-1] to [cm-1] diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index 6db4220a..65fde62a 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -136,11 +136,8 @@ # pylint: disable=bad-whitespace, line-too-long # ["name", "units", default, [lower, upper], "type","description"], -parameters = [["nuc_radius", "Ang", 50., [0, inf], "volume", "Structural radius of the core"], - ["nuc_thickness", "Ang", 40., [0, inf], "volume", "Structural thickness of shell"], - ["mag_radius", "Ang", 50., [0, inf], "volume", "Magnetic radius of the core"], - ["mag_thickness", "Ang", 40., [0, inf], "volume", "Magnetic thickness of shell"], - ["hk_radius", "Ang", 50., [0, inf], "volume", "Anisotropy radius of the core"], +parameters = [["radius", "Ang", 50., [0, inf], "volume", "Structural radius of the core"], + ["thickness", "Ang", 40., [0, inf], "volume", "Structural thickness of shell"], ["nuc_sld_core", "1e-6/Ang^2", 1.0, [-inf, inf], "", "Core scattering length density"], ["nuc_sld_shell", "1e-6/Ang^2", 1.7, [-inf, inf], "", "Scattering length density of shell"], ["nuc_sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "", "Solvent scattering length density"], @@ -177,11 +174,8 @@ def random(): radius = np.random.beta(0.5, 0.5)*(outer_radius-2) + 1 thickness = outer_radius - radius pars = dict( - nuc_radius=radius, - nuc_thickness=thickness, - mag_radius=radius, - mag_thickness=thickness, - hk_radius=radius + radius=radius, + thickness=thickness, ) return pars From f424e94cad78b30155537b4e904e91f23d5bef6f Mon Sep 17 00:00:00 2001 From: dehoni Date: Fri, 13 Sep 2024 18:14:37 +0100 Subject: [PATCH 18/22] refactored intensity calculation --- sasmodels/models/micromagnetic_FF_3D.c | 102 +++++++++++++------------ 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c index 8985b8ef..64dfce26 100644 --- a/sasmodels/models/micromagnetic_FF_3D.c +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -2,7 +2,7 @@ static double form_volume(double radius, double thickness) { - if( radius+thickness>radius+ thickness) + if( radius + thickness > radius + thickness) return M_4PI_3 * cube(radius + thickness); else return M_4PI_3 * cube(radius + thickness); @@ -47,45 +47,51 @@ static double reduced_field(double q, double Ms, double Hi, static double fqMxreal( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double qsq = qx*qx + qy*qy + qz*qz; - const double q = sqrt(qsq); - const double Hr = reduced_field(q, Ms, Hi, A); - const double DMI = DMI_length(Ms, D,q); - const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; - const double f = (Hkx*(qsq+Hr*qy*qy)-Ms*Mz*qx*qz*(1.0+Hr*square(DMI))-Hky*Hr*qx*qy)/denominator; + double qsq = qx * qx + qy * qy + qz * qz; + double q = sqrt(qsq); + double Hr = reduced_field(q, Ms, Hi, A); + double DMI = DMI_length(Ms, D,q); + double DMIz = DMI_length(Ms, D,qz); + double denominator = (qsq + Hr * (qx * qx + qy * qy) - square(Hr * DMIz * q)) / Hr; + double f = (Hkx * (qsq + Hr * qy * qy) - Ms * Mz * qx * qz * (1.0 + Hr * square(DMI)) - Hky * Hr * qx * qy) / denominator; return f; } static double fqMximag(double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double qsq = qx*qx + qy*qy + qz*qz; - const double q = sqrt(qsq); + double qsq = qx * qx + qy * qy + qz * qz; + double q = sqrt(qsq); double Hr = reduced_field(q, Ms, Hi, A); - const double DMI = DMI_length(Ms, D,q); - const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; - const double f = -qsq*(Ms*Mz*(1.0+Hr)*DMI+Hky*Hr*DMI)/denominator; + double DMI = DMI_length(Ms, D,q); + double DMIz = DMI_length(Ms, D,qz); + double DMIy = DMI_length(Ms, D,qy); + double denominator = (qsq + Hr * (qx * qx + qy * qy) - square(Hr * DMIz * q)) / Hr; + double f = - qsq * (Ms * Mz * (1.0 + Hr) * DMIy + Hky * Hr * DMIz) / denominator; return f; } static double fqMyreal( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double qsq = qx*qx + qy*qy + qz*qz; - const double q = sqrt(qsq); - const double Hr = reduced_field(q, Ms, Hi, A); - const double DMI = DMI_length(Ms, D,q); - const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; - const double f = (Hky*(qsq+Hr*qx*qx)-Ms*Mz*qy*qz*(1.0+Hr*square(DMI))-Hkx*Hr*qx*qy)/denominator; + double qsq = qx * qx + qy * qy + qz * qz; + double q = sqrt(qsq); + double Hr = reduced_field(q, Ms, Hi, A); + double DMI = DMI_length(Ms, D,q); + double DMIz = DMI_length(Ms, D,qz); + double denominator = (qsq + Hr * (qx * qx + qy * qy) - square(Hr * DMIz * q))/Hr; + double f = (Hky * (qsq + Hr * qx * qx) - Ms * Mz * qy * qz * (1.0 + Hr * square(DMI)) - Hkx * Hr * qx * qy)/denominator; return f; } static double fqMyimag( double qx, double qy, double qz, double Mz, double Hkx, double Hky, double Hi, double Ms, double A, double D) { - const double qsq = qx*qx + qy*qy + qz*qz; - const double q = sqrt(qsq); - const double Hr = reduced_field(q, Ms, Hi, A); - const double DMI = DMI_length(Ms, D,q); - const double denominator = (qsq+Hr*(qx*qx+qy*qy)-square(Hr*DMI*q))/Hr; - const double f = qsq*(Ms*Mz*(1.0+Hr)*DMI-Hkx*Hr*DMI)/denominator; + double qsq = qx * qx + qy * qy + qz * qz; + double q = sqrt(qsq); + double Hr = reduced_field(q, Ms, Hi, A); + double DMI = DMI_length(Ms, D,q); + double DMIx = DMI_length(Ms, D,qx); + double DMIz = DMI_length(Ms, D,qz); + double denominator = (qsq + Hr * (qx * qx + qy * qy) - square(Hr * DMIz * q))/Hr; + double f = qsq * (Ms * Mz * (1.0 + Hr) * DMIx - Hkx * Hr * DMIz)/denominator; return f; } @@ -98,38 +104,38 @@ Calculate_Scattering(double q, double cos_theta, double sin_theta, double radius double weights[8]; set_weights(up_i, up_f, weights); - double mz=fq(q, radius, thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); - double nuc=fq(q, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); - double hk=fq(q, radius, 0, hk_sld_core, 0, 0); + double mz = fq(q, radius, thickness, mag_sld_core, mag_sld_shell, mag_sld_solvent); + double nuc = fq(q, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent); + double hk = fq(q, radius, 0, hk_sld_core, 0, 0); double cos_gamma, sin_gamma; double sld[8]; //loop over random anisotropy axis with isotropic orientation gamma for Hkx and Hky //To be modified for textured material see also Weissmueller et al. PRB 63, 214414 (2001) double total_F2 = 0.0; - for (int i=0; i 1.0e-8) { // Since the cross section weight is significant, set the slds // to the effective slds for this cross section, call the // kernel, and add according to weight. // loop over uu, ud real, du real, dd, ud imag, du imag - form += weights[xs]*sld[xs]*sld[xs]; + form += weights[xs] * sld[xs] * sld[xs]; } } total_F2 += GAUSS_W[i] * form ; @@ -141,18 +147,20 @@ Calculate_Scattering(double q, double cos_theta, double sin_theta, double radius static double Iqxy(double qx, double qy, double radius, double thickness, double nuc_sld_core, double nuc_sld_shell, double nuc_sld_solvent, double mag_sld_core, double mag_sld_shell, double mag_sld_solvent, double hk_sld_core, double Hi, double Ms, double A, double D, double up_i, double up_f, double alpha, double beta) { - const double q = sqrt(qx*qx + qy*qy); + double sin_theta, cos_theta; + const double q = sqrt(qx * qx + qy * qy); if (q > 1.0e-16 ) { - const double cos_theta=qx/q; - const double sin_theta=qy/q; + cos_theta = qx/q; + sin_theta = qy/q; } else { - const double cos_theta=0.0; - const double sin_theta=0.0; - - double total_F2 = Calculate_Scattering(q, cos_theta, sin_theta, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent, mag_sld_core, mag_sld_shell, mag_sld_solvent, hk_sld_core, Hi, Ms, A, D, up_i, up_f, alpha, beta); - - return 0.5*1.0e-4*total_F2; + cos_theta = 0.0; + sin_theta = 0.0; } + + double total_F2 = Calculate_Scattering(q, cos_theta, sin_theta, radius, thickness, nuc_sld_core, nuc_sld_shell, nuc_sld_solvent, mag_sld_core, mag_sld_shell, mag_sld_solvent, hk_sld_core, Hi, Ms, A, D, up_i, up_f, alpha, beta); + + return 0.5 * 1.0e-4 * total_F2; + } @@ -163,7 +171,7 @@ Iq(double q, double radius, double thickness, double nuc_sld_core, double nuc_sl // slots to hold sincos function output of the orientation on the detector plane double sin_theta, cos_theta; double total_F1D = 0.0; - for (int j=0; j Date: Mon, 23 Sep 2024 08:54:20 +0100 Subject: [PATCH 19/22] add test with default values --- sasmodels/models/micromagnetic_FF_3D.c | 4 ++-- sasmodels/models/micromagnetic_FF_3D.py | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/sasmodels/models/micromagnetic_FF_3D.c b/sasmodels/models/micromagnetic_FF_3D.c index 64dfce26..e64154f0 100644 --- a/sasmodels/models/micromagnetic_FF_3D.c +++ b/sasmodels/models/micromagnetic_FF_3D.c @@ -138,9 +138,9 @@ Calculate_Scattering(double q, double cos_theta, double sin_theta, double radius form += weights[xs] * sld[xs] * sld[xs]; } } - total_F2 += GAUSS_W[i] * form ; - return total_F2; + total_F2 += GAUSS_W[i] * form ; } + return total_F2; } diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index 65fde62a..9ecad1aa 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -182,11 +182,7 @@ def random(): - -# tests = [ - # [{'radius': 20.0, 'thickness': 10.0}, 0.1, None, None, 30.0, 4.*pi/3*30**3, 1.0], - - # # The SasView test result was 0.00169, with a background of 0.001 - # [{'radius': 60.0, 'thickness': 10.0, 'sld_core': 1.0, 'sld_shell': 2.0, - # 'sld_solvent': 3.0, 'background': 0.0}, 0.4, 0.000698838], -# ] +tests = [ + [{},1.002266990452620e-03, 7.461046163627724e+03], + [{},(0.0688124, -0.0261013), 22.024], +] From f399580088f297a72d837cc0bce316208d6bf0cc Mon Sep 17 00:00:00 2001 From: dehoni Date: Mon, 23 Sep 2024 10:29:14 +0100 Subject: [PATCH 20/22] documentation reflects model is now validated --- sasmodels/models/micromagnetic_FF_3D.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sasmodels/models/micromagnetic_FF_3D.py b/sasmodels/models/micromagnetic_FF_3D.py index 9ecad1aa..8e0973e7 100644 --- a/sasmodels/models/micromagnetic_FF_3D.py +++ b/sasmodels/models/micromagnetic_FF_3D.py @@ -89,13 +89,6 @@ -Validation ----------- - -The model needs testing and validation. Your feedback is kindly requested. - - - References ---------- @@ -112,8 +105,8 @@ Authorship and Verification ---------------------------- -* **Author: Dirk Honecker **Date:** January 14, 2021 -* **Last Modified by:** +* **Author:** Dirk Honecker **Date:** January 14, 2021 +* **Last Modified by:** Dirk Honecker **Date:** September 23, 2024 * **Last Reviewed by:** """ From 6a8c7957661edf56913ecbfd2c6be25833518393 Mon Sep 17 00:00:00 2001 From: krzywon Date: Thu, 26 Sep 2024 15:05:03 -0400 Subject: [PATCH 21/22] Remove GPu acceleration from ubuntu --- .github/workflows/test.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c68549c..4953c9e4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,11 +29,7 @@ jobs: - name: setup apt dependencies for Linux if: ${{ matrix.os == 'ubuntu-latest' }} run: | - wget https://repo.radeon.com/amdgpu-install/6.1.1/ubuntu/jammy/amdgpu-install_6.1.60101-1_all.deb - sudo apt install ./amdgpu-install_6.1.60101-1_all.deb sudo apt update - sudo apt install amdgpu-dkms - sudo apt install rocm - name: Install Python dependencies run: | From ad40327f23949590f202372f745c136a2fc2e023 Mon Sep 17 00:00:00 2001 From: krzywon Date: Thu, 26 Sep 2024 15:23:48 -0400 Subject: [PATCH 22/22] Update release notes to include final changes --- CHANGES.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4f628583..49eae746 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,10 +1,12 @@ Release notes ============= -v1.0.8 2024-06-?? +v1.0.8 2024-09-26 ----------------- +* New model: Bulk ferromagnets model from marketplace * Doc update: Archive built docs on Github * Doc update: Display math correctly +* Fix error in FCC paracrystaline models * Fix parameter name checking in kernel call v1.0.7 2023-03-23