Skip to content

Commit 2e24992

Browse files
Fixing focusing issue in Union where ray position was not taken into account.
1 parent 7a9f487 commit 2e24992

File tree

2 files changed

+41
-24
lines changed

2 files changed

+41
-24
lines changed

mcstas-comps/share/union-lib.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ double z;
105105
};
106106

107107
struct focus_data_struct {
108-
Coords Aim;
108+
Coords RayAim; // Vector from ray position (within geometry) to target
109+
Coords Aim; // Vector from geometry to target
109110
double angular_focus_width;
110111
double angular_focus_height;
111112
double spatial_focus_width;
@@ -819,8 +820,8 @@ void add_element_to_int_list(struct pointer_to_1d_int_list *list,int value) {
819820
void add_element_to_focus_data_array(struct focus_data_array_struct *focus_data_array,struct focus_data_struct focus_data) {
820821
if (focus_data_array->num_elements == 0) {
821822
focus_data_array->num_elements++;
822-
focus_data_array-> elements = malloc(focus_data_array->num_elements*sizeof(struct focus_data_struct));
823-
focus_data_array-> elements[0] = focus_data;
823+
focus_data_array->elements = malloc(focus_data_array->num_elements*sizeof(struct focus_data_struct));
824+
focus_data_array->elements[0] = focus_data;
824825
} else {
825826
struct focus_data_struct *temp=malloc(focus_data_array->num_elements*sizeof(struct focus_data_struct));
826827
int iterate;
@@ -8738,13 +8739,13 @@ void generate_lists(struct Volume_struct **Volumes, struct starting_lists_struct
87388739

87398740
void randvec_target_rect_angular_union(Coords *v_out,double *solid_angle_out, struct focus_data_struct *focus_data) {
87408741
// Calls the standard McStas randvec_target_rect_angular focusing function, but is with the new data input format.
8741-
randvec_target_rect_angular(&v_out->x, &v_out->y, &v_out->z, solid_angle_out, focus_data->Aim.x,focus_data->Aim.y, focus_data->Aim.z, focus_data->angular_focus_width, focus_data->angular_focus_height,focus_data->absolute_rotation);
8742+
randvec_target_rect_angular(&v_out->x, &v_out->y, &v_out->z, solid_angle_out, focus_data->RayAim.x,focus_data->RayAim.y, focus_data->RayAim.z, focus_data->angular_focus_width, focus_data->angular_focus_height,focus_data->absolute_rotation);
87428743
//randvec_target_rect_angular(&vx, &vy, &vz, &solid_angle,aim_x, aim_y, aim_z, VarsInc.aw, VarsInc.ah, ROT_A_CURRENT_COMP);
87438744
};
87448745

87458746
void randvec_target_rect_union(Coords *v_out,double *solid_angle_out, struct focus_data_struct *focus_data) {
87468747
// Calls the standard McStas randvec_target_rect focusing function, but is with the new data input format.
8747-
randvec_target_rect(&v_out->x, &v_out->y, &v_out->z, solid_angle_out, focus_data->Aim.x,focus_data->Aim.y, focus_data->Aim.z, focus_data->spatial_focus_width, focus_data->spatial_focus_height,focus_data->absolute_rotation);
8748+
randvec_target_rect(&v_out->x, &v_out->y, &v_out->z, solid_angle_out, focus_data->RayAim.x,focus_data->RayAim.y, focus_data->RayAim.z, focus_data->spatial_focus_width, focus_data->spatial_focus_height,focus_data->absolute_rotation);
87488749
// randvec_target_rect(&vx, &vy, &vz, &solid_angle,aim_x, aim_y, aim_z, VarsInc.xw, VarsInc.yh, ROT_A_CURRENT_COMP);
87498750
};
87508751

@@ -8755,7 +8756,7 @@ void randvec_target_circle_union(Coords *v_out,double *solid_angle_out, struct f
87558756
//print_position(focus_data->Aim,"Aim vector input for randvec_target_circle");
87568757
//printf("Radius input %f\n",focus_data->spatial_focus_radius);
87578758

8758-
randvec_target_circle(&v_out->x, &v_out->y, &v_out->z, solid_angle_out, focus_data->Aim.x,focus_data->Aim.y, focus_data->Aim.z, focus_data->spatial_focus_radius);
8759+
randvec_target_circle(&v_out->x, &v_out->y, &v_out->z, solid_angle_out, focus_data->RayAim.x,focus_data->RayAim.y, focus_data->RayAim.z, focus_data->spatial_focus_radius);
87598760
//randvec_target_circle(&vx, &vy, &vz, &solid_angle, aim_x, aim_y, aim_z, focus_r);
87608761
};
87618762

@@ -8816,8 +8817,7 @@ void focus_initialize(struct geometry_struct *geometry, Coords POS_A_TARGET, Coo
88168817
{
88178818
Coords ToTarget;
88188819
//ToTarget = coords_sub(POS_A_COMP_INDEX(INDEX_CURRENT_COMP+target_index),POS_A_CURRENT_COMP);
8819-
ToTarget = coords_sub(POS_A_TARGET,POS_A_CURRENT);
8820-
//ToTarget = rot_apply(ROT_A_CURRENT_COMP, ToTarget);
8820+
ToTarget = coords_sub(POS_A_TARGET, POS_A_CURRENT);
88218821
ToTarget = rot_apply(ROT_A_CURRENT, ToTarget);
88228822
coords_get(ToTarget, &focus_data.Aim.x, &focus_data.Aim.y, &focus_data.Aim.z);
88238823
}

mcstas-comps/union/Union_master.comp

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)