@@ -197,6 +197,7 @@ DECLARE
197197 int *pre_allocated2;
198198 int *pre_allocated3;
199199 Coords ray_position;
200+
200201 Coords ray_velocity;
201202 Coords ray_velocity_rotated;
202203 Coords ray_velocity_final;
@@ -273,6 +274,7 @@ DECLARE
273274
274275 // Focusing
275276 struct focus_data_struct temporary_focus_data;
277+ struct focus_data_struct *this_focus_data;
276278 int focus_data_index;
277279
278280 // Record absorption
@@ -602,6 +604,9 @@ exit(-1);
602604 Volumes[volume_index]->geometry.geometry_parameters = Volumes[volume_index]->geometry.copy_geometry_parameters(&global_geometry_list_master->elements[geometry_list_index].Volume->geometry.geometry_parameters);
603605
604606 }
607+
608+ // Update focusing absolute_rotation before running through processes, then this will be the baseline for nonisotropic processes
609+ rot_copy(Volumes[volume_index]->geometry.focus_data_array.elements[0].absolute_rotation, ROT_A_CURRENT_COMP);
605610
606611 // This section identifies the different non isotropic processes in the current volume and give them appropriate transformation matrices
607612 // Identify the number of non isotropic processes in a material (this code can be safely executed for the same material many times)
@@ -635,17 +640,21 @@ exit(-1);
635640 temporary_focus_data = Volumes[volume_index]->geometry.focus_data_array.elements[0];
636641
637642 // Correct for process rotation
643+ // Aim
638644 temporary_focus_data.Aim = rot_apply(Volumes[volume_index]->p_physics->p_scattering_array[iterator].rotation_matrix,temporary_focus_data.Aim);
645+ // Absolute rotation
646+ rot_mul(Volumes[volume_index]->p_physics->p_scattering_array[iterator].rotation_matrix, temporary_focus_data.absolute_rotation, temp_rotation_matrix);
647+ rot_copy(temporary_focus_data.absolute_rotation, temp_rotation_matrix);
639648
640649 // Add element to focus_array_indices
641650 // focus_array_indices refers to the correct element in focus_data_array for this volume/process combination
642651 // focus_data_array[0] is the isotropic version in all cases, so the first non_isotropic goes to focus_data_array[1]
643652 // and so forth. When a process is isotropic, this array is appended with a zero.
644653 // The focus_array_indices maps process numbers to the correct focus_data_array index.
645- add_element_to_int_list(&Volumes[volume_index]->geometry.focus_array_indices,non_isotropic_found+1);
654+ add_element_to_int_list(&Volumes[volume_index]->geometry.focus_array_indices, non_isotropic_found+1);
646655
647656 // Add the new focus_data element to this volumes focus_data_array.
648- add_element_to_focus_data_array(&Volumes[volume_index]->geometry.focus_data_array,temporary_focus_data);
657+ add_element_to_focus_data_array(&Volumes[volume_index]->geometry.focus_data_array, temporary_focus_data);
649658
650659 // Quick error check to see the length is correct which indirectly confirms the indices are correct
651660 if (Volumes[volume_index]->geometry.focus_data_array.num_elements != non_isotropic_found + 2) {
@@ -703,14 +712,9 @@ exit(-1);
703712 Volumes[volume_index]->geometry.center.x = rotated_position.x;
704713 Volumes[volume_index]->geometry.center.y = rotated_position.y;
705714 Volumes[volume_index]->geometry.center.z = rotated_position.z;
706-
707- // The focus_data information need to be updated as well
708- rot_mul(ROT_A_CURRENT_COMP,Volumes[volume_index]->geometry.focus_data_array.elements[0].absolute_rotation,temp_rotation_matrix);
709- // Copy the result back to the volumes structure
710- rot_copy(Volumes[volume_index]->geometry.focus_data_array.elements[0].absolute_rotation,temp_rotation_matrix);
711-
715+
712716 // Use same rotation on the aim vector of the isotropic focus_data element
713- Volumes[volume_index]->geometry.focus_data_array.elements[0].Aim = rot_apply(Volumes[volume_index]->geometry.rotation_matrix,Volumes[volume_index]->geometry.focus_data_array.elements[0].Aim);
717+ Volumes[volume_index]->geometry.focus_data_array.elements[0].Aim = rot_apply(Volumes[volume_index]->geometry.rotation_matrix, Volumes[volume_index]->geometry.focus_data_array.elements[0].Aim);
714718
715719 // To allocate enough memory to hold information on all processes, the maximum of these is updated if this volume has more
716720 if (Volumes[volume_index]->p_physics->number_of_processes > max_number_of_processes)
@@ -1437,7 +1441,15 @@ TRACE
14371441 } else {
14381442 // Since there is a non-zero number of processes in this material, all the scattering cross section for these are calculated
14391443 my_sum = 0; k[0] = V2K*vx; k[1] = V2K*vy; k[2] = V2K*vz; p_my_trace = my_trace; wavevector = coords_set(k[0],k[1],k[2]);
1440- //for (process_start = process = Volumes[current_volume]->p_physics->p_scattering_array;process - process_start < Volumes[current_volume]->p_physics->number_of_processes;process++) {
1444+
1445+ // update focus data for this ray
1446+ int f_index;
1447+ Coords ray_position_geometry;
1448+ for (f_index=0; f_index < Volumes[current_volume]->geometry.focus_data_array.num_elements; f_index++) {
1449+ this_focus_data = &Volumes[current_volume]->geometry.focus_data_array.elements[f_index];
1450+ this_focus_data->RayAim = this_focus_data->Aim; // Temporary solution, cross section should not depend on focusing
1451+ }
1452+
14411453 int p_index;
14421454 for (p_index=0; p_index < Volumes[current_volume]->p_physics->number_of_processes; p_index++ ){ // GPU
14431455
@@ -1451,14 +1463,15 @@ TRACE
14511463 k_rotated[0] = k[0]; k_rotated[1] = k[1]; k_rotated[2] = k[2];
14521464 }
14531465
1454- // Find correct focus_data_array index for this volume/process
1455- focus_data_index = Volumes[current_volume]->geometry.focus_array_indices.elements[p_index];
1456-
14571466 // Call the probability for scattering function assighed to this specific procress (the process pointer is updated in the for loop)
14581467 process = &Volumes[current_volume]->p_physics->p_scattering_array[p_index]; // GPU Allowed
1468+
1469+ // Find correct focus_data_array index for this volume/process
1470+ focus_data_index = Volumes[current_volume]->geometry.focus_array_indices.elements[p_index];
1471+ this_focus_data = &Volumes[current_volume]->geometry.focus_data_array.elements[focus_data_index];
14591472
14601473 int physics_output;
1461- physics_output = physics_my(process->eProcess, p_my_trace, k_rotated, process->data_transfer,&Volumes[current_volume]->geometry.focus_data_array.elements[focus_data_index] , _particle);
1474+ physics_output = physics_my(process->eProcess, p_my_trace, k_rotated, process->data_transfer, this_focus_data , _particle);
14621475
14631476 my_sum += *p_my_trace;
14641477 #ifdef Union_trace_verbal_setting
@@ -1702,8 +1715,12 @@ TRACE
17021715 p_old = p;
17031716 k_old[0] = k[0];k_old[1] = k[1];k_old[2] = k[2];
17041717
1705- // Find correct focus_data_array index for this volume/process
1718+ // Find correct focus_data_array index for this volume/process and correct for ray position
17061719 focus_data_index = Volumes[current_volume]->geometry.focus_array_indices.elements[selected_process];
1720+ this_focus_data = &Volumes[current_volume]->geometry.focus_data_array.elements[focus_data_index];
1721+
1722+ Coords ray_position_geometry = coords_sub(ray_position, Volumes[current_volume]->geometry.center); // ray_position relative to geometry center
1723+ this_focus_data->RayAim = coords_sub(this_focus_data->Aim, ray_position_geometry); // Aim vector for this ray
17071724
17081725 // Rotation to local process coordinate system (for non isotropic processes)
17091726 if (Volumes[current_volume]->p_physics->p_scattering_array[selected_process].non_isotropic_rot_index != -1) {
@@ -1720,7 +1737,7 @@ TRACE
17201737
17211738 // I may replace a intial and final k with one instance that serves as both input and output
17221739 process = &Volumes[current_volume]->p_physics->p_scattering_array[selected_process]; // CPU Only
1723- if (0 == physics_scattering(process->eProcess, k_new, k, &p, process->data_transfer, &Volumes[current_volume]->geometry.focus_data_array.elements[0] , _particle)) {
1740+ if (0 == physics_scattering(process->eProcess, k_new, k, &p, process->data_transfer, this_focus_data , _particle)) {
17241741 /*
17251742 // PowderN and Single_crystal requires the option of absorbing the neutron, which is weird. If there is a scattering probability, there should be a new direction.
17261743 // It can arise from need to simplify sampling process and end up in cases where weight factor is 0, and the ray should be absorbed in these cases
0 commit comments