diff --git a/mcstas-comps/contrib/Phonon_BvK_PG.comp b/mcstas-comps/contrib/Phonon_BvK_PG.comp new file mode 100644 index 000000000..4ba9ae927 --- /dev/null +++ b/mcstas-comps/contrib/Phonon_BvK_PG.comp @@ -0,0 +1,1295 @@ +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright(C) 2000 Risoe National Laboratory. +* +* Component: Phonon_BvK_PG +* +* %I +* Written by: Kim Lefmann +* Date: 06.12.2025 +* Origin: NBI, KU +* +* A sample for phonon scattering based on cross section expressions from the Boothroyd textbook +* based upon the algorithm from component Phonon_simple (with expressions from Squires, Ch. 3) +* Using the Born-von Karman force constnts and the normal mode formalism +* +* +* %D +* Single-cylinder or slap shaped shape. +* Absorption included. +* No multiple scattering. +* No incoherent scattering emitted, but incoherent is present in attenuation +* No attenuation from coherent scattering. No Bragg scattering. +* Specialized for Pyrolytic Graphite(PG) +* +* Algorithm: +* 0. Always perform the scattering if possible (otherwise ABSORB) +* 1. Choose direction within a focusing solid angle +* 2. Select a phonon mode at random (alternatively mode number fixed by user) +* 3. Calculate the zeros of (E_i-E_f-hbar omega(kappa)) as a function of k_f +* 4. Choose one value of k_f (there always at least one possible; see e.g. Squires) +* 5. Perform the correct weight transformation +* For details: see article A. F. Davidsen et al, manuscript for J Neutron Res 2026 +* +* %P +* INPUT PARAMETERS: +* radius: [m] Outer radius of sample in (x,z) plane +* yheight: [m] Height of sample in y direction +* xwidth: [m] Horiz. dimension of sample if slap +* zdepth: [m] Depth of sample if slap + +* sigma_abs: [barns] Absorption cross section at 2200 m/s per atom +* sigma_inc: [barns] Incoherent scattering cross section per atom +* DW: [1] Debye-Waller factor; scalar value (no q-dependence) +* T: [K] Temperature +* focus_r: [m] Radius of sphere containing target. +* focus_xw: [m] horiz. dimension of a rectangular area +* focus_yh: [m] vert. dimension of a rectangular area +* focus_aw: [deg] horiz. angular dimension of a rectangular area +* focus_ah: [deg] vert. angular dimension of a rectangular area +* target_x: [m] position of target to focus at . Transverse coordinate +* target_y: [m] position of target to focus at. Vertical coordinate +* target_z: [m] position of target to focus at. Straight ahead. +* target_index: [1] relative index of component to focus at, e.g. next is +1 +* mode_input: [1] order of the phonon mode to be scattered (unphysical). In the range 0 through 11 . If mode_input == 12, then the mode is choosen at random +* verbose_input: [1] toggles verbose mode (verbose>1) or eigenvector mode (verbose==1) +* dispersion: [1] 0: do nothing special; 1: calculate and output the dispersion; 2: calculate and output the dispersion while varying v_f +* +* OUTPUT PARAMETERS: +* V_rho: [AA^-3] Unit cell density +* V_my_s: [m^-1] Attenuation factor due to incoherent scattering +* V_my_a_v: [m^-1] Attenuation factor due to absorbtion +* +* %L +* The test/example instrument Test_Phonon.instr. +* +* %E +******************************************************************************/ + +DEFINE COMPONENT Phonon_BvK_PG +DEFINITION PARAMETERS () +SETTING PARAMETERS (hh=0,kk=0,ll=0,radius=0, xwidth=0, yheight=0, zdepth=0, sigma_abs=0,sigma_inc=0,DW=1,T, +focus_r=0,focus_xw=0,focus_yh=0,focus_aw=0,focus_ah=0,target_x=0, target_y=0, target_z=0, int target_index=0, int mode_input, int e_steps_low, int e_steps_high, int verbose_input=0, int dispersion=0) +OUTPUT PARAMETERS (q_x, q_y, q_z) +/* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */ + +SHARE +%{ + +#ifndef PHONON_SIMPLE +#define PHONON_SIMPLE $Revision$ // KL comment 040125: what is this used for? +#pragma acc routine + +// ---------------- THINGS THAT COULD BE GENERAL FOR McStas -------------- + +#define T2E (1/11.605) // Kelvin to meV converter +#define pi 3.14159265358979323846264338327950288419716939937510L +#define sqrt3 1.73205080756887729352744634150587236694280525381038L +#define THz2meV 4.13566 // THz to meV converter + +#define Da2kg 1.66054e-27 //Dalton to kg converter +#define dyn2N 1e-3 // dyn/cm to N/m converter +#define hbar 1.0546E-34 +#define mn (1.0087*Da2kg) + +double nbose(double omega, double T) /* Give it another name ?? */ + { + double nb; + nb= (omega>0) ? 1+1/(exp(omega/(T*T2E))-1) : 1/(exp(-omega/(T*T2E))-1); + return nb; + } +#undef T2E + +/* Routine types from Numerical Recipies book */ +#define UNUSED (-1.11e30) +#define MAXRIDD 60 + +void fatalerror_cpu(char *s) + { + fprintf(stderr,"%s \n",s); + exit(1); + } + + void nrerror(const char *error_text){ + printf("Numerical Recipes run-time error ...\n"); + printf("%s\n",error_text); + printf("... now exiting to system.\n"); + exit(1); +} + +#pragma acc routine +void fatalerror(char *s) + { + #ifndef OPENACC + fatalerror_cpu(s); + #endif + } + + #pragma acc routine + +void bubblesort (int size , double* inputarray , int* index) +//this function modifies the inputarray by bubble sorting, and also modifies the index array as the +//index after the sorting. The index array should be initialized as index[] = {0,1,2,3,4,5,6,7...} +{ + int tempindex = 0; + int i; + int j; + for (i = 0 ; i < size-1 ; i++) + { + for (j = 0 ; j < size-1 ; j++) + { + if (inputarray[index[j]] > inputarray[index[j+1]]) + { + tempindex = index[j]; + index[j] = index[j+1]; + index[j+1] = tempindex; + } + } + } + return; +} + + +// ---------------- END GENERAL FOR McStas ---------------------------------- + +// ---------------- THINGS THAT ARE SPECIFIC FOR THE PG COMPONENT ------------ + +#define SMALL_NUMBER 1E-6 +#define V_HIGH 8000 // Highest velocity to search, corresponding to 320 meV, far above the to of the PG phonon band (202 meV along main axes) +#define MATRIX_TEST 0 // Change to 1 to write matrices to disk +#define TIME_EIGENSYSTEMS 1 + +#define DIM 12 // dimensionality of the phonon eigenvectors (4 atoms in the unit cell times 3 dimensions) +#define DV 0.001 // Velocity change used for numerical derivative [m/s] CHECK if this should be smaller + +#include +#include +#include +#include +#include "src/eigen.h" + +extern FILE *matrix_test_file, *parms_test_file; +extern int matrix_test_count; +int mode, verbose, shape; + +#define a_latt 2.461 //PG lattice constant in AA; Nicklow1972 gives 2.45 (WHICH PAGE?) +#define c_latt 6.708 // PG lattice constant in AA; Nicklow1972 gives 6.70 +#define b_length 6.646 // PG scattering legth in fm + +double M = 12.011 * Da2kg; //atomic mass of C + +#define K_l1 3.62e+5 // Force constant longitudinal nn1 - in (a,b) plane; here units of dyn +#define K_t1 1.99e+5 // Force constant transverse nn1 - in (a,b) plane +#define K_l2 1.33e+5 // Force constant longitudinal nn2 - in (a,b) plane +#define K_t2 -0.520e+5 // Force constant transverse nn2 - in (a,b) plane +#define K_l3 -0.037e+5 // Force constant longitudinal nn3 - in (a,b) plane +#define K_t3 0.288e+5 // Force constant transverse nn3 - in (a,b) plane +#define K_l4 0.058e+5 // Force constant longitudinal nn4 - along c +#define K_t4 0.0077e+5 // Force constant transverse nn4 - along c + + //Lattice basis + + // PG is hexagonal close packed with 4 atoms per cell + // Coordinates from Nicklow1972, Fig. 7: Atoms A, B, C, D + double Delta[4*3] = {0 , 0 , 0 , a_latt/(2*sqrt3) , a_latt/2 , 0 , 0 , 0 , c_latt/2 , -a_latt/(2*sqrt3) , a_latt/2 , c_latt/2}; + + // Lattice vectors from paper fig. 7 + double avec[3] = {a_latt*sqrt3/2 , a_latt*0.5 , 0}; // THIS IS NEVER USED ??!! + double bvec[3] = {a_latt*(-sqrt3/2) , a_latt*0.5 , 0}; + double cvec[3] = {0 , 0 , c_latt}; + + // reciprocal lattice vectors + double astar = 4*PI/(sqrt3*a_latt); // length of reciprocal lattice vector a* + double cstar = 2*PI/c_latt; // length of reciprocal lattice vector c* + + // Rotation matrices + // m(12*i+j) = M(i,j) + double Rot120[3][3] = {{-0.5 , sqrt3/2 , 0} , {-sqrt3/2 , -0.5 , 0} , {0 , 0 , 1}}; + double Rot120_flat[9] = {-0.5 , sqrt3/2 , 0 , -sqrt3/2 , -0.5 , 0 , 0 , 0 , 1}; + double Rot60[3][3] = {{0.5 , sqrt3/2 , 0} , {-sqrt3/2 , 0.5 , 0} , {0 , 0 , 1}}; + double Rot120rev[3][3] = {{-0.5 , -sqrt3/2 , 0} , {sqrt3/2 , -0.5 , 0} , {0 , 0 , 1}}; //rotate -120 + double Rot60rev[3][3] = {{0.5 , -sqrt3/2 , 0} , {sqrt3/2 , 0.5 , 0} , {0 , 0 , 1}}; //rotate -60 + double Rot180[3][3] = {{-1, 0, 0}, {0, -1, 0}, {0, 0, 1}}; // rotate 180 or -180 +// double Rot5[3][3] = {{0.5 , sqrt3/2 , 0} , {-sqrt3/2 , 0.5 , 0} , {0 , 0 , 1}}; //rotate 60 +// double Rot5rev[3][3] = {{0.5 , -sqrt3/2 , 0} , {sqrt3/2 , 0.5 , 0} , {0 , 0 , 1}}; //rotate -60 + + //1st neighbour + +// double r_j1[3][3] = {{-a_latt/sqrt3 , 0 , 0} , {a_latt*0.5/sqrt3 , -a_latt*0.5 , 0} , {a_latt*0.5/sqrt3 , a_latt*0.5 , 0}}; // This holds from atoms A and D +// double r_j2[3][3] = {{a_latt/sqrt3 , 0 , 0} , {-a_latt*0.5/sqrt3 , a_latt*0.5 , 0} , {-a_latt*0.5/sqrt3 , -a_latt*0.5 , 0}}; // This holds from atoms B and C + + double Phi_nn1[3][3] = {{K_l1*dyn2N , 0 , 0} , {0 , K_t1*dyn2N , 0} , {0 , 0 , K_t1*dyn2N}}; + double Phi1[3][3] = {{K_l1*dyn2N , 0 , 0} , {0 , K_t1*dyn2N , 0} , {0 , 0 , K_t1*dyn2N}}; //Phi1 = Phi_nn1 + double Phi2[3][3]; + double Phi3[3][3]; + + //2nd neighbour +// double r_j11[9][3] = {{a_latt*(-1/sqrt3) , 0 , 0} , {a_latt*0.5/sqrt3 , a_latt*(-0.5) , 0} , {a_latt*0.5/sqrt3 , a_latt*0.5 , 0} , {0 , a_latt , 0} , {-a_latt*sqrt3/2 , a_latt/2 , 0} , {-a_latt*sqrt3/2 , -a_latt/2 , 0} , {0 , -a_latt , 0} , {a_latt*sqrt3/2 , -a_latt/2 , 0} , {a_latt*sqrt3/2 , a_latt/2 , 0}};//r_j1 + r_add +// double r_j21[9][3] = {{-a_latt*(-1/sqrt3) , -a_latt*0 , 0} , {-a_latt*0.5/sqrt3 , -a_latt*(-0.5) , 0} , {-a_latt*0.5/sqrt3 , -a_latt*0.5 , 0} , {0 , a_latt , 0} , {-a_latt*sqrt3/2 , a_latt/2 , 0} , {-a_latt*sqrt3/2 , -a_latt/2 , 0} , {0 , -a_latt , 0} , {a_latt*sqrt3/2 , -a_latt/2 , 0} , {a_latt*sqrt3/2 , a_latt/2 , 0}};//r_j2 + r_add + + double Phi_nn2[3][3] = {{K_t2*dyn2N , 0 , 0} , {0 , K_l2*dyn2N , 0} , {0 , 0 , K_t2*dyn2N}}; + double Phi4[3][3] = {{K_t2*dyn2N , 0 , 0} , {0 , K_l2*dyn2N , 0} , {0 , 0 , K_t2*dyn2N}}; + double Phi5[3][3]; + double Phi6[3][3]; + double Phi7[3][3]; + double Phi8[3][3]; + double Phi9[3][3]; + + //3rd neighbour +// double r_j12[12][3] = {{a_latt*(-1/sqrt3) , 0 , 0} , {a_latt*0.5/sqrt3 , a_latt*(-0.5) , 0} , {a_latt*0.5/sqrt3 , a_latt*0.5 , 0} , {0 , a_latt , 0} , {-a_latt*sqrt3/2 , a_latt/2 , 0} , {-a_latt*sqrt3/2 , -a_latt/2 , 0} , {0 , -a_latt , 0} , {a_latt*sqrt3/2 , -a_latt/2 , 0} , {a_latt*sqrt3/2 , a_latt/2 , 0} , {2*a_latt/sqrt3 , 0 , 0} , {-a_latt/sqrt3 , a_latt , 0} , {-a_latt/sqrt3 , -a_latt , 0}};//r_j11 + r_add2 + double r_j2[12][3] = {{a_latt/sqrt3 , 0 , 0} , {-a_latt*0.5/sqrt3 , a_latt*0.5 , 0} , {-a_latt*0.5/sqrt3 , -a_latt*0.5 , 0} , {0 , a_latt , 0} , {-a_latt*sqrt3/2 , a_latt/2 , 0} , {-a_latt*sqrt3/2 , -a_latt/2 , 0} , {0 , -a_latt , 0} , {a_latt*sqrt3/2 , -a_latt/2 , 0} , {a_latt*sqrt3/2 , a_latt/2 , 0} , {-2*a_latt/sqrt3 , 0 , 0} , {a_latt/sqrt3 , -a_latt , 0} , {a_latt/sqrt3 , a_latt , 0}};//r_j21 - r_add2 + + double Phi_nn3[3][3] = {{K_l3*dyn2N , 0 , 0} , {0 , K_t3*dyn2N , 0} , {0 , 0 , K_t3*dyn2N}}; + + // c2 = 2/sqrt(6); + // c1 = 1/sqrt(6); + // c0 = 1/sqrt(2); + // c3 = 1/sqrt(3); + + double Phi10[3][3] = {{K_l3*dyn2N , 0 , 0} , {0 , K_t3*dyn2N , 0} , {0 , 0 , K_t3*dyn2N}}; //Phi_nn3 + double Phi11[3][3]; + double Phi12[3][3]; + + //4th neighbour + double r_j13[14][3] = {{-a_latt/sqrt3 , 0 , 0} , {a_latt*0.5/sqrt3 , -a_latt*0.5 , 0} , {a_latt*0.5/sqrt3 , a_latt*0.5 , 0} , {0 , a_latt , 0} , {-a_latt*sqrt3/2 , a_latt/2 , 0} , {-a_latt*sqrt3/2 , -a_latt/2 , 0} , {0 , -a_latt , 0} , {a_latt*sqrt3/2 , -a_latt/2 , 0} , {a_latt*sqrt3/2 , a_latt/2 , 0} , {2*a_latt/sqrt3 , 0 , 0} , {-a_latt/sqrt3 , a_latt , 0} , {-a_latt/sqrt3 , -a_latt , 0} , {0 , 0 , c_latt/2} , {0 , 0 , -c_latt/2}};//r_j12 + r_add3 Sublattice B and D do not have this coupling + + double Phi_nn4[3][3] = {{K_t4*dyn2N , 0 , 0} , {0 , K_t4*dyn2N , 0} , {0 , 0 , K_l4*dyn2N}}; + + double Phi13[3][3] = {{K_t4*dyn2N , 0 , 0} , {0 , K_t4*dyn2N , 0} , {0 , 0 , K_l4*dyn2N}}; //Phi_nn4; + double Phi14[3][3] = {{K_t4*dyn2N , 0 , 0} , {0 , K_t4*dyn2N , 0} , {0 , 0 , K_l4*dyn2N}}; //Phi_nn4; + +// ----------------- END SPECIFIC FOR THE PG COPONENT -------------------------- + + + +/* TODO: Det er meget langsomt at bruge pointere. Erstat med flad memory. */ +// m(12*i+j) = M(i,j) +//3*3 matrices multiplication +void matrixmultiplication( double matrix1[3][3], double matrix2[3][3], double result[3][3]) + { + // multiplies matrix1 by matrix2 and places the result in result +// double matrix1[3][3]={{*(array1), *(array1+1), *(array1+2)}, {*(array1+3), *(array1+4), *(array1+5)}, {*(array1+6), *(array1+7), *(array1+8)}}; +// double matrix2[3][3]={{*(array2), *(array2+1), *(array2+2)}, {*(array2+3), *(array2+4), *(array2+5)}, {*(array2+6), *(array2+7), *(array2+8)}}; + + result[0][0]=matrix2[0][0]*matrix1[0][0]+matrix2[1][0]*matrix1[0][1]+matrix2[2][0]*matrix1[0][2]; + result[0][1]=matrix2[0][1]*matrix1[0][0]+matrix2[1][1]*matrix1[0][1]+matrix2[2][1]*matrix1[0][2]; + result[0][2]=matrix2[0][2]*matrix1[0][0]+matrix2[1][2]*matrix1[0][1]+matrix2[2][2]*matrix1[0][2]; + result[1][0]=matrix2[0][0]*matrix1[1][0]+matrix2[1][0]*matrix1[1][1]+matrix2[2][0]*matrix1[1][2]; + result[1][1]=matrix2[0][1]*matrix1[1][0]+matrix2[1][1]*matrix1[1][1]+matrix2[2][1]*matrix1[1][2]; + result[1][2]=matrix2[0][2]*matrix1[1][0]+matrix2[1][2]*matrix1[1][1]+matrix2[2][2]*matrix1[1][2]; + result[2][0]=matrix2[0][0]*matrix1[2][0]+matrix2[1][0]*matrix1[2][1]+matrix2[2][0]*matrix1[2][2]; + result[2][1]=matrix2[0][1]*matrix1[2][0]+matrix2[1][1]*matrix1[2][1]+matrix2[2][1]*matrix1[2][2]; + result[2][2]=matrix2[0][2]*matrix1[2][0]+matrix2[1][2]*matrix1[2][1]+matrix2[2][2]*matrix1[2][2]; + + return; + } + +// TODO: (James Avery) Benchmark against pointer versions: matrix3mupltiplication or matrixmultiplication +// m(12*i+j) = M(i,j) +void matrix3x3_multiply3(const double A[9], const double B[9], const double C[9], double result[9]) +{ + // R_{i,j} = \sum_{k,l=1}^3 A_{i,k}*B_{k,l}*C_{l,j} + for(int i=0;i<3;i++) + for(int j=0;j<3;j++){ + double ij_sum = 0; + for(int k=0;k<3;k++) + for(int l=0;l<3;l++) + ij_sum += A[i*3+k]*B[k*3+l]*C[l*3+j]; + result[i*3+j] = ij_sum; + } +} + +/* TODO: (James Avery) It is slow to use points. Replace with flat memory. */ + // m(12*i+j) = M(i,j) + // Counter argument: (Kim Lefmann) pointers are now only used in the initialization. In the TRACE code, memory is flat + void matrix3multiplication(double matrix1[3][3], double matrix2[3][3], double matrix3[3][3], double result[3][3]) + { + // Performs the multiplication (matrix1*matrix2)*matrix3 and placed the result in result +//#define TEST_MULTIPLY + double temp[3][3]; + matrixmultiplication(matrix1,matrix2,temp); + matrixmultiplication(temp,matrix3,result); +#ifdef TEST_MULTIPLY + printf("Matrix3multiply called with \n"); + printf("matrix1 = ("); + for (int i=0; i<3; i++) + { + printf("( %g %g %g), ",matrix1[i][0], matrix1[i][1], matrix1[i][2]); + } + printf(")\n Matrix2 = ("); + for (int i=0; i<3; i++) + { + printf("( %g %g %g), ",matrix2[i][0], matrix2[i][1], matrix2[i][2]); + } + printf(")\n Matrix3 = ("); + for (int i=0; i<3; i++) + { + printf("( %g %g %g), ",matrix3[i][0], matrix3[i][1], matrix3[i][2]); + } + printf(")\n Temp = ("); + for (int i=0; i<3; i++) + { + printf("( %g %g %g), ",temp[i][0], temp[i][1], temp[i][2]); + } + printf(")\n Result = ("); + for (int i=0; i<3; i++) + { + printf("( %g %g %g), ",result[i][0], result[i][1], result[i][2]); + } + printf(")\n"); +#endif // TEST_MULTIPLY + + return; + } + + +/* TODO: (James Avery) Replace by standard complex.h operation */ +complex complexexp_qdotr (double* q, double* rj) +{ +// double qrjtest + double qrj = *(q)**(rj)+*(q+1)**(rj+1)+*(q+2)**(rj+2); +// printf(" q= (%g %g %g), r = (%g %g %g) qrj = %g \n",q[0],q[1],q[2],rj[0],rj[1],rj[2],qrj); +// return (cexp(qrj)); // KL comment 030125 WHY does this not run? + return (cos(qrj)+I*sin(qrj)); +} + + +void initialize_omega_q() +{ + // Make the matrix algebra that finalizes the force constant set-up + + matrix3multiplication(Rot120,Phi_nn1,Rot120rev,Phi2); //Phi2=Rot120*Phi_nn1*Rot120^(-1) + matrix3multiplication(Rot120rev,Phi_nn1,Rot120,Phi3); //Phi3=Rot120^{-1}*Phi_nn1*Rot120 + matrix3multiplication(Rot60,Phi_nn2,Rot60rev,Phi5); //Phi5=Rot60*Phi_nn2*Rot60^{-1} + matrix3multiplication(Rot120,Phi_nn2,Rot120rev,Phi6); //Phi6=Rot120*Phi_nn2*Rot120^(-1); + matrix3multiplication(Rot180,Phi_nn2,Rot180,Phi7); //Phi7=Rot180*Phi_nn2*Rot180; + matrix3multiplication(Rot120rev,Phi_nn2,Rot120,Phi8); //Phi8=Rot120^{-1}*Phi_nn2*Rot120; + matrix3multiplication(Rot60rev,Phi_nn2,Rot60,Phi9); //Phi9=Rot60^{-1}*Phi_nn2*Rot60; + matrix3multiplication(Rot120,Phi_nn3,Rot120rev,Phi11);//Phi11=Rot120*Phi_nn3*Rot120^(-1); + matrix3multiplication(Rot120rev,Phi_nn3,Rot120,Phi12);//Phi12=Rot120^{-1}*Phi_nn3*Rot120; + + return; +} + +//---------------------------- START CENTRAL FUNCTION OMEGA-Q ---------------------------- + + double omega_q(complex* parms, complex* eigenvectorgood) { + + // _______________ DETERMINE Q ____________________________ + + double vi, vf, vv_x, vv_y, vv_z, vi_x, vi_y, vi_z; + double q, qx, qy, qz, Jq, hw_phonon, hw_neutron; + double h,k,l,hk_inplane, hk_outofplane; + int disp; + + for(int ii=0;ii<8;ii++) if(isnan(creal(parms[ii])) || isnan(cimag(parms[ii]))){ + fprintf(stderr,"omega_q: Array parms contains a nan at position %d.\n",ii); + fprintf(stderr,"parms = ["); for(int i=0;i<8;i++) fprintf(stderr,"%g + i%g%s",creal(parms[i]), cimag(parms[i]), i+1<8?", ":"]\n"); + abort(); + } + + vf=parms[0]; + vi=parms[1]; + vv_x=parms[2]; + vv_y=parms[3]; + vv_z=parms[4]; + vi_x=parms[5]; + vi_y=parms[6]; + vi_z=parms[7]; + h = parms[9]; + k = parms[10]; + l = parms[11]; + disp = (int)parms[12]; + + qx=V2K*(vi_x-vf*vv_x); + qy=V2K*(vi_y-vf*vv_y); + qz=V2K*(vi_z-vf*vv_z); + + if (disp==1) /* calculate dispersion directly */ + { + printf("Dispersion calculation: "); + qx = h*astar; + qy = k*astar; //correct only for qy=0 ! + qz = l*cstar; + } + + double qvec[3]={qx,qy,qz}; + + if (verbose>=4) + printf("Enter omega_q; q = (%g, %g, %g) \n",qx,qy,qz); + + // ________________ END DETERMINE Q ________________- + + + complex Phi_diag[3*3]; + int i; + int j; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + Phi_diag[i*3+j] = Phi1[i][j]+Phi2[i][j]+Phi3[i][j]+Phi4[i][j]*(1-(*complexexp_qdotr)(&qvec[0], &r_j13[3][0]))+Phi5[i][j]*(1-(*complexexp_qdotr)(&qvec[0], &r_j13[4][0]))+Phi6[i][j]*(1-(*complexexp_qdotr)(&qvec[0], &r_j13[5][0]))+Phi7[i][j]*(1-(*complexexp_qdotr)(&qvec[0], &r_j13[6][0]))+Phi8[i][j]*(1-(*complexexp_qdotr)(&qvec[0], &r_j13[7][0]))+Phi9[i][j]*(1-(*complexexp_qdotr)(&qvec[0], &r_j13[8][0]))+Phi10[i][j]+Phi11[i][j]+Phi12[i][j]; + } + } + + complex Phi_diag1[3*3]; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + Phi_diag1[i*3+j] = Phi13[i][j]+Phi14[i][j]; + } + } + + complex Phi_offdiag1[3*3]; + complex Phi_offdiag2[3*3]; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + Phi_offdiag1[i*3+j] =-Phi1[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[0][0]))-Phi2[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[1][0]))-Phi3[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[2][0]))-Phi10[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[9][0]))-Phi11[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[10][0]))-Phi12[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[11][0])); + Phi_offdiag2[i*3+j] = conj(Phi_offdiag1[i*3+j]); + } + } + + complex Phi_6Dim[6*6]; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + Phi_6Dim[i*6+j] = Phi_diag[i*3+j]+Phi_diag1[i*3+j]; + Phi_6Dim[i*6+j+3] = Phi_offdiag1[i*3+j]; + Phi_6Dim[(i+3)*6+j] = Phi_offdiag2[i*3+j]; + Phi_6Dim[(i+3)*6+j+3] = Phi_diag[i*3+j]; // Because Phi_diag1 does not appear for the B,C, sublattices + } + } + + complex Phi_AC[3*3]; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + Phi_AC[i*3+j] = -Phi13[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[12][0]))-Phi14[i][j]*((*complexexp_qdotr)(&qvec[0], &r_j13[13][0])); + } + } + +// complex Zero_3Dim[3][3] = {{0 , 0 , 0},{0 , 0 , 0},{0 , 0 , 0}}; + + complex Phi_6Dim_offdiag[6*6]; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + Phi_6Dim_offdiag[i*6+j] = Phi_AC[i*3+j]; + Phi_6Dim_offdiag[i*6+j+3] = (complex)0.0; + Phi_6Dim_offdiag[(i+3)*6+j] = (complex)0.0; + Phi_6Dim_offdiag[(i+3)*6+j+3] = (complex)0.0; + } + } + + complex Phi_12Dim[12*12]; + for (i = 0; i < 6; i++) { + for (j = 0; j < 6; j++) { + Phi_12Dim[i*DIM+j] = Phi_6Dim[i*6+j]; + Phi_12Dim[i*DIM+j+6] = Phi_6Dim_offdiag[i*6+j]; + Phi_12Dim[(i+6)*DIM+j] = conj(Phi_6Dim_offdiag[i*6+j]); + Phi_12Dim[(i+6)*DIM+j+6] = Phi_6Dim[i*6+j]; + } + } + +#ifdef TEST_MATRICES + printf("Phi_12Dim=\n"); + for (i = 0; i < 12; i++) { + for (j = 0; j< 12; j++) { + if (j == 0) { + printf("{"); + } + printf("%g+(%g)i ", creal(Phi_12Dim[i*DIM+j]) , cimag((Phi_12Dim[i*DIM+j]))); + if (j == 11) { + printf("}\n"); + } + } + } + + printf("Phi_6Dim=\n"); + for (i = 0; i < 6; i++) { + for (j = 0; j< 6; j++) { + if (j == 0) { + printf("{"); + } + printf("%g+(%g)i ", creal(Phi_6Dim[i*6+j]) , cimag((Phi_6Dim[i*6+j]))); + if (j == 5) { + printf("}\n"); + } + } + } + + printf("Phi_diag=\n"); + for (i = 0; i < 3; i++) { + for (j = 0; j< 3; j++) { + if (j == 0) { + printf("{"); + } + printf("%g+(%g)i ", creal(Phi_diag[i*3+j]) , cimag((Phi_diag[i*3+j]))); + if (j == 2) { + printf("}\n"); + } + } + } + printf("Phi2={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}}\n",Phi2[0][0],Phi2[0][1],Phi2[0][2],Phi2[1][0],Phi2[1][1],Phi2[1][2],Phi2[2][0],Phi2[2][1],Phi2[2][2]); + printf("Phi3={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi3[0][0],Phi3[0][1],Phi3[0][2],Phi3[1][0],Phi3[1][1],Phi3[1][2],Phi3[2][0],Phi3[2][1],Phi3[2][2]); + printf("Phi5={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi5[0][0],Phi5[0][1],Phi5[0][2],Phi5[1][0],Phi5[1][1],Phi5[1][2],Phi5[2][0],Phi5[2][1],Phi5[2][2]); + printf("Phi6={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi6[0][0],Phi6[0][1],Phi6[0][2],Phi6[1][0],Phi6[1][1],Phi6[1][2],Phi6[2][0],Phi6[2][1],Phi6[2][2]); + printf("Phi7={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi7[0][0],Phi7[0][1],Phi7[0][2],Phi7[1][0],Phi7[1][1],Phi7[1][2],Phi7[2][0],Phi7[2][1],Phi7[2][2]); + printf("Phi8={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi8[0][0],Phi8[0][1],Phi8[0][2],Phi8[1][0],Phi8[1][1],Phi8[1][2],Phi8[2][0],Phi8[2][1],Phi8[2][2]); + printf("Phi9={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi9[0][0],Phi9[0][1],Phi9[0][2],Phi9[1][0],Phi9[1][1],Phi9[1][2],Phi9[2][0],Phi9[2][1],Phi9[2][2]); + printf("Phi11={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi11[0][0],Phi11[0][1],Phi11[0][2],Phi11[1][0],Phi11[1][1],Phi11[1][2],Phi11[2][0],Phi11[2][1],Phi11[2][2]); + printf("Phi12={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi12[0][0],Phi12[0][1],Phi12[0][2],Phi12[1][0],Phi12[1][1],Phi12[1][2],Phi12[2][0],Phi12[2][1],Phi12[2][2]); + printf("Phi14={{%lf,%lf,%lf},{%lf,%lf,%lf},{%lf,%lf,%lf}\n}",Phi14[0][0],Phi14[0][1],Phi14[0][2],Phi14[1][0],Phi14[1][1],Phi14[1][2],Phi14[2][0],Phi14[2][1],Phi14[2][2]); + + printf(" 1-exp(q.r_j13[3]) = %lf + i %lf \n",creal(1-(*complexexp_qdotr)(&qvec[0], &r_j13[3][0])),cimag(1-(*complexexp_qdotr)(&qvec[0], &r_j13[3][0]))); + printf(" 1-exp(q.r_j13[4]) = %lf + i %lf \n",creal(1-(*complexexp_qdotr)(&qvec[0], &r_j13[4][0])),cimag(1-(*complexexp_qdotr)(&qvec[0], &r_j13[4][0]))); + printf(" 1-exp(q.r_j13[5]) = %lf + i %lf \n",creal(1-(*complexexp_qdotr)(&qvec[0], &r_j13[5][0])),cimag(1-(*complexexp_qdotr)(&qvec[0], &r_j13[5][0]))); + printf(" 1-exp(q.r_j13[6]) = %lf + i %lf \n",creal(1-(*complexexp_qdotr)(&qvec[0], &r_j13[6][0])),cimag(1-(*complexexp_qdotr)(&qvec[0], &r_j13[6][0]))); + printf(" 1-exp(q.r_j13[7]) = %lf + i %lf \n",creal(1-(*complexexp_qdotr)(&qvec[0], &r_j13[7][0])),cimag(1-(*complexexp_qdotr)(&qvec[0], &r_j13[7][0]))); + printf(" 1-exp(q.r_j13[8]) = %lf + i %lf \n",creal(1-(*complexexp_qdotr)(&qvec[0], &r_j13[8][0])),cimag(1-(*complexexp_qdotr)(&qvec[0], &r_j13[8][0]))); + +#endif // TEST_MATRICES + + double eigenvalue[DIM]; + complex Q[DIM*DIM]; + complex matrix[DIM*DIM]; + int index[DIM]; + + + for (i=0; i= 6) + { + printf("Before bubblesort\n"); + for (i=0; i= 5) + { + printf("After bubblesort\n"); + for (i=0; i=7) + { + printf("Q = ["); + for (i = 0; i < DIM ; i++) + { + printf("\n ("); + for (j=0; j=5) + { + printf("Diagonalization done, eigenvalues (energies) are: \n ("); + for (i=0; i= 4){ + printf("Return from omega_q \n"); + printf("hw_neutron = %g (vi = %g, vf = %g)\n",hw_neutron, vi, vf); + printf("hw_phonon = %g = eigenvaluegood[%d] = %g = eigenvalues[%d] = %g\n", + hw_phonon,mode,eigenvaluegood[mode],index[mode], eigenvalue[index[mode]]); +// printf("old parms = ["); for(int i=0;i<8;i++) fprintf(stderr,"%g+i%g%s",creal(parms[i]), cimag(parms[i]), i+1<8?", ":"]\n"); + } + + parms[8] = hw_phonon; + + if (disp==1) { + printf("mode = %d, (h,k,l) = (%g,%g,%g), hw_q = %g",mode,h,k,l,hw_phonon); + printf(" polarization: ( "); + for (j = 0; j < DIM; j++) + { + printf("%g + i %g ,",creal(eigenvectorgood[j]),cimag(eigenvectorgood[j])); + } + printf(")\n"); + } + if (disp==2) { + hk_inplane = qx/astar; + hk_outofplane = qy/astar; // Derivation assume astar along x and 60 degrees between astar and bstar: + // h_ip = h + k/2 h_op = sqrt(3)*k/2 => k = 2/sqrt(3)*h_op h = h_ip - h_op/sqrt(3) + k = 2/sqrt(3)*hk_outofplane; + h = hk_inplane - hk_outofplane/sqrt(3); + l = qz/cstar; + printf("mode = %d, vf = %g, (h,k,l) = (%g,%g,%g), hw_q = %g",mode,vf,h,k,l,hw_phonon); + printf(" polarization: (%g + i %g , %g + i %g , %g + i %g) \n",creal(eigenvectorgood[0]),cimag(eigenvectorgood[0]),creal(eigenvectorgood[1]),cimag(eigenvectorgood[1]), creal(eigenvectorgood[2]),cimag(eigenvectorgood[2])); + } + + return (hw_phonon - hw_neutron); +} + +//--------------------- END CENTRAL FUNCTION OMEGA-Q ------------------------ + +// ------------------START OF THE GENERAL ROOT-FINDING CODE-------------------- + +double last_fh, last_x2; +double zridd(double (*func)(complex*,complex*), double x1, double x2, complex *parms, complex* vector, double xacc) + { + int j; + double ans, fh, fl, fm, fnew, s, xh, xl, xm, xnew; + + // fprintf(stderr,"i zridd(%g,%g, parms,%g)\n",x1,x2,xacc); + parms[0]=x1; + // fprintf(stderr,"zridd fl = omega_q\n"); + if (xacc>0) + { + fl=(*func)(parms,vector); + } + else + { + fl = last_fh; + xacc = -xacc; + if (fabs(x1-last_x2)>xacc) // KL comment 030125 WHY does the library routine zridd use complex abs() function ?? changed to fabs() + printf("*** error in zridd *** x1: %g last_x2: %g \n",x1,last_x2); + } + // fprintf(stderr,"fl = %g\n",fl); + parms[0]=x2; + // fprintf(stderr,"zridd fh = omega_q; parms[0] = x2 = %g+i%g = %g\n",creal(parms[0]), cimag(parms[0]),x2); + last_fh=fh=(*func)(parms,vector); + last_x2 = x2; + // fprintf(stderr,"fh = %g\n",fh); + if (fl*fh >= 0) + { + if (fl==0) return x1; + if (fh==0) return x2; + return UNUSED; + } + else + { + xl=x1; + xh=x2; +// printf("zridd sign change: v_low : %g v_high: %g \n",xl,xh); + ans=UNUSED; + for (j=1; j= fh ? 1.0 : -1.0)*fm/s); + if (fabs(xnew-ans) <= xacc) + return ans; + ans=xnew; + parms[0]=ans; + // fprintf(stderr,"s = %g; fl, fm, fh = %g,%g,%g; fnew = %g; fm*fm-fl*fh = %g\n", + // s, fl, fm,fh, fnew, fm*fm-fl*fh); + //fprintf(stderr,"zridd fnew = omega_q\n"); + fnew=(*func)(parms,vector); + if (fnew == 0.0) return ans; + if (fabs(fm)*SIGN(fnew) != fm) + { + xl=xm; + fl=fm; + xh=ans; + fh=fnew; + } + else + if (fabs(fl)*SIGN(fnew) != fl) + { + xh=ans; + fh=fnew; + } + else + if(fabs(fh)*SIGN(fnew) != fh) + { + xl=ans; + fl=fnew; + } + else + fatalerror("never get here in zridd"); + if (fabs(xh-xl) <= xacc) + return ans; + } + fatalerror("zridd exceeded maximum iterations"); + } + return 0.0; /* Never get here */ + } + +#pragma acc routine +double zridd_gpu(double x1, double x2, complex *parms, complex* vector, double xacc) + { + int j; + double ans, fh, fl, fm, fnew, s, xh, xl, xm, xnew; + + parms[0]=x1; + // fprintf(stderr,"fl=omega_q(%g+i%g)\n",creal(parms[0]),cimag(parms[0])); + fl=omega_q(parms,vector); + parms[0]=x2; + // fprintf(stderr,"fh=omega_q(%g+i%g)\n",creal(parms[0]),cimag(parms[0])); + fh=omega_q(parms,vector); + if (fl*fh >= 0) + { + if (fl==0) return x1; + if (fh==0) return x2; + return UNUSED; + } + else + { + xl=x1; + xh=x2; + ans=UNUSED; + for (j=1; j= fh ? 1.0 : -1.0)*fm/s); + if (fabs(xnew-ans) <= xacc) + return ans; + ans=xnew; + parms[0]=ans; + // fprintf(stderr,"fnew=omega_q(%g+i%g)\n",creal(parms[0]),cimag(parms[0])); + fnew=omega_q(parms,vector); + if (fnew == 0.0) return ans; + if (fabs(fm)*SIGN(fnew) != fm) + { + xl=xm; + fl=fm; + xh=ans; + fh=fnew; + } + else + if (fabs(fl)*SIGN(fnew) != fl) + { + xh=ans; + fh=fnew; + } + else + if(fabs(fh)*SIGN(fnew) != fh) + { + xl=ans; + fl=fnew; + } + else + fatalerror("never get here in zridd"); + if (fabs(xh-xl) <= xacc) + return ans; + } + fatalerror("zridd exceeded maximum iterations"); + } + return 0.0; /* Never get here */ + } + +#define ROOTACC 1e-8 + + int findroots(double brack_low, double brack_mid, double brack_high, double *list, int* index, double (*f)(complex*,complex*), complex *parms, complex* vector, int low_steps, int high_steps) + // *f is here omega_q + // *parms is here p_call + { + double root,range; + int i; + + if (verbose==2) + printf("Enter findroots() \n"); + + // First, find roots in energy loss side, if any + range = brack_mid-brack_low; + for (i=0; i<(low_steps-1); i++) + { + if (i==0) + root = zridd(f, brack_low+range*i/low_steps, + brack_low+range*(i+1)/low_steps, + (complex *)parms, (complex *)vector, ROOTACC); + else + root = zridd(f, brack_low+range*i/low_steps, + brack_low+range*(i+1)/low_steps, + (complex *)parms, (complex *)vector, -ROOTACC); // Re-use the previous fh value + if (root != UNUSED) + { + list[(*index)++]=root; + if (verbose >=4) + printf("--- findroots returned a root on the energy loss side: vf = %g \n",root); + } + } + + range = (brack_mid-brack_low)/(double)low_steps; + for (i=0; i=4) + printf("--- findroots returned a root on the energy loss side: vf = %g \n",root); + } + } + + // Second, find roots in energy gain side, there is always some + range = (brack_high-brack_mid)/(double)high_steps; + for (i=0; i= 4) + printf("*** findroots returned a root on the energy gain side: vf = %g \n",root); + } + } + + range = brack_high-brack_mid; + for (i=1; i= 4) + printf("*** findroots returned a root on the energy gain side: vf = %g \n",root); + } + } + + } + +#pragma acc routine + int findroots_gpu(double brack_low, double brack_mid, double brack_high, double *list, int* index, double *parms, complex* vector, int low_steps, int high_steps) + { + double root,range=brack_mid-brack_low; + int i; + + for (i=0; i 0 && yheight) shape=0; /* cylinder */ + + + V_rho = 1/(a_latt*a_latt*c_latt*sqrt3/2); // (unit: Å^-3) + V_my_s = (V_rho * 100 * sigma_inc); + V_my_a_v = (V_rho * 100 * sigma_abs * 2200); + + /* now compute target coords if a component index is supplied */ + if (!target_index && !target_x && !target_y && !target_z) target_index=1; + if (target_index){ + Coords ToTarget; + ToTarget = coords_sub(POS_A_COMP_INDEX(INDEX_CURRENT_COMP+target_index), POS_A_CURRENT_COMP); + ToTarget = rot_apply(ROT_A_CURRENT_COMP, ToTarget); + coords_get(ToTarget, &target_x, &target_y, &target_z); + } + if (!(target_x || target_y || target_z)) { + printf("Phonon_BkV_PG: %s: The target is not defined. Using direct beam (Z-axis).\n", + NAME_CURRENT_COMP); + target_z=1; + } + initialize_omega_q(); + verbose = verbose_input; + + // m(12*i+j) = M(i,j) + // OK for: Rot120 + for (i=0; i<3; i++) + for (j=0; j<3; j++) + { + printf("i,j: %i, %i ROT120: %g ROT120FLAT; %g \n",i,j,Rot120[i][j],Rot120_flat[3*i+j]); + } + %} + +TRACE +%{ + double t0, t1, t2, t3; /* Entry/exit times for shape */ + double v_i, v_f; /* Neutron velocities: initial, final */ + double vx_i, vy_i, vz_i; /* Neutron initial velocity vector */ + double dt0, dt; /* Flight times through sample */ + double l_full; /* Flight path length for non-scattered neutron */ + double l_i, l_o; /* Flight path lenght in/out for scattered neutron */ + double my_a_i; /* Initial attenuation factor */ + double my_a_f; /* Final attenuation factor */ + double solid_angle; /* Solid angle of target as seen from scattering point */ + double aim_x=0, aim_y=0, aim_z=1; /* Position of target relative to scattering point */ + double omega; /* Energy transfer */ + double qsquare; /* Square of the scattering vector */ + double bose_factor; /* Calculated value of the Bose factor */ + int nf, index; /* Number of allowed final velocities */ + double vf_list[20]; /* List of allowed final velocities */ + double J_factor, J0; /* Jacobian from delta fnc.s in cross section; elastic J-factor */ + double f1, f2; /* Probed values of omega_q minus omega */ + double p_att,p_MC,p_ph1,p_ph2,p_ph3,p_J, p_tot; /* Temporary multipliers */ + complex Gn; /* Phonon structure factor */ + complex q_dot_e; /* q dot e */ + double q_dot_r; /* q dot r */ + double qh,qk,ql,qhkx,qhky,qh_Bragg,qk_Bragg,ql_Bragg,qh_res,qk_res,qh_add,qk_add; /* components of q */ + double dist_00, dist_01, dist_10, dist_11, dist_min; /* used to calculate nearest Bragg point */ + int i,j, intersect; + + if (shape == 0) + intersect = cylinder_intersect(&t0, &t3, x, y, z, vx, vy, vz, radius, yheight); + else if (shape == 1) + intersect = box_intersect(&t0, &t3, x, y, z, vx, vy, vz, xwidth, yheight, zdepth); + + if(intersect) + { + // fprintf(stderr,"intersect\n"); + if(t0 < 0) + ABSORB; /* Neutron came from the sample or begins inside */ + + if (verbose>=2) + printf("neutron entered Phonon_BvK_PG \n"); + /* Neutron enters at t=t0. */ + dt0 = t3-t0; /* Time in sample */ + v_i = sqrt(vx*vx + vy*vy + vz*vz); + l_full = v_i * dt0; /* Length of path through sample if not scattered */ + dt = rand01()*dt0; /* Time of scattering (relative to t0) */ + l_i = v_i*dt; /* Penetration in sample at scattering */ + vx_i=vx; + vy_i=vy; + vz_i=vz; + PROP_DT(dt+t0); /* Point of scattering */ + + aim_x = target_x-x; /* Vector pointing at target (e.g. analyzer) */ + aim_y = target_y-y; + aim_z = target_z-z; + + if(focus_aw && focus_ah) { + randvec_target_rect_angular(&vx, &vy, &vz, &solid_angle, + aim_x, aim_y, aim_z, focus_aw, focus_ah, ROT_A_CURRENT_COMP); + } else if(focus_xw && focus_yh) { + randvec_target_rect(&vx, &vy, &vz, &solid_angle, + aim_x, aim_y, aim_z, focus_xw, focus_yh, ROT_A_CURRENT_COMP); + } else { + randvec_target_sphere(&vx,&vy,&vz,&solid_angle,aim_x,aim_y,aim_z, focus_r); + } + NORM(vx, vy, vz); + nf=0; + if (mode_input == 12) + mode = round(12*rand01()-0.5); // Select the phonon mode + else + mode = mode_input; // Use the given mode + if ((mode < 0) || (mode > 11)) // Undefined mode specification + { + printf("mode = %d ",mode); + nrerror("illegal value of mode"); + } + + p_call[0]=-1; // in the end this will be v_f + p_call[1]=v_i; + p_call[2]=vx; + p_call[3]=vy; + p_call[4]=vz; + p_call[5]=vx_i; + p_call[6]=vy_i; + p_call[7]=vz_i; + p_call[9]=hh; + p_call[10]=kk; + p_call[11]=ll; + p_call[12] = (double)dispersion; + + if (dispersion==1) + { + f1=omega_q(p_call,eigenvectormode); + p_call[12]=0.0; + } + +/* if (dispersion==2) + { + for(i=0; i=2) + printf("Call findroots \n"); + findroots(0, v_i, v_i+V_HIGH, vf_list, &nf, omega_q, p_call, eigenvectormode, e_steps_low, e_steps_high); + if (verbose >=2) + printf( "Findroots returned %d roots \n",nf); + #else + findroots_gpu(0, v_i, v_i+V_HIGH, vf_list, &nf, p_call, eigenvectormode, e_steps_low, e_steps_high); + #endif + + if (verbose>=3) + { + printf("Findroots done, mode %i , last phonon energy %g \n",mode,creal(p_call[8])); + } + + // ________________ ALL FROM HERE IS CALCULATION OF INTENSITY - SHOULD BE REVISITED ___________________ + + index=(int)floor(rand01()*nf); // Select random solution + v_f=vf_list[index]; + p_call[0]=v_f; // transfer choice of v_f to omega_q + + f1=omega_q(p_call,eigenvectormode); + if (verbose >= 2) + { + printf("Chosen solution is %i; v_f = %g, hw = %g, energy match is %g; eigenvector is: (", index, v_f, creal(p_call[8]), f1); + for (j=0; j= 3) + { + printf("q transforms in r.l.u to (h, k, l) = (%g, %g, %g). Nearest Bragg point: (%g, %g, %g)\n",qh,qk,ql,qh_Bragg,qk_Bragg,ql_Bragg); + printf("--------------------------------------------\n"); + } + + + if (dispersion==1) + printf("Dispersion found: (h,k,l) = (%g, %g, %g), hw = %g \n",q[0]/astar,q[1]/astar,q[2]/cstar,omega); + + qsquare=1; + Gn = 0; + + double q_Bragg[3]; // Bragg point in Å-1; Cartesian coordinates + q_Bragg[0]=qh_Bragg*astar+qk_Bragg*astar/2.0; + q_Bragg[1]=qk_Bragg*astar*2.0/sqrt3; + q_Bragg[2]=ql_Bragg*cstar; + + for (i=0; i<4; i++) // Calculate phonon structure factor; loop over atoms in unit cell + { + q_dot_e = (complex)0; + q_dot_r = 0; + for (j=0; j<3; j++) // loop over x,y,z + { + q_dot_e += (complex)q[j]*eigenvectormode[3*i+j]; + q_dot_r += q_Bragg[j]*Delta[3*i+j]; + } + if (verbose >= 7) + { + printf("i = %i , q dot r = %g , q dot e = (%g + i %g) Fn contrib = (%g + i %g)",i,q_dot_r,creal(q_dot_e),cimag(q_dot_e),creal(b_length*q_dot_e*cexp(I*q_dot_r)),cimag(b_length*q_dot_e*cexp(I*q_dot_r))); + } + Gn += b_length*q_dot_e*cexp(I*q_dot_r); // Unit fm Å-1 ; for the general lattice, this should be divided by sqrt(mass[j]) + } + if (verbose >= 7) + printf("\n"); + + if (shape == 0) + intersect = cylinder_intersect(&t0, &t3, x, y, z, vx, vy, vz, radius, yheight); + else if (shape == 1) + intersect = box_intersect(&t0, &t3, x, y, z, vx, vy, vz, xwidth, yheight, zdepth); + + if(!intersect) + { + printf("FATAL ERROR: Did not hit sample surface from inside.\n"); + exit(1); + } + + if (verbose>=2) + printf("neutron left Phonon_BvK_PG, p_init = %g,",p); + + dt = t3; + l_o = v_f*dt; + my_a_i = V_my_a_v/v_i; + my_a_f = V_my_a_v/v_f; + bose_factor=nbose(omega,T); + J0 = hbar*hbar*v_f*V2K*1E10/mn; // The J-factor for a flat mode + + + p_att = exp(-(V_my_s*(l_i+l_o)+my_a_i*l_i+my_a_f*l_o)); /* Absorption factor (units: 1) */ + p_MC = nf*solid_angle*l_full; /* Focusing factors; assume random choice of n_f possibilities (units: m) */ + if (mode_input == 12) + p_MC *= 12; //The factor 12 is due to MC choice between the 12 modes + p_ph1 = (v_f/v_i)*DW*bose_factor*V_rho*1E30; /* Cross section factor 1 (units: m^-3) */ + p_ph2 = hbar*hbar/(2*(fabs(omega)*1.6022E-22)); /* Jacobian of delta functions in cross section; and constants. Units: J s^2 */ + p_ph3 = (Gn*conj(Gn))*1E-10/M; /* Structure factor. (units: kg^-1) */ + p_J = J0/J_factor; + p_tot = p_att*p_MC*p_ph1*p_ph2*p_ph3*p_J; + p *= p_tot; + + if (verbose>=2) { + printf("nf = %d, solid_angle = %g, l_full = %g \n",nf,solid_angle,l_full); + printf("(p in SI units): p_att = %g, p_MC= %g, p_ph1 = %g, p_ph2 = %g, p_ph3 = %g, p_J = %g, bose_factor = %g, V_rho = %g, J_factor/J0 = %g, G_factor = %g +i %g, conj(G) = %g + I %g, |G|^2 = %g + I %g, ",p_att, p_MC, p_ph1, p_ph2, p_ph3, p_J, bose_factor, V_rho, J_factor/J0, creal(Gn), cimag(Gn), creal(conj(Gn)), cimag(conj(Gn)), creal(Gn*conj(Gn)), cimag(Gn*conj(Gn)) ); + printf(" p_tot = %g, p_final = %g\n",p_tot, p) ; + printf("q is (h,k,l) = (%g, %g, %g) \n",q_x/astar,q_y/astar,q_z/cstar); + } + } /* else transmit: Neutron did not hit the sample */ +%} + +MCDISPLAY +%{ + if (radius > 0 && yheight) { /* cylinder */ + cylinder(0,0,0,radius,yheight,0, 0, 1, 0); + } + else if (xwidth && yheight) { /* box/rectangle */ + box(0,0,0,xwidth,yheight,zdepth, 0, 0, 1, 0); + } +// circle("xz", 0, yheight/2.0, 0, radius); +// circle("xz", 0, -yheight/2.0, 0, radius); +// line(-radius, -yheight/2.0, 0, -radius, +yheight/2.0, 0); +// line(+radius, -yheight/2.0, 0, +radius, +yheight/2.0, 0); +// line(0, -yheight/2.0, -radius, 0, +yheight/2.0, -radius); +// line(0, -yheight/2.0, +radius, 0, +yheight/2.0, +radius); +%} + +END diff --git a/mcstas-comps/examples/ESS/KVASIR/KVASIRscript.ipynb b/mcstas-comps/examples/ESS/KVASIR/KVASIRscript.ipynb new file mode 100755 index 000000000..b2caf7bbe --- /dev/null +++ b/mcstas-comps/examples/ESS/KVASIR/KVASIRscript.ipynb @@ -0,0 +1,414 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import mcstasscript as ms # type: ignore\n", + "\n", + "configurator = ms.Configurator()\n", + "configurator.set_mcrun_path(\"/Applications/McStas-3.2.app/Contents/Resources/mcstas/3.2/bin\")\n", + "configurator.set_mcstas_path(\"/Applications/McStas-3.2.app/Contents/Resources/mcstas/3.2\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "KVASIR = ms.McStas_instr(\"KVASIR\")\n", + "#EXAMPLE: interated intensity on detector when running vanadium as sample: 0.0268478\n", + "t = KVASIR.add_parameter(\"t\", value=0) # Wedge no. (330 total to cover 0-170deg)\n", + "\n", + "l_analyzers =[2.5035035035035036, 2.5105105105105103, 2.5175175175175175, 2.5245245245245247, 2.5305305305305303, 2.5375375375375375, 2.5435435435435436, 2.5505505505505504, 2.5565565565565564, 2.5625625625625625, 2.5695695695695697, 2.5755755755755754, 2.5815815815815815, 2.5875875875875876, 2.5925925925925926, 2.5985985985985987, 2.6046046046046047, 2.6096096096096097, 2.6156156156156154, 2.6206206206206204, 2.6266266266266265, 2.6316316316316315, 2.6366366366366365, 2.6416416416416415, 2.6466466466466465, 2.6516516516516515, 2.6566566566566565, 2.6616616616616615, 2.6656656656656654, 2.6706706706706704, 2.674674674674675, 2.67967967967968, 2.6836836836836837, 2.6886886886886887, 2.6926926926926926, 2.6966966966966965, 2.7007007007007005, 2.704704704704705, 2.7087087087087087, 2.7127127127127126, 2.7157157157157155, 2.71971971971972, 2.7237237237237237, 2.7267267267267266, 2.7307307307307305, 2.7337337337337337, 2.736736736736737, 2.7407407407407405, 2.7437437437437437, 2.746746746746747, 2.74974974974975, 2.7527527527527527, 2.754754754754755, 2.7577577577577577, 2.7607607607607605, 2.7637637637637638, 2.7657657657657655, 2.7687687687687688, 2.7707707707707705, 2.7727727727727727, 2.7757757757757755, 2.7777777777777777, 2.77977977977978, 2.781781781781782, 2.7837837837837838, 2.7857857857857855, 2.7877877877877877, 2.78978978978979, 2.7907907907907905, 2.7927927927927927, 2.793793793793794, 2.7957957957957955, 2.796796796796797, 2.798798798798799, 2.7997997997998, 2.8008008008008005, 2.801801801801802, 2.8028028028028027, 2.804804804804805, 2.804804804804805] #array containg nummerical solution for distance from sample to n'th analyzer in wedge\n", + "\n", + "N_analyzer =60 #1 total number of analyzers\n", + "width = 0.0127 #m width of He3 tubes, height of analyzer crystals\n", + "dt = 2*np.arcsin(width/(2*2.5))*180/np.pi #deg vertical angle between each analyzer crystal seen from sample position\n", + "theta = np.linspace(-dt/2,-dt*N_analyzer-dt/2, N_analyzer) #deg array containg rotations" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# PARAMETERS\n", + "width= KVASIR.add_declare_var(\"double\", \"width\", value=0.0127) #m width of He3 tubes, height of analyzer crystals\n", + "d_PG= KVASIR.add_declare_var(\"double\", \"d_PG\", value=3.355) #Å lattice spacing og pyrolytic graphite\n", + "u = KVASIR.add_declare_var(\"double\",\"u\", value=1e-5) #1 small number\n", + "h_D = KVASIR.add_declare_var(\"double\", \"h_D\", value=0.4) #m heigt of detector \n", + "\n", + "Ef = KVASIR.add_declare_var(\"double\",\"Ef\", value=1.95) #meV focusing energy \n", + "d_AD = KVASIR.add_declare_var(\"double\",\"d_AD\", value=1.25) #m distance from analyzer to detactor\n", + "d_SA = KVASIR.add_declare_var(\"double\",\"d_SA\", value=2.5) #m distance from sample to central analyzer\n", + "d_GS = KVASIR.add_declare_var(\"double\",\"d_GS\", value=0.58) #m distance from guide end to sample position\n", + "\n", + "lamda_f = KVASIR.add_declare_var(\"double\", \"lambda_f\") #Å final wavelenght\n", + "KVASIR.append_initialize(\"lambda_f=1/(0.11056*sqrt(Ef));\")\n", + "\n", + "#ANALYZER CALCULATION\n", + "tA = KVASIR.add_declare_var(\"double\", \"tA\") #deg Bragg angle of analyzer\n", + "KVASIR.append_initialize(\"tA=asin(lambda_f/(2*d_PG))*RAD2DEG;\")\n", + "\n", + "dtS = KVASIR.add_declare_var(\"double\", \"dtS\", value=[*theta], array = len(theta)) #deg array containg rotations\n", + "\n", + "len = KVASIR.add_declare_var(\"double\", \"len\", value=l_analyzers, array = len(l_analyzers)) #array containg nummerical solution for distance from sample to n'th analyzer in wedge\n", + "\n", + "#DETECTOR CALCULATION\n", + "d_SDz = KVASIR.add_declare_var(\"double\", \"d_SDz\") #m vetical distance from scattering plane to center of detector\n", + "KVASIR.append_initialize(\"d_SDz=d_SA+d_AD*cos(2*tA*DEG2RAD);\")\n", + "\n", + "d_SDy = KVASIR.add_declare_var(\"double\", \"d_SDy\") #m distance from sample to detector in scattering plane\n", + "KVASIR.append_initialize(\"d_SDy=d_AD*sin(2*tA*DEG2RAD);\")\n", + "\n", + "tDy= KVASIR.add_declare_var(\"double\", \"tDy\") #deg horizontal angle between wedges \n", + "KVASIR.append_initialize(\"tDy=asin(width/(d_SDz))*RAD2DEG;\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "## SOURCE OPTION 1: DUMMY SOURCE OPTION\n", + "# source = KVASIR.add_component(f\"source\", \"Source_Maxwell_3\", AT=[0,0,0], RELATIVE=\"ABSOLUTE\")\n", + "# source.xwidth=0.01\n", + "# source.yheight=0.01\n", + "# source.Lmin= \"lambda_f-D_lambda/2\"\n", + "# source.Lmax= \"lambda_f+D_lambda/2\"\n", + "# source.dist= d_SA\n", + "# source.focus_yh= f\"width*2*{N_analyzer}\"\n", + "# source.focus_xw=f\"width*3\"\n", + "# source.T1=300\n", + "# source.T2=300\n", + "# source.T3=300\n", + "# source.I1=1E15\n", + "# source.I2=1E15\n", + "# source.I3=1E15\n", + "\n", + "## SOURCE OPTION 2: IMPORT MCPL FILE FROM PRIMARY SPECTROMETER\n", + "source = KVASIR.add_component(f\"source\", \"MCPL_input\", AT=[0,0,0], RELATIVE=\"ABSOLUTE\")\n", + "source.filename= '\"Virtual_output_endOfGuide_narrow_100mus.mcpl\"' #EXAMPLE MCPL: BIFROST GUIDE, 100mus PSC opening time, wavelength band is centered at 1.95meV and narrowed to speed up simulations\n", + "source.pos_smear = 0.005\n", + "source.dir_smear = 0.05\n", + "\n", + "#ARM DEFINES SAMPLE POSITION (0.58m is distance from BIFROST guide opening to sample position)\n", + "Arm_sample = KVASIR.add_component(f\"Arm_sample\", \"Arm\", AT=[0,0,d_GS], ROTATED = [0,f\"tDy*t\",0], RELATIVE=\"ABSOLUTE\")\n", + "\n", + "## SAMPLE OPTION 1: VANADIUM\n", + "sample = KVASIR.add_component(f\"sample\", \"Incoherent\", AT=[0,0,0], RELATIVE=\"Arm_sample\")\n", + "sample.radius=0.005\n", + "sample.yheight=0.01\n", + "sample.thickness=0.001\n", + "sample.target_index = 2\n", + "sample.focus_ah =0.5\n", + "sample.focus_aw = 20 \n", + "\n", + "## SAMPLE OPTION 1: POWDER SAMPLE\n", + "# sample = KVASIR.add_component(f\"sample\", \"PowderN\", AT=[0,0,0], RELATIVE=\"Arm_sample\")\n", + "# sample.radius=0.005\n", + "# sample.yheight=0.01\n", + "# sample.thickness=0.001\n", + "# sample.reflections=\"Na2Ca3Al2F14.laz\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "for n in range(0,N_analyzer,2): #loops placing analyzers (every second analyzer is placed to avoid shading)\n", + "\n", + " az = KVASIR.add_declare_var(\"double\", f\"az_{n}\") #m z-component of n'th analyzer relative to sample position\n", + " KVASIR.append_initialize(f\"az_{n} = len[{n}]*cos(dtS[{n}]*DEG2RAD)-d_SDz;\")\n", + " \n", + " ay = KVASIR.add_declare_var(\"double\", f\"ay_{n}\") #m y-component of n'th analyzer relative to sample position\n", + " KVASIR.append_initialize(f\"ay_{n} = len[{n}]*sin(dtS[{n}]*DEG2RAD)-d_SDy;\")\n", + "\n", + " bz = KVASIR.add_declare_var(\"double\", f\"bz_{n}\") #m z-component of detector relative to n'th analyzer\n", + " KVASIR.append_initialize(f\"bz_{n} = len[{n}]*cos(dtS[{n}]*DEG2RAD);\") \n", + " \n", + " by = KVASIR.add_declare_var(\"double\", f\"by_{n}\") #m y-component of detector relative to n'th analyzer\n", + " KVASIR.append_initialize(f\"by_{n} = len[{n}]*sin(dtS[{n}]*DEG2RAD);\")\n", + " \n", + " dtA = KVASIR.add_declare_var(\"double\", f\"dtA_{n}\") #deg scattering angle of n'th analyzer\n", + " KVASIR.append_initialize(f\"dtA_{n} = acos( (az_{n}*bz_{n} + ay_{n}*by_{n}) / (len[{n}]* sqrt(az_{n}*az_{n} + ay_{n}*ay_{n}) ) )*RAD2DEG;\")\n", + "\n", + " # GENERARING UPPER ANALYZER WEDGE\n", + " Arm = KVASIR.add_component(f\"Arm_{n}\", \"Arm\", AT=[0,0,0], ROTATED=[f\"-dtS[{n}]\",0,0], RELATIVE=\"Arm_sample\") \n", + " Analyser = KVASIR.add_component(f\"Analyzer_{n}\",\"Monochromator_flat\", AT = [0,0,f\"len[{n}]\"], ROTATED=[f\"dtA_{n}/2\",90,0], RELATIVE=f\"Arm_{n}\")\n", + " Analyser.zwidth = f\"2*len[{n}]*sin(tDy/2*DEG2RAD)\"\n", + " Analyser.yheight = width\n", + " Analyser.mosaich = 90\n", + " Analyser.mosaicv = 90\n", + " Analyser.Q = 1.87278\n", + " Analyser.r0 = 0.8\n", + "\n", + " ## GENERARING LOWER ANALYZER WEDGE\n", + " # Arm = KVASIR.add_component(f\"Armm_{n}\", \"Arm\", AT=[0,0,0], ROTATED=[f\"dtS[{n}]\",0,0], RELATIVE=\"Arm_sample\")\n", + " # Analyser = KVASIR.add_component(f\"Analyzerm_{n}\",\"Monochromator_flat\", AT = [0,0,f\"len[{n}]\"], ROTATED=[f\"-dtA_{n}/2\",90,0], RELATIVE=f\"Armm_{n}\" )\n", + " # Analyser.zwidth = f\"2*len[{n}]*sin(tDy/2*DEG2RAD)\"\n", + " # Analyser.yheight = width\n", + " # Analyser.mosaich = 90\n", + " # Analyser.mosaicv = 90\n", + " # Analyser.Q = 1.87278\n", + " # Analyser.r0 = 0.8" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "N_detectors = 1#24#230 #Number of detectors, centered around wedge (24 is recomended for single wedge to capture mosaic spread)\n", + "\n", + "for n in range(N_detectors):\n", + " ## UPPER ToF MONITOR SECTION\n", + " KVASIR.add_component(f\"arm_detector_{n}\", \"Arm\", AT = [0,0,0], RELATIVE=\"Arm_sample\", ROTATED=[0,f\"tDy*{n}-tDy*{N_detectors/2}\",0])\n", + " det_He3 = KVASIR.add_component(f\"det_He3_{n}_ToF\", \"Monitor_nD\", AT = [0,\"d_SDy\", d_SDz], AT_RELATIVE=\"PREVIOUS\", ROTATED=[0,f\"tDy*{n}-tDy*{N_detectors/2}\",0], ROTATED_RELATIVE=\"Arm_sample\")\n", + " det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=80, t, limits = [0.26,0.28], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " det_He3.xwidth = width\n", + " det_He3.yheight = \"h_D\"\n", + " det_He3.filename = f'\"Detector_{n}_ToF.dat\"'\n", + "\n", + " ## UPPER ENERGY MONITOR SECTION\n", + " # det_He3 = KVASIR.add_component(f\"det_He3_{n}\", \"Monitor_nD\", AT = [0,0, \"-u\"], AT_RELATIVE=\"PREVIOUS\")\n", + " # det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=80, energy, limits = [1.9,2.1], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " # det_He3.xwidth = width\n", + " # det_He3.yheight = \"h_D\"\n", + " # det_He3.filename = f'\"Detector_{n}.dat\"'\n", + " # # det_He3.set_WHEN(\"wedge == 1\")\n", + "\n", + "\n", + "\n", + " ## LOWER ToF MONITOR SECTION\n", + " # KVASIR.add_component(f\"arm_detector_{n}_lower\", \"Arm\", AT = [0,0,0], RELATIVE=\"Arm_sample\", ROTATED=[0,f\"tDy*{n}\",0])\n", + " # det_He3 = KVASIR.add_component(f\"det_He3_{n}_lower\", \"Monitor_nD\", AT = [0,\"-d_SDy\", d_SDz], AT_RELATIVE=\"PREVIOUS\", ROTATED=[0,f\"tDy*{n}\",0], ROTATED_RELATIVE=\"Arm_sample\")\n", + " # det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=300, t, limits = [0.27,0.278], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " # det_He3.xwidth = width\n", + " # det_He3.yheight = \"h_D\"\n", + " # det_He3.filename = f'\"Detector_{n}_ToF_lower.dat\"'\n", + "\n", + " ## LOWER ENERGY MONITOR SECTION\n", + " # det_He3 = KVASIR.add_component(f\"det_He3_{n}_ToF_lower\", \"Monitor_nD\", AT = [0,0, \"-u\"], AT_RELATIVE=\"PREVIOUS\")\n", + " # det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=300, energy, limits = [1.9,2.1], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " # det_He3.xwidth = width\n", + " # det_He3.yheight = \"h_D\"\n", + " # det_He3.filename = f'\"Detector_{n}_lower.dat\"'\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "#KVASIR.show_components()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "---- Found 5 places in McStas output with keyword 'error'. \n", + "\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "--------------------------------------------------------------------------\n", + "Primary job terminated normally, but 1 process returned\n", + "a non-zero exit code. Per user-direction, the job has been aborted.\n", + "--------------------------------------------------------------------------\n", + "--------------------------------------------------------------------------\n", + "mpirun detected that one or more processes exited with non-zero status, thus causing\n", + "the job to be terminated. The first process to do so was:\n", + "\n", + " Process name: [[57467,1],5]\n", + "----------------------------------------------------------------------\n", + "\n", + "loading system configuration\n", + "loading user configuration from /Users/amaliedavidsen/.mcstas/3.2/mccode_config.json\n", + "INFO: Using directory: \"/Volumes/T7/KVASIR/KVASIR_for_repo/KVASIR\"\n", + "INFO: Regenerating c-file: KVASIR.c\n", + "CFLAGS= -Wl,-rpath,CMD(mcpl-config --show libdir) -LCMD(mcpl-config --show libdir) -lmcpl -ICMD(mcpl-config --show includedir)\n", + " \n", + "-----------------------------------------------------------\n", + "\n", + "Generating single GPU kernel or single CPU section layout: \n", + "\n", + "-----------------------------------------------------------\n", + "\n", + "Generating GPU/CPU -DFUNNEL layout:\n", + "\n", + "-----------------------------------------------------------\n", + "INFO: Recompiling: ./KVASIR.out\n", + "./KVASIR.c:3393:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]\n", + " 3393 | } /* siminfo_init */\n", + " | ^\n", + "./KVASIR.c:14678:37: warning: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Wformat]\n", + " 14674 | MPI_MASTER(\n", + " | ~~~~~~~~~~~\n", + " 14675 | #endif\n", + " | ~~~~~~\n", + " 14676 | fprintf(stdout, \"\\n\\n Warning: You are using MCPL_input with a repeat_count of %lu:\\n - Minimum neutron count requested is %lu x %lu <= %lu\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " | %llu\n", + " 14677 | (long unsigned)repeat_count,(long unsigned)nparticles,\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14678 | (long unsigned)repeat_count,(long unsigned)repeat_cnt*nparticles); \n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14679 | #if defined (USE_MPI)\n", + " | ~~~~~~~~~~~~~~~~~~~~~\n", + " 14680 | fprintf(stdout, \" x %i MPI nodes = %lu neutrons total\\n\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14681 | mpi_node_count,(long unsigned)mpi_node_count*repeat_cnt*nparticles);\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14682 | );\n", + " | ~\n", + "./KVASIR.c:456:5: note: expanded from macro 'MPI_MASTER'\n", + " 456 | { statement; } \\\n", + " | ^~~~~~~~~\n", + "./KVASIR.c:14681:20: warning: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Wformat]\n", + " 14674 | MPI_MASTER(\n", + " | ~~~~~~~~~~~\n", + " 14675 | #endif\n", + " | ~~~~~~\n", + " 14676 | fprintf(stdout, \"\\n\\n Warning: You are using MCPL_input with a repeat_count of %lu:\\n - Minimum neutron count requested is %lu x %lu <= %lu\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14677 | (long unsigned)repeat_count,(long unsigned)nparticles,\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14678 | (long unsigned)repeat_count,(long unsigned)repeat_cnt*nparticles); \n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14679 | #if defined (USE_MPI)\n", + " | ~~~~~~~~~~~~~~~~~~~~~\n", + " 14680 | fprintf(stdout, \" x %i MPI nodes = %lu neutrons total\\n\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " | %llu\n", + " 14681 | mpi_node_count,(long unsigned)mpi_node_count*repeat_cnt*nparticles);\n", + " | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14682 | );\n", + " | ~\n", + "./KVASIR.c:456:5: note: expanded from macro 'MPI_MASTER'\n", + " 456 | { statement; } \\\n", + " | ^~~~~~~~~\n", + "./KVASIR.c:14773:36: warning: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Wformat]\n", + " 14771 | fprintf(stdout, \"\\n\\n Warning: You are using MCPL_input with a repeat_count of %lu:\\n - Neutron count requested is %lu x %lu <= %lu\",\n", + " | ~~~\n", + " | %llu\n", + " 14772 | (long unsigned)repeat_count,(long unsigned)read_neutrons,\n", + " 14773 | (long unsigned)repeat_count,(long unsigned)repeat_cnt*read_neutrons);\n", + " | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + "4 warnings generated.\n", + "[cctools-port]: generating fake signature for './KVASIR.out'\n", + "INFO: ===\n", + "Simulation 'KVASIR' (KVASIR.instr): running on 6 nodes (master is 'Amalies-MacBook-Air.local', MPI version 3.1).\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "--------------------------------------------------------------------------\n", + "Primary job terminated normally, but 1 process returned\n", + "a non-zero exit code. Per user-direction, the job has been aborted.\n", + "--------------------------------------------------------------------------\n", + "--------------------------------------------------------------------------\n", + "mpirun detected that one or more processes exited with non-zero status, thus causing\n", + "the job to be terminated. The first process to do so was:\n", + "\n", + " Process name: [[57467,1],5]\n", + " Exit code: 1\n", + "--------------------------------------------------------------------------\n", + "\n", + "\n" + ] + } + ], + "source": [ + "KVASIR.set_parameters(t=50)\n", + "KVASIR.settings(ncount=1e6, mpi=6)\n", + "data = KVASIR.backengine()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No data to plot\n" + ] + } + ], + "source": [ + "ms.make_sub_plot(data, log=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#KVASIR.show_instrument(format=\"window\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "mcstas-dev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mcstas-comps/examples/ESS/KVASIR/KVASIRscript_submit.ipynb b/mcstas-comps/examples/ESS/KVASIR/KVASIRscript_submit.ipynb new file mode 100755 index 000000000..70055f6d6 --- /dev/null +++ b/mcstas-comps/examples/ESS/KVASIR/KVASIRscript_submit.ipynb @@ -0,0 +1,413 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import mcstasscript as ms # type: ignore\n", + "\n", + "configurator = ms.Configurator()\n", + "configurator.set_mcrun_path(\"/Applications/McStas-3.2.app/Contents/Resources/mcstas/3.2/bin\")\n", + "configurator.set_mcstas_path(\"/Applications/McStas-3.2.app/Contents/Resources/mcstas/3.2\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "KVASIR = ms.McStas_instr(\"KVASIR\")\n", + "t = KVASIR.add_parameter(\"t\", value=0) # Wedge no. (330 total to cover 0-170deg)\n", + "\n", + "l_analyzers =[2.5035035035035036, 2.5105105105105103, 2.5175175175175175, 2.5245245245245247, 2.5305305305305303, 2.5375375375375375, 2.5435435435435436, 2.5505505505505504, 2.5565565565565564, 2.5625625625625625, 2.5695695695695697, 2.5755755755755754, 2.5815815815815815, 2.5875875875875876, 2.5925925925925926, 2.5985985985985987, 2.6046046046046047, 2.6096096096096097, 2.6156156156156154, 2.6206206206206204, 2.6266266266266265, 2.6316316316316315, 2.6366366366366365, 2.6416416416416415, 2.6466466466466465, 2.6516516516516515, 2.6566566566566565, 2.6616616616616615, 2.6656656656656654, 2.6706706706706704, 2.674674674674675, 2.67967967967968, 2.6836836836836837, 2.6886886886886887, 2.6926926926926926, 2.6966966966966965, 2.7007007007007005, 2.704704704704705, 2.7087087087087087, 2.7127127127127126, 2.7157157157157155, 2.71971971971972, 2.7237237237237237, 2.7267267267267266, 2.7307307307307305, 2.7337337337337337, 2.736736736736737, 2.7407407407407405, 2.7437437437437437, 2.746746746746747, 2.74974974974975, 2.7527527527527527, 2.754754754754755, 2.7577577577577577, 2.7607607607607605, 2.7637637637637638, 2.7657657657657655, 2.7687687687687688, 2.7707707707707705, 2.7727727727727727, 2.7757757757757755, 2.7777777777777777, 2.77977977977978, 2.781781781781782, 2.7837837837837838, 2.7857857857857855, 2.7877877877877877, 2.78978978978979, 2.7907907907907905, 2.7927927927927927, 2.793793793793794, 2.7957957957957955, 2.796796796796797, 2.798798798798799, 2.7997997997998, 2.8008008008008005, 2.801801801801802, 2.8028028028028027, 2.804804804804805, 2.804804804804805] #array containg nummerical solution for distance from sample to n'th analyzer in wedge\n", + "\n", + "N_analyzer =60 #1 total number of analyzers\n", + "width = 0.0127 #m width of He3 tubes, height of analyzer crystals\n", + "dt = 2*np.arcsin(width/(2*2.5))*180/np.pi #deg vertical angle between each analyzer crystal seen from sample position\n", + "theta = np.linspace(-dt/2,-dt*N_analyzer-dt/2, N_analyzer) #deg array containg rotations" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# PARAMETERS\n", + "width= KVASIR.add_declare_var(\"double\", \"width\", value=0.0127) #m width of He3 tubes, height of analyzer crystals\n", + "d_PG= KVASIR.add_declare_var(\"double\", \"d_PG\", value=3.355) #Å lattice spacing og pyrolytic graphite\n", + "u = KVASIR.add_declare_var(\"double\",\"u\", value=1e-5) #1 small number\n", + "h_D = KVASIR.add_declare_var(\"double\", \"h_D\", value=0.4) #m heigt of detector \n", + "\n", + "Ef = KVASIR.add_declare_var(\"double\",\"Ef\", value=1.95) #meV focusing energy \n", + "d_AD = KVASIR.add_declare_var(\"double\",\"d_AD\", value=1.25) #m distance from analyzer to detactor\n", + "d_SA = KVASIR.add_declare_var(\"double\",\"d_SA\", value=2.5) #m distance from sample to central analyzer\n", + "d_GS = KVASIR.add_declare_var(\"double\",\"d_GS\", value=0.58) #m distance from guide end to sample position\n", + "\n", + "lamda_f = KVASIR.add_declare_var(\"double\", \"lambda_f\") #Å final wavelenght\n", + "KVASIR.append_initialize(\"lambda_f=1/(0.11056*sqrt(Ef));\")\n", + "\n", + "#ANALYZER CALCULATION\n", + "tA = KVASIR.add_declare_var(\"double\", \"tA\") #deg Bragg angle of analyzer\n", + "KVASIR.append_initialize(\"tA=asin(lambda_f/(2*d_PG))*RAD2DEG;\")\n", + "\n", + "dtS = KVASIR.add_declare_var(\"double\", \"dtS\", value=[*theta], array = len(theta)) #deg array containg rotations\n", + "\n", + "len = KVASIR.add_declare_var(\"double\", \"len\", value=l_analyzers, array = len(l_analyzers)) #array containg nummerical solution for distance from sample to n'th analyzer in wedge\n", + "\n", + "#DETECTOR CALCULATION\n", + "d_SDz = KVASIR.add_declare_var(\"double\", \"d_SDz\") #m vetical distance from scattering plane to center of detector\n", + "KVASIR.append_initialize(\"d_SDz=d_SA+d_AD*cos(2*tA*DEG2RAD);\")\n", + "\n", + "d_SDy = KVASIR.add_declare_var(\"double\", \"d_SDy\") #m distance from sample to detector in scattering plane\n", + "KVASIR.append_initialize(\"d_SDy=d_AD*sin(2*tA*DEG2RAD);\")\n", + "\n", + "tDy= KVASIR.add_declare_var(\"double\", \"tDy\") #deg horizontal angle between wedges \n", + "KVASIR.append_initialize(\"tDy=asin(width/(d_SDz))*RAD2DEG;\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "## SOURCE OPTION 1: DUMMY SOURCE OPTION\n", + "# source = KVASIR.add_component(f\"source\", \"Source_Maxwell_3\", AT=[0,0,0], RELATIVE=\"ABSOLUTE\")\n", + "# source.xwidth=0.01\n", + "# source.yheight=0.01\n", + "# source.Lmin= \"lambda_f-D_lambda/2\"\n", + "# source.Lmax= \"lambda_f+D_lambda/2\"\n", + "# source.dist= d_SA\n", + "# source.focus_yh= f\"width*2*{N_analyzer}\"\n", + "# source.focus_xw=f\"width*3\"\n", + "# source.T1=300\n", + "# source.T2=300\n", + "# source.T3=300\n", + "# source.I1=1E15\n", + "# source.I2=1E15\n", + "# source.I3=1E15\n", + "\n", + "## SOURCE OPTION 2: IMPORT MCPL FILE FROM PRIMARY SPECTROMETER\n", + "source = KVASIR.add_component(f\"source\", \"MCPL_input\", AT=[0,0,0], RELATIVE=\"ABSOLUTE\")\n", + "source.filename= '\"Virtual_output_endOfGuide_narrow_100mus.mcpl\"' #EXAMPLE MCPL: BIFROST GUIDE, 100mus PSC opening time, wavelength band is centered at 1.95meV and narrowed to speed up simulations\n", + "source.pos_smear = 0.005\n", + "source.dir_smear = 0.05\n", + "\n", + "#ARM DEFINES SAMPLE POSITION (0.58m is distance from BIFROST guide opening to sample position)\n", + "Arm_sample = KVASIR.add_component(f\"Arm_sample\", \"Arm\", AT=[0,0,d_GS], ROTATED = [0,f\"tDy*t\",0], RELATIVE=\"ABSOLUTE\")\n", + "\n", + "## SAMPLE OPTION 1: VANADIUM\n", + "sample = KVASIR.add_component(f\"sample\", \"Incoherent\", AT=[0,0,0], RELATIVE=\"Arm_sample\")\n", + "sample.radius=0.005\n", + "sample.yheight=0.01\n", + "sample.thickness=0.001\n", + "sample.target_index = 2\n", + "sample.focus_ah =0.5\n", + "sample.focus_aw = 20 \n", + "\n", + "## SAMPLE OPTION 1: POWDER SAMPLE\n", + "# sample = KVASIR.add_component(f\"sample\", \"PowderN\", AT=[0,0,0], RELATIVE=\"Arm_sample\")\n", + "# sample.radius=0.005\n", + "# sample.yheight=0.01\n", + "# sample.thickness=0.001\n", + "# sample.reflections=\"Na2Ca3Al2F14.laz\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "for n in range(0,N_analyzer,2): #loops placing analyzers (every second analyzer is placed to avoid shading)\n", + "\n", + " az = KVASIR.add_declare_var(\"double\", f\"az_{n}\") #m z-component of n'th analyzer relative to sample position\n", + " KVASIR.append_initialize(f\"az_{n} = len[{n}]*cos(dtS[{n}]*DEG2RAD)-d_SDz;\")\n", + " \n", + " ay = KVASIR.add_declare_var(\"double\", f\"ay_{n}\") #m y-component of n'th analyzer relative to sample position\n", + " KVASIR.append_initialize(f\"ay_{n} = len[{n}]*sin(dtS[{n}]*DEG2RAD)-d_SDy;\")\n", + "\n", + " bz = KVASIR.add_declare_var(\"double\", f\"bz_{n}\") #m z-component of detector relative to n'th analyzer\n", + " KVASIR.append_initialize(f\"bz_{n} = len[{n}]*cos(dtS[{n}]*DEG2RAD);\") \n", + " \n", + " by = KVASIR.add_declare_var(\"double\", f\"by_{n}\") #m y-component of detector relative to n'th analyzer\n", + " KVASIR.append_initialize(f\"by_{n} = len[{n}]*sin(dtS[{n}]*DEG2RAD);\")\n", + " \n", + " dtA = KVASIR.add_declare_var(\"double\", f\"dtA_{n}\") #deg scattering angle of n'th analyzer\n", + " KVASIR.append_initialize(f\"dtA_{n} = acos( (az_{n}*bz_{n} + ay_{n}*by_{n}) / (len[{n}]* sqrt(az_{n}*az_{n} + ay_{n}*ay_{n}) ) )*RAD2DEG;\")\n", + "\n", + " # GENERARING UPPER ANALYZER WEDGE\n", + " Arm = KVASIR.add_component(f\"Arm_{n}\", \"Arm\", AT=[0,0,0], ROTATED=[f\"-dtS[{n}]\",0,0], RELATIVE=\"Arm_sample\") \n", + " Analyser = KVASIR.add_component(f\"Analyzer_{n}\",\"Monochromator_flat\", AT = [0,0,f\"len[{n}]\"], ROTATED=[f\"dtA_{n}/2\",90,0], RELATIVE=f\"Arm_{n}\")\n", + " Analyser.zwidth = f\"2*len[{n}]*sin(tDy/2*DEG2RAD)\"\n", + " Analyser.yheight = width\n", + " Analyser.mosaich = 90\n", + " Analyser.mosaicv = 90\n", + " Analyser.Q = 1.87278\n", + " Analyser.r0 = 0.8\n", + "\n", + " ## GENERARING LOWER ANALYZER WEDGE\n", + " # Arm = KVASIR.add_component(f\"Armm_{n}\", \"Arm\", AT=[0,0,0], ROTATED=[f\"dtS[{n}]\",0,0], RELATIVE=\"Arm_sample\")\n", + " # Analyser = KVASIR.add_component(f\"Analyzerm_{n}\",\"Monochromator_flat\", AT = [0,0,f\"len[{n}]\"], ROTATED=[f\"-dtA_{n}/2\",90,0], RELATIVE=f\"Armm_{n}\" )\n", + " # Analyser.zwidth = f\"2*len[{n}]*sin(tDy/2*DEG2RAD)\"\n", + " # Analyser.yheight = width\n", + " # Analyser.mosaich = 90\n", + " # Analyser.mosaicv = 90\n", + " # Analyser.Q = 1.87278\n", + " # Analyser.r0 = 0.8" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "N_detectors = 1#24#230 #Number of detectors, centered around wedge (24 is recomended for single wedge to capture mosaic spread)\n", + "\n", + "for n in range(N_detectors):\n", + " ## UPPER ToF MONITOR SECTION\n", + " KVASIR.add_component(f\"arm_detector_{n}\", \"Arm\", AT = [0,0,0], RELATIVE=\"Arm_sample\", ROTATED=[0,f\"tDy*{n}-tDy*{N_detectors/2}\",0])\n", + " det_He3 = KVASIR.add_component(f\"det_He3_{n}_ToF\", \"Monitor_nD\", AT = [0,\"d_SDy\", d_SDz], AT_RELATIVE=\"PREVIOUS\", ROTATED=[0,f\"tDy*{n}-tDy*{N_detectors/2}\",0], ROTATED_RELATIVE=\"Arm_sample\")\n", + " det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=80, t, limits = [0.26,0.28], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " det_He3.xwidth = width\n", + " det_He3.yheight = \"h_D\"\n", + " det_He3.filename = f'\"Detector_{n}_ToF.dat\"'\n", + "\n", + " ## UPPER ENERGY MONITOR SECTION\n", + " # det_He3 = KVASIR.add_component(f\"det_He3_{n}\", \"Monitor_nD\", AT = [0,0, \"-u\"], AT_RELATIVE=\"PREVIOUS\")\n", + " # det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=80, energy, limits = [1.9,2.1], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " # det_He3.xwidth = width\n", + " # det_He3.yheight = \"h_D\"\n", + " # det_He3.filename = f'\"Detector_{n}.dat\"'\n", + " # # det_He3.set_WHEN(\"wedge == 1\")\n", + "\n", + "\n", + "\n", + " ## LOWER ToF MONITOR SECTION\n", + " # KVASIR.add_component(f\"arm_detector_{n}_lower\", \"Arm\", AT = [0,0,0], RELATIVE=\"Arm_sample\", ROTATED=[0,f\"tDy*{n}\",0])\n", + " # det_He3 = KVASIR.add_component(f\"det_He3_{n}_lower\", \"Monitor_nD\", AT = [0,\"-d_SDy\", d_SDz], AT_RELATIVE=\"PREVIOUS\", ROTATED=[0,f\"tDy*{n}\",0], ROTATED_RELATIVE=\"Arm_sample\")\n", + " # det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=300, t, limits = [0.27,0.278], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " # det_He3.xwidth = width\n", + " # det_He3.yheight = \"h_D\"\n", + " # det_He3.filename = f'\"Detector_{n}_ToF_lower.dat\"'\n", + "\n", + " ## LOWER ENERGY MONITOR SECTION\n", + " # det_He3 = KVASIR.add_component(f\"det_He3_{n}_ToF_lower\", \"Monitor_nD\", AT = [0,0, \"-u\"], AT_RELATIVE=\"PREVIOUS\")\n", + " # det_He3.options = '\"cylinder, y, limits=[-0.2,0.2], bins=300, energy, limits = [1.9,2.1], bins=500\"' # t, limits = [0.0069,0.00695] energy, limits = [1.82,1.84]\n", + " # det_He3.xwidth = width\n", + " # det_He3.yheight = \"h_D\"\n", + " # det_He3.filename = f'\"Detector_{n}_lower.dat\"'\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "#KVASIR.show_components()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "---- Found 5 places in McStas output with keyword 'error'. \n", + "\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "----------------------------------------------------------------------\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "--------------------------------------------------------------------------\n", + "Primary job terminated normally, but 1 process returned\n", + "a non-zero exit code. Per user-direction, the job has been aborted.\n", + "--------------------------------------------------------------------------\n", + "--------------------------------------------------------------------------\n", + "mpirun detected that one or more processes exited with non-zero status, thus causing\n", + "the job to be terminated. The first process to do so was:\n", + "\n", + " Process name: [[57467,1],5]\n", + "----------------------------------------------------------------------\n", + "\n", + "loading system configuration\n", + "loading user configuration from /Users/amaliedavidsen/.mcstas/3.2/mccode_config.json\n", + "INFO: Using directory: \"/Volumes/T7/KVASIR/KVASIR_for_repo/KVASIR\"\n", + "INFO: Regenerating c-file: KVASIR.c\n", + "CFLAGS= -Wl,-rpath,CMD(mcpl-config --show libdir) -LCMD(mcpl-config --show libdir) -lmcpl -ICMD(mcpl-config --show includedir)\n", + " \n", + "-----------------------------------------------------------\n", + "\n", + "Generating single GPU kernel or single CPU section layout: \n", + "\n", + "-----------------------------------------------------------\n", + "\n", + "Generating GPU/CPU -DFUNNEL layout:\n", + "\n", + "-----------------------------------------------------------\n", + "INFO: Recompiling: ./KVASIR.out\n", + "./KVASIR.c:3393:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]\n", + " 3393 | } /* siminfo_init */\n", + " | ^\n", + "./KVASIR.c:14678:37: warning: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Wformat]\n", + " 14674 | MPI_MASTER(\n", + " | ~~~~~~~~~~~\n", + " 14675 | #endif\n", + " | ~~~~~~\n", + " 14676 | fprintf(stdout, \"\\n\\n Warning: You are using MCPL_input with a repeat_count of %lu:\\n - Minimum neutron count requested is %lu x %lu <= %lu\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " | %llu\n", + " 14677 | (long unsigned)repeat_count,(long unsigned)nparticles,\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14678 | (long unsigned)repeat_count,(long unsigned)repeat_cnt*nparticles); \n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14679 | #if defined (USE_MPI)\n", + " | ~~~~~~~~~~~~~~~~~~~~~\n", + " 14680 | fprintf(stdout, \" x %i MPI nodes = %lu neutrons total\\n\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14681 | mpi_node_count,(long unsigned)mpi_node_count*repeat_cnt*nparticles);\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14682 | );\n", + " | ~\n", + "./KVASIR.c:456:5: note: expanded from macro 'MPI_MASTER'\n", + " 456 | { statement; } \\\n", + " | ^~~~~~~~~\n", + "./KVASIR.c:14681:20: warning: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Wformat]\n", + " 14674 | MPI_MASTER(\n", + " | ~~~~~~~~~~~\n", + " 14675 | #endif\n", + " | ~~~~~~\n", + " 14676 | fprintf(stdout, \"\\n\\n Warning: You are using MCPL_input with a repeat_count of %lu:\\n - Minimum neutron count requested is %lu x %lu <= %lu\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14677 | (long unsigned)repeat_count,(long unsigned)nparticles,\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14678 | (long unsigned)repeat_count,(long unsigned)repeat_cnt*nparticles); \n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14679 | #if defined (USE_MPI)\n", + " | ~~~~~~~~~~~~~~~~~~~~~\n", + " 14680 | fprintf(stdout, \" x %i MPI nodes = %lu neutrons total\\n\",\n", + " | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " | %llu\n", + " 14681 | mpi_node_count,(long unsigned)mpi_node_count*repeat_cnt*nparticles);\n", + " | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + " 14682 | );\n", + " | ~\n", + "./KVASIR.c:456:5: note: expanded from macro 'MPI_MASTER'\n", + " 456 | { statement; } \\\n", + " | ^~~~~~~~~\n", + "./KVASIR.c:14773:36: warning: format specifies type 'unsigned long' but the argument has type 'unsigned long long' [-Wformat]\n", + " 14771 | fprintf(stdout, \"\\n\\n Warning: You are using MCPL_input with a repeat_count of %lu:\\n - Neutron count requested is %lu x %lu <= %lu\",\n", + " | ~~~\n", + " | %llu\n", + " 14772 | (long unsigned)repeat_count,(long unsigned)read_neutrons,\n", + " 14773 | (long unsigned)repeat_count,(long unsigned)repeat_cnt*read_neutrons);\n", + " | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + "4 warnings generated.\n", + "[cctools-port]: generating fake signature for './KVASIR.out'\n", + "INFO: ===\n", + "Simulation 'KVASIR' (KVASIR.instr): running on 6 nodes (master is 'Amalies-MacBook-Air.local', MPI version 3.1).\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "MCPL \u001b[91mERROR\u001b[0m: Unable to open file!\n", + "--------------------------------------------------------------------------\n", + "Primary job terminated normally, but 1 process returned\n", + "a non-zero exit code. Per user-direction, the job has been aborted.\n", + "--------------------------------------------------------------------------\n", + "--------------------------------------------------------------------------\n", + "mpirun detected that one or more processes exited with non-zero status, thus causing\n", + "the job to be terminated. The first process to do so was:\n", + "\n", + " Process name: [[57467,1],5]\n", + " Exit code: 1\n", + "--------------------------------------------------------------------------\n", + "\n", + "\n" + ] + } + ], + "source": [ + "KVASIR.set_parameters(t=50)\n", + "KVASIR.settings(ncount=1e6, mpi=6)\n", + "data = KVASIR.backengine()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "No data to plot\n" + ] + } + ], + "source": [ + "ms.make_sub_plot(data, log=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#KVASIR.show_instrument(format=\"window\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "mcstas-dev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mcstas-comps/examples/ESS/KVASIR/Virtual_output_example.mcpl b/mcstas-comps/examples/ESS/KVASIR/Virtual_output_example.mcpl new file mode 100755 index 000000000..dca479c18 Binary files /dev/null and b/mcstas-comps/examples/ESS/KVASIR/Virtual_output_example.mcpl differ