Skip to content

Commit d02b846

Browse files
Functional system for surface effects, though only supports for simple box shape.
1 parent c30628a commit d02b846

8 files changed

Lines changed: 715 additions & 60 deletions

File tree

mcstas-comps/share/union-init.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@
4848
// Initialize global_process_list
4949
// Used to facilitate communication between processes and the other types of Union components
5050
struct pointer_to_global_process_list global_process_list = {0,NULL};
51-
51+
5252
// Initialize global_material_list
5353
// Used to facilitate communication between materials and the other types of Union components
5454
struct pointer_to_global_material_list global_material_list = {0,NULL};
55+
56+
// Initialize global_surface_list
57+
// Used to facilitate communication between surface components and other types of Union components
58+
struct pointer_to_global_surface_list global_surface_list = {0,NULL};
5559

5660
// Initialize global_geometry_list
5761
// Used to facilitate communication between geometries and the other types of Union components

mcstas-comps/share/union-lib.c

Lines changed: 168 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ enum process {
3636
Template
3737
};
3838

39+
enum surface {
40+
Mirror,
41+
SurfaceTemplate
42+
};
43+
44+
enum in_or_out {
45+
inward_bound,
46+
outward_bound
47+
};
48+
3949
struct intersection_time_table_struct {
4050
int num_volumes;
4151
int *calculated;
@@ -441,6 +451,12 @@ struct pointer_to_1d_int_list masked_by_mask_index_list;
441451
//struct indexed_mask_lists_struct mask_intersect_lists;
442452
// Simpler way of storing the mask_intersect_lists
443453
struct pointer_to_1d_int_list mask_intersect_list;
454+
455+
// Surfaces
456+
// Could make structure for this and support functions?
457+
int number_of_faces;
458+
struct surface_stack_struct **surface_stack_for_each_face;
459+
struct surface_stack_struct *internal_cut_surface_stack;
444460
};
445461

446462
struct physics_struct
@@ -499,6 +515,26 @@ int (*scattering_function)(double*,double*,double*,union data_transfer_union,str
499515
// k_f, k_i, weight, parameters , focus data / function
500516
};
501517

518+
519+
union surface_data_transfer_union
520+
{
521+
//struct Mirror_surface_storage_struct *pointer_to_a_Mirror_surface_storage_struct;
522+
struct Template_surface_storage_struct *pointer_to_a_Template_surface_storage_struct;
523+
};
524+
525+
struct surface_process_struct
526+
{
527+
char name[256];
528+
enum surface eSurface;
529+
union surface_data_transfer_union data_transfer;
530+
};
531+
532+
struct surface_stack_struct
533+
{
534+
int number_of_surfaces;
535+
struct surface_process_struct **p_surface_array;
536+
};
537+
502538
struct Volume_struct
503539
{
504540
char name[256]; // User defined volume name
@@ -519,19 +555,34 @@ struct pointer_to_1d_int_list start_logic_list;
519555
struct pointer_to_1d_int_list starting_destinations_list;
520556
};
521557

522-
struct global_positions_to_transform_list_struct {
558+
struct global_positions_to_transform_list_struct
559+
{
523560
int num_elements;
524561
Coords **positions;
525562
};
526563

527-
struct global_rotations_to_transform_list_struct {
564+
struct global_rotations_to_transform_list_struct
565+
{
528566
int num_elements;
529567
Rotation **rotations;
530568
};
531569

570+
struct global_surface_element_struct
571+
{
572+
char name[256]; // Name of the process
573+
int component_index;
574+
struct surface_process_struct *p_surface_process;
575+
};
576+
577+
struct pointer_to_global_surface_list
578+
{
579+
int num_elements;
580+
struct global_surface_element_struct *elements;
581+
};
582+
532583
struct global_process_element_struct
533584
{
534-
char name[128]; // Name of the process
585+
char name[256]; // Name of the process
535586
int component_index;
536587
struct scattering_process_struct *p_scattering_process;
537588
};
@@ -1022,8 +1073,8 @@ void add_element_to_process_list(struct pointer_to_global_process_list *list,str
10221073
void add_element_to_material_list(struct pointer_to_global_material_list *list,struct global_material_element_struct new_element) {
10231074
if (list->num_elements == 0) {
10241075
list->num_elements++;
1025-
list-> elements = malloc(list->num_elements*sizeof(struct global_material_element_struct));
1026-
list-> elements[0] = new_element;
1076+
list->elements = malloc(list->num_elements*sizeof(struct global_material_element_struct));
1077+
list->elements[0] = new_element;
10271078
}
10281079
else {
10291080
struct global_material_element_struct *temp=malloc(list->num_elements*sizeof(struct global_material_element_struct));
@@ -1038,11 +1089,53 @@ void add_element_to_material_list(struct pointer_to_global_material_list *list,s
10381089
}
10391090
};
10401091

1092+
void add_element_to_surface_list(struct pointer_to_global_surface_list *list, struct global_surface_element_struct new_element) {
1093+
if (list->num_elements == 0) {
1094+
list->num_elements++;
1095+
list->elements = malloc(list->num_elements*sizeof(struct global_surface_element_struct));
1096+
list->elements[0] = new_element;
1097+
}
1098+
else {
1099+
struct global_surface_element_struct *temp=malloc(list->num_elements*sizeof(struct global_surface_element_struct));
1100+
int iterate;
1101+
for (iterate=0;iterate<list->num_elements;iterate++) temp[iterate] = list->elements[iterate];
1102+
free(list->elements);
1103+
list->num_elements++;
1104+
list-> elements = malloc(list->num_elements*sizeof(struct global_surface_element_struct));
1105+
for (iterate=0;iterate<list->num_elements-1;iterate++) list->elements[iterate] = temp[iterate];
1106+
free(temp);
1107+
list->elements[list->num_elements-1] = new_element;
1108+
}
1109+
};
1110+
1111+
void add_element_to_surface_stack(struct surface_stack_struct *list, struct surface_process_struct *new_element) {
1112+
if (list->number_of_surfaces == 0) {
1113+
list->p_surface_array = malloc(sizeof(struct surface_process_struct*));
1114+
if (!list->p_surface_array) {
1115+
fprintf(stderr, "Memory allocation failed\n");
1116+
exit(EXIT_FAILURE);
1117+
}
1118+
list->p_surface_array[0] = new_element;
1119+
list->number_of_surfaces = 1;
1120+
} else {
1121+
// Reallocate with space for one more element
1122+
struct surface_process_struct **temp = realloc(list->p_surface_array,
1123+
(list->number_of_surfaces + 1) * sizeof(struct surface_process_struct*));
1124+
if (!temp) {
1125+
fprintf(stderr, "Memory reallocation failed\n");
1126+
exit(EXIT_FAILURE);
1127+
}
1128+
list->p_surface_array = temp;
1129+
list->p_surface_array[list->number_of_surfaces] = new_element;
1130+
list->number_of_surfaces++;
1131+
}
1132+
};
1133+
10411134
void add_element_to_geometry_list(struct pointer_to_global_geometry_list *list,struct global_geometry_element_struct new_element) {
10421135
if (list->num_elements == 0) {
10431136
list->num_elements++;
1044-
list-> elements = malloc(list->num_elements*sizeof(struct global_geometry_element_struct));
1045-
list-> elements[0] = new_element;
1137+
list->elements = malloc(list->num_elements*sizeof(struct global_geometry_element_struct));
1138+
list->elements[0] = new_element;
10461139
}
10471140
else {
10481141
struct global_geometry_element_struct *temp=malloc(list->num_elements*sizeof(struct global_geometry_element_struct));
@@ -1060,8 +1153,8 @@ void add_element_to_geometry_list(struct pointer_to_global_geometry_list *list,s
10601153
void add_element_to_logger_list(struct pointer_to_global_logger_list *list,struct global_logger_element_struct new_element) {
10611154
if (list->num_elements == 0) {
10621155
list->num_elements++;
1063-
list-> elements = malloc(list->num_elements*sizeof(struct global_logger_element_struct));
1064-
list-> elements[0] = new_element;
1156+
list->elements = malloc(list->num_elements*sizeof(struct global_logger_element_struct));
1157+
list->elements[0] = new_element;
10651158
}
10661159
else {
10671160
struct global_logger_element_struct *temp=malloc(list->num_elements*sizeof(struct global_logger_element_struct));
@@ -8511,5 +8604,71 @@ void record_abs_to_file(double *r, double t1, double *r_old, double t2, double w
85118604

85128605
};
85138606

8607+
void manual_linking_function_surface(char *input_string, struct pointer_to_global_surface_list *global_surface_list, struct pointer_to_1d_int_list *accepted_surfaces, char *component_name) {
85148608

8609+
char *token;
8610+
int loop_index;
8611+
char local_string[256];
8612+
8613+
strcpy(local_string, input_string);
8614+
8615+
// get the first token
8616+
token = strtok(local_string,",");
8617+
8618+
// walk through tokens
8619+
while(token != NULL)
8620+
{
8621+
//printf( " %s\n", token );
8622+
for (loop_index=0; loop_index<global_surface_list->num_elements; loop_index++) {
8623+
if (strcmp(token, global_surface_list->elements[loop_index].name) == 0) {
8624+
add_element_to_int_list(accepted_surfaces, loop_index);
8625+
break;
8626+
}
8627+
8628+
if (loop_index == global_surface_list->num_elements - 1) {
8629+
// All possible surface names have been looked through, and the break was not executed.
8630+
// Alert the user to this problem by showing the surface name that was not found and the currently available surface definitions
8631+
printf("\n");
8632+
printf("ERROR: The surface string \"%s\" in Union geometry \"%s\" had an entry that did not match a specified surface definition. \n", input_string, component_name);
8633+
printf(" The unrecoignized surface name was: \"%s\" \n",token);
8634+
printf(" The surfaces available at this point (need to be defined before the geometry): \n");
8635+
for (loop_index=0; loop_index<global_surface_list->num_elements; loop_index++)
8636+
printf(" %s\n",global_surface_list->elements[loop_index].name);
8637+
exit(1);
8638+
}
8639+
}
8640+
8641+
// Updates the token
8642+
token = strtok(NULL,",");
8643+
}
8644+
}
8645+
8646+
void fill_surface_stack(char *input_string, struct pointer_to_global_surface_list *global_surface_list, char *component_name,
8647+
struct surface_stack_struct *surface_stack) {
8648+
// Takes empty surface_stack struct, allocates the memory and fills it with appropriate pointers to the surfaces requested in input_string
8649+
8650+
if (input_string && strlen(input_string) && strcmp(input_string, "NULL") && strcmp(input_string, "0") && strcmp(input_string, "None")) {
8651+
8652+
struct pointer_to_1d_int_list accepted_surfaces;
8653+
manual_linking_function_surface(input_string, global_surface_list, &accepted_surfaces, component_name);
8654+
8655+
surface_stack->number_of_surfaces = accepted_surfaces.num_elements;
8656+
surface_stack->p_surface_array = malloc(surface_stack->number_of_surfaces*sizeof(struct surface_process_struct*));
8657+
8658+
int loop_index;
8659+
for (loop_index=0; loop_index<accepted_surfaces.num_elements; loop_index++) {
8660+
surface_stack->p_surface_array[loop_index]=global_surface_list->elements[accepted_surfaces.elements[loop_index]].p_surface_process;
8661+
}
8662+
8663+
} else {
8664+
surface_stack->number_of_surfaces = 0;
8665+
}
8666+
8667+
}
8668+
8669+
void overwrite_if_empty(char *input_string, char *overwrite) {
8670+
if (!(input_string && strlen(input_string) && strcmp(input_string, "NULL") && strcmp(input_string, "0"))) {
8671+
strcpy(input_string, overwrite);
8672+
}
8673+
}
85158674

mcstas-comps/share/union-suffix.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,31 @@ int physics_scattering(enum process choice, double *k_final, double *k_initial,
121121
#endif
122122
return output;
123123
}
124+
125+
int physics_surface(struct surface_process_struct *surface, // surface struct, has enum for choice and pointer to data
126+
double *weight, double *wavevector, // information to surface_process, but also things it should update
127+
int *continues, // output, whether the ray continues to next layer or not
128+
double *normal_vector, enum in_or_out in_out, // information that should not be changed
129+
_class_particle *_particle) { // particle struct
130+
131+
enum surface choice = surface->eSurface;
132+
133+
int output = 0; // Error return value
134+
#ifdef SURFACE_DETECTOR
135+
switch(choice) {
136+
#ifdef SURFACE_PROCESS_MIRROR_DETECTOR
137+
case Mirror:
138+
output = Mirror_surface_function(surface->data_transfer, weight, wavevector, continues, normal_vector, in_out, _particle);
139+
break;
140+
#endif
141+
#ifdef SURFACE_PROCESS_TEMPLATE_DETECTOR
142+
case SurfaceTemplate:
143+
output = Template_surface_function(surface->data_transfer, weight, wavevector, continues, normal_vector, in_out, _particle);
144+
break;
145+
#endif
146+
default: printf("physics_surface: No surface process matches input!\n");
147+
break;
148+
}
149+
#endif
150+
return output;
151+
}

0 commit comments

Comments
 (0)