diff --git a/mcstas-comps/examples/Tests_union/Hidden_Cylinder/Hidden_Cylinder.instr b/mcstas-comps/examples/Tests_union/Hidden_Cylinder/Hidden_Cylinder.instr new file mode 100644 index 000000000..165aee6dd --- /dev/null +++ b/mcstas-comps/examples/Tests_union/Hidden_Cylinder/Hidden_Cylinder.instr @@ -0,0 +1,165 @@ +/******************************************************************************** +* +* McStas, neutron ray-tracing package +* Copyright (C) 1997-2008, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* This file was written by McStasScript, which is a +* python based McStas instrument generator written by +* Mads Bertelsen in 2019 while employed at the +* European Spallation Source Data Management and +* Software Centre +* +* Instrument: Hidden_Cylinder +* +* %Identification +* Written by: Daniel Lomholt Christensen +* Date: 15:54:48 on January 20, 2026 +* Origin: UCPH@NBI, Funded by ACTNXT +* %INSTRUMENT_SITE: Tests_union +* +* Small test instrument testing placement of low-priority Union cylinder within higher-priority Union cylinder. +* +* %Description +* A small test instrument testing the placement of one cylinder with a low priority +* fully inside another cylinder with a higher priority. This was added to test +* for an mcdisplay error that used to occur, when a cylinder is completely +* enclosed in another cylinder. +* To test this simply do +* a "mcdisplay Hidden_Cylinder.instr -c -y" +* +* %Example: pin_rad=0.0025 Detector: det_I=3.42884e-06 +* +* %Parameters +* pin_rad: [m] Radius of source +* d: [m] Distance between source and sample center +* detector_x: [m] Detector Width +* detector_y: [m] Detector Height +* det_dist: [m] Distance between detector and sample center +* +* %Link +* +* %End +********************************************************************************/ + +DEFINE INSTRUMENT Hidden_Cylinder ( +double pin_rad = 0.0025, // Radius of source +double d = 10, // Distance between source and sample center +double detector_x = 0.01, // Detector Width +double detector_y = 0.04, // Detector Height +double det_dist = 0.005 // Distance between detector and sample center +) + +DECLARE +%{ +%} + +INITIALIZE +%{ +%} + +TRACE +COMPONENT Origin = Progress_bar() +AT (0, 0, 0) ABSOLUTE + +COMPONENT source = Source_simple( + radius = pin_rad, yheight = 0, + xwidth = 0, dist = d, + focus_xw = detector_x, focus_yh = detector_y, + lambda0 = 4, dlambda = 3) +AT (0, 0, 0) RELATIVE Origin +ROTATED (0.0, 0.0, 0.0) RELATIVE Origin + +COMPONENT entry_mon = PSD_monitor( + nx = 200, ny = 200, + xwidth = detector_x, yheight = detector_x, + restore_neutron = 1) +AT (0, 0, 0.0001) RELATIVE source +ROTATED (0.0, 0.0, 0.0) RELATIVE source + +COMPONENT arm_sample_position = Arm() +AT (0, 0, d) RELATIVE source +ROTATED (0, 0, 0) RELATIVE Origin + +COMPONENT init = Union_init() +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample_inc = Incoherent_process( + sigma = 0.4 * 2, unit_cell_volume = 24.04) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample_pow = Powder_process( + reflections = "Fe.laz") +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample = Union_make_material( + process_string = "Sample_inc,Sample_pow", my_absorption = 10*2.56 * 2 / 24.04 * 100) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT gas_process = Incoherent_process( + sigma = 0.4 * 2, unit_cell_volume = 240000.04) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT sample_gas = Union_make_material( + process_string = "gas_process", my_absorption = 21.29783693843594) +AT (0, 0, 0) RELATIVE Sample +ROTATED (0.0, 0.0, 0.0) RELATIVE Sample + +COMPONENT sample_cyl_metal = Union_cylinder( + material_string = "Sample", priority = 50, + radius = 0.005 / 2, yheight = 0.034) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT sample_cyl_gas = Union_cylinder( + material_string = "sample_gas", priority = 51, + radius = 0.009 / 2, yheight = 0.053, + visualize = 1) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + + COMPONENT logger_space_zx = Union_logger_2D_space( + D_direction_1 = "z", D1_min = -0.05, + D1_max = 0.05, n1 = 300, + D_direction_2 = "x", D2_min = -0.05, + D2_max = 0.05, n2 = 300, + filename = "logger_zx.dat") +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT logger_space_zy = Union_logger_2D_space( + D_direction_1 = "z", D1_min = -0.05, + D1_max = 0.05, n1 = 300, + D_direction_2 = "y", D2_min = -0.05, + D2_max = 0.05, n2 = 300, + filename = "logger_zy.dat") +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample_environment = Union_master( + verbal = 1) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT stop = Union_stop() +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT det = PSD_monitor( + nx = 1000, ny = 1000, + filename = "det", xwidth = detector_x, + yheight = detector_y) +AT (0, 0, 0.034 / 2 + det_dist) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +FINALLY +%{ +%} + +END diff --git a/mcstas-comps/examples/Tests_union/Many_meshes/Many_meshes.instr b/mcstas-comps/examples/Tests_union/Many_meshes/Many_meshes.instr new file mode 100644 index 000000000..e36ba0924 --- /dev/null +++ b/mcstas-comps/examples/Tests_union/Many_meshes/Many_meshes.instr @@ -0,0 +1,172 @@ +/******************************************************************************** +* +* McStas, neutron ray-tracing package +* Copyright (C) 1997-2008, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* This file was written by McStasScript, which is a +* python based McStas instrument generator written by +* Mads Bertelsen in 2019 while employed at the +* European Spallation Source Data Management and +* Software Centre +* +* Instrument: Many_meshes +* +* %Identification +* Written by: Daniel Lomholt Christensen +* Date: 15:54:48 on January 20, 2026 +* Origin: UCPH@NBI, Funded by ACTNXT +* %INSTRUMENT_SITE: Tests_union +* +* Instrument testing placement of overlapping mesh components. +* +* %Description +* A small test instrument testing the placement of many overlapping +* mesh components. +* Test with: +* mcdisplay -y -c +* +* %Example: pin_rad=0.0025 Detector:det_I=4.63384e-06 +* +* %Parameters +* pin_rad: [m] Radius of source +* d: [m] Distance between source and sample center +* detector_x: [m] Detector Width +* detector_y: [m] Detector Height +* det_dist: [m] Distance between detector and sample center +* crack_width: [m] Height masking crack should be raised from the original crack +* +* %Link +* +* %End +********************************************************************************/ + +DEFINE INSTRUMENT Many_meshes ( +double pin_rad = 0.0025, // Radius of source +double d = 10, // Distance between source and sample center +double detector_x = 0.01, // Detector Width +double detector_y = 0.04, // Detector Height +double det_dist = 0.005, // Distance between detector and sample center +double crack_width = 0.003 // Height masking crack should be raised from the original crack +) +DEPENDENCY " @NCRYSTALFLAGS@ -DFUNNEL " + +DECLARE +%{ +%} + +INITIALIZE +%{ +// Start of initialize for generated imaging +%} + +TRACE +COMPONENT Origin = Progress_bar() +AT (0, 0, 0) ABSOLUTE + +COMPONENT source = Source_simple( + radius = pin_rad, yheight = 0, + xwidth = 0, dist = d, + focus_xw = detector_x, focus_yh = detector_y, + lambda0 = 4, dlambda = 3) +AT (0, 0, 0) RELATIVE Origin +ROTATED (0.0, 0.0, 0.0) RELATIVE Origin + +COMPONENT entry_mon = PSD_monitor( + nx = 200, ny = 200, + xwidth = detector_x, yheight = detector_x, + restore_neutron = 1) +AT (0, 0, 0.0001) RELATIVE source +ROTATED (0.0, 0.0, 0.0) RELATIVE source + +COMPONENT arm_sample_position = Arm() +AT (0, 0, d) RELATIVE source +ROTATED (0, 0, 0) RELATIVE Origin + +COMPONENT init = Union_init() +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample_inc = Incoherent_process( + sigma = 0.4 * 2, unit_cell_volume = 24.04) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample_pow = Powder_process( + reflections = "Fe.laz") +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample = Union_make_material( + process_string = "Sample_inc,Sample_pow", my_absorption = 10*2.56 * 2 / 24.04 * 100) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT gas_process = NCrystal_process( + cfg = "gasmix::H2/10bar") +AT (0, 0, 0) RELATIVE Sample +ROTATED (0.0, 0.0, 0.0) RELATIVE Sample + +COMPONENT sample_gas = Union_make_material( + process_string = "gas_process", my_absorption = 21.29783693843594) +AT (0, 0, 0) RELATIVE gas_process +ROTATED (0.0, 0.0, 0.0) RELATIVE gas_process + +COMPONENT arm_crack = Arm() +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (90, 0, 0) RELATIVE arm_sample_position + +COMPONENT masking_crack = Union_mesh( + filename = "test.stl", material_string = "Sample", + priority = 140, skip_convex_check = 1) +AT (0, 0, 0.0005) RELATIVE arm_crack +ROTATED (0, 0, 0) RELATIVE arm_crack + +COMPONENT crack = Union_mesh( + filename = "test.stl", material_string = "sample_gas", + priority = 139, skip_convex_check = 1, + coordinate_scale = 0.0009811453007353597) +AT (0, 0, 0) RELATIVE arm_crack +ROTATED (0, 0, 0) RELATIVE arm_crack + +COMPONENT logger_space_zx = Union_logger_2D_space( + D_direction_1 = "z", D1_min = -0.05, + D1_max = 0.05, n1 = 300, + D_direction_2 = "x", D2_min = -0.05, + D2_max = 0.05, n2 = 300, + filename = "logger_zx.dat") +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT logger_space_zy = Union_logger_2D_space( + D_direction_1 = "z", D1_min = -0.05, + D1_max = 0.05, n1 = 300, + D_direction_2 = "y", D2_min = -0.05, + D2_max = 0.05, n2 = 300, + filename = "logger_zy.dat") +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT Sample_environment = Union_master( + verbal = 1) +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT stop = Union_stop() +AT (0, 0, 0) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +COMPONENT det = PSD_monitor( + nx = 1000, ny = 1000, + filename = "det", xwidth = detector_x, + yheight = detector_y) +AT (0, 0, 0.034 / 2 + det_dist) RELATIVE arm_sample_position +ROTATED (0.0, 0.0, 0.0) RELATIVE arm_sample_position + +FINALLY +%{ +// Start of finally for generated imaging +%} + +END diff --git a/mcstas-comps/examples/Tests_union/Many_meshes/test.stl b/mcstas-comps/examples/Tests_union/Many_meshes/test.stl new file mode 100644 index 000000000..a305b45a9 Binary files /dev/null and b/mcstas-comps/examples/Tests_union/Many_meshes/test.stl differ diff --git a/mcstas-comps/share/union-lib.c b/mcstas-comps/share/union-lib.c index 82732c2f1..eac2f889a 100755 --- a/mcstas-comps/share/union-lib.c +++ b/mcstas-comps/share/union-lib.c @@ -2146,8 +2146,7 @@ void merge_lines_to_draw(struct lines_to_draw *lines_master,struct lines_to_draw if (lines_master->number_of_lines == 0) { lines_master->number_of_lines = lines_new->number_of_lines; if (!lines_master->number_of_lines) { - fprintf(stderr,"Failure allocating list in Union function merge_lines_to_draw 1 - Exit!\n"); - exit(EXIT_FAILURE); + return; } lines_master->lines = malloc(lines_master->number_of_lines*sizeof(struct line_segment)); if (!lines_master->lines) { @@ -2308,23 +2307,27 @@ struct lines_to_draw draw_line_with_highest_priority(Coords position1,Coords pos int geometry_output; // Todo: switch to nicer intersect function call - double *double_dummy = malloc(2*sizeof(double)); - int int_dummy[2]; + double *double_dummy = malloc(max_number_of_solutions*sizeof(double)); + int *int_dummy = malloc(max_number_of_solutions*sizeof(int)); // We need a storing pointer for the reallocs, to ensure that on realloc fail // All is handled correctly double *tmp; + int *tmpint; // Find intersections for (volume_index = 1;volume_index < number_of_volumes; volume_index++) { if (volume_index != N) { if (Geometries[volume_index]->eShape==mesh){ tmp = realloc(double_dummy, sizeof(double)*1000); - if ( tmp==NULL ) { + tmpint = realloc(int_dummy, sizeof(double)*1000); + if ( tmp==NULL || tmpint==NULL ) { free(tmp); + free(tmpint); printf("\nERROR: Realloc failed on double dummy"); exit(1); } else { double_dummy = tmp; + int_dummy = tmpint; tmp = realloc(temp_intersection, sizeof(double)*1000); if ( tmp == NULL){ free(tmp); diff --git a/mcstas-comps/union/Union_mesh.comp b/mcstas-comps/union/Union_mesh.comp index 9e04de93d..47eb8b280 100644 --- a/mcstas-comps/union/Union_mesh.comp +++ b/mcstas-comps/union/Union_mesh.comp @@ -509,48 +509,48 @@ void mcdisplay_mesh_function(struct lines_to_draw *lines_to_draw_output,int inde // Make sure it does not print a line if it is already printed.... (might take a while?) for (i = 0 ; i < counter ; i++){ if (print1 == 1 && coord_comp(point1 , list_startpoints[i])){ - for (j = 0 ; j < counter ; j++){ - if (coord_comp(point2 , list_startpoints[i])){ - print1 = 0; - } - } + for (j = 0 ; j < counter ; j++){ + if (coord_comp(point2 , list_startpoints[i])){ + print1 = 0; + } + } } if (print2 == 1 && coord_comp(point2 , list_startpoints[i])){ - for (j = 0 ; j < counter ; j++){ - if (coord_comp(point1 , list_startpoints[i])){ - print1 = 0; - } - } + for (j = 0 ; j < counter ; j++){ + if (coord_comp(point1 , list_startpoints[i])){ + print1 = 0; + } + } } if (print2 == 1 && coord_comp(point2 , list_startpoints[i]) ){ - for (j = 0 ; j < counter ; j++){ - if (coord_comp(point3 , list_startpoints[i])){ - print2 = 0; - } - } + for (j = 0 ; j < counter ; j++){ + if (coord_comp(point3 , list_startpoints[i])){ + print2 = 0; + } + } } if (print3 == 1 && coord_comp(point3 , list_startpoints[i]) ){ - for (j = 0 ; j < counter ; j++){ - if (coord_comp(point2 , list_startpoints[i])){ - print2 = 0; - } - } + for (j = 0 ; j < counter ; j++){ + if (coord_comp(point2 , list_startpoints[i])){ + print2 = 0; + } + } } if (print1 == 1 && coord_comp(point1 , list_startpoints[i]) ){ - for (j = 0 ; j < counter ; j++){ - if (coord_comp(point1 , list_startpoints[i])){ - print3 = 0; - } - } + for (j = 0 ; j < counter ; j++){ + if (coord_comp(point1 , list_startpoints[i])){ + print3 = 0; + } + } } if (print3 == 1 && coord_comp(point3 , list_startpoints[i])){ - for (j = 0 ; j < counter ; j++){ - if (coord_comp(point1 , list_startpoints[i])){ - print3 = 0; - } - } + for (j = 0 ; j < counter ; j++){ + if (coord_comp(point1 , list_startpoints[i])){ + print3 = 0; + } + } } - + } @@ -968,6 +968,8 @@ if(strcmp(dot, ".stl") == 0 || strcmp(dot, ".STL") == 0){ NAME_CURRENT_COMP, filename); exit(1); } +printf("\nCOMPONENT %s: Number of faces read: %d\t Number of vertices read: %d\n", + NAME_CURRENT_COMP, n_verts, n_faces); // Loop over all vertices and multiply their positions with coordinate_scale for (int i = 0; i