OpenCMISS-Iron Internal API Documentation
data_projection_routines.f90
Go to the documentation of this file.
1 
43 
45 
47 
48  USE base_routines
49  USE cmiss_mpi
51  USE constants
52  USE domain_mappings
53  USE field_routines
54  USE input_output
56  USE kinds
57  USE mesh_routines
58 #ifndef NOMPIMOD
59  USE mpi
60 #endif
61  USE sorting
62  USE strings
63  USE trees
64  USE types
65 
66 #include "macros.h"
67 
68  IMPLICIT NONE
69 
70  PRIVATE
71 
72 #ifdef NOMPIMOD
73 #include "mpif.h"
74 #endif
75 
76  !Module parameters
77 
82  INTEGER(INTG), PARAMETER :: data_projection_boundary_lines_projection_type=1
83  INTEGER(INTG), PARAMETER :: data_projection_boundary_faces_projection_type=2
84  INTEGER(INTG), PARAMETER :: data_projection_all_elements_projection_type=3
86 
91  INTEGER(INTG), PARAMETER :: data_projection_exit_tag_converged=1
92  INTEGER(INTG), PARAMETER :: data_projection_exit_tag_bounds=2
93  INTEGER(INTG), PARAMETER :: data_projection_exit_tag_max_iteration=3
94  INTEGER(INTG), PARAMETER :: data_projection_exit_tag_no_element=4
96 
97  !Module types
98 
99  !Module variables
100 
101  !Interfaces
102 
105  MODULE PROCEDURE data_projection_label_get_c
106  MODULE PROCEDURE data_projection_label_get_vs
107  END INTERFACE !DATA_PROJECTION_LABEL_GET
108 
111  MODULE PROCEDURE data_projection_label_set_c
112  MODULE PROCEDURE data_projection_label_set_vs
113  END INTERFACE !DATA_PROJECTION_LABEL_SET
114 
117 
119 
121 
123 
125 
127 
129 
131 
133 
135 
137 
139 
141 
143 
145 
147 
149 
151 
153 
155 
157 
158 CONTAINS
159 
160  !
161  !================================================================================================================================
162  !
163 
165  SUBROUTINE data_projection_absolute_tolerance_get(DATA_PROJECTION,ABSOLUTE_TOLERANCE,ERR,ERROR,*)
167  !Argument variables
168  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
169  REAL(DP), INTENT(OUT) :: ABSOLUTE_TOLERANCE
170  INTEGER(INTG), INTENT(OUT) :: ERR
171  TYPE(varying_string), INTENT(OUT) :: ERROR
172  !Local Variables
173 
174  enters("DATA_PROJECTION_ABSOLUTE_TOLERANCE_GET",err,error,*999)
175 
176  IF(ASSOCIATED(data_projection)) THEN
177  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
178  absolute_tolerance=data_projection%ABSOLUTE_TOLERANCE
179  ELSE
180  CALL flag_error("Data projection have not been finished.",err,error,*999)
181  ENDIF
182  ELSE
183  CALL flag_error("Data projection is not associated.",err,error,*999)
184  ENDIF
185 
186  exits("DATA_PROJECTION_ABSOLUTE_TOLERANCE_GET")
187  RETURN
188 999 errorsexits("DATA_PROJECTION_ABSOLUTE_TOLERANCE_GET",err,error)
189  RETURN 1
190 
192 
193  !
194  !================================================================================================================================
195  !
196 
198  SUBROUTINE data_projection_absolute_tolerance_set(DATA_PROJECTION,ABSOLUTE_TOLERANCE,ERR,ERROR,*)
200  !Argument variables
201  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
202  REAL(DP), INTENT(IN) :: ABSOLUTE_TOLERANCE
203  INTEGER(INTG), INTENT(OUT) :: ERR
204  TYPE(varying_string), INTENT(OUT) :: ERROR
205  !Local Variables
206 
207  enters("DATA_PROJECTION_ABSOLUTE_TOLERANCE_SET",err,error,*999)
208 
209  IF(ASSOCIATED(data_projection)) THEN
210  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
211  CALL flag_error("Data projection have been finished.",err,error,*999)
212  ELSE
213  IF(absolute_tolerance>=0) THEN
214  data_projection%ABSOLUTE_TOLERANCE=absolute_tolerance
215  ELSE
216  CALL flag_error("Data projection absolute tolerance must be a positive real number.",err,error,*999)
217  ENDIF
218  ENDIF
219  ELSE
220  CALL flag_error("Data projection is not associated.",err,error,*999)
221  ENDIF
222 
223  exits("DATA_PROJECTION_ABSOLUTE_TOLERANCE_SET")
224  RETURN
225 999 errorsexits("DATA_PROJECTION_ABSOLUTE_TOLERANCE_SET",err,error)
226  RETURN 1
227 
229 
230  !
231  !================================================================================================================================
232  !
233 
235  SUBROUTINE data_projection_closest_elements_find(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES, &
236  & candidate_elements,number_of_candidates,closest_elements,closest_distances,err,error,*)
238  !Argument variables
239  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
240  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
241  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
242  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
243  INTEGER(INTG), INTENT(IN) :: NUMBER_OF_CANDIDATES
244  INTEGER(INTG), INTENT(OUT) :: CLOSEST_ELEMENTS(:)
245  REAL(DP), INTENT(OUT) :: CLOSEST_DISTANCES(:)
246  INTEGER(INTG), INTENT(OUT) :: ERR
247  TYPE(varying_string), INTENT(OUT) :: ERROR
248  !Local Variables
249 
250  INTEGER(INTG) :: REGION_DIMENSIONS
251  INTEGER(INTG) :: NUMBER_OF_CLOSEST_CANDIDATES
252  REAL(DP) :: DISTANCE_VECTOR(3)
253  REAL(DP) :: DISTANCE2
254  INTEGER(INTG) :: nce
255  INTEGER(INTG) :: ELEMENT_NUMBER,insert_idx
256 
257  enters("DATA_PROJECTION_CLOSEST_ELEMENTS_FIND",err,error,*999)
258 
259  IF(ASSOCIATED(data_projection)) THEN
260  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
261  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
262  number_of_closest_candidates=SIZE(closest_elements,1)
263  !loop through the first few elements
264  DO nce=1,number_of_closest_candidates
265  element_number=candidate_elements(nce)
266  CALL field_interpolation_parameters_element_get(field_values_set_type,element_number, &
267  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
268  CALL field_interpolate_xi(no_part_deriv,data_projection%STARTING_XI,interpolated_point,err,error,*999, &
269  & field_geometric_components_type)
270  distance_vector(1:region_dimensions) = point_values-interpolated_point%VALUES(:,1)
271  distance2 = dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
272  DO insert_idx=nce,1,-1
273  IF(insert_idx>1) THEN
274  IF(distance2<closest_distances(insert_idx-1)) cycle
275  ENDIF
276  !insert the element number into the correct index
277  IF(insert_idx<nce) THEN
278  closest_distances(insert_idx+1:nce)=closest_distances(insert_idx:nce-1)
279  closest_elements(insert_idx+1:nce)=closest_elements(insert_idx:nce-1)
280  ENDIF
281  closest_distances(insert_idx)=distance2
282  closest_elements(insert_idx)=element_number
283  EXIT
284  ENDDO
285  ENDDO
286  !Loop through the rest of the elements
287  DO nce=number_of_closest_candidates+1,number_of_candidates
288  element_number=candidate_elements(nce)
289  CALL field_interpolation_parameters_element_get(field_values_set_type,element_number, &
290  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
291  CALL field_interpolate_xi(no_part_deriv,data_projection%STARTING_XI,interpolated_point,err,error,*999, &
292  & field_geometric_components_type)
293  distance_vector(1:region_dimensions)=point_values - interpolated_point%VALUES(:,1)
294  distance2 = dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
295  IF(distance2<closest_distances(number_of_closest_candidates))THEN
296  DO insert_idx=number_of_closest_candidates,1,-1
297  IF(insert_idx>1) THEN
298  IF(distance2<closest_distances(insert_idx-1)) cycle
299  ENDIF
300  !insert the element into the correct index
301  IF(insert_idx<number_of_closest_candidates) THEN
302  closest_distances(insert_idx+1:number_of_closest_candidates)=closest_distances(insert_idx: &
303  & number_of_closest_candidates-1)
304  closest_elements(insert_idx+1:number_of_closest_candidates)=closest_elements(insert_idx: &
305  & number_of_closest_candidates-1)
306  ENDIF
307  closest_distances(insert_idx)=distance2
308  closest_elements(insert_idx)=element_number
309  EXIT
310  ENDDO
311  ENDIF
312  ENDDO
313  !CLOSEST_DISTANCES=SQRT(CLOSEST_DISTANCES) !return shortest distances
314  ELSE
315  CALL flag_error("Data projection have not been finished.",err,error,*999)
316  ENDIF
317  ELSE
318  CALL flag_error("Data projection is not associated.",err,error,*999)
319  ENDIF
320 
321  exits("DATA_PROJECTION_CLOSEST_ELEMENTS_FIND")
322  RETURN
323 999 errorsexits("DATA_PROJECTION_CLOSEST_ELEMENTS_FIND",err,error)
324  RETURN 1
325 
327 
328  !
329  !================================================================================================================================
330  !
331 
333  SUBROUTINE data_projection_closest_faces_find(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
334  & candidate_element_faces,number_of_candidates,closest_elements,closest_element_faces,closest_distances,err,error,*)
336  !Argument variables
337  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
338  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
339  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
340  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
341  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENT_FACES(:)
342  INTEGER(INTG), INTENT(IN) :: NUMBER_OF_CANDIDATES
343  INTEGER(INTG), INTENT(OUT) :: CLOSEST_ELEMENTS(:)
344  INTEGER(INTG), INTENT(OUT) :: CLOSEST_ELEMENT_FACES(:)
345  REAL(DP), INTENT(OUT) :: CLOSEST_DISTANCES(:)
346  INTEGER(INTG), INTENT(OUT) :: ERR
347  TYPE(varying_string), INTENT(OUT) :: ERROR
348  !Local Variables
349  INTEGER(INTG) :: REGION_DIMENSIONS
350  INTEGER(INTG) :: NUMBER_OF_CLOSEST_CANDIDATES
351  REAL(DP) :: DISTANCE_VECTOR(3)
352  REAL(DP) :: DISTANCE2
353  INTEGER(INTG) :: nce
354  INTEGER(INTG) :: ELEMENT_NUMBER,ELEMENT_FACE_NUMBER,FACE_NUMBER,insert_idx
355 
356  enters("DATA_PROJECTION_CLOSEST_FACES_FIND",err,error,*999)
357  IF(ASSOCIATED(data_projection)) THEN
358  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
359  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
360  number_of_closest_candidates=SIZE(closest_elements,1)
361  !loop through the first few faces
362  DO nce=1,number_of_closest_candidates
363  element_number=candidate_elements(nce)
364  element_face_number=candidate_element_faces(nce)
365  face_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%TOPOLOGY%ELEMENTS%ELEMENTS( &
366  & element_number)%ELEMENT_FACES(element_face_number)
367  CALL field_interpolation_parameters_face_get(field_values_set_type,face_number, &
368  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
369  CALL field_interpolate_xi(no_part_deriv,data_projection%STARTING_XI,interpolated_point,err,error,*999, &
370  & field_geometric_components_type)
371  distance_vector(1:region_dimensions) = point_values-interpolated_point%VALUES(:,1)
372  distance2 = dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
373  DO insert_idx=nce,1,-1
374  IF(insert_idx>1) THEN
375  IF(distance2<closest_distances(insert_idx-1)) cycle
376  ENDIF
377  !insert the element number into the correct index
378  IF(insert_idx<nce) THEN
379  closest_distances(insert_idx+1:nce)=closest_distances(insert_idx:nce-1)
380  closest_elements(insert_idx+1:nce)=closest_elements(insert_idx:nce-1)
381  closest_element_faces(insert_idx+1:nce)=closest_element_faces(insert_idx:nce-1)
382  ENDIF
383  closest_distances(insert_idx)=distance2
384  closest_elements(insert_idx)=element_number
385  closest_element_faces(insert_idx)=element_face_number
386  EXIT
387  ENDDO
388  ENDDO
389  !Loop through the rest of the faces
390  DO nce=number_of_closest_candidates+1,number_of_candidates
391  element_number=candidate_elements(nce)
392  element_face_number=candidate_element_faces(nce)
393  face_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%TOPOLOGY%ELEMENTS%ELEMENTS( &
394  & element_number)%ELEMENT_FACES(element_face_number)
395  CALL field_interpolation_parameters_face_get(field_values_set_type,face_number, &
396  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
397  CALL field_interpolate_xi(no_part_deriv,data_projection%STARTING_XI,interpolated_point,err,error,*999, &
398  & field_geometric_components_type)
399  distance_vector(1:region_dimensions)=point_values - interpolated_point%VALUES(:,1)
400  distance2 = dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
401  IF(distance2<closest_distances(number_of_closest_candidates))THEN
402  DO insert_idx=number_of_closest_candidates,1,-1
403  IF(insert_idx>1) THEN
404  IF(distance2<closest_distances(insert_idx-1)) cycle
405  ENDIF
406  !insert the element into the correct index
407  IF(insert_idx<number_of_closest_candidates) THEN
408  closest_distances(insert_idx+1:number_of_closest_candidates)=closest_distances(insert_idx: &
409  & number_of_closest_candidates-1)
410  closest_elements(insert_idx+1:number_of_closest_candidates)=closest_elements(insert_idx: &
411  & number_of_closest_candidates-1)
412  closest_element_faces(insert_idx+1:number_of_closest_candidates)=closest_element_faces(insert_idx: &
413  & number_of_closest_candidates-1)
414  ENDIF
415  closest_distances(insert_idx)=distance2
416  closest_elements(insert_idx)=element_number
417  closest_element_faces(insert_idx)=element_face_number
418  EXIT
419  ENDDO
420  ENDIF
421  ENDDO
422  !CLOSEST_DISTANCES=SQRT(CLOSEST_DISTANCES) !return shortest distances
423  ELSE
424  CALL flag_error("Data projection have not been finished.",err,error,*999)
425  ENDIF
426  ELSE
427  CALL flag_error("Data projection is not associated.",err,error,*999)
428  ENDIF
429 
430  exits("DATA_PROJECTION_CLOSEST_FACES_FIND")
431  RETURN
432 999 errorsexits("DATA_PROJECTION_CLOSEST_FACES_FIND",err,error)
433  RETURN 1
434 
436 
437  !
438  !================================================================================================================================
439  !
440 
442  SUBROUTINE data_projection_closest_lines_find(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
443  & candidate_element_lines,number_of_candidates,closest_elements,closest_element_lines,closest_distances,err,error,*)
445  !Argument variables
446  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
447  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
448  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
449  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
450  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENT_LINES(:)
451  INTEGER(INTG), INTENT(IN) :: NUMBER_OF_CANDIDATES
452  INTEGER(INTG), INTENT(OUT) :: CLOSEST_ELEMENTS(:)
453  INTEGER(INTG), INTENT(OUT) :: CLOSEST_ELEMENT_LINES(:)
454  REAL(DP), INTENT(OUT) :: CLOSEST_DISTANCES(:)
455  INTEGER(INTG), INTENT(OUT) :: ERR
456  TYPE(varying_string), INTENT(OUT) :: ERROR
457  !Local Variables
458  INTEGER(INTG) :: REGION_DIMENSIONS
459  INTEGER(INTG) :: NUMBER_OF_CLOSEST_CANDIDATES
460  REAL(DP) :: DISTANCE_VECTOR(3)
461  REAL(DP) :: DISTANCE2
462  INTEGER(INTG) :: nce
463  INTEGER(INTG) :: ELEMENT_NUMBER,ELEMENT_LINE_NUMBER,LINE_NUMBER,insert_idx
464 
465  enters("DATA_PROJECTION_CLOSEST_LINES_FIND",err,error,*999)
466  IF(ASSOCIATED(data_projection)) THEN
467  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
468  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
469  number_of_closest_candidates=SIZE(closest_elements,1)
470  !loop through the first few lines
471  DO nce=1,number_of_closest_candidates
472  element_number=candidate_elements(nce)
473  element_line_number=candidate_element_lines(nce)
474  line_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%TOPOLOGY%ELEMENTS%ELEMENTS( &
475  & element_number)%ELEMENT_LINES(element_line_number)
476  CALL field_interpolation_parameters_line_get(field_values_set_type,line_number, &
477  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
478  CALL field_interpolate_xi(no_part_deriv,data_projection%STARTING_XI,interpolated_point,err,error,*999, &
479  & field_geometric_components_type)
480  distance_vector(1:region_dimensions) = point_values-interpolated_point%VALUES(:,1)
481  distance2 = dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
482  DO insert_idx=nce,1,-1
483  IF(insert_idx>1) THEN
484  IF(distance2<closest_distances(insert_idx-1)) cycle
485  ENDIF
486  !insert the element number into the correct index
487  IF(insert_idx<nce) THEN
488  closest_distances(insert_idx+1:nce)=closest_distances(insert_idx:nce-1)
489  closest_elements(insert_idx+1:nce)=closest_elements(insert_idx:nce-1)
490  closest_element_lines(insert_idx+1:nce)=closest_element_lines(insert_idx:nce-1)
491  ENDIF
492  closest_distances(insert_idx)=distance2
493  closest_elements(insert_idx)=element_number
494  closest_element_lines(insert_idx)=element_line_number
495  EXIT
496  ENDDO
497  ENDDO
498  !Loop through the rest of the lines
499  DO nce=number_of_closest_candidates+1,number_of_candidates
500  element_number=candidate_elements(nce)
501  element_line_number=candidate_element_lines(nce)
502  line_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%TOPOLOGY%ELEMENTS%ELEMENTS( &
503  & element_number)%ELEMENT_LINES(element_line_number)
504  CALL field_interpolation_parameters_line_get(field_values_set_type,line_number, &
505  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
506  CALL field_interpolate_xi(no_part_deriv,data_projection%STARTING_XI,interpolated_point,err,error,*999, &
507  & field_geometric_components_type)
508  distance_vector(1:region_dimensions)=point_values - interpolated_point%VALUES(:,1)
509  distance2 = dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
510  IF(distance2<closest_distances(number_of_closest_candidates))THEN
511  DO insert_idx=number_of_closest_candidates,1,-1
512  IF(insert_idx>1) THEN
513  IF(distance2<closest_distances(insert_idx-1)) cycle
514  ENDIF
515  !insert the element into the correct index
516  IF(insert_idx<number_of_closest_candidates) THEN
517  closest_distances(insert_idx+1:number_of_closest_candidates)=closest_distances(insert_idx: &
518  & number_of_closest_candidates-1)
519  closest_elements(insert_idx+1:number_of_closest_candidates)=closest_elements(insert_idx: &
520  & number_of_closest_candidates-1)
521  closest_element_lines(insert_idx+1:number_of_closest_candidates)=closest_element_lines(insert_idx: &
522  & number_of_closest_candidates-1)
523  ENDIF
524  closest_distances(insert_idx)=distance2
525  closest_elements(insert_idx)=element_number
526  closest_element_lines(insert_idx)=element_line_number
527  EXIT
528  ENDDO
529  ENDIF
530  ENDDO
531  !CLOSEST_DISTANCES=SQRT(CLOSEST_DISTANCES) !return shortest distances
532  ELSE
533  CALL flag_error("Data projection have not been finished.",err,error,*999)
534  ENDIF
535  ELSE
536  CALL flag_error("Data projection is not associated.",err,error,*999)
537  ENDIF
538 
539  exits("DATA_PROJECTION_CLOSEST_LINES_FIND")
540  RETURN
541 999 errorsexits("DATA_PROJECTION_CLOSEST_LINES_FIND",err,error)
542  RETURN 1
543 
545 
546  !
547  !================================================================================================================================
548  !
549 
551  SUBROUTINE data_projection_create_finish(DATA_PROJECTION,ERR,ERROR,*)
553  !Argument variables
554  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
555  INTEGER(INTG), INTENT(OUT) :: ERR
556  TYPE(varying_string), INTENT(OUT) :: ERROR
557  !Local Variables
558 
559  enters("DATA_PROJECTION_CREATE_FINISH",err,error,*999)
560 
561  IF(ASSOCIATED(data_projection)) THEN !Has to be associated
562  IF(ASSOCIATED(data_projection%DATA_POINTS)) THEN !Has to be associated
563  IF(data_projection%DATA_POINTS%DATA_POINTS_FINISHED) THEN !Has to be finished
564  IF(ASSOCIATED(data_projection%MESH)) THEN !Has to be associated
565  IF(data_projection%DATA_PROJECTION_FINISHED) THEN !Cannot be finished
566  CALL flag_error("Data projection have already been finished.",err,error,*999)
567  ELSE
568  data_projection%DATA_PROJECTION_FINISHED=.true.
569  CALL dataprojection_dataprojectionresultinitialise(data_projection,err,error, &
570  & *999)
571  ENDIF
572  ELSE
573  CALL flag_error("Data projection mesh is not associated.",err,error,*999)
574  ENDIF
575  ELSE
576  CALL flag_error("Data projection data points have not been finished.",err,error,*999)
577  ENDIF
578  ELSE
579  CALL flag_error("Data projection data points is not associated.",err,error,*999)
580  ENDIF
581  ELSE
582  CALL flag_error("Data projection is not associated.",err,error,*999)
583  ENDIF
584 
585  exits("DATA_PROJECTION_CREATE_FINISH")
586  RETURN
587 999 errorsexits("DATA_PROJECTION_CREATE_FINISH",err,error)
588  RETURN 1
589 
590  END SUBROUTINE data_projection_create_finish
591 
592  !
593  !================================================================================================================================
594  !
596  SUBROUTINE data_projection_create_start_data_points(DATA_PROJECTION_USER_NUMBER,DATA_POINTS,MESH,DATA_PROJECTION, &
597  & err,error,*)
599  !Argument variables
600  INTEGER(INTG), INTENT(IN) :: DATA_PROJECTION_USER_NUMBER
601  TYPE(data_points_type), POINTER :: DATA_POINTS
602  TYPE(mesh_type), POINTER :: MESH
603  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
604  INTEGER(INTG), INTENT(OUT) :: ERR
605  TYPE(varying_string), INTENT(OUT) :: ERROR
606  !Local Variables
607  TYPE(data_projection_ptr_type), ALLOCATABLE :: NEW_DATA_PROJECTIONS_PTR(:)
608  INTEGER(INTG) :: DATA_POINTS_REGION_DIMENSIONS,MESH_REGION_DIMENSIONS,INSERT_STATUS
609  INTEGER(INTG) :: xi_idx,data_projection_idx
610 
611  enters("DATA_PROJECTION_CREATE_START_DATA_POINTS",err,error,*999)
612 
613  NULLIFY(data_projection)
614  IF(ASSOCIATED(data_points)) THEN !Has to be associated
615  IF(data_points%DATA_POINTS_FINISHED) THEN !Has to be finished
616  IF(ASSOCIATED(mesh)) THEN !Has to be associated
617  IF(ASSOCIATED(data_projection)) THEN !Cannot be associated
618  CALL flag_error("Data projection is already associated.",err,error,*999)
619  ELSE
620  IF(ASSOCIATED(data_points%REGION)) THEN
621  data_points_region_dimensions=data_points%REGION%COORDINATE_SYSTEM%NUMBER_OF_DIMENSIONS
622  ELSEIF(ASSOCIATED(data_points%INTERFACE)) THEN
623  data_points_region_dimensions=data_points%INTERFACE%COORDINATE_SYSTEM%NUMBER_OF_DIMENSIONS
624  ELSE
625  CALL flag_error("Data points is not associated with a region or a interface.",err,error,*999)
626  ENDIF
627  IF(ASSOCIATED(mesh%REGION)) THEN
628  mesh_region_dimensions=mesh%REGION%COORDINATE_SYSTEM%NUMBER_OF_DIMENSIONS
629  ELSEIF(ASSOCIATED(mesh%INTERFACE)) THEN
630  mesh_region_dimensions=mesh%INTERFACE%COORDINATE_SYSTEM%NUMBER_OF_DIMENSIONS
631  ELSE
632  CALL flag_error("Mesh is not associated with a region or a interface.",err,error,*999)
633  ENDIF
634  IF(data_points_region_dimensions==mesh_region_dimensions) THEN !Dimension has to be equal
635  ALLOCATE(data_projection,stat=err)
636  IF(err/=0) CALL flag_error("Could not allocate data projection.",err,error,*999)
637  data_projection%USER_NUMBER=data_projection_user_number
638  data_projection%LABEL=""
639  CALL tree_item_insert(data_points%DATA_PROJECTIONS_TREE,data_projection_user_number, &
640  & data_points%NUMBER_OF_DATA_PROJECTIONS+1,insert_status,err,error,*999)
641  data_projection%DATA_PROJECTION_FINISHED=.false.
642  data_projection%DATA_POINTS=>data_points
643  data_projection%MESH=>mesh
644  data_projection%COORDINATE_SYSTEM_DIMENSIONS=data_points_region_dimensions
645  data_projection%MAXIMUM_ITERATION_UPDATE=0.5_dp
646  data_projection%MAXIMUM_NUMBER_OF_ITERATIONS=25
647  !Default always project to boundaries faces/lines when mesh dimension is equal to region dimension. If mesh dimension is less, project to all elements
648  IF(mesh%NUMBER_OF_DIMENSIONS<data_points_region_dimensions) THEN !mesh dimension < data dimension
649  data_projection%NUMBER_OF_XI=mesh%NUMBER_OF_DIMENSIONS
650  data_projection%PROJECTION_TYPE=data_projection_all_elements_projection_type
651  ELSE
652  SELECT CASE(mesh%NUMBER_OF_DIMENSIONS) !mesh dimension = data dimension
653  CASE (2)
654  data_projection%NUMBER_OF_XI=1
655  data_projection%PROJECTION_TYPE=data_projection_boundary_lines_projection_type
656  CASE (3)
657  data_projection%NUMBER_OF_XI=2
658  data_projection%PROJECTION_TYPE=data_projection_boundary_faces_projection_type
659  CASE DEFAULT
660  CALL flag_error("Mesh dimensions out of bond [1,3].",err,error,*999)
661  END SELECT
662  ENDIF
663  SELECT CASE(data_projection%NUMBER_OF_XI) !mesh dimension = data dimension
664  CASE (1)
665  data_projection%NUMBER_OF_CLOSEST_ELEMENTS=2
666  CASE (2)
667  data_projection%NUMBER_OF_CLOSEST_ELEMENTS=4
668  CASE (3)
669  data_projection%NUMBER_OF_CLOSEST_ELEMENTS=8
670  CASE DEFAULT
671  CALL flag_error("Mesh dimensions out of bond [1,3].",err,error,*999)
672  END SELECT
673  ALLOCATE(data_projection%STARTING_XI(data_projection%NUMBER_OF_XI),stat=err)
674  IF(err/=0) CALL flag_error("Could not allocate data points data projection starting xi.",err,error,*999)
675  DO xi_idx=1,data_projection%NUMBER_OF_XI
676  data_projection%STARTING_XI(xi_idx)=0.5_dp
677  ENDDO !xi_idx
678  data_projection%ABSOLUTE_TOLERANCE=1.0e-8_dp
679  data_projection%RELATIVE_TOLERANCE=1.0e-6_dp
680  IF(data_points%NUMBER_OF_DATA_PROJECTIONS>0) THEN
681  ALLOCATE(new_data_projections_ptr(data_points%NUMBER_OF_DATA_PROJECTIONS+1),stat=err)
682  IF(err/=0) CALL flag_error("Could not allocate new data projections.",err,error,*999)
683  DO data_projection_idx=1,data_points%NUMBER_OF_DATA_PROJECTIONS
684  new_data_projections_ptr(data_projection_idx)%PTR=>data_points%DATA_PROJECTIONS(data_projection_idx)%PTR
685  ENDDO !xi_idx
686  ELSE IF(data_points%NUMBER_OF_DATA_PROJECTIONS==0) THEN
687  ALLOCATE(new_data_projections_ptr(data_points%NUMBER_OF_DATA_PROJECTIONS+1),stat=err)
688  IF(err/=0) CALL flag_error("Could not allocate new data projections.",err,error,*999)
689  ELSE
690  CALL flag_error("The number of data projections is < 0.",err,error,*999)
691  ENDIF
692  !Return the pointer
693  new_data_projections_ptr(data_points%NUMBER_OF_DATA_PROJECTIONS+1)%PTR=>data_projection
694  CALL move_alloc(new_data_projections_ptr,data_points%DATA_PROJECTIONS)
695  data_points%NUMBER_OF_DATA_PROJECTIONS=data_points%NUMBER_OF_DATA_PROJECTIONS+1
696  data_projection%GLOBAL_NUMBER=data_points%NUMBER_OF_DATA_PROJECTIONS
697  ELSE
698  CALL flag_error("Dimensions bewtween the mesh region/interface and data points region/interface does not match.", &
699  & err,error,*999)
700  ENDIF !DATA_POINTS_REGION_DIMENSIONS==MESH_REGION_DIMENSIONS
701  ENDIF !ASSOCIATED(DATA_PROJECTION)
702  ELSE
703  CALL flag_error("Mesh is not associated.",err,error,*999)
704  ENDIF !ASSOCIATED(MESH)
705  ELSE
706  CALL flag_error("Data points have not been finished.",err,error,*999)
707  ENDIF !DATA_POINTS%DATA_POINTS_FINISHED
708  ELSE
709  CALL flag_error("Data points is not associated.",err,error,*999)
710  ENDIF !ASSOCIATED(DATA_POINTS)
711 
712  exits("DATA_PROJECTION_CREATE_START_DATA_POINTS")
713  RETURN
714 999 errorsexits("DATA_PROJECTION_CREATE_START_DATA_POINTS",err,error)
715  RETURN 1
716 
718 
719  !
720  !================================================================================================================================
721  !
722 
724  SUBROUTINE dataprojection_datapointcheckexist(DataProjection,dataPointUserNumber,dataPointExist,dataPointGlobalNumber,err,error,*)
726  !Argument variables
727  TYPE(data_projection_type), POINTER :: DataProjection
728  INTEGER(INTG) :: dataPointUserNumber
729  LOGICAL, INTENT(OUT) :: dataPointExist
730  INTEGER(INTG), INTENT(OUT) :: dataPointGlobalNumber
731  INTEGER(INTG), INTENT(OUT) :: err
732  TYPE(varying_string), INTENT(OUT) :: error
733  !Local Variables
734  TYPE(data_points_type), POINTER :: dataPoints
735  TYPE(tree_node_type), POINTER :: treeNode
736 
737  enters("DataProjection_DataPointCheckExist",err,error,*999)
738 
739  datapointexist=.false.
740  datapointglobalnumber=0
741  IF(ASSOCIATED(dataprojection)) THEN
742  datapoints=>dataprojection%DATA_POINTS
743  IF(ASSOCIATED(datapoints)) THEN
744  NULLIFY(treenode)
745  CALL tree_search(datapoints%DATA_POINTS_TREE,datapointusernumber,treenode,err,error,*999)
746  IF(ASSOCIATED(treenode)) THEN
747  CALL tree_node_value_get(datapoints%DATA_POINTS_TREE,treenode,datapointglobalnumber,err,error,*999)
748  datapointexist=.true.
749  ENDIF
750  ELSE
751  CALL flag_error("Data points is not associated.",err,error,*999)
752  ENDIF
753  ELSE
754  CALL flag_error("Data projection is not associated.",err,error,*999)
755  ENDIF
756 
757  exits("DataProjection_DataPointCheckExist")
758  RETURN
759 999 errorsexits("DataProjection_DataPointCheckExist",err,error)
760  RETURN 1
761 
763 
764  !
765  !================================================================================================================================
766  !
767 
769  SUBROUTINE dataprojection_dataprojectionresultinitialise(DATA_PROJECTION,ERR,ERROR,*)
771  !Argument variables
772  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
773  INTEGER(INTG), INTENT(OUT) :: ERR
774  TYPE(varying_string), INTENT(OUT) :: ERROR
775  !Local Variables
776  INTEGER(INTG) :: NUMBER_OF_DATA_POINTS
777  INTEGER(INTG) :: data_point_idx
778 
779  enters("DataProjection_DataProjectionResultInitialise",err,error,*999)
780 
781  !NULLIFY(PROJECTED_POINTS)
782  IF(ASSOCIATED(data_projection)) THEN
783  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
784  IF(ASSOCIATED(data_projection%DATA_POINTS)) THEN
785  IF(data_projection%DATA_POINTS%DATA_POINTS_FINISHED) THEN
786  number_of_data_points = data_projection%DATA_POINTS%NUMBER_OF_DATA_POINTS
787  ALLOCATE(data_projection%DATA_PROJECTION_RESULTS(number_of_data_points),stat=err)
788  IF(err/=0) CALL flag_error("Could not allocate data projection data projection results.",err,error,*999)
789  DO data_point_idx=1,number_of_data_points
790  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%USER_NUMBER=data_projection%DATA_POINTS%DATA_POINTS( &
791  & data_point_idx)%USER_NUMBER
792  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%DISTANCE=0.0_dp
793  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%ELEMENT_NUMBER=0
794  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%ELEMENT_FACE_NUMBER=0
795  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%ELEMENT_LINE_NUMBER=0
796  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%EXIT_TAG=data_projection_exit_tag_no_element
797  ALLOCATE(data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI(data_projection%NUMBER_OF_XI),stat=err)
798  ALLOCATE(data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector( &
799  & data_projection%COORDINATE_SYSTEM_DIMENSIONS),stat=err)
800  IF(err/=0) CALL flag_error("Could not allocate data projection data projection results "// &
801  & "("//trim(number_to_vstring(data_point_idx,"*",err,error))//") xi.",err,error,*999)
802  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI(1:data_projection%NUMBER_OF_XI)= &
803  & data_projection%STARTING_XI(1:data_projection%NUMBER_OF_XI)
804  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector( &
805  & 1:data_projection%COORDINATE_SYSTEM_DIMENSIONS)=0.0_dp
806  ENDDO !data_point_idx
807  ELSE
808  CALL flag_error("Data projection data points have not been finished.",err,error,*999)
809  ENDIF
810  ELSE
811  CALL flag_error("Data projection data points is not associated.",err,error,*999)
812  ENDIF
813  ELSE
814  CALL flag_error("Data projection have not been finished.",err,error,*999)
815  ENDIF
816  ELSE
817  CALL flag_error("Data projection is not associated.",err,error,*999)
818  ENDIF
819 
820  exits("DataProjection_DataProjectionResultInitialise")
821  RETURN
822 999 errors("DataProjection_DataProjectionResultInitialise",err,error)
823  exits("DataProjection_DataProjectionResultInitialise")
824  RETURN 1
825 
827 
828  !
829  !================================================================================================================================
830  !
831 
833  SUBROUTINE data_projection_destroy(DATA_PROJECTION,ERR,ERROR,*)
835  !Argument variables
836  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
837  INTEGER(INTG), INTENT(OUT) :: ERR
838  TYPE(varying_string), INTENT(OUT) :: ERROR
839  !Local Variables
840 
841  enters("DATA_PROJECTION_DESTROY",err,error,*999)
842 
843  IF(ASSOCIATED(data_projection)) THEN
844  CALL data_projection_finalise(data_projection,err,error,*999)
845  ELSE
846  CALL flag_error("Data projection is not associated.",err,error,*999)
847  ENDIF
848 
849  exits("DATA_PROJECTION_DESTROY")
850  RETURN
851 999 errorsexits("DATA_PROJECTION_DESTROY",err,error)
852  RETURN 1
853 
854  END SUBROUTINE data_projection_destroy
855 
856  !
857  !================================================================================================================================
858  !
859 
861  SUBROUTINE data_projection_finalise(DATA_PROJECTION,ERR,ERROR,*)
863  !Argument variables
864  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
865  INTEGER(INTG), INTENT(OUT) :: ERR
866  TYPE(varying_string), INTENT(OUT) :: ERROR
867  !Local Variables
868  INTEGER(INTG) :: dataPointIdx
869 
870  enters("DATA_PROJECTION_FINALISE",err,error,*999)
871 
872  IF(ASSOCIATED(data_projection)) THEN
873  IF(ALLOCATED(data_projection%STARTING_XI)) THEN
874  DEALLOCATE(data_projection%STARTING_XI)
875  ENDIF
876  IF(ALLOCATED(data_projection%DATA_PROJECTION_RESULTS)) THEN
877  DO datapointidx=1,SIZE(data_projection%DATA_PROJECTION_RESULTS,1)
878  data_projection%DATA_PROJECTION_RESULTS(datapointidx)%USER_NUMBER=0
879  data_projection%DATA_PROJECTION_RESULTS(datapointidx)%DISTANCE=0
880  data_projection%DATA_PROJECTION_RESULTS(datapointidx)%ELEMENT_NUMBER=0
881  data_projection%DATA_PROJECTION_RESULTS(datapointidx)%ELEMENT_FACE_NUMBER=0
882  data_projection%DATA_PROJECTION_RESULTS(datapointidx)%ELEMENT_LINE_NUMBER=0
883  data_projection%DATA_PROJECTION_RESULTS(datapointidx)%EXIT_TAG=0
884  IF(ALLOCATED(data_projection%DATA_PROJECTION_RESULTS(datapointidx)%XI)) THEN
885  DEALLOCATE(data_projection%DATA_PROJECTION_RESULTS(datapointidx)%XI)
886  ENDIF
887  IF(ALLOCATED(data_projection%DATA_PROJECTION_RESULTS(datapointidx)%projectionVector)) THEN
888  DEALLOCATE(data_projection%DATA_PROJECTION_RESULTS(datapointidx)%projectionVector)
889  ENDIF
890  ENDDO !dataPointIdx
891  DEALLOCATE(data_projection%DATA_PROJECTION_RESULTS)
892  ENDIF
893  DEALLOCATE(data_projection)
894  ELSE
895  CALL flag_error("Data projection is not associated.",err,error,*999)
896  ENDIF
897 
898  exits("DATA_PROJECTION_FINALISE")
899  RETURN
900 999 errorsexits("DATA_PROJECTION_FINALISE",err,error)
901  RETURN 1
902 
903  END SUBROUTINE data_projection_finalise
904 
905  !
906  !================================================================================================================================
907  !
908 
910  SUBROUTINE dataprojection_datapointglobalnumberget(DATA_PROJECTION,USER_NUMBER,GLOBAL_NUMBER,ERR,ERROR,*)
912  !Argument variables
913  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
914  INTEGER(INTG), INTENT(IN) :: USER_NUMBER
915  INTEGER(INTG), INTENT(OUT) :: GLOBAL_NUMBER
916  INTEGER(INTG), INTENT(OUT) :: ERR
917  TYPE(varying_string), INTENT(OUT) :: ERROR
918  !Local Variables
919  TYPE(data_points_type), POINTER :: DATA_POINTS
920  TYPE(varying_string) :: LOCAL_ERROR
921  TYPE(tree_node_type), POINTER :: TREE_NODE
922 
923  enters("DataProjection_DataPointGlobalNumberGet",err,error,*999)
924 
925  IF(ASSOCIATED(data_projection)) THEN
926  data_points=>data_projection%DATA_POINTS
927  IF(ASSOCIATED(data_points)) THEN
928  NULLIFY(tree_node)
929  CALL tree_search(data_points%DATA_POINTS_TREE,user_number,tree_node,err,error,*999)
930  IF(ASSOCIATED(tree_node)) THEN
931  CALL tree_node_value_get(data_points%DATA_POINTS_TREE,tree_node,global_number,err,error,*999)
932  ELSE
933  local_error="Tree node is not associates (cannot find the user number "//trim(number_to_vstring(user_number,"*",err, &
934  & error))//"."
935  CALL flag_error(local_error,err,error,*999)
936  ENDIF
937  ELSE
938  CALL flag_error("Data points is not associated.",err,error,*999)
939  ENDIF
940  ELSE
941  CALL flag_error("Data projection is not associated.",err,error,*999)
942  ENDIF
943 
944  exits("DataProjection_DataPointGlobalNumberGet")
945  RETURN
946 999 errorsexits("DataProjection_DataPointGlobalNumberGet",err,error)
947  RETURN 1
948 
950 
951  !
952  !================================================================================================================================
953  !
954 
955 
957  SUBROUTINE dataprojection_datapointsprojectionevaluate(DATA_PROJECTION,PROJECTION_FIELD,ERR,ERROR,*) !optimising
959  !Argument variables
960  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
961  TYPE(field_type), POINTER :: PROJECTION_FIELD
962  INTEGER(INTG), INTENT(OUT) :: ERR
963  TYPE(varying_string), INTENT(OUT) :: ERROR
964  !Local Variables
965  TYPE(field_interpolation_parameters_ptr_type), POINTER :: INTERPOLATION_PARAMETERS(:)
966  TYPE(field_interpolated_point_ptr_type), POINTER :: INTERPOLATED_POINTS(:)
967  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
968  TYPE(data_points_type), POINTER :: DATA_POINTS
969  TYPE(decomposition_type), POINTER :: DECOMPOSITION
970  TYPE(domain_type), POINTER :: DOMAIN
971  !TYPE(DATA_PROJECTION_PROJECTED_POINTS_TYPE), POINTER :: PROJECTED_POINTS
972  INTEGER(INTG) :: MY_COMPUTATIONAL_NODE,NUMBER_COMPUTATIONAL_NODES
973  INTEGER(INTG) :: MESH_COMPONENT_NUMBER,NUMBER_OF_DATA_POINTS
974  INTEGER(INTG) :: NUMBER_OF_ELEMENTS,NUMBER_OF_FACES,NUMBER_OF_LINES,NUMBER_OF_CANDIDATES
975  INTEGER(INTG) :: NUMBER_OF_CLOSEST_CANDIDATES,TOTAL_NUMBER_OF_CLOSEST_CANDIDATES,REDUCED_NUMBER_OF_CLOSEST_CANDIDATES
976  INTEGER(INTG), ALLOCATABLE :: GLOBAL_TO_LOCAL_NUMBER_OF_CLOSEST_CANDIDATES(:)
977  INTEGER(INTG), ALLOCATABLE :: CANDIDATE_ELEMENTS(:),CLOSEST_ELEMENTS(:,:),CANDIDATE_FACES(:),CLOSEST_FACES(:,:)
978  !INTEGER(INTG) :: NUMBER_OF_CANDIDATE_LINES
979  REAL(DP), ALLOCATABLE :: CLOSEST_DISTANCES(:,:),GLOBAL_CLOSEST_DISTANCES(:,:)
980  INTEGER(INTG), ALLOCATABLE :: GLOBAL_NUMBER_OF_CLOSEST_CANDIDATES(:)
981  INTEGER(INTG), ALLOCATABLE :: GLOBAL_MPI_DISPLACEMENTS(:),SORTING_IND_1(:),SORTING_IND_2(:)
982  INTEGER(INTG), ALLOCATABLE :: GLOBAL_NUMBER_OF_PROJECTED_POINTS(:)
983  INTEGER(INTG) :: MPI_CLOSEST_DISTANCES,DATA_PROJECTION_GLOBAL_NUMBER
984  INTEGER(INTG) :: MPI_IERROR
985  !LOGICAL :: ELEMENT_FOUND
986  !LOGICAL, ALLOCATABLE :: PROJECTION_CONVERGED(:)
987  INTEGER(INTG), ALLOCATABLE :: PROJECTED_ELEMENT(:),PROJECTED_FACE(:),PROJECTION_EXIT_TAG(:)
988  REAL(DP), ALLOCATABLE :: PROJECTED_DISTANCE(:,:),PROJECTED_XI(:,:), PROJECTION_VECTORS(:,:)
989 
990  INTEGER(INTG) :: ne,nse,ncn,ni,localElementNumber
991  INTEGER(INTG) :: temp_number,start_idx,finish_idx,data_point_idx
992 
993  LOGICAL :: BOUNDARY_PROJECTION,elementExists,ghostElement
994 
995  !INTEGER(INTG) :: NUMBER_OF_PROJECTED_POINTS,NUMBER_OF_PROJECTED_POINTS_2
996 
997  enters("DataProjection_DataPointsProjectionEvaluate",err,error,*999)
998 
999  NULLIFY(interpolation_parameters)
1000  NULLIFY(interpolated_points)
1001  IF(ASSOCIATED(data_projection)) THEN
1002  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1003  IF(ASSOCIATED(projection_field)) THEN
1004  IF(projection_field%FIELD_FINISHED) THEN
1005  IF(ASSOCIATED(data_projection%MESH,projection_field%DECOMPOSITION%MESH)) THEN
1006  data_projection%PROJECTION_FIELD=>projection_field
1007  data_projection_global_number=data_projection%GLOBAL_NUMBER
1008  data_points=>data_projection%DATA_POINTS
1009  CALL field_interpolation_parameters_initialise(projection_field,interpolation_parameters,err,error,*998, &
1010  & field_geometric_components_type)
1011  CALL field_interpolated_points_initialise(interpolation_parameters,interpolated_points,err,error,*998, &
1012  & field_geometric_components_type)
1013  interpolated_point=>interpolated_points(field_u_variable_type)%PTR
1014  decomposition=>projection_field%DECOMPOSITION
1015  mesh_component_number=projection_field%DECOMPOSITION%MESH_COMPONENT_NUMBER
1016  domain=>projection_field%DECOMPOSITION%DOMAIN(mesh_component_number)%PTR
1017  number_of_data_points=data_points%NUMBER_OF_DATA_POINTS
1018  my_computational_node=computational_node_number_get(err,error)
1019  number_computational_nodes=computational_environment%NUMBER_COMPUTATIONAL_NODES
1020  boundary_projection=(data_projection%PROJECTION_TYPE==data_projection_boundary_lines_projection_type).OR.( &
1021  & data_projection%PROJECTION_TYPE==data_projection_boundary_faces_projection_type)
1022  !#####################################################################################################################
1023  !find elements/faces/lines inside current computational node, get the boundary faces/lines only if asked
1024  !the elements/faces/lines are required to perform projection of points in the current computational node
1025  !the are all pre-allocated to the maximum array length (i.e. NUMBER_OF_ELEMENTS), but only up to the NUMBER_OF_CANDIDATESth index are assigned
1026  number_of_elements=domain%TOPOLOGY%ELEMENTS%NUMBER_OF_ELEMENTS
1027  number_of_faces=domain%TOPOLOGY%FACES%NUMBER_OF_FACES
1028  number_of_lines=domain%TOPOLOGY%LINES%NUMBER_OF_LINES
1029  number_of_candidates=0
1030  IF(ALLOCATED(data_projection%candidateElementNumbers) .AND. ALLOCATED(data_projection%localFaceLineNumbers)) THEN
1031  SELECT CASE(data_projection%PROJECTION_TYPE)
1032  CASE (data_projection_boundary_lines_projection_type) !identify all non-ghost boundary lines
1033  ALLOCATE(candidate_elements(number_of_lines),stat=err)
1034  IF(err/=0) CALL flag_error("Could not allocate candidate elements.",err,error,*999)
1035  ALLOCATE(candidate_faces(number_of_lines),stat=err)
1036  IF(err/=0) CALL flag_error("Could not allocate candidate lines.",err,error,*999)
1037  DO ne=1,SIZE(data_projection%candidateElementNumbers,1) !Loop through all candidate element defined by user number
1038  CALL decomposition_topology_element_check_exists(decomposition%TOPOLOGY,data_projection% &
1039  & candidateelementnumbers(ne),elementexists,localelementnumber,ghostelement,err,error,*999) !Check if element exists on current domain, get local number
1040  IF((elementexists) .AND. (.NOT.ghostelement)) THEN !Get non-ghost elements
1041  number_of_candidates=number_of_candidates+1
1042  candidate_elements(number_of_candidates)=localelementnumber
1043  candidate_faces(number_of_candidates)=data_projection%localFaceLineNumbers(ne) !Store element line number for line projection type
1044  ENDIF
1045  ENDDO !ne
1046  CASE (data_projection_boundary_faces_projection_type) !identify all non-ghost boundary faces
1047  IF(decomposition%MESH%NUMBER_OF_DIMENSIONS>=2) THEN
1048  ALLOCATE(candidate_elements(number_of_faces),stat=err)
1049  IF(err/=0) CALL flag_error("Could not allocate candidate elements.",err,error,*999)
1050  ALLOCATE(candidate_faces(number_of_faces),stat=err)
1051  IF(err/=0) CALL flag_error("Could not allocate candidate faces.",err,error,*999)
1052  DO ne=1,SIZE(data_projection%candidateElementNumbers,1) !Loop through all candidate element defined by user number
1053  CALL decomposition_topology_element_check_exists(decomposition%TOPOLOGY,data_projection% &
1054  & candidateelementnumbers(ne),elementexists,localelementnumber,ghostelement,err,error,*999) !Check if element exists on current domain, get local number
1055  IF((elementexists) .AND. (.NOT.ghostelement)) THEN !Get non-ghost elements
1056  number_of_candidates=number_of_candidates+1
1057  candidate_elements(number_of_candidates)=localelementnumber
1058  candidate_faces(number_of_candidates)=data_projection%localFaceLineNumbers(ne) !Store element face number for face projection type
1059  ENDIF
1060  ENDDO !ne
1061  ELSE
1062  CALL flag_error("Decomposition mesh number of dimensions has to be 2 or greater.",err,error,*999)
1063  ENDIF
1064  CASE (data_projection_all_elements_projection_type) !identify all non-ghost elements
1065  IF(data_projection%NUMBER_OF_XI==decomposition%MESH%NUMBER_OF_DIMENSIONS) THEN
1066  ALLOCATE(candidate_elements(number_of_elements),stat=err)
1067  IF(err/=0) CALL flag_error("Could not allocate candidate elements.",err,error,*999)
1068  DO ne=1,SIZE(data_projection%candidateElementNumbers,1) !Loop through all candidate element defined by user number
1069  CALL decomposition_topology_element_check_exists(decomposition%TOPOLOGY,data_projection% &
1070  & candidateelementnumbers(ne),elementexists,localelementnumber,ghostelement,err,error,*999) !Check if element exists on current domain, get local number
1071  IF((elementexists) .AND. (.NOT.ghostelement)) THEN !Get non-ghost elements
1072  number_of_candidates=number_of_candidates+1
1073  candidate_elements(number_of_candidates)=localelementnumber
1074  ENDIF
1075  ENDDO !ne
1076  ELSE
1077  CALL flag_error("Data projection number of xi has to equal to decomposition mesh number of dimensions",err, &
1078  & error,*999)
1079  ENDIF
1080  CASE DEFAULT
1081  CALL flag_error("No match for data projection type found",err,error,*999)
1082  END SELECT !DATA_PROJECTION%PROJECTION_TYPE
1083  ELSE !If user didn't define candidate element number
1084  SELECT CASE(data_projection%PROJECTION_TYPE)
1085  CASE (data_projection_boundary_lines_projection_type) !identify all non-ghost boundary lines
1086  ALLOCATE(candidate_elements(number_of_lines),stat=err)
1087  IF(err/=0) CALL flag_error("Could not allocate candidate elements.",err,error,*999)
1088  ALLOCATE(candidate_faces(number_of_lines),stat=err)
1089  IF(err/=0) CALL flag_error("Could not allocate candidate lines.",err,error,*999)
1090  DO ne=1,domain%MAPPINGS%ELEMENTS%NUMBER_OF_LOCAL
1091  IF(decomposition%TOPOLOGY%ELEMENTS%ELEMENTS(ne)%BOUNDARY_ELEMENT) THEN
1092  DO nse=1,SIZE(decomposition%TOPOLOGY%ELEMENTS%ELEMENTS(ne)%ELEMENT_LINES,1)
1093  temp_number=decomposition%TOPOLOGY%ELEMENTS%ELEMENTS(ne)%ELEMENT_LINES(nse)
1094  IF(decomposition%TOPOLOGY%LINES%LINES(temp_number)%BOUNDARY_LINE) THEN
1095  number_of_candidates=number_of_candidates+1
1096  candidate_faces(number_of_candidates)=nse
1097  candidate_elements(number_of_candidates)=ne
1098  ENDIF !boundary line
1099  ENDDO !nse
1100  ENDIF !boundary element
1101  ENDDO !ne
1102  CASE (data_projection_boundary_faces_projection_type) !identify all non-ghost boundary faces
1103  IF(decomposition%MESH%NUMBER_OF_DIMENSIONS>=2) THEN
1104  ALLOCATE(candidate_elements(number_of_faces),stat=err)
1105  IF(err/=0) CALL flag_error("Could not allocate candidate elements.",err,error,*999)
1106  ALLOCATE(candidate_faces(number_of_faces),stat=err)
1107  IF(err/=0) CALL flag_error("Could not allocate candidate faces.",err,error,*999)
1108  DO ne=1,domain%MAPPINGS%ELEMENTS%NUMBER_OF_LOCAL
1109  IF(decomposition%TOPOLOGY%ELEMENTS%ELEMENTS(ne)%BOUNDARY_ELEMENT) THEN
1110  DO nse=1,SIZE(decomposition%TOPOLOGY%ELEMENTS%ELEMENTS(ne)%ELEMENT_FACES,1)
1111  temp_number=decomposition%TOPOLOGY%ELEMENTS%ELEMENTS(ne)%ELEMENT_FACES(nse)
1112  IF(decomposition%TOPOLOGY%FACES%FACES(temp_number)%BOUNDARY_FACE) THEN
1113  number_of_candidates=number_of_candidates+1
1114  candidate_faces(number_of_candidates)=nse
1115  candidate_elements(number_of_candidates)=ne
1116  ENDIF !boundary face
1117  ENDDO !nse
1118  ENDIF !boundary element
1119  ENDDO !ne
1120  ELSE
1121  CALL flag_error("Decomposition mesh number of dimensions has to be 2 or greater.",err,error,*999)
1122  ENDIF
1123  CASE (data_projection_all_elements_projection_type) !identify all non-ghost elements
1124  IF(data_projection%NUMBER_OF_XI==decomposition%MESH%NUMBER_OF_DIMENSIONS) THEN
1125  ALLOCATE(candidate_elements(number_of_elements),stat=err)
1126  IF(err/=0) CALL flag_error("Could not allocate candidate elements.",err,error,*999)
1127  DO ne=1,domain%MAPPINGS%ELEMENTS%NUMBER_OF_LOCAL
1128  number_of_candidates=number_of_candidates+1
1129  candidate_elements(number_of_candidates)=ne
1130  ENDDO
1131  ELSE
1132  CALL flag_error("Data projection number of xi has to equal to decomposition mesh number of dimensions",err, &
1133  & error,*999)
1134  ENDIF
1135  CASE DEFAULT
1136  CALL flag_error("No match for data projection type found",err,error,*999)
1137  END SELECT !DATA_PROJECTION%PROJECTION_TYPE
1138  ENDIF
1139  !#####################################################################################################################
1140  !find the clostest elements/faces/lines for each point in the current computational node base on starting xi
1141  !the clostest elements/faces/lines are required to shrink down on the list of possible projection candiates
1142  number_of_closest_candidates=min(data_projection%NUMBER_OF_CLOSEST_ELEMENTS,number_of_candidates)
1143  ALLOCATE(closest_elements(number_of_data_points,number_of_closest_candidates),stat=err)!the information for each data point has to be stored in the corresponding rows for them to be contiguous in memory for easy MPI access
1144  IF(err/=0) CALL flag_error("Could not allocate closest elements.",err,error,*999)
1145  IF(boundary_projection) THEN
1146  ALLOCATE(closest_faces(number_of_data_points,number_of_closest_candidates),stat=err)
1147  IF(err/=0) CALL flag_error("Could not allocate closest sub element.",err,error,*999)
1148  ENDIF
1149  ALLOCATE(closest_distances(number_of_data_points,number_of_closest_candidates),stat=err)!the information for each data point has to be stored in the corresponding rows for them to be contiguous in memory for easy MPI access
1150  IF(err/=0) CALL flag_error("Could not allocate closest distances.",err,error,*999)
1151  SELECT CASE(data_projection%PROJECTION_TYPE)
1152  CASE (data_projection_boundary_lines_projection_type) !find closest candidate lines
1153  DO data_point_idx=1,number_of_data_points
1154  CALL data_projection_closest_lines_find(data_projection,interpolated_point, &
1155  & data_points%DATA_POINTS(data_point_idx)%position,candidate_elements, &
1156  & candidate_faces,number_of_candidates,closest_elements(data_point_idx,:),closest_faces( &
1157  & data_point_idx,:),closest_distances(data_point_idx,:),err,error,*999)
1158  ENDDO !data_point_idx
1159  CASE (data_projection_boundary_faces_projection_type) !find closest candidate faces
1160  DO data_point_idx=1,number_of_data_points
1161  CALL data_projection_closest_faces_find(data_projection,interpolated_point, &
1162  & data_points%DATA_POINTS(data_point_idx)%position,candidate_elements, &
1163  & candidate_faces,number_of_candidates,closest_elements(data_point_idx,:),closest_faces( &
1164  & data_point_idx,:),closest_distances(data_point_idx,:),err,error,*999)
1165  ENDDO !data_point_idx
1166  CASE (data_projection_all_elements_projection_type) !find closest candidate elements
1167  DO data_point_idx=1,number_of_data_points
1168  CALL data_projection_closest_elements_find(data_projection,interpolated_point,data_points%DATA_POINTS( &
1169  & data_point_idx)%position,candidate_elements,number_of_candidates,closest_elements(data_point_idx,:), &
1170  & closest_distances(data_point_idx,:),err,error,*999)
1171  !CLOSEST_ELEMENTS(data_point_idx,:)=DOMAIN%MAPPINGS%ELEMENTS%LOCAL_TO_GLOBAL_MAP(CLOSEST_ELEMENTS(data_point_idx,:)) !local to global element number mapping
1172  ENDDO !data_point_idx
1173  CASE DEFAULT
1174  CALL flag_error("No match for data projection type found",err,error,*999)
1175  END SELECT
1176  !#####################################################################################################################
1177  !Newton project data point to the list of closest elements, faces or lines
1178  !project the data points to each of the closest elements, use MPI if number of computational nodes is greater than 1
1179  IF(number_computational_nodes>1) THEN !use mpi
1180  !allocate arrays for mpi communication
1181  ALLOCATE(global_to_local_number_of_closest_candidates(number_of_data_points),stat=err)
1182  IF(err/=0) CALL flag_error("Could not allocate global to local number of closest elements.",err,error,*999)
1183  ALLOCATE(global_number_of_closest_candidates(number_computational_nodes),stat=err)
1184  IF(err/=0) CALL flag_error("Could not allocate all number of closest candidates.",err,error,*999)
1185  ALLOCATE(global_mpi_displacements(number_computational_nodes),stat=err)
1186  IF(err/=0) CALL flag_error("Could not allocate all displacements.",err,error,*999)
1187  ALLOCATE(global_number_of_projected_points(number_computational_nodes),stat=err)
1188  IF(err/=0) CALL flag_error("Could not allocate all number of projected points.",err,error,*999)
1189  ALLOCATE(projection_exit_tag(number_of_data_points),stat=err)
1190  IF(err/=0) CALL flag_error("Could not allocate projected.",err,error,*999)
1191  ALLOCATE(projected_element(number_of_data_points),stat=err)
1192  IF(err/=0) CALL flag_error("Could not allocate projected element.",err,error,*999)
1193  IF(boundary_projection) THEN
1194  ALLOCATE(projected_face(number_of_data_points),stat=err)
1195  IF(err/=0) CALL flag_error("Could not allocate projected sub element.",err,error,*999)
1196  ENDIF
1197  ALLOCATE(projected_distance(2,number_of_data_points),stat=err) !PROJECTED_DISTANCE(2,:) stores the compuational node number, the information for each data point has to be stored in the corresponding column for MPI_ALLREDUCE with location return to work
1198  IF(err/=0) CALL flag_error("Could not allocate projected distance.",err,error,*999)
1199  ALLOCATE(projected_xi(data_projection%NUMBER_OF_XI,number_of_data_points),stat=err) !the information for each data point is stored in the corresponding column to be consistent with PROJECTED_DISTANCE
1200  ALLOCATE(projection_vectors(data_projection%COORDINATE_SYSTEM_DIMENSIONS, number_of_data_points), stat=err) !ZJW: The projection vector for each data point is stored in the corresponding colum to be consistent with PROJECTED_DISTANCE.
1201  IF(err/=0) CALL flag_error("Could not allocate projected.",err,error,*999)
1202  ALLOCATE(sorting_ind_2(number_of_data_points),stat=err)
1203  IF(err/=0) CALL flag_error("Could not allocate sorting ind 2.",err,error,*999)
1204  !gather and distribute the number of closest elements from all computational nodes
1205  CALL mpi_allgather(number_of_closest_candidates,1,mpi_integer,global_number_of_closest_candidates,1,mpi_integer, &
1206  & computational_environment%MPI_COMM,mpi_ierror)
1207  CALL mpi_error_check("MPI_ALLGATHER",mpi_ierror,err,error,*999)
1208  total_number_of_closest_candidates=sum(global_number_of_closest_candidates,1) !sum of all number of closest candidates from all computational nodes
1209  !allocate arrays to store information gathered from all computational node
1210  ALLOCATE(global_closest_distances(number_of_data_points,total_number_of_closest_candidates),stat=err) !the information for each data point is stored in the corresponding row so they are contiguous in memory for easy MPI access
1211  IF(err/=0) CALL flag_error("Could not allocate all closest distances.",err,error,*999)
1212  ALLOCATE(sorting_ind_1(total_number_of_closest_candidates),stat=err)
1213  IF(err/=0) CALL flag_error("Could not allocate sorting ind 1.",err,error,*999)
1214  !MPI:create and commit MPI_TYPE_CONTIGUOUS
1215  CALL mpi_type_contiguous(number_of_data_points,mpi_double_precision,mpi_closest_distances,mpi_ierror)
1216  CALL mpi_error_check("MPI_TYPE_CONTIGUOUS",mpi_ierror,err,error,*999)
1217  CALL mpi_type_commit(mpi_closest_distances,mpi_ierror)
1218  CALL mpi_error_check("MPI_TYPE_COMMIT",mpi_ierror,err,error,*999)
1219  !create displacement vectors for MPI_ALLGATHERV
1220  global_mpi_displacements(1)=0
1221  DO ncn=1,(number_computational_nodes-1)
1222  global_mpi_displacements(ncn+1)=global_mpi_displacements(ncn)+global_number_of_closest_candidates(ncn)
1223  ENDDO
1224  !MPI:shares closest element distances between all domains
1225  CALL mpi_allgatherv(closest_distances(1,1),number_of_closest_candidates,mpi_closest_distances, &
1226  & global_closest_distances,global_number_of_closest_candidates,global_mpi_displacements,mpi_closest_distances, &
1227  & computational_environment%MPI_COMM,mpi_ierror)
1228  CALL mpi_error_check("MPI_ALLGATHERV",mpi_ierror,err,error,*999)
1229  reduced_number_of_closest_candidates=min(data_projection%NUMBER_OF_CLOSEST_ELEMENTS, &
1230  & total_number_of_closest_candidates)
1231  projected_distance(2,:)=my_computational_node
1232  ! find the globally closest distances in the current domain
1233  DO data_point_idx=1,number_of_data_points
1234  CALL bubble_isort(global_closest_distances(data_point_idx,:),sorting_ind_1,err,error,*999)
1235  sorting_ind_1(1:total_number_of_closest_candidates)=sorting_ind_1(1:total_number_of_closest_candidates)- &
1236  & global_mpi_displacements(my_computational_node+1) !shift the index to current computational node
1237  global_to_local_number_of_closest_candidates(data_point_idx)=0
1238  DO ne=1,reduced_number_of_closest_candidates
1239  !sorted index indicates it is in the current computational domain
1240  IF((sorting_ind_1(ne)>=1).AND.(sorting_ind_1(ne)<=global_number_of_closest_candidates(my_computational_node &
1241  & +1)))global_to_local_number_of_closest_candidates(data_point_idx)= &
1242  & global_to_local_number_of_closest_candidates(data_point_idx)+1
1243  ENDDO
1244  projected_distance(1,data_point_idx)=global_closest_distances(data_point_idx,total_number_of_closest_candidates) !assign initial distance to something large
1245  ENDDO
1246  SELECT CASE(data_projection%PROJECTION_TYPE)
1247  CASE (data_projection_boundary_lines_projection_type) !Newton project to closest lines, and find miminum projection
1248  DO data_point_idx=1,number_of_data_points
1249  number_of_closest_candidates=global_to_local_number_of_closest_candidates(data_point_idx)
1250  IF(number_of_closest_candidates>0) THEN
1251  CALL data_projection_newton_lines_evaluate(data_projection,interpolated_point, &
1252  & data_points%DATA_POINTS(data_point_idx)%position,closest_elements( &
1253  & data_point_idx,1:number_of_closest_candidates),closest_faces(data_point_idx,1: &
1254  & number_of_closest_candidates),projection_exit_tag(data_point_idx),projected_element(data_point_idx), &
1255  & projected_face(data_point_idx),projected_distance(1,data_point_idx),projected_xi(:,data_point_idx), &
1256  & projection_vectors(:, data_point_idx),err,error,*999)
1257  projected_element(data_point_idx)=domain%MAPPINGS%ELEMENTS%LOCAL_TO_GLOBAL_MAP(projected_element( &
1258  & data_point_idx)) !map the element number to global number
1259  ENDIF
1260  ENDDO
1261  CASE (data_projection_boundary_faces_projection_type) !find closest candidate faces
1262  DO data_point_idx=1,number_of_data_points
1263  number_of_closest_candidates=global_to_local_number_of_closest_candidates(data_point_idx)
1264  IF(number_of_closest_candidates>0) THEN
1265  CALL data_projection_newton_faces_evaluate(data_projection,interpolated_point, &
1266  & data_points%DATA_POINTS(data_point_idx)%position,closest_elements( &
1267  & data_point_idx,1:number_of_closest_candidates),closest_faces(data_point_idx, &
1268  & 1:number_of_closest_candidates),projection_exit_tag(data_point_idx),projected_element(data_point_idx), &
1269  & projected_face(data_point_idx),projected_distance(1,data_point_idx),projected_xi(:,data_point_idx), &
1270  & projection_vectors(:, data_point_idx),err,error,*999)
1271  projected_element(data_point_idx)=domain%MAPPINGS%ELEMENTS%LOCAL_TO_GLOBAL_MAP(projected_element( &
1272  & data_point_idx)) !map the element number to global number
1273  ENDIF
1274  ENDDO
1275  CASE (data_projection_all_elements_projection_type) !find closest candidate elements
1276  SELECT CASE(data_projection%NUMBER_OF_XI)
1277  CASE (1) !1D element
1278  DO data_point_idx=1,number_of_data_points
1279  number_of_closest_candidates=global_to_local_number_of_closest_candidates(data_point_idx)
1280  IF(number_of_closest_candidates>0) THEN
1281  CALL data_projection_newton_elements_evaluate_1(data_projection,interpolated_point,data_points% &
1282  & data_points(data_point_idx)%position,closest_elements(data_point_idx, &
1283  & 1:number_of_closest_candidates),projection_exit_tag(data_point_idx), &
1284  & projected_element(data_point_idx),projected_distance(1,data_point_idx), &
1285  & projected_xi(:,data_point_idx),projection_vectors(:, data_point_idx),err,error,*999)
1286  projected_element(data_point_idx)=domain%MAPPINGS%ELEMENTS%LOCAL_TO_GLOBAL_MAP(projected_element( &
1287  & data_point_idx)) !map the element number to global number
1288 
1289  ENDIF
1290  ENDDO
1291  CASE (2) !2D element
1292  DO data_point_idx=1,number_of_data_points
1293  number_of_closest_candidates=global_to_local_number_of_closest_candidates(data_point_idx)
1294  IF(number_of_closest_candidates>0) THEN
1295  CALL data_projection_newton_elements_evaluate_2(data_projection,interpolated_point,data_points% &
1296  & data_points(data_point_idx)%position,closest_elements(data_point_idx, &
1297  & 1:number_of_closest_candidates),projection_exit_tag(data_point_idx), &
1298  & projected_element(data_point_idx),projected_distance(1,data_point_idx), &
1299  & projected_xi(:,data_point_idx),projection_vectors(:, data_point_idx), &
1300  & err,error,*999)
1301  projected_element(data_point_idx)=domain%MAPPINGS%ELEMENTS%LOCAL_TO_GLOBAL_MAP(projected_element( &
1302  & data_point_idx)) !map the element number to global number
1303  ENDIF
1304  ENDDO
1305  CASE (3) !3D element
1306  DO data_point_idx=1,number_of_data_points
1307  number_of_closest_candidates=global_to_local_number_of_closest_candidates(data_point_idx)
1308  IF(number_of_closest_candidates>0) THEN
1309  CALL data_projection_newton_elements_evaluate_3(data_projection,interpolated_point,data_points% &
1310  & data_points(data_point_idx)%position,closest_elements(data_point_idx, &
1311  & 1:number_of_closest_candidates),projection_exit_tag(data_point_idx), &
1312  & projected_element(data_point_idx),projected_distance(1,data_point_idx), &
1313  & projected_xi(:,data_point_idx),projection_vectors(:, data_point_idx),err,error,*999)
1314  projected_element(data_point_idx)=domain%MAPPINGS%ELEMENTS%LOCAL_TO_GLOBAL_MAP(projected_element( &
1315  & data_point_idx)) !map the element number to global number
1316  ENDIF
1317  ENDDO
1318  CASE DEFAULT
1319  CALL flag_error("Data projection number of xi is invalid",err,error,*999)
1320  END SELECT
1321  CASE DEFAULT
1322  CALL flag_error("No match for data projection type found",err,error,*999)
1323  END SELECT
1324  !MPI:find the shortest projected distance in all domains
1325  CALL mpi_allreduce(mpi_in_place,projected_distance,number_of_data_points,mpi_2double_precision,mpi_minloc, &
1326  & computational_environment%MPI_COMM,mpi_ierror)
1327  CALL mpi_error_check("MPI_ALLREDUCE",mpi_ierror,err,error,*999)
1328  !sort the computational node/rank from 0 to number of computational node
1329  CALL bubble_isort(projected_distance(2,:),sorting_ind_2,err,error,*999)
1330  DO ncn=0,(number_computational_nodes-1)
1331  global_number_of_projected_points(ncn+1)=count(abs(projected_distance(2,:)-REAL(ncn))<zero_tolerance)
1332  ENDDO !ncn
1333  start_idx=sum(global_number_of_projected_points(1:my_computational_node))+1
1334  finish_idx=start_idx+global_number_of_projected_points(my_computational_node+1)-1
1335  !create displacement vectors for MPI_ALLGATHERV
1336  DO ncn=1,(number_computational_nodes-1)
1337  global_mpi_displacements(ncn+1)=global_mpi_displacements(ncn)+global_number_of_projected_points(ncn)
1338  ENDDO !ncn
1339  !MPI:shares minimum projection informationg bewteen all domains
1340  CALL mpi_allgatherv(projected_element(sorting_ind_2(start_idx:finish_idx)),global_number_of_projected_points( &
1341  & my_computational_node+1),mpi_integer,projected_element,global_number_of_projected_points, &
1342  & global_mpi_displacements,mpi_integer,computational_environment%MPI_COMM,mpi_ierror) !PROJECTED_ELEMENT
1343  CALL mpi_error_check("MPI_ALLGATHERV",mpi_ierror,err,error,*999)
1344  IF(boundary_projection) THEN
1345  CALL mpi_allgatherv(projected_face(sorting_ind_2(start_idx:finish_idx)),global_number_of_projected_points( &
1346  & my_computational_node+1),mpi_integer,projected_face,global_number_of_projected_points, &
1347  & global_mpi_displacements,mpi_integer,computational_environment%MPI_COMM,mpi_ierror) !PROJECTED_FACE
1348  CALL mpi_error_check("MPI_ALLGATHERV",mpi_ierror,err,error,*999)
1349  ENDIF
1350  DO ni=1,data_projection%NUMBER_OF_XI
1351  CALL mpi_allgatherv(projected_xi(ni,sorting_ind_2(start_idx:finish_idx)),global_number_of_projected_points( &
1352  & my_computational_node+1),mpi_double_precision,projected_xi(ni,:),global_number_of_projected_points, &
1353  & global_mpi_displacements,mpi_double_precision,computational_environment%MPI_COMM,mpi_ierror) !PROJECTED_XI
1354  CALL mpi_error_check("MPI_ALLGATHERV",mpi_ierror,err,error,*999)
1355  ENDDO
1356  CALL mpi_allgatherv(projection_exit_tag(sorting_ind_2(start_idx:finish_idx)),global_number_of_projected_points( &
1357  & my_computational_node+1),mpi_integer,projection_exit_tag,global_number_of_projected_points, &
1358  & global_mpi_displacements,mpi_integer,computational_environment%MPI_COMM,mpi_ierror) !PROJECTION_EXIT_TAG
1359  CALL mpi_error_check("MPI_ALLGATHERV",mpi_ierror,err,error,*999)
1360  DO ni=1,data_projection%COORDINATE_SYSTEM_DIMENSIONS
1361  CALL mpi_allgatherv(projection_vectors(ni, sorting_ind_2(start_idx:finish_idx)),global_number_of_projected_points( &
1362  & my_computational_node+1),mpi_double_precision,projection_vectors(ni,:),global_number_of_projected_points, &
1363  & global_mpi_displacements,mpi_double_precision,computational_environment%MPI_COMM,mpi_ierror) !PROJECTION_VECTORS
1364  CALL mpi_error_check("MPI_ALLGATHERV",mpi_ierror,err,error,*999)
1365  ENDDO
1366  !assign projection information to projected points
1367  DO data_point_idx=1,number_of_data_points
1368  data_projection%DATA_PROJECTION_RESULTS(sorting_ind_2(data_point_idx))%EXIT_TAG=projection_exit_tag( &
1369  & data_point_idx)
1370  data_projection%DATA_PROJECTION_RESULTS(sorting_ind_2(data_point_idx))%ELEMENT_NUMBER=projected_element( &
1371  & data_point_idx)
1372  data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%DISTANCE=projected_distance(1,data_point_idx)
1373  data_projection%DATA_PROJECTION_RESULTS(sorting_ind_2(data_point_idx))%XI(1:data_projection%NUMBER_OF_XI)= &
1374  & projected_xi(1:data_projection%NUMBER_OF_XI,data_point_idx)
1375  data_projection%DATA_PROJECTION_RESULTS(sorting_ind_2(data_point_idx))%projectionVector( &
1376  & 1:data_projection%COORDINATE_SYSTEM_DIMENSIONS)=projection_vectors( &
1377  & 1:data_projection%COORDINATE_SYSTEM_DIMENSIONS,data_point_idx)
1378  ENDDO !data_point_idx
1379  projected_xi(:,sorting_ind_2)=projected_xi
1380  projection_vectors(:, sorting_ind_2)=projection_vectors
1381  projected_element(sorting_ind_2)=projected_element
1382  IF(data_projection%PROJECTION_TYPE==data_projection_boundary_lines_projection_type) THEN
1383  DO data_point_idx=1,number_of_data_points
1384  data_projection%DATA_PROJECTION_RESULTS(sorting_ind_2(data_point_idx))%ELEMENT_LINE_NUMBER=projected_face( &
1385  & data_point_idx)
1386  ENDDO !data_point_idx
1387  ELSEIF(data_projection%PROJECTION_TYPE==data_projection_boundary_faces_projection_type) THEN
1388  DO data_point_idx=1,number_of_data_points
1389  data_projection%DATA_PROJECTION_RESULTS(sorting_ind_2(data_point_idx))%ELEMENT_FACE_NUMBER=projected_face( &
1390  & data_point_idx)
1391  ENDDO !data_point_idx
1392  ENDIF
1393  ELSE !no need to use mpi
1394  SELECT CASE(data_projection%PROJECTION_TYPE)
1395  CASE (data_projection_boundary_lines_projection_type) !Newton project to closest lines, and find miminum projection
1396  DO data_point_idx=1,number_of_data_points
1397  CALL data_projection_newton_lines_evaluate(data_projection,interpolated_point,data_points%DATA_POINTS( &
1398  & data_point_idx)%position,closest_elements(data_point_idx,:),closest_faces(data_point_idx,:), &
1399  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%EXIT_TAG,data_projection% &
1400  & data_projection_results(data_point_idx)%ELEMENT_NUMBER,data_projection% &
1401  & data_projection_results(data_point_idx)%ELEMENT_LINE_NUMBER,data_projection%DATA_PROJECTION_RESULTS( &
1402  & data_point_idx)%DISTANCE,data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI, &
1403  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector,err,error,*999)
1404  ENDDO
1405  CASE (data_projection_boundary_faces_projection_type) !find closest candidate faces
1406  DO data_point_idx=1,number_of_data_points
1407  CALL data_projection_newton_faces_evaluate(data_projection,interpolated_point,data_points%DATA_POINTS( &
1408  & data_point_idx)%position,closest_elements(data_point_idx,:),closest_faces(data_point_idx,:), &
1409  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%EXIT_TAG,data_projection% &
1410  & data_projection_results(data_point_idx)%ELEMENT_NUMBER,data_projection% &
1411  & data_projection_results(data_point_idx)%ELEMENT_FACE_NUMBER,data_projection%DATA_PROJECTION_RESULTS( &
1412  & data_point_idx)%DISTANCE,data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI, &
1413  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector,err,error,*999)
1414  ENDDO
1415  CASE (data_projection_all_elements_projection_type) !find closest candidate elements
1416  SELECT CASE(data_projection%NUMBER_OF_XI)
1417  CASE (1) !1D mesh
1418  DO data_point_idx=1,number_of_data_points
1419  CALL data_projection_newton_elements_evaluate_1(data_projection,interpolated_point,data_points% &
1420  & data_points(data_point_idx)%position,closest_elements(data_point_idx,:),data_projection% &
1421  & data_projection_results(data_point_idx)%EXIT_TAG,data_projection%DATA_PROJECTION_RESULTS( &
1422  & data_point_idx)%ELEMENT_NUMBER, data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%DISTANCE, &
1423  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI, &
1424  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector,&
1425  & err,error,*999)
1426  ENDDO
1427  CASE (2) !2D mesh
1428  DO data_point_idx=1,number_of_data_points
1429  CALL data_projection_newton_elements_evaluate_2(data_projection,interpolated_point,data_points% &
1430  & data_points(data_point_idx)%position,closest_elements(data_point_idx,:),data_projection% &
1431  & data_projection_results(data_point_idx)%EXIT_TAG,data_projection%DATA_PROJECTION_RESULTS( &
1432  & data_point_idx)%ELEMENT_NUMBER,data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%DISTANCE, &
1433  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI, &
1434  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector, &
1435  & err,error,*999)
1436  ENDDO
1437  CASE (3) !3D mesh
1438  DO data_point_idx=1,number_of_data_points
1439  CALL data_projection_newton_elements_evaluate_3(data_projection,interpolated_point,data_points% &
1440  & data_points(data_point_idx)%position,closest_elements(data_point_idx,:),data_projection% &
1441  & data_projection_results(data_point_idx)%EXIT_TAG,data_projection%DATA_PROJECTION_RESULTS( &
1442  & data_point_idx)%ELEMENT_NUMBER,data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%DISTANCE, &
1443  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%XI, &
1444  & data_projection%DATA_PROJECTION_RESULTS(data_point_idx)%projectionVector, &
1445  & err,error,*999)
1446  ENDDO
1447  CASE DEFAULT
1448  CALL flag_error("Data projection number of xi is invalid",err,error,*999)
1449  END SELECT !DATA_PROJECTION%NUMBER_OF_XI
1450  CASE DEFAULT
1451  CALL flag_error("No match for data projection type found",err,error,*999)
1452  END SELECT
1453  ENDIF !NUMBER_COMPUTATIONAL_NODES>1
1454  data_projection%DATA_PROJECTION_PROJECTED=.true.
1455  ELSE
1456  CALL flag_error("Data projection and projection field are not sharing the same mesh.",err,error,*999)
1457  ENDIF !ASSOCIATED(DATA_PROJECTION%MESH,PROJECTION_FIELD%DECOMPOSITION%MESH)
1458  ELSE
1459  CALL flag_error("Projection field have not been finished.",err,error,*999)
1460  ENDIF !PROJECTION_FIELD%FIELD_FINISHED
1461  ELSE
1462  CALL flag_error("Projection field is not associated.",err,error,*999)
1463  ENDIF !ASSOCIATED(PROJECTION_FIELD)
1464  ELSE
1465  CALL flag_error("Data projection have not been finished.",err,error,*999)
1466  ENDIF !DATA_PROJECTION%DATA_PROJECTION_FINISHED
1467  ELSE
1468  CALL flag_error("Data projection is not associated.",err,error,*999)
1469  ENDIF !ASSOCIATED(DATA_PROJECTION)
1470 
1471  ! Deallocate arrays used within this routine
1472  IF(ALLOCATED(candidate_elements)) DEALLOCATE(candidate_elements)
1473  IF(ALLOCATED(candidate_faces)) DEALLOCATE(candidate_faces)
1474  IF(ALLOCATED(closest_elements)) DEALLOCATE(closest_elements)
1475  IF(ALLOCATED(closest_faces)) DEALLOCATE(closest_faces)
1476  IF(ALLOCATED(closest_distances)) DEALLOCATE(closest_distances)
1477  IF(ALLOCATED(global_to_local_number_of_closest_candidates)) DEALLOCATE(global_to_local_number_of_closest_candidates)
1478  IF(ALLOCATED(global_number_of_closest_candidates)) DEALLOCATE(global_number_of_closest_candidates)
1479  IF(ALLOCATED(global_mpi_displacements)) DEALLOCATE(global_mpi_displacements)
1480  IF(ALLOCATED(global_number_of_projected_points)) DEALLOCATE(global_number_of_projected_points)
1481  IF(ALLOCATED(projection_exit_tag)) DEALLOCATE(projection_exit_tag)
1482  IF(ALLOCATED(projected_element)) DEALLOCATE(projected_element)
1483  IF(ALLOCATED(projected_face)) DEALLOCATE(projected_face)
1484  IF(ALLOCATED(projected_distance)) DEALLOCATE(projected_distance)
1485  IF(ALLOCATED(projected_xi)) DEALLOCATE(projected_xi)
1486  IF(ALLOCATED(projection_vectors)) DEALLOCATE(projection_vectors)
1487  IF(ALLOCATED(sorting_ind_2)) DEALLOCATE(sorting_ind_2)
1488  IF(ALLOCATED(global_closest_distances)) DEALLOCATE(global_closest_distances)
1489  IF(ALLOCATED(sorting_ind_1)) DEALLOCATE(sorting_ind_1)
1490 
1491  exits("DataProjection_DataPointsProjectionEvaluate")
1492  RETURN
1493 999 IF(ALLOCATED(candidate_elements)) DEALLOCATE(candidate_elements)
1494  IF(ALLOCATED(candidate_faces)) DEALLOCATE(candidate_faces)
1495  IF(ALLOCATED(closest_elements)) DEALLOCATE(closest_elements)
1496  IF(ALLOCATED(closest_faces)) DEALLOCATE(closest_faces)
1497  IF(ALLOCATED(closest_distances)) DEALLOCATE(closest_distances)
1498  IF(ALLOCATED(global_to_local_number_of_closest_candidates)) DEALLOCATE(global_to_local_number_of_closest_candidates)
1499  IF(ALLOCATED(global_number_of_closest_candidates)) DEALLOCATE(global_number_of_closest_candidates)
1500  IF(ALLOCATED(global_mpi_displacements)) DEALLOCATE(global_mpi_displacements)
1501  IF(ALLOCATED(global_number_of_projected_points)) DEALLOCATE(global_number_of_projected_points)
1502  IF(ALLOCATED(projection_exit_tag)) DEALLOCATE(projection_exit_tag)
1503  IF(ALLOCATED(projected_element)) DEALLOCATE(projected_element)
1504  IF(ALLOCATED(projected_face)) DEALLOCATE(projected_face)
1505  IF(ALLOCATED(projected_distance)) DEALLOCATE(projected_distance)
1506  IF(ALLOCATED(projected_xi)) DEALLOCATE(projected_xi)
1507  IF(ALLOCATED(projection_vectors)) DEALLOCATE(projection_vectors)
1508  IF(ALLOCATED(sorting_ind_2)) DEALLOCATE(sorting_ind_2)
1509  IF(ALLOCATED(global_closest_distances)) DEALLOCATE(global_closest_distances)
1510  IF(ALLOCATED(sorting_ind_1)) DEALLOCATE(sorting_ind_1)
1511 998 errorsexits("DataProjection_DataPointsProjectionEvaluate",err,error)
1512  RETURN 1
1513 
1515 
1516  !
1517  !================================================================================================================================
1518  !
1519 
1521  SUBROUTINE dataprojection_datapointspositionevaluate(dataProjection,field,fieldVariableType,err,error,*)
1523  !Argument variables
1524  TYPE(data_projection_type), POINTER :: dataProjection
1525  TYPE(field_type), POINTER :: field
1526  INTEGER(INTG), INTENT(IN) :: fieldVariableType
1527  INTEGER(INTG), INTENT(OUT) :: ERR
1528  TYPE(varying_string), INTENT(OUT) :: ERROR
1529  !Local Variables
1530  INTEGER(INTG) :: dataPointIdx,elementNumber,coordIdx
1531  TYPE(data_points_type), POINTER :: dataPoints
1532  TYPE(field_interpolated_point_ptr_type), POINTER :: interpolatedPoints(:)
1533  TYPE(field_interpolated_point_type), POINTER :: interpolatedPoint
1534  TYPE(field_interpolation_parameters_ptr_type), POINTER :: interpolationParameters(:)
1535 
1536  enters("DataProjection_DataPointsPositionEvaluate",err,error,*999)
1537 
1538  IF(ASSOCIATED(field)) THEN
1539  IF (field%TYPE==field_geometric_type.OR.field%TYPE==field_geometric_general_type) THEN
1540  IF(ASSOCIATED(dataprojection)) THEN
1541  datapoints=>dataprojection%DATA_POINTS
1542  IF(ASSOCIATED(datapoints)) THEN
1543  NULLIFY(interpolatedpoints)
1544  NULLIFY(interpolationparameters)
1545  CALL field_interpolation_parameters_initialise(field,interpolationparameters,err,error,*999, &
1546  & field_geometric_components_type)
1547  CALL field_interpolated_points_initialise(interpolationparameters,interpolatedpoints,err,error,*999, &
1548  & field_geometric_components_type)
1549  interpolatedpoint=>interpolatedpoints(fieldvariabletype)%PTR
1550  !Loop through data points
1551  DO datapointidx=1,datapoints%NUMBER_OF_DATA_POINTS
1552  elementnumber=dataprojection%DATA_PROJECTION_RESULTS(datapointidx)%ELEMENT_NUMBER
1553  CALL field_interpolation_parameters_element_get(field_values_set_type,elementnumber, &
1554  & interpolationparameters(fieldvariabletype)%PTR,err,error,*999,field_geometric_components_type)
1555  CALL field_interpolate_xi(no_part_deriv,dataprojection%DATA_PROJECTION_RESULTS(datapointidx)%XI, &
1556  & interpolatedpoint,err,error,*999,field_geometric_components_type)
1557  DO coordidx=1,SIZE(datapoints%DATA_POINTS(datapointidx)%position)
1558  datapoints%DATA_POINTS(datapointidx)%position(coordidx)=interpolatedpoint%VALUES(coordidx,no_part_deriv)
1559  ENDDO !coordIdx
1560  ENDDO !dataPointIdx
1561  ELSE
1562  CALL flag_error("Data points is not associated.",err,error,*999)
1563  ENDIF
1564  ELSE
1565  CALL flag_error("Data projection is not associated.",err,error,*999)
1566  ENDIF
1567  ELSE
1568  CALL flag_error("Cannot evaluate data points position on field other than geometric or geometric general type.", &
1569  & err,error,*999)
1570  ENDIF
1571  ELSE
1572  CALL flag_error("Field is not associated.",err,error,*999)
1573  ENDIF
1574 
1575  exits("DataProjection_DataPointsPositionEvaluate")
1576  RETURN
1577 999 errorsexits("DataProjection_DataPointsPositionEvaluate",err,error)
1578  RETURN 1
1579 
1581 
1582  !
1583  !================================================================================================================================
1584  !
1585 
1587  SUBROUTINE dataprojection_maximuminterationupdateget(DATA_PROJECTION,MAXIMUM_ITERATION_UPDATE,ERR,ERROR,*)
1589  !Argument variables
1590  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
1591  REAL(DP), INTENT(OUT) :: MAXIMUM_ITERATION_UPDATE
1592  INTEGER(INTG), INTENT(OUT) :: ERR
1593  TYPE(varying_string), INTENT(OUT) :: ERROR
1594  !Local Variables
1595  enters("DataProjection_MaximumInterationUpdateGet",err,error,*999)
1596 
1597  IF(ASSOCIATED(data_projection)) THEN
1598  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1599  maximum_iteration_update=data_projection%MAXIMUM_ITERATION_UPDATE
1600  ELSE
1601  CALL flag_error("Data projection have not been finished.",err,error,*999)
1602  ENDIF
1603  ELSE
1604  CALL flag_error("Data projection is not associated.",err,error,*999)
1605  ENDIF
1606 
1607  exits("DataProjection_MaximumInterationUpdateGet")
1608  RETURN
1609 999 errorsexits("DataProjection_MaximumInterationUpdateGet",err,error)
1610  RETURN 1
1611 
1613 
1614  !
1615  !================================================================================================================================
1616  !
1617 
1619  SUBROUTINE dataprojection_maximuminterationupdateset(DATA_PROJECTION,MAXIMUM_ITERATION_UPDATE,ERR,ERROR,*)
1621  !Argument variables
1622  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
1623  REAL(DP), INTENT(IN) :: MAXIMUM_ITERATION_UPDATE
1624  INTEGER(INTG), INTENT(OUT) :: ERR
1625  TYPE(varying_string), INTENT(OUT) :: ERROR
1626  !Local Variables
1627 
1628  enters("DataProjection_MaximumInterationUpdateSet",err,error,*999)
1629 
1630  IF(ASSOCIATED(data_projection)) THEN
1631  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1632  CALL flag_error("Data projection have been finished.",err,error,*999)
1633  ELSE
1634  IF((maximum_iteration_update>=0.1).AND.(maximum_iteration_update<=1)) THEN
1635  data_projection%MAXIMUM_ITERATION_UPDATE=maximum_iteration_update
1636  ELSE
1637  CALL flag_error("Data projection maximum iteration update must be between 0.1 and 1.",err,error,*999)
1638  ENDIF
1639  ENDIF
1640  ELSE
1641  CALL flag_error("Data projection is not associated.",err,error,*999)
1642  ENDIF
1643 
1644  exits("DataProjection_MaximumInterationUpdateSet")
1645  RETURN
1646 999 errorsexits("DataProjection_MaximumInterationUpdateSet",err,error)
1647  RETURN 1
1648 
1650 
1651 
1652  !
1653  !================================================================================================================================
1654  !
1655 
1657  SUBROUTINE dataprojection_maximumnumberofiterationsget(DATA_PROJECTION,MAXIMUM_NUMBER_OF_ITERATIONS,ERR,ERROR,*)
1659  !Argument variables
1660  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
1661  INTEGER(INTG), INTENT(OUT) :: MAXIMUM_NUMBER_OF_ITERATIONS
1662  INTEGER(INTG), INTENT(OUT) :: ERR
1663  TYPE(varying_string), INTENT(OUT) :: ERROR
1664  !Local Variables
1665 
1666  enters("DataProjection_MaximumNumberOfIterationsGet",err,error,*999)
1667 
1668  IF(ASSOCIATED(data_projection)) THEN
1669  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1670  maximum_number_of_iterations=data_projection%MAXIMUM_NUMBER_OF_ITERATIONS
1671  ELSE
1672  CALL flag_error("Data projection have not been finished.",err,error,*999)
1673  ENDIF
1674  ELSE
1675  CALL flag_error("Data projection is not associated.",err,error,*999)
1676  ENDIF
1677 
1678  exits("DataProjection_MaximumNumberOfIterationsGet")
1679  RETURN
1680 999 errorsexits("DataProjection_MaximumNumberOfIterationsGet",err,error)
1681  RETURN 1
1682 
1684 
1685  !
1686  !================================================================================================================================
1687  !
1688 
1690  SUBROUTINE dataprojection_maximumnumberofiterationsset(DATA_PROJECTION,MAXIMUM_NUMBER_OF_ITERATIONS,ERR,ERROR,*)
1692  !Argument variables
1693  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
1694  INTEGER(INTG), INTENT(IN) :: MAXIMUM_NUMBER_OF_ITERATIONS
1695  INTEGER(INTG), INTENT(OUT) :: ERR
1696  TYPE(varying_string), INTENT(OUT) :: ERROR
1697  !Local Variables
1698 
1699  enters("DataProjection_MaximumNumberOfIterationsSet",err,error,*999)
1700 
1701  IF(ASSOCIATED(data_projection)) THEN
1702  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1703  CALL flag_error("Data projection have been finished.",err,error,*999)
1704  ELSE
1705  IF(maximum_number_of_iterations>=1) THEN
1706  data_projection%MAXIMUM_NUMBER_OF_ITERATIONS=maximum_number_of_iterations
1707  ELSE
1708  CALL flag_error("Data projection maximum number of iterations must be at least 1.",err,error,*999)
1709  ENDIF
1710  ENDIF
1711  ELSE
1712  CALL flag_error("Data projection is not associated.",err,error,*999)
1713  ENDIF
1714 
1715  exits("DataProjection_MaximumNumberOfIterationsSet")
1716  RETURN
1717 999 errorsexits("DataProjection_MaximumNumberOfIterationsSet",err,error)
1718  RETURN 1
1719 
1721 
1722  !
1723  !================================================================================================================================
1724  !
1725 
1727  SUBROUTINE data_projection_newton_elements_evaluate_1(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
1728  & projection_exit_tag,projection_element_number,projection_distance,projection_xi,projection_vector,err,error,*)
1729  !Argument variables
1730  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
1731  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
1732  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
1733  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
1734  INTEGER(INTG), INTENT(OUT) :: PROJECTION_EXIT_TAG
1735  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_NUMBER
1736  REAL(DP), INTENT(OUT) :: PROJECTION_DISTANCE
1737  REAL(DP), INTENT(OUT) :: PROJECTION_XI(1)
1738  REAL(DP), INTENT(OUT) :: PROJECTION_VECTOR(3)
1739  INTEGER(INTG), INTENT(OUT) :: ERR
1740  TYPE(varying_string), INTENT(OUT) :: ERROR
1741 
1742  !Local Variables
1743  LOGICAL :: INSIDE_REGION,CONVERGED
1744  INTEGER(INTG) :: ELEMENT_NUMBER !local element number in current computational domain
1745  INTEGER(INTG) :: REGION_DIMENSIONS
1746  INTEGER(INTG) :: BOUND,EXIT_TAG
1747  REAL(DP) :: XI(1),XI_NEW(1),XI_UPDATE(1),XI_UPDATE_NORM
1748  REAL(DP) :: DISTANCE_VECTOR(3),RELATIVE_TOLERANCE,ABSOLUTE_TOLERANCE
1749  REAL(DP) :: FUNCTION_VALUE,FUNCTION_VALUE_NEW
1750  REAL(DP) :: FUNCTION_GRADIENT,FUNCTION_HESSIAN
1751  REAL(DP) :: MAXIMUM_DELTA,MINIMUM_DELTA,DELTA
1752  REAL(DP) :: PREDICTED_REDUCTION,PREDICTION_ACCURACY
1753 
1754  INTEGER(INTG) :: ne,itr1,itr2
1755 
1756  enters("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_1",err,error,*999)
1757 
1758  IF(ASSOCIATED(data_projection)) THEN
1759  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1760  projection_exit_tag=data_projection_exit_tag_no_element
1761  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
1762  relative_tolerance=data_projection%RELATIVE_TOLERANCE
1763  absolute_tolerance=data_projection%ABSOLUTE_TOLERANCE
1764  maximum_delta=data_projection%MAXIMUM_ITERATION_UPDATE
1765  minimum_delta=0.025_dp*maximum_delta !need to set a minimum, in case if it gets too small
1766  DO ne=1,SIZE(candidate_elements,1) !project on each candidate elements
1767  element_number=candidate_elements(ne)
1769  converged=.false.
1770  delta=0.5_dp*maximum_delta !start at half the MAXIMUM_DELTA as we do not know if quadratic model is a good approximation yet
1771  CALL field_interpolation_parameters_element_get(field_values_set_type,element_number,interpolated_point% &
1772  & interpolation_parameters,err,error,*999,field_geometric_components_type)
1773  xi=data_projection%STARTING_XI
1774  CALL field_interpolate_xi(second_part_deriv,xi,interpolated_point,err,error,*999,field_geometric_components_type)
1775  distance_vector(1:region_dimensions)=point_values-interpolated_point%VALUES(:,no_part_deriv)
1776  function_value=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
1777  main_loop: DO itr1=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(outer loop)
1778  !Check for bounds [0,1]
1779  IF(abs(xi(1))<zero_tolerance) THEN
1780  bound=-1 !bound at negative direction
1781  ELSEIF(abs(xi(1)-1.0_dp)<zero_tolerance) THEN
1782  bound=1 !bound at positive direction
1783  ELSE !inside the bounds
1784  bound=0
1785  ENDIF
1786  !FUNCTION_GRADIENT
1787  function_gradient=-2.0_dp* &
1788  & (dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,first_part_deriv)))
1789  !FUNCTION_HESSIAN
1790  function_hessian=-2.0_dp*(&
1791  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,second_part_deriv))- &
1792  & dot_product(interpolated_point%VALUES(:,first_part_deriv),interpolated_point%VALUES(:,first_part_deriv)))
1793  !A model trust region approach, directly taken from CMISS CLOS22: V = -(H + EIGEN_SHIFT*I)g
1794  !The calculation of EIGEN_SHIFT are only approximated as oppose to the common trust region approach
1795  DO itr2=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(inner loop: adjust region size) usually EXIT at 1 or 2 iterations
1796  inside_region=.false.
1797  IF(function_hessian>absolute_tolerance) THEN !positive: minimum exists
1798  xi_update(1)=-function_gradient/function_hessian
1799  xi_update_norm=dabs(xi_update(1))
1800  inside_region=xi_update_norm<=delta
1801  ENDIF !positive
1802  IF(.NOT.inside_region) THEN !minimum not in the region
1803  xi_update(1)=-dsign(delta,function_gradient)
1804  xi_update_norm=delta
1805  ENDIF
1806  IF((bound/=0).AND.(bound>0.EQV.xi_update(1)>0.0_dp)) THEN !projection go out of element bound
1808  EXIT main_loop
1809  ENDIF
1810  converged=xi_update_norm<absolute_tolerance !first half of the convergence test (before collision detection)
1811  xi_new=xi+xi_update !update XI
1812  IF(xi_new(1)<0.0_dp) THEN !boundary collision check
1813  xi_new(1)=0.0_dp
1814  ELSEIF(xi_new(1)>1.0_dp) THEN
1815  xi_new(1)=1.0_dp
1816  ENDIF
1817  CALL field_interpolate_xi(second_part_deriv,xi_new,interpolated_point,err,error,*999,field_geometric_components_type)
1818  distance_vector=point_values-interpolated_point%VALUES(:,no_part_deriv)
1819  function_value_new=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
1820  converged=converged.AND.(dabs(function_value_new-function_value)/(1.0_dp+function_value)<relative_tolerance) !second half of the convergence test
1821  IF(converged) EXIT !converged: exit inner loop first
1822  IF((function_value_new-function_value)>absolute_tolerance) THEN !bad model: reduce step size
1823  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
1824  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
1825  EXIT main_loop
1826  ENDIF
1827  delta=dmax1(minimum_delta,0.25_dp*delta)
1828  ELSE
1829  predicted_reduction=xi_update(1)*(function_gradient+0.5_dp*function_hessian*xi_update(1))
1830  prediction_accuracy=(function_value_new-function_value)/predicted_reduction
1831  IF(prediction_accuracy<0.01_dp) THEN !bad model: reduce region size
1832  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
1833  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
1834  EXIT main_loop
1835  ENDIF
1836  delta=dmax1(minimum_delta,0.5_dp*delta)
1837  ELSEIF(prediction_accuracy>0.9_dp.AND.prediction_accuracy<1.1_dp) THEN !good model: increase region size
1838  delta=dmin1(maximum_delta,2.0_dp*delta)
1839  EXIT
1840  ELSE !ok model: keep the current region size
1841  EXIT
1842  ENDIF
1843  ENDIF
1844  ENDDO !itr2 (inner loop: adjust region size)
1845  function_value=function_value_new
1846  xi=xi_new
1847  IF(converged) THEN
1849  EXIT
1850  ENDIF
1851  ENDDO main_loop !itr1 (outer loop)
1852  IF(exit_tag==data_projection_exit_tag_no_element.AND.itr1>=data_projection%MAXIMUM_NUMBER_OF_ITERATIONS) &
1854  IF((projection_exit_tag==data_projection_exit_tag_no_element).OR.(dsqrt(function_value)<projection_distance)) THEN
1855  projection_exit_tag=exit_tag
1856  projection_element_number=element_number
1857  projection_distance=dsqrt(function_value)
1858  projection_xi=xi
1859  projection_vector=distance_vector
1860  ENDIF
1861  ENDDO !ne
1862  ELSE
1863  CALL flag_error("Data projection have not been finished.",err,error,*999)
1864  ENDIF
1865  ELSE
1866  CALL flag_error("Data projection is not associated.",err,error,*999)
1867  ENDIF
1868 
1869  exits("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_1")
1870  RETURN
1871 999 errorsexits("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_1",err,error)
1872  RETURN 1
1873 
1875 
1876  !
1877  !================================================================================================================================
1878  !
1879 
1881  SUBROUTINE data_projection_newton_elements_evaluate_2(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
1882  & projection_exit_tag,projection_element_number,projection_distance,projection_xi,projection_vector,err,error,*)
1883  !Argument variables
1884  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
1885  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
1886  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
1887  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
1888  INTEGER(INTG), INTENT(OUT) :: PROJECTION_EXIT_TAG
1889  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_NUMBER
1890  REAL(DP), INTENT(OUT) :: PROJECTION_DISTANCE
1891  REAL(DP), INTENT(OUT) :: PROJECTION_XI(2)
1892  REAL(DP), INTENT(OUT) :: PROJECTION_VECTOR(3)
1893  INTEGER(INTG), INTENT(OUT) :: ERR
1894  TYPE(varying_string), INTENT(OUT) :: ERROR
1895 
1896  !Local Variables
1897  TYPE(domain_mapping_type), POINTER :: DOMAIN_MAPPING
1898  LOGICAL :: FREE,CONVERGED,INSIDE_REGION
1899  INTEGER(INTG) :: ELEMENT_NUMBER
1900  INTEGER(INTG) :: MESH_COMPONENT_NUMBER,REGION_DIMENSIONS
1901  INTEGER(INTG) :: BOUND(2),EXIT_TAG
1902  REAL(DP) :: XI(2),XI_NEW(2),XI_UPDATE(2),XI_UPDATE_NORM
1903  REAL(DP) :: DISTANCE_VECTOR(3),RELATIVE_TOLERANCE,ABSOLUTE_TOLERANCE
1904  REAL(DP) :: FUNCTION_VALUE,FUNCTION_VALUE_NEW
1905  REAL(DP) :: FUNCTION_GRADIENT(2),FUNCTION_GRADIENT_NORM
1906  REAL(DP) :: FUNCTION_HESSIAN(2,2),HESSIAN_DIAGONAL(2)
1907  REAL(DP) :: TEMP1,TEMP2,DET,EIGEN_MIN,EIGEN_MAX,EIGEN_SHIFT
1908  REAL(DP) :: MAXIMUM_DELTA,MINIMUM_DELTA,DELTA
1909  REAL(DP) :: PREDICTED_REDUCTION,PREDICTION_ACCURACY
1910 
1911 
1912  INTEGER(INTG) :: ne,ni,nifix,itr1,itr2
1913 
1914  enters("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_2",err,error,*999)
1915 
1916  IF(ASSOCIATED(data_projection)) THEN
1917  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
1918  projection_exit_tag=data_projection_exit_tag_no_element
1919  mesh_component_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%MESH_COMPONENT_NUMBER
1920  domain_mapping=>interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%DOMAIN(mesh_component_number)% &
1921  & ptr%MAPPINGS%ELEMENTS
1922  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
1923  relative_tolerance=data_projection%RELATIVE_TOLERANCE
1924  absolute_tolerance=data_projection%ABSOLUTE_TOLERANCE
1925  maximum_delta=data_projection%MAXIMUM_ITERATION_UPDATE
1926  minimum_delta=0.025_dp*maximum_delta !need to set a minimum, in case if it gets too small
1927  DO ne=1,SIZE(candidate_elements,1) !project on each candidate elements
1928  element_number=candidate_elements(ne)
1930  converged=.false.
1931  delta=0.5_dp*maximum_delta !start at half the MAXIMUM_DELTA as we do not know if quadratic model is a good approximation yet
1932  CALL field_interpolation_parameters_element_get(field_values_set_type,element_number, &
1933  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
1934  xi=data_projection%STARTING_XI
1935  CALL field_interpolate_xi(second_part_deriv,xi,interpolated_point,err,error,*999,field_geometric_components_type)
1936  distance_vector(1:region_dimensions)=point_values-interpolated_point%VALUES(:,no_part_deriv)
1937  function_value=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
1938  main_loop: DO itr1=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(outer loop)
1939  !Check for bounds [0,1]
1940  DO ni=1,2
1941  IF(abs(xi(ni))<zero_tolerance) THEN
1942  bound(ni)=-1 !bound at negative direction
1943  ELSEIF(abs(xi(ni)-1.0_dp)<zero_tolerance) THEN
1944  bound(ni)=1 !bound at positive direction
1945  ELSE !inside the bounds
1946  bound(ni)=0
1947  ENDIF
1948  ENDDO !ni
1949  !FUNCTION_GRADIENT
1950  function_gradient(1)= &
1951  & -2.0_dp*(dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s1)))
1952  function_gradient(2)= &
1953  & -2.0_dp*(dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s2)))
1954  !FUNCTION_HESSIAN
1955  function_hessian(1,1)= -2.0_dp*(&
1956  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s1_s1))- &
1957  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s1)))
1958  function_hessian(1,2)= -2.0_dp*(&
1959  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s1_s2))- &
1960  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s2)))
1961  function_hessian(2,2)= -2.0_dp*(&
1962  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s2_s2))- &
1963  & dot_product(interpolated_point%VALUES(:,part_deriv_s2),interpolated_point%VALUES(:,part_deriv_s2)))
1964  !A model trust region approach, a Newton step is taken if the minimum lies inside the trust region (DELTA), if not, shift the step towards the steepest descent
1965  temp1=0.5_dp*(function_hessian(1,1)+function_hessian(2,2))
1966  temp2=dsqrt((0.5_dp*(function_hessian(1,1)-function_hessian(2,2)))**2+function_hessian(1,2)**2)
1967  eigen_min=temp1-temp2
1968  eigen_max=temp1+temp2
1969  function_gradient_norm=dsqrt(dot_product(function_gradient,function_gradient))
1970  DO itr2=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(inner loop: adjust region size) usually EXIT at 1 or 2 iterations
1971  temp1=function_gradient_norm/delta
1972  inside_region=(eigen_min>=temp1).AND.(eigen_min>absolute_tolerance) !estimate if the solution is inside the trust region without calculating a newton step, this also guarantees the hessian matrix is positive definite
1973  IF(inside_region) THEN
1974  det=eigen_min*eigen_max !det(H)
1975  hessian_diagonal(1)=function_hessian(1,1)
1976  hessian_diagonal(2)=function_hessian(2,2)
1977  ELSE
1978  eigen_shift=max(temp1-eigen_min,absolute_tolerance) !shift towards steepest decent
1979  det=temp1*(eigen_max+eigen_shift) !det(H)
1980  hessian_diagonal(1)=function_hessian(1,1)+eigen_shift
1981  hessian_diagonal(2)=function_hessian(2,2)+eigen_shift
1982  ENDIF
1983  xi_update(1)=-(hessian_diagonal(2)*function_gradient(1)-function_hessian(1,2)*function_gradient(2))/det
1984  xi_update(2)=(function_hessian(1,2)*function_gradient(1)-hessian_diagonal(1)*function_gradient(2))/det
1985  xi_update_norm=dsqrt(dot_product(xi_update,xi_update))
1986  free=.true.
1987  DO ni=1,2
1988  IF((bound(ni)/=0).AND.(bound(ni)>0.EQV.xi_update(ni)>0.0_dp)) THEN !projection go out of element bound
1989  IF(.NOT.free) THEN !both xi are fixed
1991  EXIT main_loop
1992  ENDIF
1993  free=.false.
1994  nifix=ni
1995  ENDIF
1996  ENDDO !ni
1997  IF(free) THEN !both xi are free
1998  IF(.NOT.inside_region) THEN
1999  IF(xi_update_norm>0.0_dp) THEN
2000  xi_update=delta/xi_update_norm*xi_update !readjust XI_UPDATE to lie on the region bound
2001  ENDIF
2002  ENDIF
2003  ELSE !xi are not free
2004  xi_update(nifix)=0.0_dp
2005  ni=3-nifix
2006  inside_region=.false.
2007  IF(function_hessian(ni,ni)>0.0_dp) THEN !positive: minimum exists in the unbounded direction
2008  xi_update(ni)=-function_gradient(ni)/function_hessian(ni,ni)
2009  xi_update_norm=dabs(xi_update(ni))
2010  inside_region=xi_update_norm<=delta
2011  ENDIF
2012  IF(.NOT.inside_region) THEN !minimum not in the region
2013  xi_update(ni)=-dsign(delta,function_gradient(ni))
2014  xi_update_norm=delta
2015  ENDIF
2016  ENDIF !if xi is free
2017  converged=xi_update_norm<absolute_tolerance !first half of the convergence test
2018  xi_new=xi+xi_update !update XI
2019  DO ni=1,2
2020  IF(xi_new(ni)<0.0_dp) THEN !boundary collision check
2021  xi_new(ni)=0.0_dp
2022  xi_new(3-ni)=xi(3-ni)-xi_update(3-ni)*xi(ni)/xi_update(ni)
2023  ELSEIF(xi_new(ni)>1.0_dp) THEN
2024  xi_new(ni)=1.0_dp
2025  xi_new(3-ni)=xi(3-ni)+xi_update(3-ni)*(1.0_dp-xi(ni))/xi_update(ni)
2026  ENDIF
2027  ENDDO
2028  CALL field_interpolate_xi(second_part_deriv,xi_new,interpolated_point,err,error,*999,field_geometric_components_type)
2029  distance_vector(1:region_dimensions)=point_values-interpolated_point%VALUES(:,no_part_deriv)
2030  function_value_new=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
2031  converged=converged.AND.(dabs(function_value_new-function_value)/(1.0_dp+function_value)<relative_tolerance) !second half of the convergence test (before collision detection)
2032  IF(converged) EXIT !converged: exit inner loop first
2033  IF((function_value_new-function_value)>absolute_tolerance) THEN !bad model: reduce step size
2034  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2035  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2036  EXIT main_loop
2037  ENDIF
2038  delta=dmax1(minimum_delta,0.25_dp*delta)
2039  ELSE
2040  predicted_reduction=dot_product(function_gradient,xi_update)+ &
2041  & 0.5_dp*(xi_update(1)*(xi_update(1)*function_hessian(1,1)+2.0_dp*xi_update(2)*function_hessian(1,2))+ &
2042  & xi_update(2)**2*function_hessian(2,2))
2043  prediction_accuracy=(function_value_new-function_value)/predicted_reduction
2044  IF(prediction_accuracy<0.01_dp) THEN !bad model: reduce region size
2045  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2046  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2047  EXIT main_loop
2048  ENDIF
2049  delta=dmax1(minimum_delta,0.5_dp*delta)
2050  ELSEIF(prediction_accuracy>0.9_dp.AND.prediction_accuracy<1.1_dp) THEN !good model: increase region size
2051  delta=dmin1(maximum_delta,2.0_dp*delta)
2052  EXIT
2053  ELSE !ok model: keep the current region size
2054  EXIT
2055  ENDIF
2056  ENDIF
2057  ENDDO !itr2 (inner loop: adjust region size)
2058  function_value=function_value_new
2059  xi=xi_new
2060  IF(converged) THEN
2062  EXIT
2063  ENDIF
2064  ENDDO main_loop !itr1 (outer loop)
2065  IF(exit_tag==data_projection_exit_tag_no_element.AND.itr1>=data_projection%MAXIMUM_NUMBER_OF_ITERATIONS) &
2067  IF((projection_exit_tag==data_projection_exit_tag_no_element).OR.(dsqrt(function_value)<projection_distance)) THEN
2068  !IF(.NOT.ELEMENT_FOUND) ELEMENT_FOUND=.TRUE.
2069  projection_exit_tag=exit_tag
2070  projection_element_number=element_number
2071  projection_distance=dsqrt(function_value)
2072  projection_xi=xi
2073  projection_vector=distance_vector
2074  ENDIF
2075  ENDDO !ne
2076  ELSE
2077  CALL flag_error("Data projection have not been finished.",err,error,*999)
2078  ENDIF
2079  ELSE
2080  CALL flag_error("Data projection is not associated.",err,error,*999)
2081  ENDIF
2082 
2083  exits("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_2")
2084  RETURN
2085 999 errorsexits("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_2",err,error)
2086  RETURN 1
2087 
2089 
2090  !
2091  !================================================================================================================================
2092  !
2093 
2095  SUBROUTINE data_projection_newton_elements_evaluate_3(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
2096  & projection_exit_tag,projection_element_number,projection_distance,projection_xi,projection_vector,err,error,*)
2097  !Argument variables
2098  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2099  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
2100  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
2101  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
2102  INTEGER(INTG), INTENT(OUT) :: PROJECTION_EXIT_TAG
2103  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_NUMBER
2104  REAL(DP), INTENT(OUT) :: PROJECTION_DISTANCE
2105  REAL(DP), INTENT(OUT) :: PROJECTION_XI(3)
2106  REAL(DP), INTENT(OUT) :: PROJECTION_VECTOR(3)
2107  INTEGER(INTG), INTENT(OUT) :: ERR
2108  TYPE(varying_string), INTENT(OUT) :: ERROR
2109 
2110  !Local Variables
2111  TYPE(domain_mapping_type), POINTER :: DOMAIN_MAPPING
2112  LOGICAL :: FREE,CONVERGED,INSIDE_REGION
2113  INTEGER(INTG) :: ELEMENT_NUMBER
2114  INTEGER(INTG) :: MESH_COMPONENT_NUMBER
2115  INTEGER(INTG) :: NBOUND,BOUND(3),EXIT_TAG
2116  REAL(DP) :: XI(3),XI_NEW(3),XI_UPDATE(3),XI_UPDATE_NORM
2117  REAL(DP) :: DISTANCE_VECTOR(3),RELATIVE_TOLERANCE,ABSOLUTE_TOLERANCE
2118  REAL(DP) :: FUNCTION_VALUE,FUNCTION_VALUE_NEW
2119  REAL(DP) :: FUNCTION_GRADIENT(3),FUNCTION_GRADIENT_NORM,FUNCTION_GRADIENT2(2)
2120  REAL(DP) :: FUNCTION_HESSIAN(3,3),HESSIAN_DIAGONAL(3),FUNCTION_HESSIAN2(2,2),HESSIAN_DIAGONAL2(2)
2121  REAL(DP) :: TEMP1,TEMP2,TEMP3,TEMP4,DET,TRACE,TRACE2,EIGEN_MIN,EIGEN_MAX,EIGEN_SHIFT
2122  REAL(DP) :: MAXIMUM_DELTA,MINIMUM_DELTA,DELTA
2123  REAL(DP) :: PREDICTED_REDUCTION,PREDICTION_ACCURACY
2124 
2125 
2126  INTEGER(INTG) :: ne,ni,ni2(2),nb,nifix,nifix2(2),itr1,itr2,nbfix,mi
2127 
2128  enters("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_3",err,error,*999)
2129 
2130  IF(ASSOCIATED(data_projection)) THEN
2131  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2132  projection_exit_tag=data_projection_exit_tag_no_element
2133  mesh_component_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%MESH_COMPONENT_NUMBER
2134  domain_mapping=>interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%DOMAIN(mesh_component_number)% &
2135  & ptr%MAPPINGS%ELEMENTS
2136  !REGION_DIMENSIONS=DATA_PROJECTION%COORDINATE_SYSTEM_DIMENSIONS
2137  relative_tolerance=data_projection%RELATIVE_TOLERANCE
2138  absolute_tolerance=data_projection%ABSOLUTE_TOLERANCE
2139  maximum_delta=data_projection%MAXIMUM_ITERATION_UPDATE
2140  minimum_delta=0.025_dp*maximum_delta !need to set a minimum, in case if it gets too small
2141  DO ne=1,SIZE(candidate_elements,1) !project on each candidate elements
2142  element_number=candidate_elements(ne)
2144  converged=.false.
2145  delta=0.5_dp*maximum_delta !start at half the MAXIMUM_DELTA as we do not know if quadratic model is a good approximation yet
2146  CALL field_interpolation_parameters_element_get(field_values_set_type,element_number, &
2147  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
2148  xi=data_projection%STARTING_XI
2149  CALL field_interpolate_xi(second_part_deriv,xi,interpolated_point,err,error,*999,field_geometric_components_type)
2150  distance_vector=point_values-interpolated_point%VALUES(:,no_part_deriv)
2151  function_value=dot_product(distance_vector,distance_vector)
2152  main_loop: DO itr1=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(outer loop)
2153  !Check for bounds [0,1]
2154  DO ni=1,3
2155  IF(abs(xi(ni))<zero_tolerance) THEN
2156  bound(ni)=-1 !bound at negative direction
2157  ELSEIF(abs(xi(ni)-1.0_dp)<zero_tolerance) THEN
2158  bound(ni)=1 !bound at positive direction
2159  ELSE !inside the bounds
2160  bound(ni)=0
2161  ENDIF
2162  ENDDO !ni
2163  !FUNCTION_GRADIENT
2164  function_gradient(1)=-2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s1)))
2165  function_gradient(2)=-2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s2)))
2166  function_gradient(3)=-2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s3)))
2167  !FUNCTION_HESSIAN
2168  function_hessian(1,1)= -2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s1_s1))- &
2169  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s1)))
2170  function_hessian(1,2)= -2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s1_s2))- &
2171  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s2)))
2172  function_hessian(1,3)= -2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s1_s3))- &
2173  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s3)))
2174  function_hessian(2,2)= -2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s2_s2))- &
2175  & dot_product(interpolated_point%VALUES(:,part_deriv_s2),interpolated_point%VALUES(:,part_deriv_s2)))
2176  function_hessian(2,3)= -2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s2_s3))- &
2177  & dot_product(interpolated_point%VALUES(:,part_deriv_s2),interpolated_point%VALUES(:,part_deriv_s3)))
2178  function_hessian(3,3)= -2.0_dp*(dot_product(distance_vector,interpolated_point%VALUES(:,part_deriv_s3_s3))- &
2179  & dot_product(interpolated_point%VALUES(:,part_deriv_s3),interpolated_point%VALUES(:,part_deriv_s3)))
2180  !A model trust region approach, a Newton step is taken if the solution lies inside the trust region (DELTA), if not, shift the step towards the steepest descent
2181  trace=function_hessian(1,1)+function_hessian(2,2)+function_hessian(3,3) !tr(H)
2182  trace2=function_hessian(1,1)*function_hessian(2,2)+function_hessian(1,1)*function_hessian(3,3)+ &
2183  & function_hessian(2,2)*function_hessian(3,3)-function_hessian(1,2)**2-function_hessian(1,3)**2- &
2184  & function_hessian(2,3)**2 !tr(H**2)-(tr(H))**2
2185  det=function_hessian(1,1)*function_hessian(2,2)*function_hessian(3,3)- &
2186  & function_hessian(1,1)*function_hessian(2,3)**2-function_hessian(2,2)*function_hessian(1,3)**2- &
2187  & function_hessian(3,3)*function_hessian(1,2)**2+ &
2188  & 2.0_dp*function_hessian(1,2)*function_hessian(1,3)*function_hessian(2,3) !det(H)
2189  temp1=-trace/3.0_dp
2190  temp2=trace2/3.0_dp
2191  temp3=temp2-temp1**2
2192  IF(temp3>-1.0e-5_dp) THEN !include some negatives for numerical errors
2193  eigen_min=-temp1 !all eigenvalues are the same
2194  ELSE
2195  temp3=dsqrt(-temp3)
2196  temp4=(det+3.0_dp*(temp1*temp2)-2.0_dp*temp1**3)/(2.0_dp*temp3**3)
2197  eigen_min=2.0_dp*temp3*dcos((dacos(temp4)+twopi)/3.0_dp)-temp1
2198  ENDIF
2199  function_gradient_norm=dsqrt(dot_product(function_gradient,function_gradient))
2200  DO itr2=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(inner loop: adjust region size) usually EXIT at 1 or 2 iterations
2201  temp1=function_gradient_norm/delta
2202  inside_region=(eigen_min>=temp1).AND.(eigen_min>absolute_tolerance) !estimate if the solution is inside the trust region without calculating a newton step, this also guarantees the hessian matrix is positive definite
2203  IF(inside_region) THEN
2204  hessian_diagonal(1)=function_hessian(1,1)
2205  hessian_diagonal(2)=function_hessian(2,2)
2206  hessian_diagonal(3)=function_hessian(3,3)
2207  ELSE
2208  eigen_shift=max(temp1-eigen_min,absolute_tolerance) !shift towards steepest decent
2209  det=det+eigen_shift*(trace2+eigen_shift*(trace+eigen_shift)) !shift the determinant
2210  hessian_diagonal(1)=function_hessian(1,1)+eigen_shift
2211  hessian_diagonal(2)=function_hessian(2,2)+eigen_shift
2212  hessian_diagonal(3)=function_hessian(3,3)+eigen_shift
2213  ENDIF
2214  temp2=function_hessian(1,3)*function_hessian(2,3)-function_hessian(1,2)*hessian_diagonal(3)
2215  temp3=function_hessian(1,2)*function_hessian(2,3)-function_hessian(1,3)*hessian_diagonal(2)
2216  temp4=function_hessian(1,2)*function_hessian(1,3)-function_hessian(2,3)*hessian_diagonal(1)
2217  xi_update(1)=((function_hessian(2,3)**2-hessian_diagonal(2)*hessian_diagonal(3))*function_gradient(1)- &
2218  & temp2*function_gradient(2)-temp3*function_gradient(3))/det
2219  xi_update(2)=((function_hessian(1,3)**2-hessian_diagonal(1)*hessian_diagonal(3))*function_gradient(2)- &
2220  & temp2*function_gradient(1)-temp4*function_gradient(3))/det
2221  xi_update(3)=((function_hessian(1,2)**2-hessian_diagonal(1)*hessian_diagonal(2))*function_gradient(3)- &
2222  & temp3*function_gradient(1)-temp4*function_gradient(2))/det
2223  xi_update_norm=dsqrt(dot_product(xi_update,xi_update))
2224  free=.true.
2225  nbound=0
2226  DO ni=1,3
2227  IF((bound(ni)/=0).AND.(bound(ni)>0.EQV.xi_update(ni)>0.0_dp)) THEN !projection go out of element bound
2228  nbound=nbound+1
2229  free=.false.
2230  IF(nbound<=2) THEN
2231  nifix2(nbound)=ni
2232  ELSE !all xi are fixed
2234  EXIT main_loop
2235  ENDIF
2236  ENDIF
2237  ENDDO !ni
2238  IF(free) THEN !all xi are free
2239  IF(.NOT.inside_region) THEN
2240  IF(xi_update_norm>0.0_dp) THEN
2241  xi_update=delta/xi_update_norm*xi_update !readjust XI_UPDATE to lie on the region bound
2242  ENDIF
2243  ENDIF
2244  ELSE !at least one of the xi are not free
2245  !try 2D projection
2246  free=.true.
2247  nifix=nifix2(1)
2248  IF(nbound==2) THEN
2249  IF(xi_update(nifix2(2))>xi_update(nifix2(1))) nifix=nifix2(2) !only fix the direction that is most strongly suggesting leaving the element
2250  ENDIF
2251  xi_update(nifix)=0.0_dp
2252  ni2(1)=1+mod(nifix,3)
2253  ni2(2)=1+mod(nifix+1,3)
2254  !FUNCTION_GRADIENT2
2255  function_gradient2(1)=function_gradient(ni2(1))
2256  function_gradient2(2)=function_gradient(ni2(2))
2257  !FUNCTION_HESSIAN2
2258  function_hessian2(1,1)=function_hessian(ni2(1),ni2(1))
2259  function_hessian2(1,2)=function_hessian(ni2(1),ni2(2))
2260  function_hessian2(2,2)=function_hessian(ni2(2),ni2(2))
2261  !re-estimate the trust solution in 2D
2262  temp1=0.5_dp*(function_hessian2(1,1)+function_hessian2(2,2))
2263  temp2=dsqrt((0.5_dp*(function_hessian2(1,1)-function_hessian2(2,2)))**2+function_hessian2(1,2)**2)
2264  eigen_min=temp1-temp2
2265  eigen_max=temp1+temp2
2266  temp3=dsqrt(dot_product(function_gradient2,function_gradient2))/delta
2267  inside_region=(eigen_min>=temp3).AND.(eigen_min>absolute_tolerance) !estimate if the solution is inside the trust region without calculating a newton step, this also guarantees the hessian matrix is positive definite
2268  IF(inside_region) THEN
2269  det=eigen_min*eigen_max !determinant of FUNCTION_HESSIAN
2270  hessian_diagonal2(1)=function_hessian2(1,1)
2271  hessian_diagonal2(2)=function_hessian2(2,2)
2272  ELSE
2273  eigen_shift=max(temp3-eigen_min,absolute_tolerance) !shift towards steepest decent
2274  det=temp3*(eigen_max+eigen_shift) !determinant of shifted FUNCTION_HESSIAN
2275  hessian_diagonal2(1)=function_hessian2(1,1)+eigen_shift
2276  hessian_diagonal2(2)=function_hessian2(2,2)+eigen_shift
2277  ENDIF
2278  xi_update(ni2(1))=-(hessian_diagonal2(2)*function_gradient2(1)-function_hessian2(1,2)*function_gradient2(2))/det
2279  xi_update(ni2(2))=(function_hessian2(1,2)*function_gradient2(1)-hessian_diagonal2(1)*function_gradient2(2))/det
2280  xi_update_norm=dsqrt(dot_product(xi_update,xi_update))
2281  !check again for bounds
2282  DO nb=1,2
2283  IF((bound(ni2(nb))/=0).AND.(bound(ni2(nb))>0.EQV.xi_update(ni2(nb))>0.0_dp)) THEN !projection go out of element bound
2284  IF(.NOT.free) THEN !both xi are fixed
2286  EXIT main_loop
2287  ENDIF
2288  free=.false.
2289  nbfix=nb
2290  ENDIF
2291  ENDDO !ni
2292  IF(free) THEN !both xi are free
2293  IF(.NOT.inside_region) THEN
2294  IF(xi_update_norm>0.0_dp) THEN
2295  xi_update=delta/xi_update_norm*xi_update !readjust XI_UPDATE to lie on the region bound
2296  ENDIF
2297  ENDIF
2298  ELSE !xi are not free
2299  xi_update(ni2(nbfix))=0.0_dp
2300  ni=ni2(3-nbfix)
2301  inside_region=.false.
2302  IF(function_hessian(ni,ni)>0.0_dp) THEN !positive: minimum exists in the unbounded direction
2303  xi_update(ni)=-function_gradient(ni)/function_hessian(ni,ni)
2304  xi_update_norm=dabs(xi_update(ni))
2305  inside_region=xi_update_norm<=delta
2306  ENDIF
2307  IF(.NOT.inside_region) THEN !minimum not in the region
2308  xi_update(ni)=-dsign(delta,function_gradient(ni))
2309  xi_update_norm=delta
2310  ENDIF
2311  ENDIF !if xi are free (2D)
2312  ENDIF !if xi are free (3D)
2313  converged=xi_update_norm<absolute_tolerance !first half of the convergence test
2314  xi_new=xi+xi_update !update XI
2315  DO ni=1,3
2316  IF(abs(xi_update(ni))<zero_tolerance) THEN !FPE Handling
2317  IF(xi_new(ni)<0.0_dp) THEN
2318  xi_new(ni)=0.0_dp
2319  DO mi = 1,3
2320  IF(mi /= ni) THEN
2321  xi_new(mi)=xi(mi)-xi_update(mi)
2322  ENDIF
2323  ENDDO
2324  ELSEIF(xi_new(ni)>1.0_dp) THEN
2325  xi_new(ni)=1.0_dp
2326  DO mi = 1,3
2327  IF(mi /= ni) THEN
2328  xi_new(mi)=xi(mi)+xi_update(mi)
2329  ENDIF
2330  ENDDO
2331  ENDIF
2332  ELSEIF(xi_new(ni)<0.0_dp) THEN !boundary collision check
2333  xi_new(ni)=0.0_dp
2334  xi_new=xi-xi_update*xi(ni)/xi_update(ni)
2335  ELSEIF(xi_new(ni)>1.0_dp) THEN
2336  xi_new(ni)=1.0_dp
2337  xi_new=xi+xi_update*(1.0_dp-xi(ni))/xi_update(ni)
2338  ENDIF
2339  ENDDO !ni
2340  CALL field_interpolate_xi(second_part_deriv,xi_new,interpolated_point,err,error,*999,field_geometric_components_type)
2341  distance_vector=point_values-interpolated_point%VALUES(:,no_part_deriv)
2342  function_value_new=dot_product(distance_vector,distance_vector)
2343  converged=converged.AND.(dabs(function_value_new-function_value)/(1.0_dp+function_value)<relative_tolerance) !second half of the convergence test (before collision detection)
2344  IF(converged) EXIT !converged: exit inner loop first
2345  IF((function_value_new-function_value)>absolute_tolerance) THEN !bad model: reduce step size
2346  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2347  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2348  EXIT main_loop
2349  ENDIF
2350  delta=dmax1(minimum_delta,0.25_dp*delta)
2351  ELSE
2352  predicted_reduction=dot_product(function_gradient,xi_update)+ &
2353  & 0.5_dp*(xi_update(1)*(xi_update(1)*function_hessian(1,1)+2.0_dp*xi_update(2)*function_hessian(1,2)+ &
2354  & 2.0_dp*xi_update(3)*function_hessian(1,3))+xi_update(2)*(xi_update(2)*function_hessian(2,2)+ &
2355  & 2.0_dp*xi_update(3)*function_hessian(2,3))+xi_update(2)**2*function_hessian(2,2))
2356  IF (abs(predicted_reduction) < zero_tolerance) THEN
2357  converged = .true. ! prediction reduction converged
2358  EXIT
2359  ENDIF
2360  prediction_accuracy=(function_value_new-function_value)/predicted_reduction
2361  IF(prediction_accuracy<0.01_dp) THEN !bad model: reduce region size
2362  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2363  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2364  EXIT main_loop
2365  ENDIF
2366  delta=dmax1(minimum_delta,0.5_dp*delta)
2367  ELSEIF(prediction_accuracy>0.9_dp.AND.prediction_accuracy<1.1_dp) THEN !good model: increase region size
2368  delta=dmin1(maximum_delta,2.0_dp*delta)
2369  EXIT
2370  ELSE !ok model: keep the current region size
2371  EXIT
2372  ENDIF
2373  ENDIF
2374  ENDDO !itr2 (inner loop: adjust region size)
2375  function_value=function_value_new
2376  xi=xi_new
2377  IF(converged) THEN
2379  EXIT
2380  ENDIF
2381  ENDDO main_loop !itr1 (outer loop)
2382  IF(exit_tag==data_projection_exit_tag_no_element.AND.itr1>=data_projection%MAXIMUM_NUMBER_OF_ITERATIONS) &
2384  IF((projection_exit_tag==data_projection_exit_tag_no_element).OR.(dsqrt(function_value)<projection_distance)) THEN
2385  !IF(.NOT.ELEMENT_FOUND) ELEMENT_FOUND=.TRUE.
2386  projection_exit_tag=exit_tag
2387  projection_element_number=element_number
2388  projection_distance=dsqrt(function_value)
2389  projection_xi=xi
2390  projection_vector=distance_vector
2391  ENDIF
2392  ENDDO !ne
2393  ELSE
2394  CALL flag_error("Data projection have not been finished.",err,error,*999)
2395  ENDIF
2396  ELSE
2397  CALL flag_error("Data projection is not associated.",err,error,*999)
2398  ENDIF
2399 
2400  exits("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_3")
2401  RETURN
2402 999 errorsexits("DATA_PROJECTION_NEWTON_ELEMENTS_EVALUATE_3",err,error)
2403  RETURN 1
2404 
2406 
2407  !
2408  !================================================================================================================================
2409  !
2410 
2412  SUBROUTINE data_projection_newton_faces_evaluate(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
2413  & candidate_element_faces,projection_exit_tag,projection_element_number,projection_element_face_number,projection_distance, &
2414  & projection_xi,projection_vector,err,error,*)
2415  !Argument variables
2416  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2417  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
2418  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
2419  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
2420  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENT_FACES(:)
2421  INTEGER(INTG), INTENT(OUT) :: PROJECTION_EXIT_TAG
2422  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_NUMBER
2423  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_FACE_NUMBER
2424  REAL(DP), INTENT(OUT) :: PROJECTION_DISTANCE
2425  REAL(DP), INTENT(OUT) :: PROJECTION_XI(2)
2426  REAL(DP), INTENT(OUT) :: PROJECTION_VECTOR(3)
2427  INTEGER(INTG), INTENT(OUT) :: ERR
2428  TYPE(varying_string), INTENT(OUT) :: ERROR
2429 
2430  !Local Variables
2431  TYPE(domain_mapping_type), POINTER :: DOMAIN_MAPPING
2432  LOGICAL :: FREE,CONVERGED,INSIDE_REGION
2433  INTEGER(INTG) :: ELEMENT_NUMBER,ELEMENT_FACE_NUMBER,FACE_NUMBER
2434  INTEGER(INTG) :: MESH_COMPONENT_NUMBER,REGION_DIMENSIONS
2435  INTEGER(INTG) :: BOUND(2),EXIT_TAG
2436  REAL(DP) :: XI(2),XI_NEW(2),XI_UPDATE(2),XI_UPDATE_NORM
2437  REAL(DP) :: DISTANCE_VECTOR(3),RELATIVE_TOLERANCE,ABSOLUTE_TOLERANCE
2438  REAL(DP) :: FUNCTION_VALUE,FUNCTION_VALUE_NEW
2439  REAL(DP) :: FUNCTION_GRADIENT(2),FUNCTION_GRADIENT_NORM
2440  REAL(DP) :: FUNCTION_HESSIAN(2,2),HESSIAN_DIAGONAL(2)
2441  REAL(DP) :: TEMP1,TEMP2,DET,EIGEN_MIN,EIGEN_MAX,EIGEN_SHIFT
2442  REAL(DP) :: MAXIMUM_DELTA,MINIMUM_DELTA,DELTA
2443  REAL(DP) :: PREDICTED_REDUCTION,PREDICTION_ACCURACY
2444 
2445 
2446  INTEGER(INTG) :: ne,ni,nifix,itr1,itr2
2447 
2448  enters("DATA_PROJECTION_NEWTON_FACES_EVALUATE",err,error,*999)
2449 
2450  IF(ASSOCIATED(data_projection)) THEN
2451  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2452  projection_exit_tag=data_projection_exit_tag_no_element
2453  mesh_component_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%MESH_COMPONENT_NUMBER
2454  domain_mapping=>interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%DOMAIN(mesh_component_number)% &
2455  & ptr%MAPPINGS%ELEMENTS
2456  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
2457  relative_tolerance=data_projection%RELATIVE_TOLERANCE
2458  absolute_tolerance=data_projection%ABSOLUTE_TOLERANCE
2459  maximum_delta=data_projection%MAXIMUM_ITERATION_UPDATE
2460  minimum_delta=0.025_dp*maximum_delta !need to set a minimum, in case if it gets too small
2461  DO ne=1,SIZE(candidate_elements,1) !project on each candidate elements
2462  element_number=candidate_elements(ne)
2463  element_face_number=candidate_element_faces(ne)
2464  face_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%TOPOLOGY%ELEMENTS%ELEMENTS( &
2465  & element_number)%ELEMENT_FACES(element_face_number)
2467  converged=.false.
2468  delta=0.5_dp*maximum_delta !start at half the MAXIMUM_DELTA as we do not know if quadratic model is a good approximation yet
2469  CALL field_interpolation_parameters_face_get(field_values_set_type,face_number, &
2470  & interpolated_point%INTERPOLATION_PARAMETERS,err,error,*999,field_geometric_components_type)
2471  xi=data_projection%STARTING_XI
2472  CALL field_interpolate_xi(second_part_deriv,xi,interpolated_point,err,error,*999,field_geometric_components_type)
2473  distance_vector(1:region_dimensions)=point_values-interpolated_point%VALUES(:,no_part_deriv)
2474  function_value=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
2475  main_loop: DO itr1=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(outer loop)
2476  !Check for bounds [0,1]
2477  DO ni=1,2
2478  IF(abs(xi(ni))<zero_tolerance) THEN
2479  bound(ni)=-1 !bound at negative direction
2480  ELSEIF(abs(xi(ni)-1.0_dp)<zero_tolerance) THEN
2481  bound(ni)=1 !bound at positive direction
2482  ELSE !inside the bounds
2483  bound(ni)=0
2484  ENDIF
2485  ENDDO !ni
2486  !FUNCTION_GRADIENT
2487  function_gradient(1)= &
2488  & -2.0_dp*(dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s1)))
2489  function_gradient(2)= &
2490  & -2.0_dp*(dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s2)))
2491  !FUNCTION_HESSIAN
2492  function_hessian(1,1)= -2.0_dp*(&
2493  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s1_s1))- &
2494  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s1)))
2495  function_hessian(1,2)= -2.0_dp*(&
2496  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s1_s2))- &
2497  & dot_product(interpolated_point%VALUES(:,part_deriv_s1),interpolated_point%VALUES(:,part_deriv_s2)))
2498  function_hessian(2,2)= -2.0_dp*(&
2499  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,part_deriv_s2_s2))- &
2500  & dot_product(interpolated_point%VALUES(:,part_deriv_s2),interpolated_point%VALUES(:,part_deriv_s2)))
2501  !A model trust region approach, a Newton step is taken if the minimum lies inside the trust region (DELTA), if not, shift the step towards the steepest descent
2502  temp1=0.5_dp*(function_hessian(1,1)+function_hessian(2,2))
2503  temp2=dsqrt((0.5_dp*(function_hessian(1,1)-function_hessian(2,2)))**2+function_hessian(1,2)**2)
2504  eigen_min=temp1-temp2
2505  eigen_max=temp1+temp2
2506  function_gradient_norm=dsqrt(dot_product(function_gradient,function_gradient))
2507  DO itr2=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(inner loop: adjust region size) usually EXIT at 1 or 2 iterations
2508  temp1=function_gradient_norm/delta
2509  inside_region=(eigen_min>=temp1).AND.(eigen_min>absolute_tolerance) !estimate if the solution is inside the trust region without calculating a newton step, this also guarantees the hessian matrix is positive definite
2510  IF(inside_region) THEN
2511  det=eigen_min*eigen_max !det(H)
2512  hessian_diagonal(1)=function_hessian(1,1)
2513  hessian_diagonal(2)=function_hessian(2,2)
2514  ELSE
2515  eigen_shift=max(temp1-eigen_min,absolute_tolerance) !shift towards steepest decent
2516  det=temp1*(eigen_max+eigen_shift) !det(H)
2517  hessian_diagonal(1)=function_hessian(1,1)+eigen_shift
2518  hessian_diagonal(2)=function_hessian(2,2)+eigen_shift
2519  ENDIF
2520  xi_update(1)=-(hessian_diagonal(2)*function_gradient(1)-function_hessian(1,2)*function_gradient(2))/det
2521  xi_update(2)=(function_hessian(1,2)*function_gradient(1)-hessian_diagonal(1)*function_gradient(2))/det
2522  xi_update_norm=dsqrt(dot_product(xi_update,xi_update))
2523  free=.true.
2524  DO ni=1,2
2525  IF((bound(ni)/=0).AND.(bound(ni)>0.EQV.xi_update(ni)>0.0_dp)) THEN !projection go out of element bound
2526  IF(.NOT.free) THEN !both xi are fixed
2528  EXIT main_loop
2529  ENDIF
2530  free=.false.
2531  nifix=ni
2532  ENDIF
2533  ENDDO !ni
2534  IF(free) THEN !both xi are free
2535  IF(.NOT.inside_region) THEN
2536  IF(xi_update_norm>0.0_dp) THEN
2537  xi_update=delta/xi_update_norm*xi_update !readjust XI_UPDATE to lie on the region bound
2538  ENDIF
2539  ENDIF
2540  ELSE !xi are not free
2541  xi_update(nifix)=0.0_dp
2542  ni=3-nifix
2543  inside_region=.false.
2544  IF(function_hessian(ni,ni)>0.0_dp) THEN !positive: minimum exists in the unbounded direction
2545  xi_update(ni)=-function_gradient(ni)/function_hessian(ni,ni)
2546  xi_update_norm=dabs(xi_update(ni))
2547  inside_region=xi_update_norm<=delta
2548  ENDIF
2549  IF(.NOT.inside_region) THEN !minimum not in the region
2550  xi_update(ni)=-dsign(delta,function_gradient(ni))
2551  xi_update_norm=delta
2552  ENDIF
2553  ENDIF !if xi is free
2554  converged=xi_update_norm<absolute_tolerance !first half of the convergence test
2555  xi_new=xi+xi_update !update XI
2556  DO ni=1,2
2557  IF(xi_new(ni)<0.0_dp) THEN !boundary collision check
2558  xi_new(ni)=0.0_dp
2559  xi_new(3-ni)=xi(3-ni)-xi_update(3-ni)*xi(ni)/xi_update(ni)
2560  ELSEIF(xi_new(ni)>1.0_dp) THEN
2561  xi_new(ni)=1.0_dp
2562  xi_new(3-ni)=xi(3-ni)+xi_update(3-ni)*(1.0_dp-xi(ni))/xi_update(ni)
2563  ENDIF
2564  ENDDO
2565  CALL field_interpolate_xi(second_part_deriv,xi_new,interpolated_point,err,error,*999,field_geometric_components_type)
2566  distance_vector=point_values-interpolated_point%VALUES(:,no_part_deriv)
2567  function_value_new=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
2568  converged=converged.AND.(dabs(function_value_new-function_value)/(1.0_dp+function_value)<relative_tolerance) !second half of the convergence test (before collision detection)
2569  IF(converged) THEN
2570  function_value=function_value_new
2571  EXIT !converged: exit inner loop first
2572  ENDIF
2573  IF((function_value_new-function_value)>absolute_tolerance) THEN !bad model: reduce step size
2574  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2575  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2576  function_value=function_value_new
2577  EXIT main_loop
2578  ENDIF
2579  delta=dmax1(minimum_delta,0.25_dp*delta)
2580  ELSE
2581  predicted_reduction=dot_product(function_gradient,xi_update)+ &
2582  & 0.5_dp*(xi_update(1)*(xi_update(1)*function_hessian(1,1)+2.0_dp*xi_update(2)*function_hessian(1,2))+ &
2583  & xi_update(2)**2*function_hessian(2,2))
2584  prediction_accuracy=(function_value_new-function_value)/predicted_reduction
2585  IF(prediction_accuracy<0.01_dp) THEN !bad model: reduce region size
2586  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2587  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2588  function_value=function_value_new
2589  EXIT main_loop
2590  ENDIF
2591  delta=dmax1(minimum_delta,0.5_dp*delta)
2592  ELSEIF(prediction_accuracy>0.9_dp.AND.prediction_accuracy<1.1_dp) THEN !good model: increase region size
2593  delta=dmin1(maximum_delta,2.0_dp*delta)
2594  function_value=function_value_new
2595  EXIT
2596  ELSE !ok model: keep the current region size
2597  function_value=function_value_new
2598  EXIT
2599  ENDIF
2600  ENDIF
2601  ENDDO !itr2 (inner loop: adjust region size)
2602  function_value=function_value_new
2603  xi=xi_new
2604  IF(converged) THEN
2606  EXIT
2607  ENDIF
2608  ENDDO main_loop !itr1 (outer loop)
2609  IF(exit_tag==data_projection_exit_tag_no_element.AND.itr1>=data_projection%MAXIMUM_NUMBER_OF_ITERATIONS) &
2611  IF((projection_exit_tag==data_projection_exit_tag_no_element).OR.(dsqrt(function_value)<projection_distance)) THEN
2612  !IF(.NOT.ELEMENT_FOUND) ELEMENT_FOUND=.TRUE.
2613  projection_exit_tag=exit_tag
2614  projection_element_number=element_number
2615  projection_element_face_number=element_face_number
2616  projection_distance=dsqrt(function_value)
2617  projection_xi=xi
2618  projection_vector=distance_vector
2619  ENDIF
2620  ENDDO !ne
2621  ELSE
2622  CALL flag_error("Data projection have not been finished.",err,error,*999)
2623  ENDIF
2624  ELSE
2625  CALL flag_error("Data projection is not associated.",err,error,*999)
2626  ENDIF
2627 
2628  exits("DATA_PROJECTION_NEWTON_FACES_EVALUATE")
2629  RETURN
2630 999 errorsexits("DATA_PROJECTION_NEWTON_FACES_EVALUATE",err,error)
2631  RETURN 1
2632 
2634 
2635  !
2636  !================================================================================================================================
2637  !
2638 
2640  SUBROUTINE data_projection_newton_lines_evaluate(DATA_PROJECTION,INTERPOLATED_POINT,POINT_VALUES,CANDIDATE_ELEMENTS, &
2641  & candidate_element_lines,projection_exit_tag,projection_element_number,projection_element_line_number,projection_distance, &
2642  & projection_xi,projection_vector,err,error,*)
2643  !Argument variables
2644  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2645  TYPE(field_interpolated_point_type), POINTER :: INTERPOLATED_POINT
2646  REAL(DP), INTENT(IN) :: POINT_VALUES(:)
2647  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENTS(:)
2648  INTEGER(INTG), INTENT(IN) :: CANDIDATE_ELEMENT_LINES(:)
2649  INTEGER(INTG), INTENT(OUT) :: PROJECTION_EXIT_TAG
2650  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_NUMBER
2651  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_LINE_NUMBER
2652  REAL(DP), INTENT(OUT) :: PROJECTION_DISTANCE
2653  REAL(DP), INTENT(OUT) :: PROJECTION_XI(1)
2654  REAL(DP), INTENT(OUT) :: PROJECTION_VECTOR(3)
2655  INTEGER(INTG), INTENT(OUT) :: ERR
2656  TYPE(varying_string), INTENT(OUT) :: ERROR
2657 
2658  !Local Variables
2659  LOGICAL :: INSIDE_REGION,CONVERGED
2660  INTEGER(INTG) :: ELEMENT_NUMBER,ELEMENT_LINE_NUMBER,LINE_NUMBER !local element number in current computational domain
2661  INTEGER(INTG) :: REGION_DIMENSIONS
2662  INTEGER(INTG) :: BOUND,EXIT_TAG
2663  REAL(DP) :: XI(1),XI_NEW(1),XI_UPDATE(1),XI_UPDATE_NORM
2664  REAL(DP) :: DISTANCE_VECTOR(3),RELATIVE_TOLERANCE,ABSOLUTE_TOLERANCE
2665  REAL(DP) :: FUNCTION_VALUE,FUNCTION_VALUE_NEW
2666  REAL(DP) :: FUNCTION_GRADIENT,FUNCTION_HESSIAN
2667  REAL(DP) :: MAXIMUM_DELTA,MINIMUM_DELTA,DELTA
2668  REAL(DP) :: PREDICTED_REDUCTION,PREDICTION_ACCURACY
2669 
2670  INTEGER(INTG) :: ne,itr1,itr2
2671 
2672  enters("DATA_PROJECTION_NEWTON_LINES_EVALUATE",err,error,*999)
2673 
2674  IF(ASSOCIATED(data_projection)) THEN
2675  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2676  projection_exit_tag=data_projection_exit_tag_no_element
2677  region_dimensions=data_projection%COORDINATE_SYSTEM_DIMENSIONS
2678  relative_tolerance=data_projection%RELATIVE_TOLERANCE
2679  absolute_tolerance=data_projection%ABSOLUTE_TOLERANCE
2680  maximum_delta=data_projection%MAXIMUM_ITERATION_UPDATE
2681  minimum_delta=0.025_dp*maximum_delta !need to set a minimum, in case if it gets too small
2682  DO ne=1,SIZE(candidate_elements,1) !project on each candidate elements
2683  element_number=candidate_elements(ne)
2684  element_line_number=candidate_element_lines(ne)
2685  line_number=interpolated_point%INTERPOLATION_PARAMETERS%FIELD%DECOMPOSITION%TOPOLOGY%ELEMENTS%ELEMENTS( &
2686  & element_number)%ELEMENT_LINES(element_line_number)
2688  converged=.false.
2689  delta=0.5_dp*maximum_delta !start at half the MAXIMUM_DELTA as we do not know if quadratic model is a good approximation yet
2690  CALL field_interpolation_parameters_line_get(field_values_set_type,line_number,interpolated_point% &
2691  & interpolation_parameters,err,error,*999,field_geometric_components_type)
2692  xi=data_projection%STARTING_XI
2693  CALL field_interpolate_xi(second_part_deriv,xi,interpolated_point,err,error,*999,field_geometric_components_type)
2694  distance_vector(1:region_dimensions)=point_values-interpolated_point%VALUES(:,no_part_deriv)
2695  function_value=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
2696  main_loop: DO itr1=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(outer loop)
2697  !Check for bounds [0,1]
2698  IF(abs(xi(1))<zero_tolerance) THEN
2699  bound=-1 !bound at negative direction
2700  ELSEIF(abs(xi(1)-1.0_dp)<zero_tolerance) THEN
2701  bound=1 !bound at positive direction
2702  ELSE !inside the bounds
2703  bound=0
2704  ENDIF
2705  !FUNCTION_GRADIENT
2706  function_gradient=-2.0_dp* &
2707  & (dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,first_part_deriv)))
2708  !FUNCTION_HESSIAN
2709  function_hessian=-2.0_dp*(&
2710  & dot_product(distance_vector(1:region_dimensions),interpolated_point%VALUES(:,second_part_deriv))- &
2711  & dot_product(interpolated_point%VALUES(:,first_part_deriv),interpolated_point%VALUES(:,first_part_deriv)))
2712  !A model trust region approach, directly taken from CMISS CLOS22: V = -(H + EIGEN_SHIFT*I)g
2713  !The calculation of EIGEN_SHIFT are only approximated as oppose to the common trust region approach
2714  DO itr2=1,data_projection%MAXIMUM_NUMBER_OF_ITERATIONS !(inner loop: adjust region size) usually EXIT at 1 or 2 iterations
2715  inside_region=.false.
2716  IF(function_hessian>absolute_tolerance) THEN !positive: minimum exists
2717  xi_update(1)=-function_gradient/function_hessian
2718  xi_update_norm=dabs(xi_update(1))
2719  inside_region=xi_update_norm<=delta
2720  ENDIF !positive
2721  IF(.NOT.inside_region) THEN !minimum not in the region
2722  xi_update(1)=-dsign(delta,function_gradient)
2723  xi_update_norm=delta
2724  ENDIF
2725  IF((bound/=0).AND.(bound>0.EQV.xi_update(1)>0.0_dp)) THEN !projection go out of element bound
2727  EXIT main_loop
2728  ENDIF
2729  converged=xi_update_norm<absolute_tolerance !first half of the convergence test (before collision detection)
2730  xi_new=xi+xi_update !update XI
2731  IF(xi_new(1)<0.0_dp) THEN !boundary collision check
2732  xi_new(1)=0.0_dp
2733  ELSEIF(xi_new(1)>1.0_dp) THEN
2734  xi_new(1)=1.0_dp
2735  ENDIF
2736  CALL field_interpolate_xi(second_part_deriv,xi_new,interpolated_point,err,error,*999,field_geometric_components_type)
2737  distance_vector=point_values-interpolated_point%VALUES(:,no_part_deriv)
2738  function_value_new=dot_product(distance_vector(1:region_dimensions),distance_vector(1:region_dimensions))
2739  converged=converged.AND.(dabs(function_value_new-function_value)/(1.0_dp+function_value)<relative_tolerance) !second half of the convergence test
2740  IF(converged) EXIT !converged: exit inner loop first
2741  IF((function_value_new-function_value)>absolute_tolerance) THEN !bad model: reduce step size
2742  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2743  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2744  EXIT main_loop
2745  ENDIF
2746  delta=dmax1(minimum_delta,0.25_dp*delta)
2747  ELSE
2748  predicted_reduction=xi_update(1)*(function_gradient+0.5_dp*function_hessian*xi_update(1))
2749  prediction_accuracy=(function_value_new-function_value)/predicted_reduction
2750  IF(prediction_accuracy<0.01_dp) THEN !bad model: reduce region size
2751  IF(delta<=minimum_delta) THEN !something went wrong, MINIMUM_DELTA too large? not likely to happen if MINIMUM_DELTA is small
2752  exit_tag=data_projection_exit_tag_max_iteration ! it will get stucked!!
2753  EXIT main_loop
2754  ENDIF
2755  delta=dmax1(minimum_delta,0.5_dp*delta)
2756  ELSEIF(prediction_accuracy>0.9_dp.AND.prediction_accuracy<1.1_dp) THEN !good model: increase region size
2757  delta=dmin1(maximum_delta,2.0_dp*delta)
2758  EXIT
2759  ELSE !ok model: keep the current region size
2760  EXIT
2761  ENDIF
2762  ENDIF
2763  ENDDO !itr2 (inner loop: adjust region size)
2764  function_value=function_value_new
2765  xi=xi_new
2766  IF(converged) THEN
2768  EXIT
2769  ENDIF
2770  ENDDO main_loop !itr1 (outer loop)
2771  IF(exit_tag==data_projection_exit_tag_no_element.AND.itr1>=data_projection%MAXIMUM_NUMBER_OF_ITERATIONS) &
2773  IF((projection_exit_tag==data_projection_exit_tag_no_element).OR.(dsqrt(function_value)<projection_distance)) THEN
2774  projection_exit_tag=exit_tag
2775  projection_element_number=element_number
2776  projection_element_line_number=element_line_number
2777  projection_distance=dsqrt(function_value)
2778  projection_xi=xi
2779  projection_vector=distance_vector
2780  ENDIF
2781  ENDDO !ne
2782  ELSE
2783  CALL flag_error("Data projection have not been finished.",err,error,*999)
2784  ENDIF
2785  ELSE
2786  CALL flag_error("Data projection is not associated.",err,error,*999)
2787  ENDIF
2788 
2789  exits("DATA_PROJECTION_NEWTON_LINES_EVALUATE")
2790  RETURN
2791 999 errorsexits("DATA_PROJECTION_NEWTON_LINES_EVALUATE",err,error)
2792  RETURN 1
2793 
2795 
2796  !
2797  !================================================================================================================================
2798  !
2799 
2801  SUBROUTINE dataprojection_numberofclosestelementsget(DATA_PROJECTION,NUMBER_OF_CLOSEST_ELEMENTS,ERR,ERROR,*)
2803  !Argument variables
2804  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2805  INTEGER(INTG), INTENT(OUT) :: NUMBER_OF_CLOSEST_ELEMENTS
2806  INTEGER(INTG), INTENT(OUT) :: ERR
2807  TYPE(varying_string), INTENT(OUT) :: ERROR
2808  !Local Variables
2809 
2810  enters("DataProjection_NumberOfClosestElementsGet",err,error,*999)
2811 
2812  IF(ASSOCIATED(data_projection)) THEN
2813  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2814  number_of_closest_elements=data_projection%NUMBER_OF_CLOSEST_ELEMENTS
2815  ELSE
2816  CALL flag_error("Data projection have not been finished.",err,error,*999)
2817  ENDIF
2818  ELSE
2819  CALL flag_error("Data projection is not associated.",err,error,*999)
2820  ENDIF
2821 
2822  exits("DataProjection_NumberOfClosestElementsGet")
2823  RETURN
2824 999 errorsexits("DataProjection_NumberOfClosestElementsGet",err,error)
2825  RETURN 1
2826 
2828 
2829  !
2830  !================================================================================================================================
2831  !
2832 
2834  SUBROUTINE dataprojection_numberofclosestelementsset(DATA_PROJECTION,NUMBER_OF_CLOSEST_ELEMENTS,ERR,ERROR,*)
2836  !Argument variables
2837  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2838  INTEGER(INTG), INTENT(IN) :: NUMBER_OF_CLOSEST_ELEMENTS
2839  INTEGER(INTG), INTENT(OUT) :: ERR
2840  TYPE(varying_string), INTENT(OUT) :: ERROR
2841  !Local Variables
2842 
2843  enters("DataProjection_NumberOfClosestElementsSet",err,error,*999)
2844 
2845  IF(ASSOCIATED(data_projection)) THEN
2846  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2847  CALL flag_error("Data projection have been finished.",err,error,*999)
2848  ELSE
2849  IF(number_of_closest_elements>=1) THEN
2850  data_projection%NUMBER_OF_CLOSEST_ELEMENTS=number_of_closest_elements
2851  ELSE
2852  CALL flag_error("Data projection number of closest elements must be at least 1.",err,error,*999)
2853  ENDIF
2854  ENDIF
2855  ELSE
2856  CALL flag_error("Data projection is not associated.",err,error,*999)
2857  ENDIF
2858 
2859  exits("DataProjection_NumberOfClosestElementsSet")
2860  RETURN
2861 999 errorsexits("DataProjection_NumberOfClosestElementsSet",err,error)
2862  RETURN 1
2863 
2865 
2866  !
2867  !================================================================================================================================
2868  !
2869 
2871  SUBROUTINE dataprojection_projectioncandidatesset(dataProjection,elementUserNumber,localFaceLineNumbers,err,error,*)
2873  !Argument variables
2874  TYPE(data_projection_type), POINTER :: dataProjection
2875  INTEGER(INTG), INTENT(IN) :: elementUserNumber(:)
2876  INTEGER(INTG), INTENT(IN) :: localFaceLineNumbers(:)
2877  INTEGER(INTG), INTENT(OUT) :: err
2878  TYPE(varying_string), INTENT(OUT) :: error
2879  !Local Variables
2880  INTEGER(INTG) :: elementIdx,elementMeshNumber
2881  INTEGER(INTG) :: meshComponentNumber=1
2882  LOGICAL :: elementExists
2883 
2884  enters("DataProjection_ProjectionCandidatesSet",err,error,*999)
2885 
2886  IF(ASSOCIATED(dataprojection)) THEN
2887  IF(SIZE(elementusernumber,1)==SIZE(localfacelinenumbers,1)) THEN
2888  ALLOCATE(dataprojection%candidateElementNumbers(SIZE(elementusernumber,1)),stat=err)
2889  IF(err/=0) CALL flag_error("Could not allocate candidiate element numbers.",err,error,*998)
2890  ALLOCATE(dataprojection%localFaceLineNumbers(SIZE(localfacelinenumbers,1)),stat=err)
2891  IF(err/=0) CALL flag_error("Could not allocate candidiate local face/line numbers.",err,error,*999)
2892  DO elementidx=1,SIZE(elementusernumber,1)
2893  CALL meshtopologyelementcheckexists(dataprojection%MESH,meshcomponentnumber,elementusernumber(elementidx), &
2894  & elementexists,elementmeshnumber,err,error,*999)
2895  IF(elementexists) THEN
2896  dataprojection%candidateElementNumbers(elementidx)=elementusernumber(elementidx)
2897  dataprojection%localFaceLineNumbers(elementidx)=localfacelinenumbers(elementidx)
2898  ELSE
2899  CALL flag_error("Element with user number ("//trim(number_to_vstring &
2900  & (elementusernumber(elementidx),"*",err,error))//") does not exist.",err,error,*999)
2901  ENDIF
2902  ENDDO !elementIdx
2903  ELSE
2904  CALL flag_error("Input user element numbers and face numbers sizes do not match.",err,error,*999)
2905  ENDIF
2906  ELSE
2907  CALL flag_error("Data projection is not associated.",err,error,*999)
2908  ENDIF
2909 
2910  exits("DataProjection_ProjectionCandidatesSet")
2911  RETURN
2912 999 IF(ALLOCATED(dataprojection%candidateElementNumbers)) THEN
2913  DEALLOCATE(dataprojection%candidateElementNumbers)
2914  END IF
2915  IF(ALLOCATED(dataprojection%localFaceLineNumbers)) THEN
2916  DEALLOCATE(dataprojection%localFaceLineNumbers)
2917  END IF
2918 998 errorsexits("DataProjection_ProjectionCandidatesSet",err,error)
2919  RETURN 1
2920 
2922 
2923  !
2924  !================================================================================================================================
2925  !
2926 
2928  SUBROUTINE data_projection_projection_type_get(DATA_PROJECTION,PROJECTION_TYPE,ERR,ERROR,*)
2930  !Argument variables
2931  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2932  INTEGER(INTG), INTENT(OUT) :: PROJECTION_TYPE
2933  INTEGER(INTG), INTENT(OUT) :: ERR
2934  TYPE(varying_string), INTENT(OUT) :: ERROR
2935  !Local Variables
2936 
2937  enters("DATA_PROJECTION_PROJECTION_TYPE_GET",err,error,*999)
2938 
2939  IF(ASSOCIATED(data_projection)) THEN
2940  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2941  projection_type=data_projection%PROJECTION_TYPE
2942  ELSE
2943  CALL flag_error("Data projection have not been finished.",err,error,*999)
2944  ENDIF
2945  ELSE
2946  CALL flag_error("Data projection is not associated.",err,error,*999)
2947  ENDIF
2948 
2949  exits("DATA_PROJECTION_PROJECTION_TYPE_GET")
2950  RETURN
2951 999 errorsexits("DATA_PROJECTION_PROJECTION_TYPE_GET",err,error)
2952  RETURN 1
2953 
2955 
2956  !
2957  !================================================================================================================================
2958  !
2959 
2961  SUBROUTINE data_projection_projection_type_set(DATA_PROJECTION,PROJECTION_TYPE,ERR,ERROR,*)
2963  !Argument variables
2964  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
2965  INTEGER(INTG), INTENT(IN) :: PROJECTION_TYPE
2966  INTEGER(INTG), INTENT(OUT) :: ERR
2967  TYPE(varying_string), INTENT(OUT) :: ERROR
2968  !Local Variables
2969  REAL(DP), ALLOCATABLE :: STARTING_XI(:)
2970 
2971  enters("DATA_PROJECTION_PROJECTION_TYPE_SET",err,error,*999)
2972 
2973  IF(ASSOCIATED(data_projection)) THEN
2974  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
2975  CALL flag_error("Data projection have been finished.",err,error,*999)
2976  ELSE
2977  data_projection%PROJECTION_TYPE=projection_type
2978  SELECT CASE(projection_type)
2980  data_projection%NUMBER_OF_XI=1
2982  data_projection%NUMBER_OF_XI=2
2984  data_projection%NUMBER_OF_XI=data_projection%MESH%NUMBER_OF_DIMENSIONS
2985  CASE DEFAULT
2986  CALL flag_error("Input projection type is undefined.",err,error,*999)
2987  END SELECT
2988  IF(data_projection%NUMBER_OF_XI/=SIZE(data_projection%STARTING_XI,1)) THEN
2989  ALLOCATE(starting_xi(data_projection%NUMBER_OF_XI),stat=err)
2990  IF(err/=0) CALL flag_error("Could not allocate starting xi.",err,error,*999)
2991  IF(data_projection%NUMBER_OF_XI>SIZE(data_projection%STARTING_XI,1)) THEN
2992  starting_xi(1:SIZE(data_projection%STARTING_XI,1))=data_projection%STARTING_XI(1:SIZE(data_projection%STARTING_XI,1))
2993  starting_xi(SIZE(data_projection%STARTING_XI,1):data_projection%NUMBER_OF_XI)=0.5_dp
2994  ELSE
2995  starting_xi(1:SIZE(data_projection%STARTING_XI,1))=data_projection%STARTING_XI(1:data_projection%NUMBER_OF_XI)
2996  ENDIF
2997  DEALLOCATE(data_projection%STARTING_XI)
2998  ALLOCATE(data_projection%STARTING_XI(data_projection%NUMBER_OF_XI),stat=err)
2999  IF(err/=0) CALL flag_error("Could not allocate data projection starting xi.",err,error,*999)
3000  data_projection%STARTING_XI(1:data_projection%NUMBER_OF_XI)=starting_xi(1:data_projection%NUMBER_OF_XI)
3001  ENDIF
3002  ENDIF
3003  ELSE
3004  CALL flag_error("Data projection is not associated.",err,error,*999)
3005  ENDIF
3006 
3007  exits("DATA_PROJECTION_PROJECTION_TYPE_SET")
3008  RETURN
3009 999 errorsexits("DATA_PROJECTION_PROJECTION_TYPE_SET",err,error)
3010  RETURN 1
3011 
3013 
3014  !
3015  !================================================================================================================================
3016  !
3017 
3019  SUBROUTINE data_projection_relative_tolerance_get(DATA_PROJECTION,RELATIVE_TOLERANCE,ERR,ERROR,*)
3021  !Argument variables
3022  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3023  REAL(DP), INTENT(OUT) :: RELATIVE_TOLERANCE
3024  INTEGER(INTG), INTENT(OUT) :: ERR
3025  TYPE(varying_string), INTENT(OUT) :: ERROR
3026  !Local Variables
3027 
3028  enters("DATA_PROJECTION_RELATIVE_TOLERANCE_GET",err,error,*999)
3029 
3030  IF(ASSOCIATED(data_projection)) THEN
3031  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3032  relative_tolerance=data_projection%RELATIVE_TOLERANCE
3033  ELSE
3034  CALL flag_error("Data projection have not been finished.",err,error,*999)
3035  ENDIF
3036  ELSE
3037  CALL flag_error("Data projection is not associated.",err,error,*999)
3038  ENDIF
3039 
3040  exits("DATA_PROJECTION_RELATIVE_TOLERANCE_GET")
3041  RETURN
3042 999 errorsexits("DATA_PROJECTION_RELATIVE_TOLERANCE_GET",err,error)
3043  RETURN 1
3044 
3046 
3047  !
3048  !================================================================================================================================
3049  !
3050 
3052  SUBROUTINE data_projection_relative_tolerance_set(DATA_PROJECTION,RELATIVE_TOLERANCE,ERR,ERROR,*)
3054  !Argument variables
3055  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3056  REAL(DP), INTENT(IN) :: RELATIVE_TOLERANCE
3057  INTEGER(INTG), INTENT(OUT) :: ERR
3058  TYPE(varying_string), INTENT(OUT) :: ERROR
3059  !Local Variables
3060  enters("DATA_PROJECTION_RELATIVE_TOLERANCE_SET",err,error,*999)
3061 
3062  IF(ASSOCIATED(data_projection)) THEN
3063  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3064  CALL flag_error("Data projection have been finished.",err,error,*999)
3065  ELSE
3066  IF(relative_tolerance>=0) THEN
3067  data_projection%RELATIVE_TOLERANCE=relative_tolerance
3068  ELSE
3069  CALL flag_error("Data projection relative tolerance must be a positive real number.",err,error,*999)
3070  ENDIF
3071  ENDIF
3072  ELSE
3073  CALL flag_error("Data projection is not associated.",err,error,*999)
3074  ENDIF
3075 
3076  exits("DATA_PROJECTION_RELATIVE_TOLERANCE_SET")
3077  RETURN
3078 999 errorsexits("DATA_PROJECTION_RELATIVE_TOLERANCE_SET",err,error)
3079  RETURN 1
3080 
3082 
3083 
3084  !
3085  !================================================================================================================================
3086  !
3087 
3089  SUBROUTINE data_projection_starting_xi_get(DATA_PROJECTION,STARTING_XI,ERR,ERROR,*)
3091  !Argument variables
3092  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3093  REAL(DP), INTENT(OUT) :: STARTING_XI(:)
3094  INTEGER(INTG), INTENT(OUT) :: ERR
3095  TYPE(varying_string), INTENT(OUT) :: ERROR
3096  !Local Variables
3097  CHARACTER(LEN=MAXSTRLEN) :: LOCAL_ERROR
3098 
3099  enters("DATA_PROJECTION_STARTING_XI_GET",err,error,*999)
3100 
3101  IF(ASSOCIATED(data_projection)) THEN
3102  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3103  IF(SIZE(starting_xi,1)>=SIZE(data_projection%STARTING_XI,1)) THEN
3104  starting_xi(1:SIZE(data_projection%STARTING_XI,1))=data_projection%STARTING_XI(1:SIZE(data_projection%STARTING_XI,1))
3105  ELSE
3106  WRITE(local_error,'("The size of the supplied starting xi array of ",I2," is too small. The size must be >= ",I2,".")' &
3107  & )SIZE(starting_xi,1),SIZE(data_projection%STARTING_XI,1)
3108  CALL flag_error(local_error,err,error,*999)
3109  ENDIF
3110  ELSE
3111  CALL flag_error("Data projection have not been finished.",err,error,*999)
3112  ENDIF
3113  ELSE
3114  CALL flag_error("Data projection is not associated.",err,error,*999)
3115  ENDIF
3116 
3117  exits("DATA_PROJECTION_STARTING_XI_GET")
3118  RETURN
3119 999 errorsexits("DATA_PROJECTION_STARTING_XI_GET",err,error)
3120  RETURN 1
3121 
3122  END SUBROUTINE data_projection_starting_xi_get
3123 
3124  !
3125  !================================================================================================================================
3126  !
3127 
3129  SUBROUTINE data_projection_starting_xi_set(DATA_PROJECTION,STARTING_XI,ERR,ERROR,*)
3131  !Argument variables
3132  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3133  REAL(DP), INTENT(IN) :: STARTING_XI(:)
3134  INTEGER(INTG), INTENT(OUT) :: ERR
3135  TYPE(varying_string), INTENT(OUT) :: ERROR
3136  !Local Variables
3137  INTEGER(INTG) :: ni
3138  LOGICAL :: VALID_INPUT
3139 
3140  enters("DATA_PROJECTION_STARTING_XI_SET",err,error,*999)
3141 
3142  IF(ASSOCIATED(data_projection)) THEN
3143  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3144  CALL flag_error("Data projection have been finished.",err,error,*999)
3145  ELSE
3146  IF(SIZE(starting_xi,1)==SIZE(data_projection%STARTING_XI,1)) THEN
3147  valid_input=.true.
3148  DO ni=1,SIZE(starting_xi,1)
3149  IF((starting_xi(ni)<0).OR.(starting_xi(ni)>1)) THEN
3150  valid_input=.false.
3151  EXIT !this do
3152  ENDIF
3153  ENDDO
3154  IF(valid_input) THEN
3155  data_projection%STARTING_XI(1:SIZE(starting_xi))=starting_xi(1:SIZE(starting_xi))
3156  ELSE
3157  CALL flag_error("Data projection starting xi must be between 0 and 1.",err,error,*999)
3158  ENDIF
3159  ELSE
3160  CALL flag_error("Data projection starting xi dimension mismatch.",err,error,*999)
3161  ENDIF
3162  ENDIF
3163  ELSE
3164  CALL flag_error("Data projection is not associated.",err,error,*999)
3165  ENDIF
3166 
3167  exits("DATA_PROJECTION_STARTING_XI_SET")
3168  RETURN
3169 999 errorsexits("DATA_PROJECTION_STARTING_XI_SET",err,error)
3170  RETURN 1
3171 
3172  END SUBROUTINE data_projection_starting_xi_set
3173 
3174  !
3175  !================================================================================================================================
3176  !
3177 
3179  SUBROUTINE data_projection_element_set(DATA_PROJECTION,DATA_POINT_USER_NUMBER,ELEMENT_USER_NUMBER,ERR,ERROR,*)
3181  !Argument variables
3182  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3183  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3184  INTEGER(INTG), INTENT(IN) :: ELEMENT_USER_NUMBER
3185  INTEGER(INTG), INTENT(OUT) :: ERR
3186  TYPE(varying_string), INTENT(OUT) :: ERROR
3187  !Local Variables
3188  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3189  LOGICAL :: DATA_POINT_EXISTS
3190 
3191  enters("DATA_PROJECTION_ELEMENT_SET",err,error,*999)
3192 
3193  IF(ASSOCIATED(data_projection)) THEN
3194  CALL dataprojection_datapointcheckexist(data_projection,data_point_user_number,data_point_exists, &
3195  & data_point_global_number,err,error,*999)
3196  IF(data_point_exists) THEN
3197  data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%ELEMENT_NUMBER=element_user_number
3198  ELSE
3199  CALL flag_error("Data point with user number ("//trim(number_to_vstring &
3200  & (data_point_user_number,"*",err,error))//") does not exist.",err,error,*999)
3201  ENDIF
3202  ELSE
3203  CALL flag_error("Data projection is not associated.",err,error,*999)
3204  ENDIF
3205 
3206  exits("DATA_PROJECTION_ELEMENT_SET")
3207  RETURN
3208 999 errorsexits("DATA_PROJECTION_ELEMENT_SET",err,error)
3209  RETURN 1
3210 
3211  END SUBROUTINE data_projection_element_set
3212 
3213  !
3214  !================================================================================================================================
3215  !
3216 
3218  SUBROUTINE data_projection_result_distance_get(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_DISTANCE,ERR,ERROR,*)
3220  !Argument variables
3221  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3222  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3223  REAL(DP), INTENT(OUT) :: PROJECTION_DISTANCE
3224  INTEGER(INTG), INTENT(OUT) :: ERR
3225  TYPE(varying_string), INTENT(OUT) :: ERROR
3226  !Local Variables
3227  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3228 
3229  enters("DATA_PROJECTION_RESULT_DISTANCE_GET",err,error,*999)
3230 
3231  IF(ASSOCIATED(data_projection)) THEN
3232  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3233  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3234  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3235  & data_point_global_number,err,error,*999)
3236  projection_distance=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%DISTANCE
3237  ELSE
3238  CALL flag_error("Data projection have not been projected.",err,error,*999)
3239  ENDIF
3240  ELSE
3241  CALL flag_error("Data projection have not been finished.",err,error,*999)
3242  ENDIF
3243  ELSE
3244  CALL flag_error("Data projection is not associated.",err,error,*999)
3245  ENDIF
3246 
3247  exits("DATA_PROJECTION_RESULT_DISTANCE_GET")
3248  RETURN
3249 999 errorsexits("DATA_PROJECTION_RESULT_DISTANCE_GET",err,error)
3250  RETURN 1
3251 
3253 
3254  !
3255  !================================================================================================================================
3256  !
3257 
3259  SUBROUTINE data_projection_label_get_vs(DATA_PROJECTION,LABEL,ERR,ERROR,*)
3261  !Argument variables
3262  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3263  TYPE(varying_string), INTENT(OUT) :: LABEL
3264  INTEGER(INTG), INTENT(OUT) :: ERR
3265  TYPE(varying_string), INTENT(OUT) :: ERROR
3266  !Local Variables
3267 
3268  enters("DATA_PROJECTION_LABEL_GET_VS",err,error,*999)
3269 
3270  IF(ASSOCIATED(data_projection)) THEN
3271  label=data_projection%LABEL
3272  ELSE
3273  CALL flag_error("Data projection is not associated.",err,error,*999)
3274  ENDIF
3275 
3276  exits("DATA_PROJECTION_LABEL_GET_VS")
3277  RETURN
3278 999 errorsexits("DATA_PROJECTION_LABEL_GET_VS",err,error)
3279  RETURN 1
3280 
3281  END SUBROUTINE data_projection_label_get_vs
3282 
3283  !
3284  !================================================================================================================================
3285  !
3286 
3288  SUBROUTINE data_projection_label_get_c(DATA_PROJECTION,LABEL,ERR,ERROR,*)
3290  !Argument variables
3291  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3292  CHARACTER(LEN=*), INTENT(OUT) :: LABEL
3293  INTEGER(INTG), INTENT(OUT) :: ERR
3294  TYPE(varying_string), INTENT(OUT) :: ERROR
3295  !Local Variables
3296  INTEGER(INTG) :: C_LENGTH,VS_LENGTH
3297 
3298  enters("DATA_PROJECTION_LABEL_GET_C",err,error,*999)
3299 
3300  IF(ASSOCIATED(data_projection)) THEN
3301  c_length=len(label)
3302  vs_length=len_trim(data_projection%LABEL)
3303  IF(c_length>vs_length) THEN
3304  label=char(len_trim(data_projection%LABEL))
3305  ELSE
3306  label=char(data_projection%LABEL,c_length)
3307  ENDIF
3308  ELSE
3309  CALL flag_error("Data projection is not associated.",err,error,*999)
3310  ENDIF
3311 
3312  exits("DATA_PROJECTION_LABEL_GET_C")
3313  RETURN
3314 999 errorsexits("DATA_PROJECTION_LABEL_GET_C",err,error)
3315  RETURN 1
3316 
3317  END SUBROUTINE data_projection_label_get_c
3318 
3319  !
3320  !================================================================================================================================
3321  !
3322 
3324  SUBROUTINE data_projection_label_set_c(DATA_PROJECTION,LABEL,ERR,ERROR,*)
3326  !Argument variables
3327  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3328  CHARACTER(LEN=*), INTENT(IN) :: LABEL
3329  INTEGER(INTG), INTENT(OUT) :: ERR
3330  TYPE(varying_string), INTENT(OUT) :: ERROR
3331  !Local Variables
3332 
3333  enters("DATA_PROJECTION_LABEL_SET_C",err,error,*999)
3334 
3335  IF(ASSOCIATED(data_projection)) THEN
3336  data_projection%LABEL=label
3337  ELSE
3338  CALL flag_error("Data projection is not associated.",err,error,*999)
3339  ENDIF
3340 
3341  exits("DATA_PROJECTION_LABEL_SET_C")
3342  RETURN
3343 999 errorsexits("DATA_PROJECTION_LABEL_SET_C",err,error)
3344  RETURN 1
3345 
3346  END SUBROUTINE data_projection_label_set_c
3347 
3348  !
3349  !================================================================================================================================
3350  !
3351 
3353  SUBROUTINE data_projection_label_set_vs(DATA_PROJECTION,LABEL,ERR,ERROR,*)
3355  !Argument variables
3356  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3357  TYPE(varying_string), INTENT(IN) :: LABEL
3358  INTEGER(INTG), INTENT(OUT) :: ERR
3359  TYPE(varying_string), INTENT(OUT) :: ERROR
3360  !Local Variables
3361 
3362  enters("DATA_PROJECTION_LABEL_SET_VS",err,error,*999)
3363 
3364  IF(ASSOCIATED(data_projection)) THEN
3365  data_projection%LABEL=label
3366  ELSE
3367  CALL flag_error("Data projection is not associated.",err,error,*999)
3368  ENDIF
3369 
3370  exits("DATA_PROJECTION_LABEL_SET_VS")
3371  RETURN
3372 999 errorsexits("DATA_PROJECTION_LABEL_SET_VS",err,error)
3373  RETURN 1
3374 
3375  END SUBROUTINE data_projection_label_set_vs
3376 
3377  !
3378  !================================================================================================================================
3379  !
3380 
3382  SUBROUTINE data_projection_result_element_number_get(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_ELEMENT_NUMBER, &
3383  & err,error,*)
3385  !Argument variables
3386  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3387  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3388  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_NUMBER
3389  INTEGER(INTG), INTENT(OUT) :: ERR
3390  TYPE(varying_string), INTENT(OUT) :: ERROR
3391  !Local Variables
3392  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3393 
3394  enters("DATA_PROJECTION_RESULT_ELEMENT_NUMBER_GET",err,error,*999)
3395 
3396  IF(ASSOCIATED(data_projection)) THEN
3397  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3398  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3399  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3400  & data_point_global_number,err,error,*999)
3401  projection_element_number=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%ELEMENT_NUMBER
3402  ELSE
3403  CALL flag_error("Data projection have not been projected.",err,error,*999)
3404  ENDIF
3405  ELSE
3406  CALL flag_error("Data projection have not been finished.",err,error,*999)
3407  ENDIF
3408  ELSE
3409  CALL flag_error("Data projection is not associated.",err,error,*999)
3410  ENDIF
3411 
3412  exits("DATA_PROJECTION_RESULT_ELEMENT_NUMBER_GET")
3413  RETURN
3414 999 errorsexits("DATA_PROJECTION_RESULT_ELEMENT_NUMBER_GET",err,error)
3415  RETURN 1
3416 
3418 
3419  !
3420  !================================================================================================================================
3421  !
3422 
3424  SUBROUTINE dataprojection_resultelementfacenumberget(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_ELEMENT_FACE_NUMBER &
3425  & ,err,error,*)
3427  !Argument variables
3428  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3429  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3430  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_FACE_NUMBER
3431  INTEGER(INTG), INTENT(OUT) :: ERR
3432  TYPE(varying_string), INTENT(OUT) :: ERROR
3433  !Local Variables
3434  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3435 
3436  enters("DataProjection_ResultElementFaceNumberGet",err,error,*999)
3437 
3438  IF(ASSOCIATED(data_projection)) THEN
3439  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3440  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3441  ! Check if boundary faces projection type was set
3442  IF(data_projection%PROJECTION_TYPE==data_projection_boundary_faces_projection_type) THEN
3443  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3444  & data_point_global_number,err,error,*999)
3445  projection_element_face_number=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%ELEMENT_FACE_NUMBER
3446  ELSE
3447  CALL flag_error("Data projection data projection projection type is not set to boundary faces projection type.", &
3448  & err,error,*999)
3449  ENDIF
3450  ELSE
3451  CALL flag_error("Data projection have not been projected.",err,error,*999)
3452  ENDIF
3453  ELSE
3454  CALL flag_error("Data projection have not been finished.",err,error,*999)
3455  ENDIF
3456  ELSE
3457  CALL flag_error("Data projection is not associated.",err,error,*999)
3458  ENDIF
3459 
3460  exits("DataProjection_ResultElementFaceNumberGet")
3461  RETURN
3462 999 errorsexits("DataProjection_ResultElementFaceNumberGet",err,error)
3463  RETURN 1
3464 
3466 
3467  !
3468  !================================================================================================================================
3469  !
3470 
3472  SUBROUTINE dataprojection_resultelementlinenumberget(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_ELEMENT_LINE_NUMBER &
3473  & ,err,error,*)
3475  !Argument variables
3476  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3477  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3478  INTEGER(INTG), INTENT(OUT) :: PROJECTION_ELEMENT_LINE_NUMBER
3479  INTEGER(INTG), INTENT(OUT) :: ERR
3480  TYPE(varying_string), INTENT(OUT) :: ERROR
3481  !Local Variables
3482  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3483 
3484  enters("DataProjection_ResultElementLineNumberGet",err,error,*999)
3485 
3486  IF(ASSOCIATED(data_projection)) THEN
3487  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3488  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3489  ! Check if boundary lines projection type was set
3490  IF(data_projection%PROJECTION_TYPE==data_projection_boundary_lines_projection_type) THEN
3491  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3492  & data_point_global_number,err,error,*999)
3493  projection_element_line_number=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%ELEMENT_LINE_NUMBER
3494  ELSE
3495  CALL flag_error("Data projection data projection projection type is not set to boundary lines projection type.", &
3496  & err,error,*999)
3497  ENDIF
3498  ELSE
3499  CALL flag_error("Data projection have not been projected.",err,error,*999)
3500  ENDIF
3501  ELSE
3502  CALL flag_error("Data projection have not been finished.",err,error,*999)
3503  ENDIF
3504  ELSE
3505  CALL flag_error("Data projection is not associated.",err,error,*999)
3506  ENDIF
3507 
3508  exits("DataProjection_ResultElementLineNumberGet")
3509  RETURN
3510 999 errorsexits("DataProjection_ResultElementLineNumberGet",err,error)
3511  RETURN 1
3512 
3514 
3515  !
3516  !================================================================================================================================
3517  !
3518 
3520  SUBROUTINE data_projection_result_exit_tag_get(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_EXIT_TAG,ERR,ERROR,*)
3522  !Argument variables
3523  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3524  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3525  INTEGER(INTG), INTENT(OUT) :: PROJECTION_EXIT_TAG
3526  INTEGER(INTG), INTENT(OUT) :: ERR
3527  TYPE(varying_string), INTENT(OUT) :: ERROR
3528  !Local Variables
3529  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3530 
3531  enters("DATA_PROJECTION_RESULT_EXIT_TAG_GET",err,error,*999)
3532 
3533  IF(ASSOCIATED(data_projection)) THEN
3534  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3535  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3536  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3537  & data_point_global_number,err,error,*999)
3538  projection_exit_tag=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%EXIT_TAG
3539  ELSE
3540  CALL flag_error("Data projection have not been projected.",err,error,*999)
3541  ENDIF
3542  ELSE
3543  CALL flag_error("Data projection have not been finished.",err,error,*999)
3544  ENDIF
3545  ELSE
3546  CALL flag_error("Data projection is not associated.",err,error,*999)
3547  ENDIF
3548 
3549  exits("DATA_PROJECTION_RESULT_EXIT_TAG_GET")
3550  RETURN
3551 999 errorsexits("DATA_PROJECTION_RESULT_EXIT_TAG_GET",err,error)
3552  RETURN 1
3553 
3555 
3556  !
3557  !================================================================================================================================
3558  !
3559 
3561  SUBROUTINE data_projection_result_xi_get(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_XI,ERR,ERROR,*)
3563  !Argument variables
3564  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3565  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3566  REAL(DP), INTENT(OUT) :: PROJECTION_XI(:)
3567  INTEGER(INTG), INTENT(OUT) :: ERR
3568  TYPE(varying_string), INTENT(OUT) :: ERROR
3569  !Local Variables
3570  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3571 
3572  enters("DATA_PROJECTION_RESULT_XI_GET",err,error,*999)
3573 
3574  IF(ASSOCIATED(data_projection)) THEN
3575  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3576  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3577  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3578  & data_point_global_number,err,error,*999)
3579  IF(SIZE(projection_xi,1)==SIZE(data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%XI,1)) THEN
3580  projection_xi=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%XI
3581  ELSE
3582  CALL flag_error("projection xi has size of "//trim(number_to_vstring(SIZE(projection_xi,1),"*",err,error))// &
3583  & "but it needs to have size of "// &
3584  & trim(number_to_vstring(SIZE(data_projection%DATA_PROJECTION_RESULTS &
3585  & (data_point_global_number)%XI,1),"*",err,error))// &
3586  & "." ,err,error,*999)
3587  ENDIF
3588  ELSE
3589  CALL flag_error("Data projection have not been projected.",err,error,*999)
3590  ENDIF
3591  ELSE
3592  CALL flag_error("Data projection have not been finished.",err,error,*999)
3593  ENDIF
3594  ELSE
3595  CALL flag_error("Data projection is not associated.",err,error,*999)
3596  ENDIF
3597 
3598  exits("DATA_PROJECTION_RESULT_XI_GET")
3599  RETURN
3600 999 errorsexits("DATA_PROJECTION_RESULT_XI_GET",err,error)
3601  RETURN 1
3602 
3603  END SUBROUTINE data_projection_result_xi_get
3604 
3605  !
3606  !================================================================================================================================
3607  !
3608 
3610  SUBROUTINE data_projection_result_xi_set(DATA_PROJECTION,DATA_POINT_USER_NUMBER,PROJECTION_XI,ERR,ERROR,*)
3612  !Argument variables
3613  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3614  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3615  REAL(DP), INTENT(IN) :: PROJECTION_XI(:)
3616  INTEGER(INTG), INTENT(OUT) :: ERR
3617  TYPE(varying_string), INTENT(OUT) :: ERROR
3618  !Local Variables
3619  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3620 
3621  enters("DATA_PROJECTION_RESULT_XI_SET",err,error,*999)
3622 
3623  IF(ASSOCIATED(data_projection)) THEN
3624  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3625  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3626  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3627  & data_point_global_number,err,error,*999)
3628  IF(SIZE(projection_xi,1)==SIZE(data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%XI,1)) THEN
3629  data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%XI(1:SIZE(projection_xi,1))= &
3630  & projection_xi(1:SIZE(projection_xi,1))
3631  ELSE
3632  CALL flag_error("projection xi has size of "//trim(number_to_vstring(SIZE(projection_xi,1),"*",err,error))// &
3633  & "but it needs to have size of "// &
3634  & trim(number_to_vstring(SIZE(data_projection%DATA_PROJECTION_RESULTS &
3635  & (data_point_global_number)%XI,1),"*",err,error))// &
3636  & "." ,err,error,*999)
3637  ENDIF
3638  ELSE
3639  CALL flag_error("Data projection have not been projected.",err,error,*999)
3640  ENDIF
3641  ELSE
3642  CALL flag_error("Data projection have not been finished.",err,error,*999)
3643  ENDIF
3644  ELSE
3645  CALL flag_error("Data projection is not associated.",err,error,*999)
3646  ENDIF
3647 
3648  exits("DATA_PROJECTION_RESULT_XI_SET")
3649  RETURN
3650 999 errorsexits("DATA_PROJECTION_RESULT_XI_SET",err,error)
3651  RETURN 1
3652 
3653  END SUBROUTINE data_projection_result_xi_set
3654 
3655  !
3656  !================================================================================================================================
3657  !
3658 
3660  SUBROUTINE dataprojection_resultprojectionvectorget(DATA_PROJECTION,DATA_POINT_USER_NUMBER,projectionVector,ERR,ERROR,*)
3662  !Argument variables
3663  TYPE(data_projection_type), POINTER :: DATA_PROJECTION
3664  INTEGER(INTG), INTENT(IN) :: DATA_POINT_USER_NUMBER
3665  REAL(DP), INTENT(OUT) :: projectionVector(:)
3666  INTEGER(INTG), INTENT(OUT) :: ERR
3667  TYPE(varying_string), INTENT(OUT) :: ERROR
3668  !Local Variables
3669  INTEGER(INTG) :: DATA_POINT_GLOBAL_NUMBER
3670 
3671  enters("DataProjection_ResultProjectionVectorGet",err,error,*999)
3672 
3673  IF(ASSOCIATED(data_projection)) THEN
3674  IF(data_projection%DATA_PROJECTION_FINISHED) THEN
3675  IF(data_projection%DATA_PROJECTION_PROJECTED) THEN
3676  CALL dataprojection_datapointglobalnumberget(data_projection,data_point_user_number, &
3677  & data_point_global_number,err,error,*999)
3678  IF(SIZE(projectionvector,1)>=SIZE(data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)%projectionVector, &
3679  & 1)) THEN
3680  projectionvector=data_projection%DATA_PROJECTION_RESULTS(data_point_global_number)% &
3681  & projectionvector(1:data_projection%COORDINATE_SYSTEM_DIMENSIONS)
3682  ELSE
3683  CALL flag_error("projection vector has size of "//trim(number_to_vstring(SIZE(projectionvector,1),"*",err,error))// &
3684  & "but it needs to have size of "// &
3685  & trim(number_to_vstring(SIZE(data_projection%DATA_PROJECTION_RESULTS &
3686  & (data_point_global_number)%projectionVector,1),"*",err,error))// &
3687  & "." ,err,error,*999)
3688  ENDIF
3689  ELSE
3690  CALL flag_error("Data projection have not been projected.",err,error,*999)
3691  ENDIF
3692  ELSE
3693  CALL flag_error("Data projection have not been finished.",err,error,*999)
3694  ENDIF
3695  ELSE
3696  CALL flag_error("Data projection is not associated.",err,error,*999)
3697  ENDIF
3698 
3699  exits("DataProjection_ResultProjectionVectorGet")
3700  RETURN
3701 999 errorsexits("DataProjection_ResultProjectionVectorGet",err,error)
3702  RETURN 1
3703 
3705 
3706  !
3707  !================================================================================================================================
3708  !
3709 
3710 END MODULE data_projection_routines
subroutine data_projection_label_set_c(DATA_PROJECTION, LABEL, ERR, ERROR,)
Sets the label for a data projection for varying string labels.
subroutine, public enters(NAME, ERR, ERROR,)
Records the entry into the named procedure and initialises the error code.
subroutine, public data_projection_create_start_data_points(DATA_PROJECTION_USER_NUMBER, DATA_POINTS, MESH, DATA_PROJECTION, ERR, ERROR,)
Starts the process of creating data projection.
integer, parameter ptr
Pointer integer kind.
Definition: kinds.f90:58
subroutine dataprojection_datapointcheckexist(DataProjection, dataPointUserNumber, dataPointExist, dataPointGlobalNumber, err, error,)
Checks that a user data point number is defined for a specific data projection.
integer(intg), parameter second_part_deriv
Second partial derivative i.e., d^2u/ds^2.
Definition: constants.f90:179
subroutine, public data_projection_result_xi_get(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_XI, ERR, ERROR,)
Gets the projection xi for a data point identified by a given global number.
Converts a number to its equivalent varying string representation.
Definition: strings.f90:161
Implements trees of base types.
Definition: trees.f90:45
subroutine, public dataprojection_numberofclosestelementsget(DATA_PROJECTION, NUMBER_OF_CLOSEST_ELEMENTS, ERR, ERROR,)
Gets the number of closest elements for a data projection.
Contains information on the mesh decomposition.
Definition: types.f90:1063
subroutine, public data_projection_element_set(DATA_PROJECTION, DATA_POINT_USER_NUMBER, ELEMENT_USER_NUMBER, ERR, ERROR,)
Sets the element for a data projection.
subroutine, public data_projection_projection_type_set(DATA_PROJECTION, PROJECTION_TYPE, ERR, ERROR,)
Sets the projection type for a data projection.
subroutine, public dataprojection_resultprojectionvectorget(DATA_PROJECTION, DATA_POINT_USER_NUMBER, projectionVector, ERR, ERROR,)
Gets the projection vector for a data point identified by a given global number.
integer(intg), parameter data_projection_exit_tag_max_iteration
Data projection exited due to it attaining maximum number of iteration specified by user...
subroutine, public data_projection_result_distance_get(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_DISTANCE, ERR, ERROR,)
Gets the projection distance for a data point identified by a given global number.
subroutine, public dataprojection_maximumnumberofiterationsset(DATA_PROJECTION, MAXIMUM_NUMBER_OF_ITERATIONS, ERR, ERROR,)
Sets the maximum number of iterations for a data projection.
integer(intg), parameter no_part_deriv
No partial derivative i.e., u.
Definition: constants.f90:177
Sets/changes the label for a data projection.
subroutine, public dataprojection_maximuminterationupdateset(DATA_PROJECTION, MAXIMUM_ITERATION_UPDATE, ERR, ERROR,)
Sets the maximum iteration update for a data projection.
Contains information on the data points defined on a region.
Definition: types.f90:333
integer(intg), parameter data_projection_exit_tag_bounds
Data projection exited due to it hitting the bound and continue to travel out of the element...
subroutine, public tree_search(TREE, KEY, X, ERR, ERROR,)
Searches a tree to see if it contains a key.
Definition: trees.f90:1277
This module contains all string manipulation and transformation routines.
Definition: strings.f90:45
subroutine, public data_projection_projection_type_get(DATA_PROJECTION, PROJECTION_TYPE, ERR, ERROR,)
Gets the projection type for a data projection.
subroutine, public dataprojection_datapointsprojectionevaluate(DATA_PROJECTION, PROJECTION_FIELD, ERR, ERROR,)
Evaluates data projection.
integer(intg), parameter first_part_deriv
First partial derivative i.e., du/ds.
Definition: constants.f90:178
subroutine data_projection_newton_lines_evaluate(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, CANDIDATE_ELEMENT_LINES, PROJECTION_EXIT_TAG, PROJECTION_ELEMENT_NUMBER, PROJECTION_ELEMENT_LINE_NUMBER, PROJECTION_DISTANCE, PROJECTION_XI, PROJECTION_VECTOR, ERR, ERROR,)
Find the projection of a data point onto element lines (slight difference to DATA_PROJECTION_NEWTON_E...
A buffer type to allow for an array of pointers to a DATA_PROJECTION_TYPE.
Definition: types.f90:313
integer(intg), parameter part_deriv_s2
First partial derivative in the s2 direction i.e., du/ds2.
Definition: constants.f90:183
subroutine data_projection_label_get_vs(DATA_PROJECTION, LABEL, ERR, ERROR,)
Gets the label for a data projection for varying string labels.
Contains information for a field defined on a region.
Definition: types.f90:1346
This module provides an iso_varying_string module, conformant to the API specified in ISO/IEC 1539-2:...
subroutine data_projection_newton_elements_evaluate_1(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, PROJECTION_EXIT_TAG, PROJECTION_ELEMENT_NUMBER, PROJECTION_DISTANCE, PROJECTION_XI, PROJECTION_VECTOR, ERR, ERROR,)
Find the projection of a data point onto 1D elements.
This module contains all program wide constants.
Definition: constants.f90:45
subroutine data_projection_closest_elements_find(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, NUMBER_OF_CANDIDATES, CLOSEST_ELEMENTS, CLOSEST_DISTANCES, ERR, ERROR,)
Find the closest elements to a data point based on starting xi guess.
integer(intg), parameter part_deriv_s1
First partial derivative in the s1 direction i.e., du/ds1.
Definition: constants.f90:181
subroutine, public data_projection_relative_tolerance_set(DATA_PROJECTION, RELATIVE_TOLERANCE, ERR, ERROR,)
Sets the relative tolerance for a data projection.
integer(intg), parameter, public data_projection_boundary_faces_projection_type
The boundary face projection type for data projection, only projects to boundary faces of the mesh...
subroutine, public dataprojection_maximumnumberofiterationsget(DATA_PROJECTION, MAXIMUM_NUMBER_OF_ITERATIONS, ERR, ERROR,)
Gets the maximum number of iterations for a data projection.
subroutine, public dataprojection_projectioncandidatesset(dataProjection, elementUserNumber, localFaceLineNumbers, err, error,)
Sets the candidates element numbers and local line/face numbers for a data projection.
integer(intg), parameter, public data_projection_boundary_lines_projection_type
The boundary line projection type for data projection, only projects to boundary lines of the mesh...
subroutine, public exits(NAME)
Records the exit out of the named procedure.
This module contains all type definitions in order to avoid cyclic module references.
Definition: types.f90:70
subroutine, public dataprojection_numberofclosestelementsset(DATA_PROJECTION, NUMBER_OF_CLOSEST_ELEMENTS, ERR, ERROR,)
Sets the number of closest elements for a data projection.
subroutine dataprojection_datapointglobalnumberget(DATA_PROJECTION, USER_NUMBER, GLOBAL_NUMBER, ERR, ERROR,)
Gets the user number for a data point identified by a given global number.
subroutine data_projection_label_get_c(DATA_PROJECTION, LABEL, ERR, ERROR,)
Gets the label for a data projection for character labels.
This module handles all data projection routines.
integer(intg), parameter part_deriv_s3
First partial derivative in the s3 direction i.e., du/ds3.
Definition: constants.f90:186
This module contains all the low-level base routines e.g., all debug, control, and low-level communic...
integer(intg), parameter part_deriv_s1_s1
Second partial derivative in the s1 direction i.e., d^2u/ds1ds1.
Definition: constants.f90:182
subroutine data_projection_closest_faces_find(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, CANDIDATE_ELEMENT_FACES, NUMBER_OF_CANDIDATES, CLOSEST_ELEMENTS, CLOSEST_ELEMENT_FACES, CLOSEST_DISTANCES, ERR, ERROR,)
Find the closest faces to a data point base on starting xi guess.
integer(intg), parameter part_deriv_s2_s3
Cross derivative in the s2 and s3 direction i.e., d^2u/ds2ds3.
Definition: constants.f90:189
subroutine, public data_projection_starting_xi_set(DATA_PROJECTION, STARTING_XI, ERR, ERROR,)
Sets the starting xi for a data projection.
integer(intg), parameter part_deriv_s1_s3
Cross derivative in the s1 and s3 direction i.e., d^2u/ds1ds3.
Definition: constants.f90:188
This module contains all computational environment variables.
This module contains CMISS MPI routines.
Definition: cmiss_mpi.f90:45
This module handles all domain mappings routines.
This module contains all procedures for sorting. NOTE: THE ROUTINES IN THIS MODULE HAVE NOT BEEN TEST...
Definition: sorting.f90:45
subroutine data_projection_newton_faces_evaluate(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, CANDIDATE_ELEMENT_FACES, PROJECTION_EXIT_TAG, PROJECTION_ELEMENT_NUMBER, PROJECTION_ELEMENT_FACE_NUMBER, PROJECTION_DISTANCE, PROJECTION_XI, PROJECTION_VECTOR, ERR, ERROR,)
Find the projection of a data point onto element faces (slight difference to DATA_PROJECTION_NEWTON_E...
type(computational_environment_type), target, public computational_environment
The computational environment the program is running in.
Contains information on a mesh defined on a region.
Definition: types.f90:503
subroutine, public data_projection_result_exit_tag_get(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_EXIT_TAG, ERR, ERROR,)
Gets the projection exit tag for a data point identified by a given global number.
subroutine, public dataprojection_maximuminterationupdateget(DATA_PROJECTION, MAXIMUM_ITERATION_UPDATE, ERR, ERROR,)
Gets the maximum iteration update for a data projection.
subroutine data_projection_newton_elements_evaluate_2(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, PROJECTION_EXIT_TAG, PROJECTION_ELEMENT_NUMBER, PROJECTION_DISTANCE, PROJECTION_XI, PROJECTION_VECTOR, ERR, ERROR,)
Find the projection of a data point onto 2D elements.
subroutine, public data_projection_result_element_number_get(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_ELEMENT_NUMBER, ERR, ERROR,)
Gets the projection element number for a data point identified by a given global number.
Contains the interpolated value (and the derivatives wrt xi) of a field at a point. Old CMISS name XG.
Definition: types.f90:1129
subroutine, public data_projection_starting_xi_get(DATA_PROJECTION, STARTING_XI, ERR, ERROR,)
Gets the starting xi for a data projection.
subroutine data_projection_newton_elements_evaluate_3(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, PROJECTION_EXIT_TAG, PROJECTION_ELEMENT_NUMBER, PROJECTION_DISTANCE, PROJECTION_XI, PROJECTION_VECTOR, ERR, ERROR,)
Find the projection of a data point onto 3D elements.
subroutine, public data_projection_absolute_tolerance_get(DATA_PROJECTION, ABSOLUTE_TOLERANCE, ERR, ERROR,)
Gets the absolute tolerance for a data projection.
real(dp), parameter twopi
The double value of 2pi.
Definition: constants.f90:58
subroutine, public data_projection_relative_tolerance_get(DATA_PROJECTION, RELATIVE_TOLERANCE, ERR, ERROR,)
Gets the relative tolerance for a data projection.
integer(intg), parameter part_deriv_s1_s2
Cross derivative in the s1 and s2 direction i.e., d^2u/ds1ds2.
Definition: constants.f90:185
integer(intg), parameter part_deriv_s2_s2
Second partial derivative in the s2 direction i.e., d^2u/ds2ds2.
Definition: constants.f90:184
subroutine, public data_projection_absolute_tolerance_set(DATA_PROJECTION, ABSOLUTE_TOLERANCE, ERR, ERROR,)
Sets the absolute tolerance for a data projection.
integer(intg), parameter data_projection_exit_tag_converged
Data projection exited due to it being converged.
integer(intg), parameter part_deriv_s3_s3
Second partial derivative in the s3 direction i.e., d^2u/ds3ds3.
Definition: constants.f90:187
Contains information on the domain mappings (i.e., local and global numberings).
Definition: types.f90:904
A pointer to the domain decomposition for this domain.
Definition: types.f90:938
subroutine, public tree_item_insert(TREE, KEY, VALUE, INSERT_STATUS, ERR, ERROR,)
Inserts a tree node into a red-black tree.
Definition: trees.f90:769
subroutine, public errors(NAME, ERR, ERROR)
Records the exiting error of the subroutine.
integer(intg), parameter data_projection_exit_tag_no_element
Data projection exited due to no local element found, this happens when none of the candidate element...
subroutine data_projection_finalise(DATA_PROJECTION, ERR, ERROR,)
Finalise a data projection.
subroutine, public tree_node_value_get(TREE, TREE_NODE, VALUE, ERR, ERROR,)
Gets the value at a specified tree node.
Definition: trees.f90:1059
subroutine, public data_projection_result_xi_set(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_XI, ERR, ERROR,)
Sets the projection xi for a data point identified by a given global number.
subroutine data_projection_closest_lines_find(DATA_PROJECTION, INTERPOLATED_POINT, POINT_VALUES, CANDIDATE_ELEMENTS, CANDIDATE_ELEMENT_LINES, NUMBER_OF_CANDIDATES, CLOSEST_ELEMENTS, CLOSEST_ELEMENT_LINES, CLOSEST_DISTANCES, ERR, ERROR,)
Find the closest lines to a data point base on starting xi guess.
subroutine, public data_projection_create_finish(DATA_PROJECTION, ERR, ERROR,)
Finishes the process of creating data projection.
Flags an error condition.
subroutine dataprojection_dataprojectionresultinitialise(DATA_PROJECTION, ERR, ERROR,)
Initialises the data projection part in a given data points. %%%%% THIS NEED TO BE CHANGED!!! TIM...
subroutine, public dataprojection_resultelementfacenumberget(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_ELEMENT_FACE_NUMBER, ERR, ERROR,)
Gets the projection element face number for a data point identified by a given global number...
integer(intg) function, public computational_node_number_get(ERR, ERROR)
Returns the number/rank of the computational nodes.
integer(intg), parameter, public data_projection_all_elements_projection_type
The element projection type for data projection, projects to all elements in mesh.
subroutine data_projection_label_set_vs(DATA_PROJECTION, LABEL, ERR, ERROR,)
Sets the label for a data projection for varying string labels.
subroutine, public dataprojection_datapointspositionevaluate(dataProjection, field, fieldVariableType, err, error,)
Evaluate the data points position in a field based on data projection.
subroutine, public dataprojection_resultelementlinenumberget(DATA_PROJECTION, DATA_POINT_USER_NUMBER, PROJECTION_ELEMENT_LINE_NUMBER, ERR, ERROR,)
Gets the projection element line number for a data point identified by a given global number...
subroutine, public data_projection_destroy(DATA_PROJECTION, ERR, ERROR,)
Destroys a data projection.
real(dp), parameter zero_tolerance
Definition: constants.f90:70
This module contains all kind definitions.
Definition: kinds.f90:45
subroutine, public mpi_error_check(ROUTINE, MPI_ERR_CODE, ERR, ERROR,)
Checks to see if an MPI error has occured during an MPI call and flags a CMISS error it if it has...
Definition: cmiss_mpi.f90:84
This module handles all formating and input and output.