1!!-------------------------------------------------------
2!!---- Crystallographic Fortran Modules Library (CrysFML)
3!!-------------------------------------------------------
4!!---- The CrysFML project is distributed under LGPL. In agreement with the
5!!---- Intergovernmental Convention of the ILL, this software cannot be used
6!!---- in military applications.
7!!----
8!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
9!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
10!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
11!!----
12!!---- Authors: Juan Rodriguez-Carvajal (ILL)
13!!----          Javier Gonzalez-Platas  (ULL)
14!!----
15!!---- Contributors: Laurent Chapon     (ILL)
16!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
17!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
18!!----               Tierry Roisnel     (CDIFX,Rennes France)
19!!----               Eric Pellegrini    (ILL)
20!!----
21!!---- This library is free software; you can redistribute it and/or
22!!---- modify it under the terms of the GNU Lesser General Public
23!!---- License as published by the Free Software Foundation; either
24!!---- version 3.0 of the License, or (at your option) any later version.
25!!----
26!!---- This library is distributed in the hope that it will be useful,
27!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
28!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29!!---- Lesser General Public License for more details.
30!!----
31!!---- You should have received a copy of the GNU Lesser General Public
32!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
33!!----
34!!----
35!!---- MODULE: CFML_GlobalDeps  (Linux version)
36!!----   INFO: Precision for CrysFML library and Operating System information
37!!----         All the global variables defined in this module are implicitly public.
38!!----
39!!---- HISTORY
40!!--..    Update: 02/03/2011
41!!--..
42!!---- VARIABLES
43!!--..
44!!--..    Operating system
45!!--..
46!!----    OPS
47!!----    OPS_NAME
48!!----    OPS_SEP
49!!--..
50!!--..    Precision Data
51!!--..
52!!----    SP
53!!----    DP
54!!----    CP
55!!--..
56!!--..    Trigonometric
57!!--..
58!!----    PI
59!!----    TO_DEG
60!!----    TO_RAD
61!!----    TPI
62!!--..
63!!--..    Numeric
64!!--..
65!!----    DEPS
66!!----    EPS
67!!--..
68!!---- FUNCTIONS
69!!--..
70!!----    DIRECTORY_EXISTS
71!!----
72!!---- SUBROUTINES
73!!--..
74!!----    WRITE_DATE_TIME
75!!----
76!!
77Module CFML_GlobalDeps
78
79   !---- Variables ----!
80   implicit None
81
82   public
83
84   !------------------------------------!
85   !---- Operating System variables ----!
86   !------------------------------------!
87
88   !!----
89   !!---- OPS
90   !!----   Integer variable 1: Windows, 2: Linux, 3: MacOs, ....
91   !!----   This is a variable set by the user of the library for the case
92   !!----   that there is no external library with a procedure for getting
93   !!----   the operating system.
94   !!----
95   !!---- Update: March 2009
96   !!
97   integer, parameter :: OPS= 2    ! Linux
98
99   !!----
100   !!---- OPS_NAME
101   !!----   Character variable containing the name of the operating system
102   !!----   This is a variable set by the user of the library for the case
103   !!----   that there is no external library with a procedure for getting
104   !!----   the operating system.
105   !!----
106   !!---- Update: March 2009
107   !!
108   character(len=*), parameter :: OPS_NAME="Linux"
109
110   !!----
111   !!---- OPS_SEP
112   !!----   ASCII code of directory separator character
113   !!----   Here it is written explicitly as a character variable
114   !!----
115   !!---- Update: March 2009
116   !!
117   character(len=*), parameter :: OPS_SEP="/"
118
119   !------------------------------!
120   !---- Precision Parameters ----!
121   !------------------------------!
122
123   !!----
124   !!---- SP
125   !!----    SP: Single precision ( sp = selected_real_kind(6,30) )
126   !!----
127   !!---- Update: January - 2009
128   !!
129   integer, parameter :: sp = selected_real_kind(6,30)
130
131   !!----
132   !!---- DP
133   !!----    DP: Double precision ( dp = selected_real_kind(14,150) )
134   !!----
135   !!---- Update: January - 2009
136   !!
137   integer, parameter :: dp = selected_real_kind(14,150)
138
139   !!----
140   !!---- CP
141   !!----    CP: Current precision
142   !!----
143   !!---- Update: January - 2009
144   !!
145   integer, parameter :: cp = sp
146
147   !----------------------------------!
148   !---- Trigonometric Parameters ----!
149   !----------------------------------!
150
151   !!----
152   !!---- PI
153   !!----    real(kind=dp), parameter ::  pi = 3.141592653589793238463_dp
154   !!----
155   !!----    Pi value
156   !!----
157   !!---- Update: January - 2009
158   !!
159   real(kind=dp), parameter ::  pi = 3.141592653589793238463_dp
160
161   !!----
162   !!---- TO_DEG
163   !!----    real(kind=dp), parameter ::  to_DEG = 180.0_dp/pi
164   !!----
165   !!----    Conversion from Radians to Degrees
166   !!----
167   !!---- Update: January - 2009
168   !!
169   real(kind=dp), parameter ::  to_DEG  = 180.0_dp/pi
170
171   !!----
172   !!---- TO_RAD
173   !!----    real(kind=dp), parameter ::  to_RAD  = pi/180.0_dp
174   !!----
175   !!----    Conversion from Degrees to Radians
176   !!----
177   !!---- Update: January - 2009
178   !!
179   real(kind=dp), parameter ::  to_RAD  = pi/180.0_dp
180
181   !!----
182   !!---- TPI
183   !!----  real(kind=dp), parameter ::  tpi = 6.283185307179586476925_dp
184   !!----
185   !!----  2.0*Pi value
186   !!----
187   !!---- Update: January - 2009
188   !!
189   real(kind=dp), parameter ::  tpi = 6.283185307179586476925_dp
190
191   !----------------------------!
192   !---- Numeric Parameters ----!
193   !----------------------------!
194
195   !!----
196   !!---- DEPS
197   !!----    real(kind=dp), parameter :: deps=0.00000001_dp
198   !!----
199   !!----    Epsilon value use for comparison of real numbers
200   !!----
201   !!---- Update: January - 2009
202   !!
203   real(kind=dp), parameter, public :: deps=0.00000001_dp
204
205   !!----
206   !!----  EPS
207   !!----     real(kind=cp), public ::  eps=0.00001_cp
208   !!----
209   !!----     Epsilon value use for comparison of real numbers
210   !!----
211   !!----  Update: January - 2009
212   !!
213   real(kind=cp),  parameter, public  ::  eps=0.00001_cp
214
215 Contains
216
217   !-------------------!
218   !---- Functions ----!
219   !-------------------!
220
221   !!----
222   !!---- Function Directory_Exists(Dirname) Result(info)
223   !!----    character(len=*), intent(in) :: Dirname
224   !!----    logical                      :: info
225   !!----
226   !!---- Generic function dependent of the compiler that return
227   !!---- a logical value if a directory exists or not.
228   !!----
229   !!---- Update: April - 2009
230   !!
231   Function Directory_Exists(Dirname) Result(info)
232      !---- Argument ----!
233      character(len=*), intent(in) :: Dirname
234      logical                      :: info
235
236      !---- Local Variables ----!
237      character(len=512) :: linea
238      integer            :: nlong
239
240      ! Init value
241      info=.false.
242
243      linea=trim(dirname)
244      nlong=len_trim(linea)
245      if (nlong ==0) return
246
247      if (linea(nlong:nlong) /= ops_sep) linea=trim(linea)//ops_sep
248
249      ! All compilers except Intel
250      inquire(file=trim(linea)//'.' , exist=info)
251
252      ! Intel
253      !inquire(directory=trim(linea), exist=info)
254
255      return
256   End Function Directory_Exists
257
258   !---------------------!
259   !---- Subroutines ----!
260   !---------------------!
261
262   !!----
263   !!---- Subroutine Write_Date_Time(lun,dtim)
264   !!----  integer,         optional,intent(in) :: lun
265   !!----  character(len=*),optional,intent(out):: dtim
266   !!----
267   !!---- Generic subroutine for writing the date and time
268   !!---- in form   Date: Day/Month/Year  Time: hour:minute:second
269   !!---- to a file with logical unit = lun. The output argument
270   !!---- can be provided to get a string with the same information
271   !!----
272   !!---- Updated: January - 2014
273   !!
274   Subroutine Write_Date_Time(lun,dtim)
275     integer,         optional,intent(in) :: lun
276     character(len=*),optional,intent(out):: dtim
277     !--- Local variables ----!
278     character (len=10) :: dat
279     character (len=10) :: tim
280     call date_and_time(date=dat,time=tim)
281     if(present(lun)) &
282     write(unit=lun,fmt="(/,4a)") &
283       " => Date: ",dat(7:8)//"/"//dat(5:6)//"/"//dat(1:4),      &
284         "  Time: ",tim(1:2)//":"//tim(3:4)//":"//tim(5:10)
285     if(present(dtim)) &
286      dtim="#   Date: "//dat(7:8)//"/"//dat(5:6)//"/"//dat(1:4)//      &
287            "  Time: "//tim(1:2)//":"//tim(3:4)//":"//tim(5:10)
288     return
289   End Subroutine Write_Date_Time
290
291End Module CFML_GlobalDeps
292!!-------------------------------------------------------
293!!---- Crystallographic Fortran Modules Library (CrysFML)
294!!-------------------------------------------------------
295!!---- The CrysFML project is distributed under LGPL. In agreement with the
296!!---- Intergovernmental Convention of the ILL, this software cannot be used
297!!---- in military applications.
298!!----
299!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
300!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
301!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
302!!----
303!!---- Authors: Juan Rodriguez-Carvajal (ILL)
304!!----          Javier Gonzalez-Platas  (ULL)
305!!----
306!!---- Contributors: Laurent Chapon     (ILL)
307!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
308!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
309!!----               Tierry Roisnel     (CDIFX,Rennes France)
310!!----               Eric Pellegrini    (ILL)
311!!----
312!!---- This library is free software; you can redistribute it and/or
313!!---- modify it under the terms of the GNU Lesser General Public
314!!---- License as published by the Free Software Foundation; either
315!!---- version 3.0 of the License, or (at your option) any later version.
316!!----
317!!---- This library is distributed in the hope that it will be useful,
318!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
319!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
320!!---- Lesser General Public License for more details.
321!!----
322!!---- You should have received a copy of the GNU Lesser General Public
323!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
324!!----
325!!----
326!!---- MODULE: CFML_Math_General
327!!----   INFO: Mathematic general utilities for use in Crystallography and
328!!----         Solid State Physics and Chemistry.
329!!----
330!!---- HISTORY
331!!----    Updated: 02/03/2011
332!!----
333!!---- DEPENDENCIES
334!!----
335!!----    CFML_GlobalDeps
336!!----
337!!---- VARIABLES
338!!--++    EPSS                         [Private]
339!!--++    EP_SS                        [Private]
340!!----    ERR_MathGen
341!!----    ERR_MathGen_Mess
342!!----
343!!---- PROCEDURES
344!!----    Functions:
345!!--..
346!!--..    Trigonometric Functions
347!!----       ACOSD
348!!--++       ACOSD_dp                  [Overloaded]
349!!--++       ACOSD_sp                  [Overloaded]
350!!----       ASIND
351!!--++       ASIND_dp                  [Overloaded]
352!!--++       ASIND_sp                  [Overloaded]
353!!----       ATAN2D
354!!--++       ATAN2D_dp                 [Overloaded]
355!!--++       ATAN2D_sp                 [Overloaded]
356!!----       ATAND
357!!--++       ATAND_dp                  [Overloaded]
358!!--++       ATAND_sp                  [Overloaded]
359!!----       COSD
360!!--++       COSD_dp                   [Overloaded]
361!!--++       COSD_sp                   [Overloaded]
362!!----       SIND
363!!--++       SIND_dp                   [Overloaded]
364!!--++       SIND_sp                   [Overloaded]
365!!----       TAND
366!!--++       TAND_dp                   [Overloaded]
367!!--++       TAND_sp                   [Overloaded]
368!!--..
369!!--..    Special Functions
370!!----       BESSJ0
371!!----       BESSJ1
372!!----       BESSJ
373!!--..
374!!--..    Scalar Functions
375!!----       FACTORIAL
376!!----       NEGLIGIBLE
377!!--++       NEGLIGIBLEC               [Overloaded]
378!!--++       NEGLIGIBLER               [Overloaded]
379!!----       PGCD
380!!----       PPCM
381!!----       PYTHAG
382!!--++       PYTHAG_dp                 [Overloaded]
383!!--++       PYTHAG_sp                 [Overloaded]
384!!--..
385!!--..    Arrays and Vectors Functions
386!!----       CO_LINEAR
387!!--++       CO_LINEAR_C               [Overloaded]
388!!--++       CO_LINEAR_I               [Overloaded]
389!!--++       CO_LINEAR_R               [Overloaded]
390!!----       CO_PRIME
391!!----       EQUAL_MATRIX
392!!--++       EQUAL_MATRIX_I            [Overloaded]
393!!--++       EQUAL_MATRIX_R            [Overloaded]
394!!----       EQUAL_VECTOR
395!!--++       EQUAL_VECTOR_I            [Overloaded]
396!!--++       EQUAL_VECTOR_R            [Overloaded]
397!!----       EUCLIDEAN_NORM
398!!----       IMAXLOC
399!!--++       IMAXLOC_I                 [Overloaded]
400!!--++       IMAXLOC_R                 [OVerloaded]
401!!----       IMINLOC
402!!--++       IMINLOC_I                 [Overloaded]
403!!--++       IMINLOC_R                 [OVerloaded]
404!!----       LOCATE
405!!--++       LOCATE_I                  [Overloaded]
406!!--++       LOCATE_IB                 [Overloaded]
407!!--++       LOCATE_R                  [Overloaded]
408!!--++       LOCATE_RB                 [Overloaded]
409!!----       LOWER_TRIANGULAR
410!!--++       LOWER_TRIANGULAR_I        [Overloaded]
411!!--++       LOWER_TRIANGULAR_R        [Overloaded]
412!!----       MODULO_LAT
413!!----       NORM
414!!--++       NORM_I                    [Overloaded]
415!!--++       NORM_R                    [Overloaded]
416!!----       OUTERPROD
417!!--++       OUTERPROD_dp              [Overloaded]
418!!--++       OUTERPROD_sp              [Overloaded]
419!!----       SCALAR
420!!--++       SCALAR_I                  [Overloaded]
421!!--++       SCALAR_R                  [Overloaded]
422!!----       TRACE
423!!--++       TRACE_C                   [Overloaded]
424!!--++       TRACE_I                   [Overloaded]
425!!--++       TRACE_R                   [Overloaded]
426!!----       UPPER_TRIANGULAR
427!!--++       UPPER_TRIANGULAR_I        [Overloaded]
428!!--++       UPPER_TRIANGULAR_R        [Overloaded]
429!!----       ZBELONG
430!!--++       ZBELONGM                  [Overloaded]
431!!--++       ZBELONGN                  [Overloaded]
432!!--++       ZBELONGV                  [Overloaded]
433!!--..
434!!----
435!!----    Subroutines:
436!!--..
437!!--..    Init Routine
438!!----       INIT_ERR_MATHGEN
439!!----       SET_EPSG
440!!----       SET_EPSG_DEFAULT
441!!--..
442!!--..    Trigonometric Subroutines
443!!----       RTAN
444!!--++       RTAN_dp                   [Overloaded]
445!!--++       RTAN_sp                   [Overloaded]
446!!--..
447!!--..    Arrays and Vectors Functions
448!!----       CO_PRIME_VECTOR
449!!----       DETERMINANT
450!!--++       DETERMINANT_C             [Overloaded]
451!!--++       DETERMINANT_R             [Overloaded]
452!!----       DIAGONALIZE_SH
453!!--++       DIAGONALIZE_HERM          [Overloaded]
454!!--++       DIAGONALIZE_SYMM          [Overloaded]
455!!--++       EIGSRT                    [Private]
456!!----       FIRST_DERIVATIVE
457!!----       IN_SORT
458!!----       INVERT_MATRIX
459!!----       LINEAR_DEPENDENT
460!!--++       LINEAR_DEPENDENTC         [Overloaded]
461!!--++       LINEAR_DEPENDENTI         [Overloaded]
462!!--++       LINEAR_DEPENDENTR         [Overloaded]
463!!----       LU_BACKSUB
464!!----       LU_DECOMP
465!!----       MATINV
466!!--++       PARTITION                 [Private]
467!!----       POINTS_IN_LINE2D
468!!----       RANK
469!!--++       RANK_dp                   [Overloaded]
470!!--++       RANK_sp                   [Overloaded]
471!!----       SECOND_DERIVATIVE
472!!----       SMOOTHINGVEC
473!!----       SORT
474!!--++       SORT_I                    [Overloaded]
475!!--++       SORT_R                    [Overloaded]
476!!----       SORT_STRINGS
477!!----       SPLINE
478!!----       SPLINT
479!!----       SVDCMP
480!!--++       SVDCMP_dp                 [Overloaded]
481!!--++       SVDCMP_sp                 [Overloaded]
482!!----       SWAP
483!!--++       SWAP_C                    [Overloaded]
484!!--++       SWAP_CM                   [Overloaded]
485!!--++       SWAP_CV                   [Overloaded]
486!!--++       SWAP_I                    [Overloaded]
487!!--++       SWAP_IM                   [Overloaded]
488!!--++       SWAP_IV                   [Overloaded]
489!!--++       SWAP_R                    [Overloaded]
490!!--++       SWAP_RM                   [Overloaded]
491!!--++       SWAP_RV                   [Overloaded]
492!!--++       MASKED_SWAP_R             [Overloaded]
493!!--++       MASKED_SWAP_RM            [Overloaded]
494!!--++       MASKED_SWAP_RV            [Overloaded]
495!!--++       TQLI1                     [Private]
496!!--++       TQLI2                     [Private]
497!!--++       TRED1                     [Private]
498!!--++       TRED2                     [Private]
499!!--++
500!!
501 Module CFML_Math_General
502    !---- Use Modules ----!
503    Use CFML_GlobalDeps
504
505    !---- Variables ----!
506    implicit none
507
508    private
509
510    !---- List of public functions ----!
511    public :: Bessj0, Bessj1, Bessj, Factorial, Pgcd, Ppcm, Modulo_Lat, Co_Prime, &
512              Euclidean_Norm,Erf
513
514    !---- List of public overloaded procedures: functions ----!
515    public :: Acosd, Asind, Atan2d, Atand, Cosd, Sind, Tand, Negligible, Pythag,   &
516              Co_Linear, Equal_Matrix, Equal_Vector, Locate, Outerprod, Trace,     &
517              Zbelong, Imaxloc, Iminloc, Norm, Scalar, In_limits, Lower_Triangular,&
518              Upper_Triangular
519
520    !---- List of private functions ----!
521    private :: Acosd_dp, Acosd_sp, Asind_dp, Asind_sp, Atan2d_dp, Atan2d_sp,       &
522               Atand_dp, Atand_sp, Cosd_dp, Cosd_sp, Sind_dp, Sind_sp, Tand_dp,    &
523               Tand_sp, Negligiblec, Negligibler, Pythag_dp, Pythag_sp,            &
524               Co_linear_C, Co_linear_I, Co_linear_R, Equal_Matrix_I,              &
525               Equal_Matrix_R, Equal_Vector_I, Equal_Vector_R, Locate_I, Locate_R, &
526               Outerprod_dp, Outerprod_sp, Trace_C, Trace_I, Trace_R, ZbelongM,    &
527               ZbelongN, ZbelongV, Imaxloc_I, Imaxloc_R, Iminloc_R, Iminloc_I,     &
528               Norm_I, Norm_R, Scalar_I, Scalar_R, Locate_Ib, Locate_Rb,           &
529               In_limits_dp, In_limits_sp, In_Limits_int, Lower_Triangular_I,      &
530               Lower_Triangular_R, Upper_Triangular_I, Upper_Triangular_R
531
532    !---- List of public subroutines ----!
533    public ::  Init_Err_Mathgen, Invert_Matrix, LU_Decomp, LU_Backsub, Matinv,        &
534               Sort_Strings, Spline, Splint, Set_Epsg, Set_Epsg_Default,In_Sort,      &
535               First_Derivative, Second_Derivative, SmoothingVec, Points_in_Line2D,   &
536               Co_Prime_vector
537
538    !---- List of public overloaded procedures: subroutines ----!
539    public ::  RTan, Determinant, Diagonalize_Sh, Linear_Dependent, Rank, Sort,   &
540               Svdcmp, Swap
541
542    !---- List of private subroutines ----!
543    private :: RTan_dp, RTan_sp, Determinant_C,Determinant_R, Diagonalize_Herm,   &
544               Diagonalize_Symm, Eigsrt, Linear_DependentC, Linear_DependentI,    &
545               Linear_DependentR, Rank_dp, Rank_sp, Sort_I, Sort_R, Svdcmp_dp,    &
546               Svdcmp_sp, Swap_C, Swap_Cm, Swap_Cv, Swap_I, Swap_Im, Swap_Iv,     &
547               Swap_R, Swap_Rm, Swap_Rv, Masked_Swap_R, Masked_Swap_Rm,           &
548               Masked_Swap_Rv, Tqli1, Tqli2, Tred1, Tred2, Partition
549
550
551    !---- Definitions ----!
552
553    !!--++
554    !!--++ EPSS
555    !!--++    real(kind=cp)  :: epss=1.0E-5_cp
556    !!--++
557    !!--++    Internal epsilon value used for comparing reals to integers
558    !!--++    in crystallographic applications where the maximum precision in the
559    !!--++    measured values is of the order of 10^-5.
560    !!--++
561    !!--++ Update: April - 2005
562    !!
563    real(kind=cp),   private :: epss=1.0E-5_cp
564
565    !!--++
566    !!--++ EP_SS
567    !!--++    real(kind=cp), parameter, private  :: ep_ss=1.0E-12_cp
568    !!--++
569    !!--++    Internal epsilon value used for comparison in matrix operations
570    !!--++
571    !!--++ Update: February - 2005
572    !!
573    real(kind=cp), parameter, private :: ep_ss=1.0E-12_cp
574
575    !!----
576    !!---- ERR_MathGen
577    !!----    logical :: ERR_MathGen
578    !!----
579    !!----    Logical Variable indicating an error in CFML_Math_General module
580    !!----
581    !!---- Update: February - 2005
582    !!
583    logical, public :: ERR_MathGen
584
585    !!----
586    !!---- ERR_MathGen_Mess
587    !!----    character(len=150) :: ERR_MathGen_Mess
588    !!----
589    !!----    String containing information about the last error
590    !!----
591    !!---- Update: February - 2005
592    !!
593    character(len=150), public:: ERR_MathGen_Mess
594
595    !!----
596    !!---- Primes
597    !!----    integer, parameter, dimension(1000), public :: primes
598    !!----
599    !!----    List of the first 1000 prime numbers.
600    !!----    Used by the subroutine Co_Prime_Vector and function Co_Prime
601    !!----
602    !!----  Created: January - 2011
603    !!
604    integer, parameter, dimension(1000), public :: primes =                                       &
605           (/ 2,      3,      5,      7,     11,     13,     17,     19,     23,     29,  &
606             31,     37,     41,     43,     47,     53,     59,     61,     67,     71,  &
607             73,     79,     83,     89,     97,    101,    103,    107,    109,    113,  &
608            127,    131,    137,    139,    149,    151,    157,    163,    167,    173,  &
609            179,    181,    191,    193,    197,    199,    211,    223,    227,    229,  &
610            233,    239,    241,    251,    257,    263,    269,    271,    277,    281,  &
611            283,    293,    307,    311,    313,    317,    331,    337,    347,    349,  &
612            353,    359,    367,    373,    379,    383,    389,    397,    401,    409,  &
613            419,    421,    431,    433,    439,    443,    449,    457,    461,    463,  &
614            467,    479,    487,    491,    499,    503,    509,    521,    523,    541,  &
615            547,    557,    563,    569,    571,    577,    587,    593,    599,    601,  &
616            607,    613,    617,    619,    631,    641,    643,    647,    653,    659,  &
617            661,    673,    677,    683,    691,    701,    709,    719,    727,    733,  &
618            739,    743,    751,    757,    761,    769,    773,    787,    797,    809,  &
619            811,    821,    823,    827,    829,    839,    853,    857,    859,    863,  &
620            877,    881,    883,    887,    907,    911,    919,    929,    937,    941,  &
621            947,    953,    967,    971,    977,    983,    991,    997,   1009,   1013,  &
622           1019,   1021,   1031,   1033,   1039,   1049,   1051,   1061,   1063,   1069,  &
623           1087,   1091,   1093,   1097,   1103,   1109,   1117,   1123,   1129,   1151,  &
624           1153,   1163,   1171,   1181,   1187,   1193,   1201,   1213,   1217,   1223,  &
625           1229,   1231,   1237,   1249,   1259,   1277,   1279,   1283,   1289,   1291,  &
626           1297,   1301,   1303,   1307,   1319,   1321,   1327,   1361,   1367,   1373,  &
627           1381,   1399,   1409,   1423,   1427,   1429,   1433,   1439,   1447,   1451,  &
628           1453,   1459,   1471,   1481,   1483,   1487,   1489,   1493,   1499,   1511,  &
629           1523,   1531,   1543,   1549,   1553,   1559,   1567,   1571,   1579,   1583,  &
630           1597,   1601,   1607,   1609,   1613,   1619,   1621,   1627,   1637,   1657,  &
631           1663,   1667,   1669,   1693,   1697,   1699,   1709,   1721,   1723,   1733,  &
632           1741,   1747,   1753,   1759,   1777,   1783,   1787,   1789,   1801,   1811,  &
633           1823,   1831,   1847,   1861,   1867,   1871,   1873,   1877,   1879,   1889,  &
634           1901,   1907,   1913,   1931,   1933,   1949,   1951,   1973,   1979,   1987,  &
635           1993,   1997,   1999,   2003,   2011,   2017,   2027,   2029,   2039,   2053,  &
636           2063,   2069,   2081,   2083,   2087,   2089,   2099,   2111,   2113,   2129,  &
637           2131,   2137,   2141,   2143,   2153,   2161,   2179,   2203,   2207,   2213,  &
638           2221,   2237,   2239,   2243,   2251,   2267,   2269,   2273,   2281,   2287,  &
639           2293,   2297,   2309,   2311,   2333,   2339,   2341,   2347,   2351,   2357,  &
640           2371,   2377,   2381,   2383,   2389,   2393,   2399,   2411,   2417,   2423,  &
641           2437,   2441,   2447,   2459,   2467,   2473,   2477,   2503,   2521,   2531,  &
642           2539,   2543,   2549,   2551,   2557,   2579,   2591,   2593,   2609,   2617,  &
643           2621,   2633,   2647,   2657,   2659,   2663,   2671,   2677,   2683,   2687,  &
644           2689,   2693,   2699,   2707,   2711,   2713,   2719,   2729,   2731,   2741,  &
645           2749,   2753,   2767,   2777,   2789,   2791,   2797,   2801,   2803,   2819,  &
646           2833,   2837,   2843,   2851,   2857,   2861,   2879,   2887,   2897,   2903,  &
647           2909,   2917,   2927,   2939,   2953,   2957,   2963,   2969,   2971,   2999,  &
648           3001,   3011,   3019,   3023,   3037,   3041,   3049,   3061,   3067,   3079,  &
649           3083,   3089,   3109,   3119,   3121,   3137,   3163,   3167,   3169,   3181,  &
650           3187,   3191,   3203,   3209,   3217,   3221,   3229,   3251,   3253,   3257,  &
651           3259,   3271,   3299,   3301,   3307,   3313,   3319,   3323,   3329,   3331,  &
652           3343,   3347,   3359,   3361,   3371,   3373,   3389,   3391,   3407,   3413,  &
653           3433,   3449,   3457,   3461,   3463,   3467,   3469,   3491,   3499,   3511,  &
654           3517,   3527,   3529,   3533,   3539,   3541,   3547,   3557,   3559,   3571,  &
655           3581,   3583,   3593,   3607,   3613,   3617,   3623,   3631,   3637,   3643,  &
656           3659,   3671,   3673,   3677,   3691,   3697,   3701,   3709,   3719,   3727,  &
657           3733,   3739,   3761,   3767,   3769,   3779,   3793,   3797,   3803,   3821,  &
658           3823,   3833,   3847,   3851,   3853,   3863,   3877,   3881,   3889,   3907,  &
659           3911,   3917,   3919,   3923,   3929,   3931,   3943,   3947,   3967,   3989,  &
660           4001,   4003,   4007,   4013,   4019,   4021,   4027,   4049,   4051,   4057,  &
661           4073,   4079,   4091,   4093,   4099,   4111,   4127,   4129,   4133,   4139,  &
662           4153,   4157,   4159,   4177,   4201,   4211,   4217,   4219,   4229,   4231,  &
663           4241,   4243,   4253,   4259,   4261,   4271,   4273,   4283,   4289,   4297,  &
664           4327,   4337,   4339,   4349,   4357,   4363,   4373,   4391,   4397,   4409,  &
665           4421,   4423,   4441,   4447,   4451,   4457,   4463,   4481,   4483,   4493,  &
666           4507,   4513,   4517,   4519,   4523,   4547,   4549,   4561,   4567,   4583,  &
667           4591,   4597,   4603,   4621,   4637,   4639,   4643,   4649,   4651,   4657,  &
668           4663,   4673,   4679,   4691,   4703,   4721,   4723,   4729,   4733,   4751,  &
669           4759,   4783,   4787,   4789,   4793,   4799,   4801,   4813,   4817,   4831,  &
670           4861,   4871,   4877,   4889,   4903,   4909,   4919,   4931,   4933,   4937,  &
671           4943,   4951,   4957,   4967,   4969,   4973,   4987,   4993,   4999,   5003,  &
672           5009,   5011,   5021,   5023,   5039,   5051,   5059,   5077,   5081,   5087,  &
673           5099,   5101,   5107,   5113,   5119,   5147,   5153,   5167,   5171,   5179,  &
674           5189,   5197,   5209,   5227,   5231,   5233,   5237,   5261,   5273,   5279,  &
675           5281,   5297,   5303,   5309,   5323,   5333,   5347,   5351,   5381,   5387,  &
676           5393,   5399,   5407,   5413,   5417,   5419,   5431,   5437,   5441,   5443,  &
677           5449,   5471,   5477,   5479,   5483,   5501,   5503,   5507,   5519,   5521,  &
678           5527,   5531,   5557,   5563,   5569,   5573,   5581,   5591,   5623,   5639,  &
679           5641,   5647,   5651,   5653,   5657,   5659,   5669,   5683,   5689,   5693,  &
680           5701,   5711,   5717,   5737,   5741,   5743,   5749,   5779,   5783,   5791,  &
681           5801,   5807,   5813,   5821,   5827,   5839,   5843,   5849,   5851,   5857,  &
682           5861,   5867,   5869,   5879,   5881,   5897,   5903,   5923,   5927,   5939,  &
683           5953,   5981,   5987,   6007,   6011,   6029,   6037,   6043,   6047,   6053,  &
684           6067,   6073,   6079,   6089,   6091,   6101,   6113,   6121,   6131,   6133,  &
685           6143,   6151,   6163,   6173,   6197,   6199,   6203,   6211,   6217,   6221,  &
686           6229,   6247,   6257,   6263,   6269,   6271,   6277,   6287,   6299,   6301,  &
687           6311,   6317,   6323,   6329,   6337,   6343,   6353,   6359,   6361,   6367,  &
688           6373,   6379,   6389,   6397,   6421,   6427,   6449,   6451,   6469,   6473,  &
689           6481,   6491,   6521,   6529,   6547,   6551,   6553,   6563,   6569,   6571,  &
690           6577,   6581,   6599,   6607,   6619,   6637,   6653,   6659,   6661,   6673,  &
691           6679,   6689,   6691,   6701,   6703,   6709,   6719,   6733,   6737,   6761,  &
692           6763,   6779,   6781,   6791,   6793,   6803,   6823,   6827,   6829,   6833,  &
693           6841,   6857,   6863,   6869,   6871,   6883,   6899,   6907,   6911,   6917,  &
694           6947,   6949,   6959,   6961,   6967,   6971,   6977,   6983,   6991,   6997,  &
695           7001,   7013,   7019,   7027,   7039,   7043,   7057,   7069,   7079,   7103,  &
696           7109,   7121,   7127,   7129,   7151,   7159,   7177,   7187,   7193,   7207,  &
697           7211,   7213,   7219,   7229,   7237,   7243,   7247,   7253,   7283,   7297,  &
698           7307,   7309,   7321,   7331,   7333,   7349,   7351,   7369,   7393,   7411,  &
699           7417,   7433,   7451,   7457,   7459,   7477,   7481,   7487,   7489,   7499,  &
700           7507,   7517,   7523,   7529,   7537,   7541,   7547,   7549,   7559,   7561,  &
701           7573,   7577,   7583,   7589,   7591,   7603,   7607,   7621,   7639,   7643,  &
702           7649,   7669,   7673,   7681,   7687,   7691,   7699,   7703,   7717,   7723,  &
703           7727,   7741,   7753,   7757,   7759,   7789,   7793,   7817,   7823,   7829,  &
704           7841,   7853,   7867,   7873,   7877,   7879,   7883,   7901,   7907,   7919 /)
705
706    !---- Interfaces - Overloaded ----!
707    Interface  Acosd
708       Module Procedure Acosd_dp
709       Module Procedure Acosd_sp
710    End Interface
711
712    Interface  Asind
713       Module Procedure Asind_dp
714       Module Procedure Asind_sp
715    End Interface
716
717    Interface  Atan2d
718       Module Procedure Atan2d_dp
719       Module Procedure Atan2d_sp
720    End Interface
721
722    Interface  Atand
723       Module Procedure Atand_dp
724       Module Procedure Atand_sp
725    End Interface
726
727    Interface  Cosd
728       Module Procedure Cosd_dp
729       Module Procedure Cosd_sp
730    End Interface
731
732    Interface  Sind
733       Module Procedure Sind_dp
734       Module Procedure Sind_sp
735    End Interface
736
737    Interface  Tand
738       Module Procedure Tand_dp
739       Module Procedure Tand_sp
740    End Interface
741
742    Interface  Negligible
743       Module Procedure Negligibler
744       Module Procedure Negligiblec
745    End Interface
746
747    Interface  Pythag
748       Module Procedure Pythag_dp
749       Module Procedure Pythag_sp
750    End Interface
751
752    Interface  Co_Linear
753       Module Procedure Co_linear_C
754       Module Procedure Co_linear_I
755       Module Procedure Co_linear_R
756    End Interface
757
758    Interface  Equal_Matrix
759       Module Procedure Equal_Matrix_I
760       Module Procedure Equal_Matrix_R
761    End Interface
762
763    Interface  Equal_Vector
764       Module Procedure Equal_Vector_I
765       Module Procedure Equal_Vector_R
766    End Interface
767
768    Interface  IMaxloc
769       Module Procedure IMaxloc_I
770       Module Procedure IMaxloc_R
771    End Interface
772
773    Interface  IMinloc
774       Module Procedure IMinloc_I
775       Module Procedure IMinloc_R
776    End Interface
777
778    Interface  Locate
779       Module Procedure Locate_I
780       Module Procedure Locate_R
781       Module Procedure Locate_Ib
782       Module Procedure Locate_Rb
783    End Interface
784
785    Interface  Lower_Triangular
786       Module Procedure Lower_Triangular_I
787       Module Procedure Lower_Triangular_R
788    End Interface
789
790    Interface Norm
791       Module Procedure Norm_I
792       Module Procedure Norm_R
793    End Interface Norm
794
795    Interface  Outerprod
796       Module Procedure Outerprod_dp
797       Module Procedure Outerprod_sp
798    End Interface
799
800    Interface Scalar
801       Module Procedure Scalar_I
802       Module Procedure Scalar_R
803    End Interface Scalar
804
805    Interface  Trace
806       Module Procedure Trace_C
807       Module Procedure Trace_I
808       Module Procedure Trace_R
809    End Interface
810
811    Interface  Upper_Triangular
812       Module Procedure Upper_Triangular_I
813       Module Procedure Upper_Triangular_R
814    End Interface
815
816    Interface  Zbelong
817       Module Procedure ZbelongM
818       Module Procedure ZbelongN
819       Module Procedure ZbelongV
820    End Interface
821
822    Interface  Rtan
823       Module Procedure Rtan_dp
824       Module Procedure Rtan_sp
825    End Interface
826
827    Interface  Determinant
828       Module Procedure Determinant_c
829       Module Procedure Determinant_r
830    End Interface
831
832    Interface  Diagonalize_SH
833       Module Procedure Diagonalize_HERM
834       Module Procedure Diagonalize_SYMM
835    End Interface
836
837    Interface In_Limits
838       Module Procedure In_Limits_int
839       Module Procedure In_Limits_dp
840       Module Procedure In_Limits_sp
841    End Interface
842
843    Interface  Linear_Dependent
844       Module Procedure Linear_Dependentc
845       Module Procedure Linear_Dependenti
846       Module Procedure Linear_Dependentr
847    End Interface
848
849    Interface  Rank
850       Module Procedure Rank_dp
851       Module Procedure Rank_sp
852    End Interface
853
854    Interface  Sort
855       Module Procedure Sort_I
856       Module Procedure Sort_R
857    End Interface
858
859    Interface  Svdcmp
860       Module Procedure Svdcmp_dp
861       Module Procedure Svdcmp_sp
862    End Interface
863
864    Interface Swap
865        Module Procedure swap_c
866        Module Procedure swap_cm
867        Module Procedure swap_cv
868        Module Procedure swap_i
869        Module Procedure swap_im
870        Module Procedure swap_iv
871        Module Procedure swap_r
872        Module Procedure swap_rm
873        Module Procedure swap_rv
874        Module Procedure masked_swap_r
875        Module Procedure masked_swap_rm
876        Module Procedure masked_swap_rv
877    End interface
878
879 Contains
880
881    !---- Functions ----!
882
883    !!----
884    !!---- Elemental Function Acosd(x) Result(arc_cos)
885    !!----    real(kind=sp/dp), intent(in) :: x
886    !!----    real(kind=sp/dp)             :: arc_cos
887    !!----
888    !!----    Inverse cosine function -> output in Degrees
889    !!----
890    !!---- Update: February - 2005
891    !!
892
893    !!--++
894    !!--++ Elemental Function Acosd_dp(x) Result(arc_cos)
895    !!--++    real(kind=dp), intent(in) :: x
896    !!--++    real(kind=dp)             :: arc_cos
897    !!--++
898    !!--++    (OVERLOADED)
899    !!--++    Inverse cosine function -> output in Degrees
900    !!--++
901    !!--++ Update: February - 2005
902    !!
903    Elemental Function Acosd_dp(x) Result(arc_cos)
904       !---- Argument ----!
905       real(kind=dp), intent(in) :: x
906       real(kind=dp)             :: arc_cos
907
908       if (abs(x) > 1.0_dp ) then
909          if (x > 0.0_dp)  then
910             arc_cos=0.0_dp
911          else
912             arc_cos=180.0_dp
913          end if
914       else
915          arc_cos=acos(x)*to_DEG
916       end if
917
918       return
919    End Function Acosd_dp
920
921    !!--++
922    !!--++ Elemental Function Acosd_sp(x) Result(arc_cos)
923    !!--++    real(kind=sp), intent(in) :: x
924    !!--++    real(kind=sp)             :: arc_cos
925    !!--++
926    !!--++    (OVERLOADED)
927    !!--++    Inverse cosine function -> output in Degrees
928    !!--++
929    !!--++ Update: February - 2005
930    !!
931    Elemental Function Acosd_sp(x) Result(arc_cos)
932       !---- Argument ----!
933       real(kind=sp), intent(in) :: x
934       real(kind=sp)             :: arc_cos
935
936       if (abs(x) > 1.0_sp ) then
937          if (x > 0.0_sp)  then
938             arc_cos=0.0_sp
939          else
940             arc_cos=180.0_sp
941          end if
942       else
943          arc_cos=acos(x)*to_DEG
944       end if
945
946       return
947    End Function Acosd_sp
948
949    !!----
950    !!---- Function Asind(x) Result(arc_sin)
951    !!----    real(kind=sp/dp), intent(in) :: x
952    !!----    real(kind=sp/dp)             :: arc_sin
953    !!----
954    !!----    Inverse sine function -> output in Degrees
955    !!----
956    !!---- Update: February - 2005
957    !!
958
959    !!--++
960    !!--++ Elemental Function Asind_dp(x) result(arc_sin)
961    !!--++    real(kind=dp), intent(in) :: x
962    !!--++    real(kind=dp)             :: arc_sin
963    !!--++
964    !!--++    (OVERLOADED)
965    !!--++    Inverse sine function -> output in Degrees
966    !!--++
967    !!--++ Update: February - 2005
968    !!
969    Elemental Function Asind_dp(x) Result(arc_sin)
970       !---- Argument ----!
971       real(kind=dp), intent(in) :: x
972       real(kind=dp)             :: arc_sin
973
974       if (abs(x) > 1.0_dp ) then
975          if (x > 0.0_dp) then
976             arc_sin=90.0_dp
977          else
978             arc_sin=-90.0_dp
979          end if
980       else
981          arc_sin=asin(x)*to_DEG
982       end if
983
984       return
985    End Function Asind_dp
986
987    !!--++
988    !!--++ Elemental Function Asind_sp(x) result(arc_sin)
989    !!--++    real(kind=sp), intent(in) :: x
990    !!--++    real(kind=sp)             :: arc_sin
991    !!--++
992    !!--++    (OVERLOADED)
993    !!--++    Inverse sine function -> output in Degrees
994    !!--++
995    !!--++ Update: February - 2005
996    !!
997    Elemental Function Asind_sp(x) Result(arc_sin)
998       !---- Argument ----!
999       real(kind=sp), intent(in) :: x
1000       real(kind=sp)             :: arc_sin
1001
1002       if (abs(x) > 1.0_sp ) then
1003          if (x > 0.0_sp) then
1004             arc_sin=90.0_sp
1005          else
1006             arc_sin=-90.0_sp
1007          end if
1008       else
1009          arc_sin=asin(x)*to_DEG
1010       end if
1011
1012       return
1013    End Function Asind_sp
1014
1015    !!----
1016    !!---- Elemental Function Atan2d(y,x) Result(atande)
1017    !!----    real(kind=sp/dp), intent(in) :: y,x
1018    !!----    real(kind=sp/dp)             :: atande
1019    !!----
1020    !!----    Inverse tangent function of y/x
1021    !!----    y,x have the same units -> output in Degrees
1022    !!----
1023    !!---- Update: February - 2005
1024    !!
1025
1026    !!--++
1027    !!--++ Elemental Function Atan2d_dp(y,x) Result(atande)
1028    !!--++    real(kind=dp), intent(in) :: y,x
1029    !!--++    real(kind=dp)             :: atande
1030    !!--++
1031    !!--++    (OVERLOADED)
1032    !!--++    Inverse tangent function of y/x
1033    !!--++    y,x have the same units -> output in Degrees
1034    !!--++
1035    !!--++ Update: February - 2005
1036    !!
1037    Elemental Function Atan2d_dp(y,x) Result(atand)
1038       !---- Argument ----!
1039       real(kind=dp), intent(in) :: y,x
1040       real(kind=dp)             :: atand
1041
1042       atand=atan2(y,x)*to_DEG
1043
1044       return
1045    End Function Atan2d_dp
1046
1047    !!--++
1048    !!--++ Elemental Function Atan2d_sp(y,x) Result(atande)
1049    !!--++    real(kind=sp), intent(in) :: y,x
1050    !!--++    real(kind=sp)             :: atande
1051    !!--++
1052    !!--++    (OVERLOADED)
1053    !!--++    Inverse tangent function of y/x
1054    !!--++    y,x have the same units -> output in Degrees
1055    !!--++
1056    !!--++ Update: February - 2005
1057    !!
1058    Elemental Function Atan2d_sp(y,x) Result(atande)
1059       !---- Argument ----!
1060       real(kind=sp), intent(in) :: y,x
1061       real(kind=sp)             :: atande
1062
1063       atande=atan2(y,x)*to_DEG
1064
1065       return
1066    End Function Atan2d_sp
1067
1068    !!----
1069    !!---- Elemental Function Atand(x) Result(atande)
1070    !!----    real(kind=sp/dp), intent(in) :: x
1071    !!----    real(kind=sp/dp)             :: atande
1072    !!----
1073    !!----    Inverse tangent function, X no units -> output in Degrees
1074    !!----
1075    !!---- Update: February - 2005
1076    !!
1077
1078    !!--++
1079    !!--++ Elemental Function Atand_dp(x) result(atande)
1080    !!--++    real(kind=dp), intent(in) :: x
1081    !!--++    real(kind=dp)             :: atande
1082    !!--++
1083    !!--++    (OVERLOADED)
1084    !!--++    Inverse tangent function, X no units -> output in Degrees
1085    !!--++
1086    !!--++ Update: February - 2005
1087    !!
1088    Elemental Function Atand_dp(x) Result(atand)
1089       !---- Argument ----!
1090       real(kind=dp), intent(in) :: x
1091       real(kind=dp)             :: atand
1092
1093       atand=atan(x)*to_DEG
1094
1095       return
1096    End Function Atand_dp
1097
1098    !!--++
1099    !!--++ Function Atand_sp(x) result(atande)
1100    !!--++    real(kind=sp), intent(in) :: x
1101    !!--++    real(kind=sp)             :: atande
1102    !!--++
1103    !!--++    (OVERLOADED)
1104    !!--++    Inverse tangent function, X no units -> output in Degrees
1105    !!--++
1106    !!--++ Update: February - 2005
1107    !!
1108    Elemental Function Atand_sp(x) Result(atande)
1109       !---- Argument ----!
1110       real(kind=sp), intent(in) :: x
1111       real(kind=sp)             :: atande
1112
1113       atande=atan(x)*to_DEG
1114
1115       return
1116    End Function Atand_sp
1117
1118
1119
1120    !!----
1121    !!---- Elemental Function Cosd(x) Result(cosine)
1122    !!----    real(kind=sp/dp), intent(in) :: x
1123    !!----    real(kind=sp/dp)             :: cosine
1124    !!----
1125    !!----    Cosine function, X in degrees
1126    !!----
1127    !!---- Update: February - 2005
1128    !!
1129
1130    !!--++
1131    !!--++ Elemental Function Cosd_dp(x) Result(cosine)
1132    !!--++    real(kind=dp), intent(in) :: x
1133    !!--++    real(kind=dp)             :: cosine
1134    !!--++
1135    !!--++    (OVERLOADED)
1136    !!--++    Cosine function, X in degrees
1137    !!--++
1138    !!--++ Update: February - 2005
1139    !!
1140    Elemental Function Cosd_dp(x) Result(cosine)
1141       !---- Argument ----!
1142       real(kind=dp), intent(in) :: x
1143       real(kind=dp)             :: cosine
1144
1145       cosine=cos(to_RAD*x)
1146
1147       return
1148    End Function Cosd_dp
1149
1150    !!--++
1151    !!--++ Elemental Function Cosd_sp(x) Result(cosine)
1152    !!--++    real(kind=sp), intent(in) :: x
1153    !!--++    real(kind=sp)             :: cosine
1154    !!--++
1155    !!--++    (OVERLOADED)
1156    !!--++    Cosine function, X in degrees
1157    !!--++
1158    !!--++ Update: February - 2005
1159    !!
1160    Elemental Function Cosd_sp(x) Result(cosine)
1161       !---- Argument ----!
1162       real(kind=sp), intent(in) :: x
1163       real(kind=sp)             :: cosine
1164
1165       cosine=cos(to_RAD*x)
1166
1167       return
1168    End Function Cosd_sp
1169
1170    !!----
1171    !!---- Elemental Function Sind(x) Result(sine)
1172    !!----    real(kind=sp/dp), intent(in) :: x
1173    !!----    real(kind=sp/dp)             :: sine
1174    !!----
1175    !!----    Sine function, X in degrees
1176    !!----
1177    !!---- Update: February - 2005
1178    !!
1179
1180    !!--++
1181    !!--++ Elemental Function Sind_dp(x) Result(sine)
1182    !!--++    real(kind=dp), intent(in) :: x
1183    !!--++    real(kind=dp)             :: sine
1184    !!--++
1185    !!--++    (OVERLOADED)
1186    !!--++    Sine function, X in degrees
1187    !!--++
1188    !!--++ Update: February - 2005
1189    !!
1190    Elemental Function Sind_dp(x) Result(sine)
1191       !---- Argument ----!
1192       real(kind=dp), intent(in) :: x
1193       real(kind=dp)             :: sine
1194
1195       sine=sin(to_RAD*x)
1196
1197       return
1198    End Function Sind_dp
1199
1200    !!--++
1201    !!--++ Elemental Function Sind_sp(x) Result(sine)
1202    !!--++    real(kind=sp), intent(in) :: x
1203    !!--++    real(kind=sp)             :: sine
1204    !!--++
1205    !!--++    (OVERLOADED)
1206    !!--++    Sine function, X in degrees
1207    !!--++
1208    !!--++ Update: February - 2005
1209    !!
1210    Elemental Function Sind_sp(x) Result(sine)
1211       !---- Argument ----!
1212       real(kind=sp), intent(in) :: x
1213       real(kind=sp)             :: sine
1214
1215       sine=sin(to_RAD*x)
1216
1217       return
1218    End Function Sind_sp
1219
1220    !!----
1221    !!---- Elemental Function Tand(x) Result(tande)
1222    !!----    real(kind=sp/dp), intent(in) :: x
1223    !!----    real(kind=sp/dp)             :: tande
1224    !!----
1225    !!----    Tangent function, X in degrees
1226    !!----
1227    !!---- Update: February - 2005
1228    !!
1229
1230    !!--++
1231    !!--++ Elemental Function Tand_dp(x) Result(tande)
1232    !!--++    real(kind=dp), intent(in) :: x
1233    !!--++    real(kind=dp)             :: tande
1234    !!--++
1235    !!--++    (OVERLOADED)
1236    !!--++    Tangent function, X in degrees
1237    !!--++
1238    !!--++ Update: February - 2005
1239    !!
1240    Elemental Function Tand_dp(x) Result(tand)
1241       !---- Argument ----!
1242       real(kind=dp), intent(in) :: x
1243       real(kind=dp)             :: tand
1244
1245       tand=tan(to_RAD*x)
1246
1247       return
1248    End Function Tand_dp
1249
1250    !!--++
1251    !!--++ Elemental Function Tand_sp(x) Result(tande)
1252    !!--++    real(kind=sp), intent(in) :: x
1253    !!--++    real(kind=sp)             :: tande
1254    !!--++
1255    !!--++    (OVERLOADED)
1256    !!--++    Tangent function, X in degrees
1257    !!--++
1258    !!--++ Update: February - 2005
1259    !!
1260    Elemental Function Tand_sp(x) Result(tande)
1261       !---- Argument ----!
1262       real(kind=sp), intent(in) :: x
1263       real(kind=sp)             :: tande
1264
1265       tande=tan(to_RAD*x)
1266
1267       return
1268    End Function Tand_sp
1269
1270    !!----
1271    !!---- Elemental Function BessJ0(x) Result(bessj_0)
1272    !!----    real(kind=sp), intent(in) :: x
1273    !!----    real(kind=sp)             :: bessj_0
1274    !!----
1275    !!----    Bessel Fuction J0(x)
1276    !!----
1277    !!---- Update: February - 2005
1278    !!
1279    Elemental Function BessJ0(x) Result(bessj_0)
1280       !---- Arguments ----!
1281       real(kind=cp), intent(in) :: x
1282       real(kind=cp)             :: bessj_0
1283
1284       !---- Local variables ----!
1285       real(kind=dp), parameter :: p1=   1.0_dp
1286       real(kind=dp), parameter :: p2=  -0.1098628627e-2_dp
1287       real(kind=dp), parameter :: p3=   0.2734510407e-4_dp
1288       real(kind=dp), parameter :: p4=  -0.2073370639e-5_dp
1289       real(kind=dp), parameter :: p5=   0.2093887211e-6_dp
1290       real(kind=dp), parameter :: q1=  -0.1562499995e-1_dp
1291       real(kind=dp), parameter :: q2=   0.1430488765e-3_dp
1292       real(kind=dp), parameter :: q3=  -0.6911147651e-5_dp
1293       real(kind=dp), parameter :: q4=   0.7621095161e-6_dp
1294       real(kind=dp), parameter :: q5=  -0.934945152e-7_dp
1295       real(kind=dp), parameter :: r1=   57568490574.0_dp
1296       real(kind=dp), parameter :: r2=  -13362590354.0_dp ! corrected by LCC and ADA 16 june 2004
1297       real(kind=dp), parameter :: r3=     651619640.7_dp
1298       real(kind=dp), parameter :: r4=     -11214424.18_dp
1299       real(kind=dp), parameter :: r5=         77392.33017_dp
1300       real(kind=dp), parameter :: r6=          -184.9052456_dp
1301       real(kind=dp), parameter :: s1=   57568490411.0_dp
1302       real(kind=dp), parameter :: s2=    1029532985.0_dp
1303       real(kind=dp), parameter :: s3=       9494680.718_dp
1304       real(kind=dp), parameter :: s4=         59272.64853_dp
1305       real(kind=dp), parameter :: s5=           267.8532712_dp
1306       real(kind=dp), parameter :: s6=             1.0_dp
1307
1308       real(kind=dp)            :: y
1309       real(kind=cp)            :: ax, xx, z
1310
1311       if (abs(x) < 1.0e-05) then
1312          bessj_0=1.0
1313          return
1314       end if
1315       if (abs(x) < 8.0)then
1316          y=x**2
1317          bessj_0=(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))))/(s1+y*(s2+y*(s3+y*  &
1318                  (s4+y*(s5+y*s6)))))
1319       else
1320          ax=abs(x)
1321          z=8.0/ax
1322          y=z**2
1323          xx=ax-0.785398164
1324          bessj_0=sqrt(0.636619772/ax)*(cos(xx)*(p1+y*(p2+y*(p3+y*(p4+y*  &
1325                  p5))))-z*sin(xx)*(q1+y*(q2+y*(q3+y*(q4+y*q5)))))
1326       end if
1327
1328       return
1329    End Function BessJ0
1330
1331    !!----
1332    !!---- Elemental Function BessJ1(x) Result(bessj_1)
1333    !!----    real(kind=sp), intent(in) : x
1334    !!----    real(kind=sp)             : bessj_1
1335    !!----
1336    !!----    Bessel Fuction J1(x)
1337    !!----
1338    !!---- Update: February - 2005
1339    !!
1340    Elemental Function BessJ1(x) Result(bessj_1)
1341       !---- Arguments ----!
1342       real(kind=cp), intent(in) :: x
1343       real(kind=cp)             :: bessj_1
1344
1345       !---- Local variales ----!
1346       real(kind=dp), parameter :: p1= 1.0_dp
1347       real(kind=dp), parameter :: p2=  0.183105e-2_dp
1348       real(kind=dp), parameter :: p3= -0.3516396496e-4_dp
1349       real(kind=dp), parameter :: p4=  0.2457520174e-5_dp
1350       real(kind=dp), parameter :: p5= -0.240337019e-6_dp
1351       real(kind=dp), parameter :: q1=  0.04687499995_dp
1352       real(kind=dp), parameter :: q2= -0.2002690873e-3_dp
1353       real(kind=dp), parameter :: q3=  0.8449199096e-5_dp
1354       real(kind=dp), parameter :: q4= -0.88228987e-6_dp
1355       real(kind=dp), parameter :: q5=  0.105787412e-6_dp
1356       real(kind=dp), parameter :: r1=  72362614232.0_dp
1357       real(kind=dp), parameter :: r2=  -7895059235.0_dp
1358       real(kind=dp), parameter :: r3=    242396853.1_dp
1359       real(kind=dp), parameter :: r4=     -2972611.439_dp
1360       real(kind=dp), parameter :: r5=        15704.48260_dp
1361       real(kind=dp), parameter :: r6=          -30.16036606_dp
1362       real(kind=dp), parameter :: s1= 144725228442.0_dp
1363       real(kind=dp), parameter :: s2=   2300535178.0_dp
1364       real(kind=dp), parameter :: s3=     18583304.74_dp
1365       real(kind=dp), parameter :: s4=        99447.43394_dp
1366       real(kind=dp), parameter :: s5=          376.9991397_dp
1367       real(kind=dp), parameter :: s6=            1.0_dp
1368
1369       real(kind=dp)            :: y
1370       real(kind=cp)            :: ax,xx,z
1371
1372       if (abs(x) < 1.0e-05) then
1373          bessj_1=0.0
1374          return
1375       end if
1376       if (abs(x) < 8.0)then
1377          y=x**2
1378          bessj_1=x*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))))/(s1+y*(s2+y*(s3+  &
1379                  y*(s4+y*(s5+y*s6)))))
1380       else
1381          ax=abs(x)
1382          z=8.0/ax
1383          y=z**2
1384          xx=ax-2.356194491
1385          bessj_1=sqrt(0.636619772/ax)*(cos(xx)*(p1+y*(p2+y*(p3+y*(p4+y*p5))))  &
1386                       -z*sin(xx)*(q1+y*(q2+y*(q3+y*(q4+y*q5)))))*sign(1.0_cp,x)
1387       end if
1388
1389       return
1390    End Function BessJ1
1391
1392    !!----
1393    !!---- Function BessJ(n,x) Result (bessj)
1394    !!----    real(kind=cp), intent(in) : x
1395    !!----    real(kind=cp)             : bessj
1396    !!----
1397    !!----    Bessel Fuction Jn(x)
1398    !!----    Returns the Bessel function Jn(x) for any real x and n >= 2.
1399    !!----
1400    !!----  Update:  June - 2004
1401    !!
1402    Function BessJ(n,x) Result(bessj_n)
1403       !---- Arguments ----!
1404       integer,        intent(in)  :: n
1405       real (kind=cp), intent(in)  :: x
1406       real (kind=cp)              :: bessj_n
1407
1408       !---- Local Arguments ----!
1409       integer,    parameter       :: iacc=40
1410       integer                     :: j,jsum,m
1411       real (kind=cp), parameter   :: bigno=1.e10,bigni=1.e-10
1412       real (kind=cp)              :: ax,bj,bjm,suma,tox
1413       real (kind=cp), save        :: bjp
1414
1415       if (n==0) then
1416          bessj_n=Bessj0(x)
1417          return
1418       else if (n==1) then
1419          bessj_n=Bessj1(x)
1420          return
1421       end if
1422
1423       ax=abs(x)
1424       if (ax==0.0)then
1425          bessj_n=0.0
1426          return
1427
1428       else if (ax > float(n))then ! Upwards recurrence from J0 and J1.
1429          tox=2./ax
1430          bjm=bessj0(ax)
1431          bj=bessj1(ax)
1432          do j=1,n-1
1433             bjp=j*tox*bj-bjm
1434             bjm=bj
1435             bj=bjp
1436          end do
1437          bessj_n=bj
1438          return
1439
1440       else ! Downwards recurrence from an even m here computed.
1441            !Make IACC larger to increase accuracy.
1442          tox=2./ax
1443          m=2*((n+int(sqrt(float(IACC*n))))/2)
1444          bessj_n=0.
1445          jsum=0       !jsum will alternate between 0 and 1; when it is 1, we
1446                       !accumulate in sum the even terms in (5.5.16).
1447          suma=0.
1448          bjp=0.
1449          bj=1.0
1450          do j=m,1,-1 ! The downward recurrence.
1451             bjm=j*tox*bj-bjp
1452             bjp=bj
1453             bj=bjm
1454             if (abs(bj)>BIGNO) then ! Renormalize to prevent overflows.
1455                bj=bj*BIGNI
1456                bjp=bjp*BIGNI
1457                bessj_n=bessj_n*BIGNI
1458                suma=suma*BIGNI
1459             end if
1460             if (jsum/=0) suma=suma+bj  ! Accumulate the sum.
1461             jsum=1-jsum                ! Change 0 to 1 or vice versa.
1462             if (j==n) bessj_n=bjp      ! the unnormalized answer.
1463          end do
1464          suma=2.*suma-bj          ! Compute (5.5.16)
1465          bessj_n=bessj_n/suma     ! and use it to normalize the answer.
1466       end if
1467       if ((x<0.0).and.(mod(n,2)==1)) bessj_n=-bessj_n
1468       return
1469    End Function BessJ
1470
1471    !!----
1472    !!---- Function ERF(X)
1473    !!----    real(kind=cp), intent(in) : x
1474    !!----    real(kind=cp)             : Erf
1475    !!----
1476    !!----    Error Function
1477    !!----    Returns the Error Function
1478    !!----
1479    !!----  Update:  January - 2016
1480    !!----
1481    Elemental Function Erf(X) Result(Fn_Val)
1482       !---- Arguments ----!
1483       real (kind=cp), intent(in) :: x
1484       real (kind=cp)             :: fn_Val
1485
1486       !---- Local Variables ----!
1487       real (kind=cp), parameter :: C    = 0.564189583547756_cp
1488       real (kind=cp), parameter :: ONE  = 1.0_cp
1489       real (kind=cp), parameter :: HALF = 0.5_cp
1490       real (kind=cp), parameter :: ZERO = 0.0_cp
1491
1492       real (kind=dp), parameter :: A(5) = (/0.771058495001320D-04, -0.133733772997339D-02, 0.323076579225834D-01, &
1493                                             0.479137145607681D-01,  0.128379167095513D+00 /)
1494       real (kind=dp), parameter :: B(3) = (/0.301048631703895D-02,  0.538971687740286D-01, 0.375795757275549D+00 /)
1495       real (kind=dp), parameter :: P(8) = (/-1.36864857382717D-07,  5.64195517478974D-01,  7.21175825088309D+00, &
1496                                              4.31622272220567D+01,  1.52989285046940D+02,  3.39320816734344D+02, &
1497                                              4.51918953711873D+02,  3.00459261020162D+02 /)
1498       real (kind=dp), parameter :: Q(8) = (/ 1.00000000000000D+00,  1.27827273196294D+01,  7.70001529352295D+01, &
1499                                              2.77585444743988D+02,  6.38980264465631D+02,  9.31354094850610D+02, &
1500                                              7.90950925327898D+02,  3.00459260956983D+02 /)
1501       real (kind=dp), parameter :: R(5) = (/ 2.10144126479064D+00,  2.62370141675169D+01,  2.13688200555087D+01, &
1502                                              4.65807828718470D+00,  2.82094791773523D-01 /)
1503       real (kind=dp), parameter :: S(4) = (/ 9.41537750555460D+01,  1.87114811799590D+02,  9.90191814623914D+01, &
1504                                              1.80124575948747D+01 /)
1505
1506       real (kind=cp) :: ax, bot, t, top, x2
1507
1508       !> Init
1509       ax = ABS(x)
1510
1511       if (ax <= half) then
1512          t = x*x
1513          top = ((((a(1)*t + a(2))*t + a(3))*t + a(4))*t + a(5)) + one
1514          bot = ((b(1)*t + b(2))*t + b(3))*t + one
1515          fn_val = x*(top/bot)
1516          return
1517       end if
1518
1519       if (ax <= 4.0_cp) then
1520          top = ((((((p(1)*ax + p(2))*ax + p(3))*ax + p(4))*ax + p(5))*ax  &
1521              + p(6))*ax + p(7))*ax + p(8)
1522          bot = ((((((q(1)*ax + q(2))*ax + q(3))*ax + q(4))*ax + q(5))*ax  &
1523              + q(6))*ax + q(7))*ax + q(8)
1524
1525          fn_val = half + (half - exp(-x*x)*top/bot)
1526          if (x < zero) fn_val = -fn_val
1527          return
1528       end if
1529
1530       if (ax < 5.8_cp) then
1531          x2 = x*x
1532          t = one / x2
1533          top = (((r(1)*t + r(2))*t + r(3))*t + r(4))*t + r(5)
1534          bot = (((s(1)*t + s(2))*t + s(3))*t + s(4))*t + one
1535          fn_val = (c - top/(x2*bot)) / ax
1536          fn_val = half + (half - exp(-x2)*fn_val)
1537          if (x < zero) fn_val = -fn_val
1538          return
1539       end if
1540
1541       fn_val = SIGN(one, x)
1542       return
1543    End Function Erf
1544
1545    !!----
1546    !!---- Elemental Function Factorial(n) Result(fact)
1547    !!----    integer, intent(in) : n
1548    !!----
1549    !!----    Factorial of N
1550    !!----
1551    !!---- Update: February - 2005
1552    !!
1553    Elemental Function Factorial(n) Result(fact)
1554       !---- Argument ----!
1555       integer, intent(in) :: n
1556       integer             :: fact
1557
1558       !---- Local variables ----!
1559       integer   :: nt, np
1560
1561       if (n ==0) then
1562          fact=1
1563       else
1564          nt=1
1565          np=abs(n)
1566          do
1567             nt=nt*np
1568             np=np-1
1569             if(np == 1) exit
1570          end do
1571          fact=nt
1572       end if
1573
1574       return
1575    End Function Factorial
1576
1577    !!----
1578    !!---- Elemental Function Negligible(v)
1579    !!----    complex/real(kind=sp),    intent( in) :: v
1580    !!----
1581    !!----    Provides the value .TRUE. if the real/complex
1582    !!----    number V is less than EPS
1583    !!----
1584    !!---- Update: February - 2005
1585    !!
1586
1587    !!--++
1588    !!--++ Elemental Function Negligiblec(v)
1589    !!--++    complex, intent( in) :: v
1590    !!--++
1591    !!--++    (OVERLOADED)
1592    !!--++    Calculate if a complex number is negligible
1593    !!--++
1594    !!--++ Update: February - 2005
1595    !!
1596    Elemental Function Negligiblec(v) Result(Neglig)
1597       !---- Argument ----!
1598       complex, intent( in) :: v
1599       logical              :: Neglig
1600
1601       Neglig=.false.
1602       if (abs(v) > epss) return
1603       Neglig=.true.
1604
1605       return
1606    End Function Negligiblec
1607
1608    !!--++
1609    !!--++ Elemental Function Negligibler(v)
1610    !!--++    real(kind=cp), intent( in) :: v
1611    !!--++
1612    !!--++    (OVERLOADED)
1613    !!--++    Determines if a real number is negligible (abs < EPSS)
1614    !!--++
1615    !!--++ Update: February - 2005
1616    !!
1617    Elemental Function Negligibler(v) Result(neglig)
1618       !---- Argument ----!
1619       real(kind=cp), intent( in) :: v
1620       logical                    :: Neglig
1621
1622       Neglig=.false.
1623       if (abs(v) > epss) return
1624       Neglig=.true.
1625
1626       return
1627    End Function Negligibler
1628
1629    !!----
1630    !!---- Function Pgcd(i,j) Result(mcd)
1631    !!----    integer, intent(in) :: i
1632    !!----    integer, intent(in) :: j
1633    !!----    integer             :: mcd
1634    !!----
1635    !!----    Function calculating the maximum common divisor of two integers
1636    !!----
1637    !!---- Update: February - 2005
1638    !!
1639    Function Pgcd(a,b) Result(mcd)
1640       !---- Arguments ----!
1641       integer, intent(in) :: a,b
1642       integer             :: mcd
1643
1644       !---- Local variables ----!
1645       integer  :: u,v,m
1646
1647       u=max(a,b)
1648       v=min(a,b)
1649       m=0
1650       do
1651          if (m == 1) exit
1652          m=mod(u,v)
1653          u=v
1654          v=m
1655       end do
1656       mcd=u
1657
1658       return
1659    End Function Pgcd
1660
1661    !!----
1662    !!---- Function Ppcm(i,j) result(mcm)
1663    !!----    integer, intent(in) :: i
1664    !!----    integer, intent(in) :: j
1665    !!----    integer             :: mcm
1666    !!----
1667    !!----    Function calculating the minimum common multiple of two integers
1668    !!----
1669    !!---- Update: February - 2005
1670    !!
1671    Function Ppcm(a,b) result(mcm)
1672       !---- Arguments ----!
1673       integer, intent(in) :: a,b
1674       integer             :: mcm
1675
1676       !---- Local variables ----!
1677       integer :: u,v,w,i
1678
1679       u=max(a,b)
1680       v=min(a,b)
1681       mcm=1
1682       if (v <= 1) then
1683          mcm=u
1684          return
1685       end if
1686       w=int(sqrt(real(u)))+1
1687       do i=2,w
1688          do
1689             if(.not. ((mod(u,i)==0) .or. (mod(v,i)==0)) ) exit
1690             mcm=mcm*i
1691             if (modulo(u,i) == 0) u=u/i
1692             if (modulo(v,i) == 0) v=v/i
1693          end do
1694       end do
1695
1696       return
1697    End Function Ppcm
1698
1699    !!----
1700    !!---- Function Pythag(a,b) Result (c)
1701    !!----    real(sp/dp),intent(in):: a,b
1702    !!----    real(sp/dp)           :: c
1703    !!--<<
1704    !!----    Computes c=sqrt(a^2 +b^2 ) without destructive underflow or overflow.
1705    !!----    Adapted from Numerical Recipes.
1706    !!-->>
1707    !!----
1708    !!---- Update: February - 2005
1709    !!
1710
1711    !!--++
1712    !!--++ Function Pythag_dp(a,b) Result (c)
1713    !!--++    real(dp),intent(in):: a,b
1714    !!--++    real(dp)           :: c
1715    !!--++
1716    !!--++    (OVERLOADED)
1717    !!--++    Computes c=sqrt(a^2 +b^2 ) without destructive underflow or overflow.
1718    !!--++    Adapted from Numerical Recipes.
1719    !!--++
1720    !!--++ Update: February - 2005
1721    !!
1722    Function Pythag_dp(a,b) Result (c)
1723       !---- Arguments ----!
1724       real(kind=dp),intent(in):: a,b
1725       real(kind=dp)           :: c
1726
1727       !---- Local variables ----!
1728       real(kind=dp)           :: absa,absb
1729
1730       absa=abs(a)
1731       absb=abs(b)
1732       if (absa >absb)then
1733          c=absa*sqrt(1.0_dp+(absb/absa)**2)
1734       else
1735          if (absb < tiny(1.0_dp))then
1736             c=0.0
1737          else
1738             c=absb*sqrt(1.0_dp+(absa/absb)**2)
1739          end if
1740       end if
1741
1742       return
1743    End Function Pythag_dp
1744
1745    !!--++
1746    !!--++ Function Pythag_sp(a,b) result (c)
1747    !!--++    real(sp),intent(in):: a,b
1748    !!--++    real(sp)           :: c
1749    !!--++
1750    !!--++    (OVERLOADED)
1751    !!--++    Computes c=sqrt(a^2 +b^2 ) without destructive underflow or overflow.
1752    !!--++    Adapted from Numerical Recipes.
1753    !!--++
1754    !!--++ Update: February - 2005
1755    !!
1756    Function Pythag_sp(a,b) Result (c)
1757       !---- Arguments ----!
1758       real(kind=sp),intent(in):: a,b
1759       real(kind=sp)           :: c
1760
1761       !---- Local variables ----!
1762       real(kind=sp)           :: absa,absb
1763
1764       absa=abs(a)
1765       absb=abs(b)
1766       if (absa > absb) then
1767          c=absa*sqrt(1.0_sp+(absb/absa)**2)
1768       else
1769          if (absb < tiny(1.0_sp)) then
1770             c=0.0
1771          else
1772             c=absb*sqrt(1.0_sp+(absa/absb)**2)
1773          end if
1774       end if
1775
1776       return
1777    End Function Pythag_sp
1778
1779    !!----
1780    !!---- Logical Function Co_Linear(A,B,N)
1781    !!----    complex/integer/real(kind=sp), dimension(:), intent(in)  :: a
1782    !!----    complex/integer/real(kind=sp), dimension(:), intent(in)  :: b
1783    !!----    integer,                                     intent(in)  :: n
1784    !!----
1785    !!----    Provides the value .TRUE. if the vectors A and B are co-linear
1786    !!----
1787    !!---- Update: February - 2005
1788    !!
1789
1790    !!--++
1791    !!--++ Logical Function Co_Linear_C(A, B, N)
1792    !!--++    complex, dimension(:), intent(in)  :: a
1793    !!--++    complex, dimension(:), intent(in)  :: b
1794    !!--++    integer,               intent(in)  :: n
1795    !!--++
1796    !!--++    (OVERLOADED)
1797    !!--++    Determines if two complex vectors are co-linear
1798    !!--++
1799    !!--++ Update: February - 2005
1800    !!
1801    Function Co_linear_C(a,b,n) Result(co_linear)
1802       !---- Argument ----!
1803       complex, dimension(:), intent(in) :: a,b
1804       integer,               intent(in) :: n
1805       logical                           :: co_linear
1806
1807       !---- Local variables ----!
1808       integer :: i,ia,ib
1809       complex :: c
1810
1811       co_linear=.true.
1812       do i=1,n
1813          if (abs(a(i)) > epss) then
1814             ia=i
1815             exit
1816          end if
1817       end do
1818       do i=1,n
1819          if (abs(b(i)) > epss) then
1820             ib=i
1821             exit
1822          end if
1823       end do
1824       if (ia /= ib) then
1825          co_linear=.false.
1826          return
1827       else
1828          c=a(ia)/b(ib)
1829          do i=1,n
1830             if (abs(a(i)-c*b(i)) > epss) then
1831                co_linear=.false.
1832                return
1833             end if
1834          end do
1835       end if
1836
1837       return
1838    End Function Co_linear_C
1839
1840    !!--++
1841    !!--++ Logical Function Co_Linear_I(A, B, N)
1842    !!--++    integer, dimension(:), intent(in)  :: a
1843    !!--++    integer, dimension(:), intent(in)  :: b
1844    !!--++    integer,               intent(in)  :: n
1845    !!--++
1846    !!--++    (OVERLOADED)
1847    !!--++    Determines if two integer vectors are co-linear
1848    !!--++
1849    !!--++ Update: October - 2008
1850    !!
1851    Function Co_linear_I(a,b,n) Result(co_linear)
1852       !---- Argument ----!
1853       integer, dimension(:), intent(in) :: a,b
1854       integer,               intent(in) :: n
1855       logical                           :: co_linear
1856
1857       !---- Local variables ----!
1858       integer       :: i,ia,ib
1859       real(kind=cp) :: c
1860
1861       co_linear=.true.
1862       do i=1,n
1863          if (abs(a(i)) > 0) then
1864             ia=i
1865             exit
1866          end if
1867       end do
1868       do i=1,n
1869          if (abs(b(i)) > 0) then
1870             ib=i
1871             exit
1872          end if
1873       end do
1874       if (ia /= ib) then
1875          co_linear=.false.
1876          return
1877       else
1878          c=real(a(ia))/real(b(ib))
1879          do i=1,n
1880             if (abs( real(a(i))-c*real(b(i)) ) > epss) then
1881                co_linear=.false.
1882                return
1883             end if
1884          end do
1885       end if
1886
1887       return
1888    End Function Co_linear_I
1889
1890    !!--++
1891    !!--++ Logical Function Co_Linear_R(A, B, N)
1892    !!--++    real(kind=cp), dimension(:), intent(in)  :: a
1893    !!--++    real(kind=cp), dimension(:), intent(in)  :: b
1894    !!--++    integer,                     intent(in)  :: n
1895    !!--++
1896    !!--++    (OVERLOADED)
1897    !!--++    Determines if two real vectors are co-linear
1898    !!--++
1899    !!--++ Update: February - 2005
1900    !!
1901    Function Co_linear_R(a,b,n) Result(co_linear)
1902       !---- Argument ----!
1903       real(kind=cp), dimension(:), intent(in) :: a,b
1904       integer,                     intent(in) :: n
1905       logical                                 :: co_linear
1906
1907       !---- Local variables ----!
1908       integer       :: i,ia,ib
1909       real(kind=cp) :: c
1910
1911       co_linear=.true.
1912       do i=1,n
1913          if (abs(a(i)) > epss) then
1914             ia=i
1915             exit
1916          end if
1917       end do
1918       do i=1,n
1919          if (abs(b(i)) > epss) then
1920             ib=i
1921             exit
1922          end if
1923       end do
1924       if (ia /= ib) then
1925          co_linear=.false.
1926          return
1927       else
1928          c=a(ia)/b(ib)
1929          do i=1,n
1930             if (abs(a(i)-c*b(i)) > epss) then
1931                co_linear=.false.
1932                return
1933             end if
1934          end do
1935       end if
1936
1937       return
1938    End Function Co_linear_R
1939
1940    !!----
1941    !!---- Function Co_Prime(v,imax) result(cop)
1942    !!----   integer, dimension(:), intent(in) :: v
1943    !!----   integer,  optional,    intent(in) :: imax !Maximun prime number to be tested
1944    !!----   Logical                           :: cop
1945    !!----
1946    !!---- Provides the value .TRUE. if the array V contains co-prime
1947    !!---- integers: there is no common divisor for all the integers.
1948    !!---- Only the first 1000 prime numbers are stored in the module array "primes"
1949    !!---- imax is the maximum prime number to be tested. It is calculated if not given.
1950    !!----
1951    !!---- Created: January - 2011
1952    !!---- Updated: February - 2012  (JRC) (imax argument made optional, really not needed)
1953    !!
1954    Function Co_Prime(v,imax) result(cop)
1955      integer, dimension(:), intent(in) :: v
1956      integer, optional,     intent(in) :: imax
1957      Logical                           :: cop
1958      !---- Local variables ----!
1959      integer :: i,j,im,k,dimv,imaxv,maxv
1960
1961      cop=.true.
1962      maxv=maxval(abs(v))
1963      if(present(imax)) then
1964        imaxv=imax
1965      else
1966        imaxv=maxv
1967      end if
1968      !---- If the maximum value of the indices is 1 they are coprimes
1969      if (maxv == 1) return
1970      if (maxv == 0) then
1971         cop=.false.
1972         return
1973      end if
1974      !---- Search the maximum prime number to be tested
1975      if (imaxv > 7919) then
1976        im=1000
1977      else
1978        do i=1,1000
1979           if(imaxv > primes(i)) cycle
1980           im=i
1981           exit
1982        end do
1983      end if
1984
1985      !---- Indices greater than 1
1986      dimv=size(v)
1987      do_p: do i=1,im
1988         k=primes(i)
1989         do j=1,dimv
1990            if( mod(v(j),k) /= 0) cycle do_p
1991         end do
1992         cop=.false.
1993         exit
1994      end do do_p
1995
1996      return
1997    End Function Co_Prime
1998
1999    !!----
2000    !!---- Logical Function Equal_Matrix(A,B,N)
2001    !!----    integer/real(kind=cp), dimension(:,:), intent(in)  :: a,b
2002    !!----    integer,                               intent(in)  :: n
2003    !!----
2004    !!----    Provides the value .TRUE. if the array A is equal to array B
2005    !!----
2006    !!---- Update: February - 2005
2007    !!
2008
2009    !!--++
2010    !!--++ Logical Function Equal_Matrix_I(A, B, N)
2011    !!--++    integer, dimension(:,:), intent(in)  :: a
2012    !!--++    integer, dimension(:,:), intent(in)  :: b
2013    !!--++    integer,                 intent(in)  :: n
2014    !!--++
2015    !!--++    (OVERLOADED)
2016    !!--++    Determines if two integer arrays are equal in NxN
2017    !!--++
2018    !!--++ Update: February - 2005
2019    !!
2020    Function Equal_Matrix_I(a,b,n) result(info)
2021       !---- Argument ----!
2022       integer, dimension(:,:), intent(in) :: a,b
2023       integer                , intent(in) :: n
2024       logical                             :: info
2025
2026       !---- Local variables ----!
2027       integer :: i,j
2028
2029       info=.false.
2030       do i=1,n
2031          do j=1,n
2032             if (a(i,j) /= b(i,j)) return
2033          end do
2034       end do
2035       info=.true.
2036
2037       return
2038    End Function Equal_Matrix_I
2039
2040    !!--++
2041    !!--++ Logical Function Equal_Matrix_R(A, B, N)
2042    !!--++    real(kind=sp), dimension(:,:), intent(in)  :: a
2043    !!--++    real(kind=sp), dimension(:,:), intent(in)  :: b
2044    !!--++    integer,                       intent(in)  :: n
2045    !!--++
2046    !!--++    (OVERLOADED)
2047    !!--++    Determines if two integer arrays are equal in NxN
2048    !!--++
2049    !!--++ Update: February - 2005
2050    !!
2051    Function Equal_Matrix_R(a,b,n) result(info)
2052       !---- Argument ----!
2053       real(kind=cp), dimension(:,:)   , intent(in) :: a,b
2054       integer,                          intent(in) :: n
2055       logical                                      :: info
2056
2057       !---- Local variables ----!
2058       integer :: i,j
2059
2060       info=.false.
2061       do i=1,n
2062          do j=1,n
2063             if (abs(a(i,j) - b(i,j)) > epss ) return
2064          end do
2065       end do
2066       info=.true.
2067
2068       return
2069    End Function Equal_Matrix_R
2070
2071    !!----
2072    !!---- Logical Function Equal_Vector(A,B,N)
2073    !!----    integer/real(kind=sp), dimension(:),   intent(in)  :: a,b
2074    !!----    integer,                               intent(in)  :: n
2075    !!----
2076    !!----    Provides the value .TRUE. if the vector A is equal to vector B
2077    !!----
2078    !!---- Update: February - 2005
2079    !!
2080
2081    !!--++
2082    !!--++ Logical Function Equal_Vector_I(A, B, N)
2083    !!--++    integer, dimension(:), intent(in)  :: a
2084    !!--++    integer, dimension(:), intent(in)  :: b
2085    !!--++    integer,               intent(in)  :: n
2086    !!--++
2087    !!--++    (OVERLOADED)
2088    !!--++    Determines if two integer vectors are equal in N
2089    !!--++
2090    !!--++ Update: February - 2005
2091    !!
2092    Function Equal_Vector_I(a,b,n) result(info)
2093       !---- Argument ----!
2094       integer, dimension(:),   intent(in) :: a,b
2095       integer                , intent(in) :: n
2096       logical                             :: info
2097
2098       !---- Local variables ----!
2099       integer :: i
2100
2101       info=.false.
2102       do i=1,n
2103          if (a(i) /= b(i)) return
2104       end do
2105       info=.true.
2106
2107       return
2108    End Function Equal_Vector_I
2109
2110    !!--++
2111    !!--++ Logical Function Equal_Vector_R(A, B, N)
2112    !!--++    real(kind=sp), dimension(:), intent(in)  :: a
2113    !!--++    real(kind=sp), dimension(:), intent(in)  :: b
2114    !!--++    integer,                     intent(in)  :: n
2115    !!--++
2116    !!--++    (OVERLOADED)
2117    !!--++    Determines if two real(kind=sp) vectors are equal in N
2118    !!--++
2119    !!--++ Update: February - 2005
2120    !!
2121    Function Equal_Vector_R(a,b,n) result(info)
2122       !---- Argument ----!
2123       real(kind=cp), dimension(:)   ,   intent(in) :: a,b
2124       integer,                          intent(in) :: n
2125       logical                                      :: info
2126
2127       !---- Local variables ----!
2128       integer :: i
2129
2130       info=.false.
2131       do i=1,n
2132          if (abs(a(i) - b(i)) > epss ) return
2133       end do
2134       info=.true.
2135
2136       return
2137    End Function Equal_Vector_R
2138
2139    !!----
2140    !!----  Function Euclidean_Norm(n,x) Result(Fn_Val)
2141    !!----    Integer,                      Intent(In)  :: n
2142    !!----    Real (Kind=cp), Dimension(:), Intent(In)  :: x
2143    !!----    Real (Kind=cp)                            :: Fn_Val
2144    !!----
2145    !!----  This function calculates safely the Euclidean norm of a vector.
2146    !!----  Intermediate overflows are avoided using this function. The original
2147    !!----  name "enorm" from MINPACK has been changed and the subroutine has
2148    !!----  been translated to Fortran 90.
2149    !!----
2150    !!----
2151    !!--..  Original documentation (from MINPACK):
2152    !!--..
2153    !!--..  Function enorm
2154    !!--..
2155    !!--..  Given an n-vector x, this function calculates the euclidean norm of x.
2156    !!--..
2157    !!--..  The euclidean norm is computed by accumulating the sum of squares in
2158    !!--..  three different sums.  The sums of squares for the small and large
2159    !!--..  components are scaled so that no overflows occur.  Non-destructive
2160    !!--..  underflows are permitted.  Underflows and overflows do not occur in the
2161    !!--..  computation of the unscaled sum of squares for the intermediate
2162    !!--..  components.  The definitions of small, intermediate and large components
2163    !!--..  depend on two constants, rdwarf and rgiant.  The main restrictions on
2164    !!--..  these constants are that rdwarf**2 not underflow and rgiant**2 not
2165    !!--..  overflow.  The constants given here are suitable for every known computer.
2166    !!--..
2167    !!--..  The function statement is
2168    !!--..
2169    !!--..    REAL (kind=cp) function enorm(n,x)
2170    !!--..
2171    !!--..  where
2172    !!--..
2173    !!--..    n is a positive integer input variable.
2174    !!--..
2175    !!--..    x is an input array of length n.
2176    !!--..
2177    !!--..  Subprograms called
2178    !!--..
2179    !!--..    Fortran-supplied ... ABS,SQRT
2180    !!--..
2181    !!--..  Argonne National Laboratory. MINPACK project. march 1980.
2182    !!--..  Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More
2183    !!----
2184    !!----  Update: August - 2009
2185    !!----
2186    Function Euclidean_Norm(n,x) Result(Fn_Val)
2187       !---- Arguments ----!
2188       Integer,                      Intent(In)  :: n
2189       Real (Kind=cp), Dimension(:), Intent(In)  :: x
2190       Real (Kind=cp)                            :: Fn_Val
2191
2192       !--- Local Variables ---!
2193       Integer                   :: i
2194       Real (Kind=cp)            :: agiant, floatn, s1, s2, s3, xabs, x1max, x3max
2195       Real (Kind=cp), Parameter :: one = 1.0_cp, zero = 0.0_cp, rdwarf = 3.834e-20_cp,  &
2196                                   rgiant = 1.304e+19_cp
2197
2198       s1 = zero
2199       s2 = zero
2200       s3 = zero
2201       x1max = zero
2202       x3max = zero
2203       floatn = n
2204       agiant = rgiant/floatn
2205       do i = 1, n
2206          xabs = Abs(x(i))
2207          if (.Not. (xabs > rdwarf .AND. xabs < agiant)) then
2208             ! sum for large components.
2209             if (xabs > rdwarf) then
2210                if (xabs > x1max) then
2211                   s1 = one + s1*(x1max/xabs)**2
2212                   x1max = xabs
2213                   cycle
2214                end if
2215                s1 = s1 + (xabs/x1max)**2
2216                cycle
2217             End If
2218
2219             ! sum for small components.
2220             If (xabs > x3max) Then
2221                s3 = one + s3*(x3max/xabs)**2
2222                x3max = xabs
2223                Cycle
2224             End If
2225
2226             If (xabs /= zero) s3 = s3 + (xabs/x3max)**2
2227             Cycle
2228          End if
2229
2230          !  sum for intermediate components.
2231          s2 = s2 + xabs**2
2232       End Do
2233
2234       ! calculation of norm.
2235       If (s1 /= zero) Then
2236          Fn_Val = x1max*Sqrt(s1 + (s2/x1max)/x1max)
2237          Return
2238       End If
2239
2240       If (s2 /= zero) Then
2241          If (s2 >= x3max) Fn_Val = Sqrt(s2*(one + (x3max/s2)*(x3max*s3)))
2242          If (s2 < x3max) Fn_Val = Sqrt(x3max*((s2/x3max) + (x3max*s3)))
2243          Return
2244       End If
2245
2246       Fn_Val = x3max*Sqrt(s3)
2247
2248       Return
2249    End Function Euclidean_Norm
2250
2251    !!----
2252    !!---- Function Imaxloc(arr) Result(mav)
2253    !!----  real(kind=sp)/integer, dimension(:), intent(in) :: arr
2254    !!----  integer                                         :: mav
2255    !!----
2256    !!----   Index of maxloc on an array
2257    !!----
2258    !!---- Update: February - 2005
2259    !!
2260
2261    !!--++
2262    !!--++ Function Imaxloc_I(arr) Result(mav)
2263    !!--++  integer, dimension(:), intent(in) :: arr
2264    !!--++  integer                           :: mav
2265    !!--++
2266    !!--++   Index of maxloc on an array (from Numerical Recipes)
2267    !!--++
2268    !!--++ Update: February - 2005
2269    !!
2270    Function Imaxloc_I(iarr) Result(mav)
2271       !---- Arguments ----!
2272       integer, dimension(:), intent(in) :: iarr
2273       integer                           :: mav
2274
2275       !---- Local variables ----!
2276       integer, dimension(1) :: imax
2277
2278       imax=maxloc(iarr(:))
2279       mav=imax(1)
2280
2281       return
2282    End Function Imaxloc_I
2283
2284    !!--++
2285    !!--++ Function Imaxloc_R(arr) Result(mav)
2286    !!--++  real(kind=sp), dimension(:), intent(in) :: arr
2287    !!--++  integer                                 :: mav
2288    !!--++
2289    !!--++   Index of maxloc on an array (from Numerical Recipes)
2290    !!--++
2291    !!--++ Update: February - 2005
2292    !!
2293    Function Imaxloc_R(arr) Result(mav)
2294       !---- Arguments ----!
2295       real(kind=cp), dimension(:), intent(in) :: arr
2296       integer                                 :: mav
2297
2298       !---- Local variables ----!
2299       integer, dimension(1) :: imax
2300
2301       imax=maxloc(arr(:))
2302       mav=imax(1)
2303
2304       return
2305    End Function Imaxloc_R
2306
2307    !!----
2308    !!---- Function Iminloc(arr)  Result(miv)
2309    !!----  real(kind=sp)/integer, dimension(:), intent(in) :: arr
2310    !!----  integer                                         :: miv
2311    !!----
2312    !!----   Index of minloc on an array  (from Numerical Recipes)
2313    !!----
2314    !!---- Update: February - 2005
2315    !!
2316
2317    !!--++
2318    !!--++ Function Iminloc_I(arr)  Result(miv)
2319    !!--++  integer, dimension(:), intent(in) :: arr
2320    !!--++  integer                           :: miv
2321    !!--++
2322    !!--++   Index of minloc on an array (from Numerical Recipes)
2323    !!--++
2324    !!--++ Update: February - 2005
2325    !!
2326    Function Iminloc_I(arr)  Result(miv)
2327       !---- Arguments ----!
2328       integer, dimension(:), intent(in) :: arr
2329       integer                           :: miv
2330
2331       !---- Local variables ----!
2332       integer, dimension(1) :: imin
2333
2334       imin=minloc(arr(:))
2335       miv=imin(1)
2336
2337       return
2338    End Function Iminloc_I
2339
2340    !!--++
2341    !!--++ Function Iminloc_R(arr)  Result(miv)
2342    !!--++  real(kind=sp), dimension(:), intent(in) :: arr
2343    !!--++  integer                                 :: miv
2344    !!--++
2345    !!--++   Index of minloc on an array (from Numerical Recipes)
2346    !!--++
2347    !!--++ Update: February - 2005
2348    !!
2349    Function Iminloc_R(arr)  Result(miv)
2350       !---- Arguments ----!
2351       real(kind=cp), dimension(:), intent(in) :: arr
2352       integer                                 :: miv
2353
2354       !---- Local variables ----!
2355       integer, dimension(1) :: imin
2356
2357       imin=minloc(arr(:))
2358       miv=imin(1)
2359
2360       return
2361    End Function Iminloc_R
2362
2363    !!----
2364    !!---- Function in_limits(n,limits,vect) result(ok)
2365    !!----   integer,                      intent(in) :: n
2366    !!----   integer/real, dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2367    !!----   integer/real, dimension(n),   intent(in) :: vect
2368    !!----   logical                                  :: ok
2369    !!----
2370    !!----   Logical function that is true if all the components of the vector vect
2371    !!----   are within the limits:   limits(1,i)  <= vect(i) <=  limits(2,i), for all i.
2372    !!----
2373    !!----   Updated: March - 2013
2374    !!
2375    !!--++
2376    !!--++ Function in_limits_int(n,limits,vect) result(ok)
2377    !!--++   integer,                 intent(in) :: n
2378    !!--++   integer, dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2379    !!--++   integer, dimension(n),   intent(in) :: vect
2380    !!--++   logical                              :: ok
2381    !!--++
2382    !!--++   Logical function that is true if all the components of the vector vect
2383    !!--++   are within the limits:   limits(1,i)  <= vect(i) <=  limits(2,i), for all i.
2384    !!--++
2385    !!--++   Updated: March - 2013
2386    !!
2387    Function in_limits_int(n,limits,vect) result(ok)
2388      integer,                 intent(in) :: n
2389      integer, dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2390      integer, dimension(n),   intent(in) :: vect
2391      logical :: ok
2392      integer :: i
2393      ok=.true.
2394      do i=1,n
2395        if(vect(i) >= limits(1,i) .and. vect(i) <= limits(2,i)) cycle
2396        ok=.false.
2397        exit
2398      end do
2399      return
2400    End Function in_limits_int
2401
2402    !!--++
2403    !!--++ Function in_limits_dp(n,limits,vect) result(ok)
2404    !!--++   integer,                       intent(in) :: n
2405    !!--++   real(kind=dp), dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2406    !!--++   real(kind=dp), dimension(n),   intent(in) :: vect
2407    !!--++   logical                                   :: ok
2408    !!--++
2409    !!--++   Logical function that is true if all the components of the vector vect
2410    !!--++   are within the limits:   limits(1,i)  <= vect(i) <=  limits(2,i), for all i.
2411    !!--++
2412    !!--++   Updated: March - 2013
2413    !!
2414    Function in_limits_dp(n,limits,vect) result(ok)
2415      integer,                       intent(in) :: n
2416      real(kind=dp), dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2417      real(kind=dp), dimension(n),   intent(in) :: vect
2418      logical :: ok
2419      integer :: i
2420      ok=.true.
2421      do i=1,n
2422        if(vect(i) >= limits(1,i) .and. vect(i) <= limits(2,i)) cycle
2423        ok=.false.
2424        exit
2425      end do
2426      return
2427    End Function in_limits_dp
2428
2429    !!--++
2430    !!--++ Function in_limits_sp(n,limits,vect) result(ok)
2431    !!--++   integer,                       intent(in) :: n
2432    !!--++   real(kind=sp), dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2433    !!--++   real(kind=sp), dimension(n),   intent(in) :: vect
2434    !!--++   logical                                   :: ok
2435    !!--++
2436    !!--++   Logical function that is true if all the components of the vector vect
2437    !!--++   are within the limits:   limits(1,i)  <= vect(i) <=  limits(2,i), for all i.
2438    !!--++
2439    !!--++   Updated: March - 2013
2440    !!
2441    Function in_limits_sp(n,limits,vect) result(ok)
2442      integer,                       intent(in) :: n
2443      real(kind=sp), dimension(:,:), intent(in) :: limits   ! Normally (2,n)
2444      real(kind=sp), dimension(n),   intent(in) :: vect
2445      logical :: ok
2446      integer :: i
2447      ok=.true.
2448      do i=1,n
2449        if(vect(i) >= limits(1,i) .and. vect(i) <= limits(2,i)) cycle
2450        ok=.false.
2451        exit
2452      end do
2453      return
2454    End Function in_limits_sp
2455
2456    !!----
2457    !!---- Function Locate(xx, n, x) Result(j)
2458    !!----     or
2459    !!---- Function Locate(xx,x) Result(j)
2460    !!----
2461    !!----    integer/real(kind=sp), dimension(n),intent(in)  :: xx
2462    !!----    integer ,                           intent(in)  :: n
2463    !!----    integer/real(kind=sp),              intent(in)  :: x
2464    !!----    integer ,                           intent(out) :: j
2465    !!----
2466    !!----    Function for locating the index J of an array XX(N)
2467    !!----    satisfying:
2468    !!--<<
2469    !!----               XX(J) <= X < XX(J+1)
2470    !!-->>
2471    !!----
2472    !!---- Update: June - 2011
2473    !!
2474
2475    !!--++
2476    !!--++ Function Locate_I(xx, n, x) Result(j)
2477    !!--++    integer, dimension(:),intent(in)  :: xx
2478    !!--++    integer ,             intent(in)  :: n
2479    !!--++    integer,              intent(in)  :: x
2480    !!--++    integer ,             intent(out) :: j
2481    !!--++
2482    !!--++    Subroutine for locating the index J of an array XX(N)
2483    !!--++    satisfying:
2484    !!--++
2485    !!--++               XX(J) <= X < XX(J+1)
2486    !!--++
2487    !!--++
2488    !!--++ Update: June - 2011
2489    !!
2490    Function Locate_I(xx,n,x) Result(j)
2491       !---- Argument ----!
2492       integer, dimension(:), intent(in):: xx
2493       integer ,              intent(in):: n
2494       integer,               intent(in):: x
2495       integer                          :: j
2496
2497       !---- Local Variables ----!
2498       integer :: jl, ju, jm
2499
2500       if(x <= xx(1)) then
2501         j=1
2502         return
2503       end if
2504       if(x >= xx(n)) then
2505         j=n
2506         return
2507       end if
2508       jl=0
2509       ju=n+1
2510       do
2511          if(ju-jl <= 1) exit
2512          jm=(ju+jl)/2
2513          if ((xx(n) > xx(1)) .eqv. (x > xx(jm))) then
2514             jl=jm
2515          else
2516             ju=jm
2517          end if
2518       end do
2519       j=jl
2520
2521       return
2522    End Function Locate_I
2523    !!--++
2524    !!--++ Function Locate_Ib(xx, x) Result(j)
2525    !!--++    integer, dimension(:),intent(in)  :: xx
2526    !!--++    integer,              intent(in)  :: x
2527    !!--++    integer ,             intent(out) :: j
2528    !!--++
2529    !!--++    Subroutine for locating the index J of an array XX(:)
2530    !!--++    satisfying:
2531    !!--++
2532    !!--++               XX(J) <= X < XX(J+1)
2533    !!--++
2534    !!--++
2535    !!--++ Update: June - 2011
2536    Function Locate_Ib(xx,x) Result(j)
2537       !---- Argument ----!
2538       integer, dimension(:), intent(in):: xx
2539       integer,               intent(in):: x
2540       integer                          :: j
2541
2542       !---- Local Variables ----!
2543       integer :: jl, ju, jm, i1,i2
2544       integer, dimension(1) :: mi
2545
2546       mi=lbound(xx)
2547       i1=mi(1)
2548       mi=ubound(xx)
2549       i2=mi(1)
2550
2551       if(x <= xx(i1)) then
2552         j=i1
2553         return
2554       end if
2555       if(x >= xx(i2)) then
2556         j=i2
2557         return
2558       end if
2559       jl=i1-1
2560       ju=i2+1
2561       do
2562          if(ju-jl <= 1) exit
2563          jm=(ju+jl)/2
2564          if ((xx(i2) > xx(i1)) .eqv. (x > xx(jm))) then
2565             jl=jm
2566          else
2567             ju=jm
2568          end if
2569       end do
2570       j=jl
2571       return
2572    End Function Locate_Ib
2573    !!--++
2574    !!--++ Function Locate_R(xx, n, x) Result(j)
2575    !!--++    real(kind=cp), dimension(:),intent(in)  :: xx
2576    !!--++    integer ,                   intent(in)  :: n
2577    !!--++    real(kind=cp),              intent(in)  :: x
2578    !!--++    integer ,                   intent(out) :: j
2579    !!--++
2580    !!--++    Function for locating the index J of an array XX(N)
2581    !!--++    satisfying:
2582    !!--++
2583    !!--++               XX(J) <= X < XX(J+1)
2584    !!--++
2585    !!--++
2586    !!--++ Update: June - 2011
2587    !!
2588    Function Locate_R(xx,n,x) Result(j)
2589       !---- Argument ----!
2590       real(kind=cp), dimension(:), intent(in):: xx
2591       integer ,                    intent(in):: n
2592       real(kind=cp),               intent(in):: x
2593       integer                                :: j
2594
2595       !---- Local Variables ----!
2596       integer :: jl, ju, jm
2597
2598       if(x <= xx(1)) then
2599         j=1
2600         return
2601       end if
2602       if(x >= xx(n)) then
2603         j=n
2604         return
2605       end if
2606       jl=0
2607       ju=n+1
2608       do
2609          if(ju-jl <= 1) exit
2610          jm=(ju+jl)/2
2611          if ((xx(n) > xx(1)) .eqv. (x > xx(jm))) then
2612             jl=jm
2613          else
2614             ju=jm
2615          end if
2616       end do
2617       j=jl
2618
2619       return
2620    End Function Locate_R
2621
2622    !!--++
2623    !!--++ Function Locate_Rb(xx, x) Result(j)
2624    !!--++    real(kind=cp), dimension(:),intent(in)  :: xx
2625    !!--++    real(kind=cp),              intent(in)  :: x
2626    !!--++    integer ,                   intent(out) :: j
2627    !!--++
2628    !!--++    Function for locating the index J of an array XX(:)
2629    !!--++    satisfying:
2630    !!--++
2631    !!--++               XX(J) <= X < XX(J+1)
2632    !!--++
2633    !!--++
2634    !!--++ Update: June - 2011
2635    !!
2636    Function Locate_Rb(xx,x) Result(j)
2637       !---- Argument ----!
2638       real(kind=cp), dimension(:), intent(in):: xx
2639       real(kind=cp),               intent(in):: x
2640       integer                                :: j
2641
2642       !---- Local Variables ----!
2643       integer :: jl, ju, jm, i1,i2
2644       integer, dimension(1) :: mi
2645
2646       mi=lbound(xx)
2647       i1=mi(1)
2648       mi=ubound(xx)
2649       i2=mi(1)
2650
2651       if(x <= xx(i1)) then
2652         j=i1
2653         return
2654       end if
2655       if(x >= xx(i2)) then
2656         j=i2
2657         return
2658       end if
2659       jl=i1-1
2660       ju=i2+1
2661       do
2662          if(ju-jl <= 1) exit
2663          jm=(ju+jl)/2
2664          if ((xx(i2) > xx(i1)) .eqv. (x > xx(jm))) then
2665             jl=jm
2666          else
2667             ju=jm
2668          end if
2669       end do
2670       j=jl
2671
2672       return
2673    End Function Locate_Rb
2674
2675    !!----
2676    !!---- Function Lower_Triangular_I(A,n) Result (T)
2677    !!----   integer, dimension(:,:), intent(in) :: A
2678    !!----   integer,                 intent(in) :: n
2679    !!----   integer, dimension(n,n)             :: T
2680    !!----
2681    !!----   Updated: October - 2014
2682    !!----
2683    Function Lower_Triangular_I(A,n) Result (T)
2684       !---- Argument ----!
2685       integer, dimension(:,:), intent(in) :: A
2686       integer,                 intent(in) :: n
2687       integer, dimension(n,n)             :: T
2688       integer :: i,j,p,q,m
2689       m=n
2690       p=size(A(:,1)); q=size(A(1,:))
2691       if(n > p .or. n > q) m=min(p,q)
2692       T=0
2693       do j=1,m
2694         do i=j,m
2695           T(i,j)=A(i,j)
2696         end do
2697       end do
2698    End Function  Lower_Triangular_I
2699
2700    !!----
2701    !!---- Function Lower_Triangular_R(A,n) Result (T)
2702    !!----   real(kind=cp), dimension(:,:), intent(in) :: A
2703    !!----   integer,                       intent(in) :: n
2704    !!----   real(kind=cp), dimension(n,n)             :: T
2705    !!----
2706    !!----   Updated: October - 2014
2707    !!----
2708    Function Lower_Triangular_R(A,n) Result (T)
2709       !---- Argument ----!
2710       real(kind=cp), dimension(:,:), intent(in) :: A
2711       integer,                       intent(in) :: n
2712       real(kind=cp), dimension(n,n)             :: T
2713       integer :: i,j,p,q,m
2714       m=n
2715       p=size(A(:,1)); q=size(A(1,:))
2716       if(n > p .or. n > q) m=min(p,q)
2717       T=0
2718       do j=1,m
2719         do i=j,m
2720           T(i,j)=A(i,j)
2721         end do
2722       end do
2723    End Function  Lower_Triangular_R
2724
2725    !!---- Function Modulo_Lat(U)
2726    !!----    real(kind=cp), dimension(:), intent(in) :: u
2727    !!----
2728    !!----    Reduces a real vector to another with components in
2729    !!----    the interval [0,1)
2730    !!----
2731    !!---- Updated: February - 2005
2732    !!
2733    Function Modulo_Lat(u) result(v)
2734       !---- Argument ----!
2735       real(kind=cp), dimension(:), intent( in) :: u
2736       real(kind=cp), dimension(1:size(u))      :: v
2737
2738       v=mod(u+10.0_cp,1.0_cp)
2739
2740       return
2741    End Function  Modulo_Lat
2742
2743    !!----
2744    !!---- Function Norm(X,G) Result(R)
2745    !!----    real(kind=cp)/integer, dimension(:),   intent(in) :: x
2746    !!----    real(kind=cp),         dimension(:,:), intent(in) :: g
2747    !!----
2748    !!----    Calculate the Norm of a vector
2749    !!----
2750    !!---- Update: April - 2009
2751    !!
2752
2753    !!--++
2754    !!--++ Function Norm_I(X,G) Result(R)
2755    !!--++    integer,      dimension(:),   intent(in) :: x
2756    !!--++    real(kind=cp),dimension(:,:), intent(in) :: g
2757    !!--++
2758    !!--++    Calculate the Norm of a vector
2759    !!--++
2760    !!--++ Update: April - 2009
2761    !!
2762    Function Norm_I(X,G) Result(R)
2763       !---- Arguments ----!
2764       integer,       dimension(:),   intent(in) :: x
2765       real(kind=cp), dimension(:,:), intent(in) :: g
2766       real(kind=cp)                             :: r
2767
2768       if (size(x)*size(x) /= size(g)) then
2769          r=tiny(0.0)
2770       else
2771          r=sqrt(dot_product(real(x), matmul(g,real(x))))
2772       end if
2773
2774       return
2775    End Function Norm_I
2776
2777    !!--++
2778    !!--++ Function Norm_R(X,G) Result(R)
2779    !!--++    real(kind=cp),dimension(:),   intent(in) :: x
2780    !!--++    real(kind=cp),dimension(:,:), intent(in) :: g
2781    !!--++
2782    !!--++    Calculate the Norm of a vector
2783    !!--++
2784    !!--++ Update: April - 2009
2785    !!
2786    Function Norm_R(X,G) Result(R)
2787       !---- Arguments ----!
2788       real(kind=cp), dimension(:),   intent(in) :: x
2789       real(kind=cp), dimension(:,:), intent(in) :: g
2790       real(kind=cp)                             :: r
2791
2792       if (size(x)*size(x) /= size(g)) then
2793          r=tiny(0.0)
2794       else
2795          r=sqrt(dot_product(x, matmul(g,x)))
2796       end if
2797
2798       return
2799    End Function Norm_R
2800
2801
2802    !!----
2803    !!---- Function Outerprod(a,b) Result(c)
2804    !!----    real(sp/dp),dimension(:),intent(in)    :: a,b
2805    !!----    real(sp/dp),dimension(size(a),size(b)) :: c
2806    !!----
2807    !!----    Computes the outer product (tensorial product) of two
2808    !!----    vectors to give a tensor (matrix) as the result:
2809    !!--<<
2810    !!----                   c(i,j) = a(i)*b(j).
2811    !!-->>
2812    !!--..    It uses the intrinsic Fortran 90 function SPREAD.
2813    !!--..    Function adapted from Numerical Recipes.
2814    !!----
2815    !!---- Update: February - 2005
2816    !!
2817
2818    !!--++
2819    !!--++ Function Outerprod_dp(a,b) Result(c)
2820    !!--++    real(dp),dimension(:),intent(in)    :: a,b
2821    !!--++    real(dp),dimension(size(a),size(b)) :: c
2822    !!--++
2823    !!--++    (OVERLOADED)
2824    !!--++    Computes the outer product (tensorial product) of two
2825    !!--++    vectors to give a tensor (matrix) as the result:
2826    !!--++                   c(i,j) = a(i)*b(j).
2827    !!--++
2828    !!--++    It uses the intrinsic Fortran 90 function SPREAD.
2829    !!--++    Taken from Numerical Recipes.
2830    !!--++
2831    !!--++ Update: February - 2005
2832    !!
2833    Function Outerprod_dp(a,b)  Result(c)
2834       !---- Arguments ----!
2835       real(kind=dp),dimension(:),intent(in)    :: a,b
2836       real(kind=dp),dimension(size(a),size(b)) :: c
2837
2838       c =spread(a,dim=2,ncopies=size(b))*spread(b,dim=1,ncopies=size(a))
2839
2840       return
2841    End Function Outerprod_dp
2842
2843    !!--++
2844    !!--++ Function Outerprod_sp(a,b) Result(c)
2845    !!--++    real(sp),dimension(:),intent(in)    :: a,b
2846    !!--++    real(sp),dimension(size(a),size(b)) :: c
2847    !!--++
2848    !!--++    (OVERLOADED)
2849    !!--++    Computes the outer product (tensorial product) of two
2850    !!--++    vectors to give a tensor (matrix) as the result:
2851    !!--++                   c(i,j) = a(i)*b(j).
2852    !!--++
2853    !!--++    It uses the intrinsic Fortran 90 function SPREAD.
2854    !!--++    Taken from Numerical Recipes.
2855    !!--++
2856    !!--++ Update: February - 2005
2857    !!
2858    Function Outerprod_sp(a,b)  Result(c)
2859       !---- Arguments ----!
2860       real(kind=sp),dimension(:),intent(in)    :: a,b
2861       real(kind=sp),dimension(size(a),size(b)) :: c
2862
2863       c =spread(a,dim=2,ncopies=size(b))*spread(b,dim=1,ncopies=size(a))
2864
2865       return
2866    End Function Outerprod_sp
2867
2868    !!----
2869    !!---- Function Scalar(X,Y,G) Result(R)
2870    !!----    integer/real(kind=cp), dimension(:),   intent(in) :: x
2871    !!----    integer/real(kind=cp), dimension(:),   intent(in) :: y
2872    !!----    real(kind=cp),         dimension(:,:), intent(in) :: g
2873    !!----
2874    !!----    Scalar Product including metrics
2875    !!----
2876    !!---- Update: April - 2009
2877    !!
2878
2879    !!--++
2880    !!--++ Function Scalar_R(X,Y,G) Result(R)
2881    !!--++    integer, dimension(:),   intent(in) :: x
2882    !!--++    integer, dimension(:),   intent(in) :: y
2883    !!--++    real(kind=cp), dimension(:,:), intent(in) :: g
2884    !!--++
2885    !!--++    Scalar Product including metrics
2886    !!--++
2887    !!--++ Update: April - 2009
2888    !!
2889    Function Scalar_I(X,Y,G) Result(R)
2890       !---- Arguments ----!
2891       integer, dimension(:),   intent(in) :: x
2892       integer, dimension(:),   intent(in) :: y
2893       real(kind=cp), dimension(:,:), intent(in) :: g
2894       real(kind=cp)                             :: r
2895
2896       if (size(x)/= size(y) .or. size(x)*size(x) /= size(g)) then
2897          r=tiny(0.0)
2898       else
2899          r=dot_product(real(x), matmul(g,real(y)))
2900       end if
2901
2902       return
2903    End Function Scalar_I
2904
2905    !!--++
2906    !!--++ Function Scalar_R(X,Y,G) Result(R)
2907    !!--++    real(kind=cp), dimension(:),   intent(in) :: x
2908    !!--++    real(kind=cp), dimension(:),   intent(in) :: y
2909    !!--++    real(kind=cp), dimension(:,:), intent(in) :: g
2910    !!--++
2911    !!--++    Scalar Product including metrics
2912    !!--++
2913    !!--++ Update: April - 2009
2914    !!
2915    Function Scalar_R(X,Y,G) Result(R)
2916       !---- Arguments ----!
2917       real(kind=cp), dimension(:),   intent(in) :: x
2918       real(kind=cp), dimension(:),   intent(in) :: y
2919       real(kind=cp), dimension(:,:), intent(in) :: g
2920       real(kind=cp)                             :: r
2921
2922       if (size(x)/= size(y) .or. size(x)*size(x) /= size(g)) then
2923          r=tiny(0.0)
2924       else
2925          r=dot_product(x, matmul(g,y))
2926       end if
2927
2928       return
2929    End Function Scalar_R
2930
2931    !!----
2932    !!---- Function Trace(A)
2933    !!----    complex/integer/real(kind=cp), dimension(:,:), intent(in)  :: a
2934    !!----
2935    !!----    Provides the trace of a complex/real or integer matrix
2936    !!----
2937    !!---- Update: February - 2005
2938    !!
2939
2940    !!--++
2941    !!--++ Function Trace_C(A)
2942    !!--++    complex, dimension(:,:), intent(in)  :: a
2943    !!--++
2944    !!--++    (OVERLOADED)
2945    !!--++    Calculates the trace of a complex nxn array
2946    !!--++
2947    !!--++ Update: February - 2005
2948    !!
2949    Function Trace_C(a) Result(b)
2950       !---- Argument ----!
2951       complex, dimension(:,:), intent(in) :: a
2952       complex                             :: b
2953
2954       !---- Local variables ----!
2955       integer :: i,imax
2956
2957       b=(0.0,0.0)
2958       imax=min(size(a,1),size(a,2))
2959       do i=1,imax
2960          b=b+a(i,i)
2961       end do
2962
2963       return
2964    End Function Trace_C
2965
2966    !!--++
2967    !!--++ Function Trace_I(A)
2968    !!--++    integer, dimension(:,:), intent(in)  :: a
2969    !!--++
2970    !!--++    (OVERLOADED)
2971    !!--++    Calculates the trace of an integer 3x3 array
2972    !!--++
2973    !!--++ Update: February - 2005
2974    !!
2975    Function Trace_I(a) Result(b)
2976       !---- Argument ----!
2977       integer, dimension(:,:), intent(in) :: a
2978       integer                             :: b
2979
2980       !---- Local variables ----!
2981       integer :: i,imax
2982
2983       b=0
2984       imax=min(size(a,1),size(a,2))
2985       do i=1,imax
2986          b=b+a(i,i)
2987       end do
2988
2989       return
2990    End Function Trace_I
2991
2992    !!--++
2993    !!--++ Function Trace_R(A)
2994    !!--++    real(kind=cp), dimension(:,:), intent(in)  :: a
2995    !!--++
2996    !!--++    (OVERLOADED)
2997    !!--++    Calculates the trace of a real 3x3 array
2998    !!--++
2999    !!--++ Update: February - 2005
3000    !!
3001    Function Trace_R(a) Result(b)
3002       !---- Argument ----!
3003       real(kind=cp), dimension(:,:), intent(in) :: a
3004       real(kind=cp)                             :: b
3005
3006       !---- Local variables ----!
3007       integer :: i,imax
3008
3009       b=0.0
3010       imax=min(size(a,1),size(a,2))
3011       do i=1,imax
3012          b=b+a(i,i)
3013       end do
3014
3015       return
3016    End Function Trace_R
3017
3018
3019    !!----
3020    !!---- Function Upper_Triangular_I(A,n) Result (T)
3021    !!----   integer, dimension(:,:), intent(in) :: A
3022    !!----   integer,                 intent(in) :: n
3023    !!----   integer, dimension(n,n)             :: T
3024    !!----
3025    !!----   Updated: October - 2014
3026    !!----
3027    Function Upper_Triangular_I(A,n) Result (T)
3028       !---- Argument ----!
3029       integer, dimension(:,:), intent(in) :: A
3030       integer,                 intent(in) :: n
3031       integer, dimension(n,n)             :: T
3032       integer :: i,j,p,q,m
3033       m=n
3034       p=size(A(:,1)); q=size(A(1,:))
3035       if(n > p .or. n > q) m=min(p,q)
3036       T=0
3037       do j=1,m
3038         do i=1,j
3039           T(i,j)=A(i,j)
3040         end do
3041       end do
3042    End Function  Upper_Triangular_I
3043
3044    !!----
3045    !!---- Function Upper_Triangular_R(A,n) Result (T)
3046    !!----   real(kind=cp), dimension(:,:), intent(in) :: A
3047    !!----   integer,                       intent(in) :: n
3048    !!----   real(kind=cp), dimension(n,n)             :: T
3049    !!----
3050    !!----   Updated: October - 2014
3051    !!----
3052    Function Upper_Triangular_R(A,n) Result (T)
3053       !---- Argument ----!
3054       real(kind=cp), dimension(:,:), intent(in) :: A
3055       integer,                       intent(in) :: n
3056       real(kind=cp), dimension(n,n)             :: T
3057       integer :: i,j,p,q,m
3058       m=n
3059       p=size(A(:,1)); q=size(A(1,:))
3060       if(n > p .or. n > q) m=min(p,q)
3061       T=0
3062       do j=1,m
3063         do i=1,j
3064           T(i,j)=A(i,j)
3065         end do
3066       end do
3067    End Function  Upper_Triangular_R
3068
3069    !!----
3070    !!---- Logical Function Zbelong(V)
3071    !!----    real(kind=cp),   dimension(:,:), intent( in) :: v
3072    !!----                      or
3073    !!----    real(kind=cp),   dimension(:),   intent( in) :: v
3074    !!----                      or
3075    !!----    real(kind=cp),                   intent( in) :: v
3076    !!----
3077    !!----    Provides the value .TRUE. if the real number (or array) V is close enough
3078    !!----    (whithin EPS) to an integer.
3079    !!----
3080    !!---- Update: February - 2005
3081    !!
3082
3083    !!--++
3084    !!--++ Logical Function ZbelongM(V)
3085    !!--++    real(kind=cp),   dimension(:,:), intent( in) :: v
3086    !!--++
3087    !!--++    (OVERLOADED)
3088    !!--++    Determines if a real array is an Integer matrix
3089    !!--++
3090    !!--++ Update: February - 2005
3091    !!
3092    Function ZbelongM(v) Result(belong)
3093       !---- Argument ----!
3094       real(kind=cp),   dimension(:,:), intent( in) :: v
3095       logical                                      :: belong
3096
3097       !---- Local variables ----!
3098       real(kind=cp),   dimension(size(v,1),size(v,2)) :: vec
3099
3100       vec= abs(real(nint (v))-v)
3101       belong=.not. ANY(vec > epss)
3102
3103       return
3104    End Function ZbelongM
3105
3106    !!--++
3107    !!--++ Logical Function ZbelongN(A)
3108    !!--++    real(kind=cp),  intent(in)  :: a
3109    !!--++
3110    !!--++    (OVERLOADED)
3111    !!--++    Determines if a real number is an Integer
3112    !!--++
3113    !!--++ Update: February - 2005
3114   !!
3115    Function ZbelongN(a) Result(belong)
3116       !---- Argument ----!
3117       real(kind=cp), intent( in) :: a
3118       logical                    :: belong
3119
3120       belong=.false.
3121       if (abs(real(nint (a))-a) > epss) return
3122       belong=.true.
3123
3124       return
3125    End Function ZbelongN
3126
3127    !!--++
3128    !!--++ Logical Function ZbelongV(V)
3129    !!--++    real(kind=sp),   dimension(:), intent( in) :: v
3130    !!--++
3131    !!--++    (OVERLOADED)
3132    !!--++    Determines if a real vector is an Integer vector
3133    !!--++
3134    !!--++ Update: February - 2005
3135    !!
3136    Function ZbelongV(v) Result(belong)
3137       !---- Argument ----!
3138       real(kind=cp),   dimension(:), intent( in) :: v
3139       logical                                    :: belong
3140
3141       !---- Local variables ----!
3142       integer                             :: i
3143       real(kind=cp),   dimension(size(v)) :: vec
3144
3145       belong=.false.
3146       vec= abs(real(nint (v))-v)
3147       do i=1,size(v)
3148          if (vec(i) > epss) return
3149       end do
3150       belong=.true.
3151
3152       return
3153    End Function ZbelongV
3154
3155    !---------------------!
3156    !---- Subroutines ----!
3157    !---------------------!
3158
3159    !!----
3160    !!---- Subroutine Init_Err_Mathgen()
3161    !!----
3162    !!----    Initialize the errors flags in CFML_Math_General
3163    !!----
3164    !!---- Update: February - 2005
3165    !!
3166    Subroutine Init_Err_MathGen()
3167
3168       ERR_MathGen=.false.
3169       ERR_MathGen_Mess=" "
3170
3171       return
3172    End Subroutine Init_Err_MathGen
3173
3174    !!----
3175    !!---- Subroutine Set_Epsg(Neweps)
3176    !!----    real(kind=cp), intent( in) :: neweps
3177    !!----
3178    !!----    Sets global EPSS to the value "neweps"
3179    !!----
3180    !!---- Update: April - 2005
3181    !!
3182    Subroutine Set_Epsg(Neweps)
3183       !---- Arguments ----!
3184       real(kind=cp), intent( in) :: neweps
3185
3186       epss=neweps
3187
3188       return
3189    End Subroutine Set_Epsg
3190
3191    !!----
3192    !!---- Subroutine Set_Epsg_Default()
3193    !!----
3194    !!----    Sets global EPSS to the default value: epss=1.0E-5_sp
3195    !!----
3196    !!---- Update: April - 2005
3197    !!
3198    Subroutine Set_Epsg_Default()
3199
3200       epss=1.0E-5_sp
3201
3202       return
3203    End Subroutine Set_Epsg_Default
3204
3205    !!----
3206    !!---- Subroutine Rtan(y,x,ang,deg)
3207    !!----    real(sp/dp),               intent( in) :: x,y
3208    !!----    real(sp/dp),               intent(out) :: ang
3209    !!----    character(len=*),optional, intent( in) :: deg
3210    !!----
3211    !!----    Returns ang=arctan(y/x) in the quadrant where the signs sin(ang) and
3212    !!----    cos(ang) are those of y and x. If deg is present, return ang in degrees.
3213    !!----
3214    !!---- Update: February - 2005
3215    !!
3216
3217    !!--++
3218    !!--++ Subroutine Rtan_dp(y,x,ang,deg)
3219    !!--++    real(dp),                  intent( in) :: x,y
3220    !!--++    real(dp),                  intent(out) :: ang
3221    !!--++    character(len=*),optional, intent( in) :: deg
3222    !!--++
3223    !!--++    (OVERLOADED)
3224    !!--++    Returns ang=arctan(y/x) in the quadrant where the signs sin(ang) and
3225    !!--++    cos(ang) are those of y and x. If deg is present, return ang in degrees.
3226    !!--++
3227    !!--++ Update: February - 2005
3228    !!
3229    Subroutine Rtan_dp(y,x,ang,deg)
3230       !---- Arguments ----!
3231       real(kind=dp),              Intent( In)   :: x,y
3232       real(kind=dp),              Intent(Out)   :: ang
3233       character(len=*), optional, Intent( In)   :: deg
3234
3235       !---- Local variables ----!
3236       real(kind=dp):: abx,aby
3237
3238       abx=abs(x)
3239       aby=abs(y)
3240       if ((abx < eps) .and. (aby < eps)) then
3241          ang = 0.0_dp
3242          return
3243       else if(abx < eps) then
3244          ang = pi/2.0_dp
3245       else if(aby < abx) then
3246          ang = atan(aby/abx)
3247          if(x < 0.0_dp) ang = pi-ang
3248       else
3249          ang = pi/2.0_dp - atan(abx/aby)
3250          if(x < 0.0_dp) ang = pi-ang
3251       end if
3252       if (y < 0.0_dp) ang = -ang
3253       if (present(deg)) ang = ang*to_deg
3254
3255       return
3256    End Subroutine Rtan_dp
3257
3258    !!--++
3259    !!--++ Subroutine Rtan_sp(x,y,ang,deg)
3260    !!--++    real(sp),                  intent( in) :: x,y
3261    !!--++    real(sp),                  intent(out) :: ang
3262    !!--++    character(len=*),optional, intent( in) :: deg
3263    !!--++
3264    !!--++    (OVERLOADED)
3265    !!--++    Returns ang=arctan(y/x) in the quadrant where the signs sin(ang) and
3266    !!--++    cos(ang) are those of y and x. If deg is present, return ang in degrees.
3267    !!--++
3268    !!--++ Update: February - 2005
3269    !!
3270    Subroutine Rtan_sp(y,x,ang,deg)
3271       !---- Arguments ----!
3272       real(kind=sp),              Intent( In)   :: x,y
3273       real(kind=sp),              Intent(Out)   :: ang
3274       character(len=*), optional, Intent( In)   :: deg
3275
3276       !---- local variables ----!
3277       real(kind=sp):: abx,aby
3278
3279       abx=abs(x)
3280       aby=abs(y)
3281       if ((abx < eps) .and. (aby < eps)) then
3282          ang = 0.0_sp
3283          return
3284       else if(abx < eps) then
3285          ang = pi/2.0_sp
3286       else if(aby < abx) then
3287          ang = atan(aby/abx)
3288          if(x < 0.0_sp) ang = pi-ang
3289       else
3290          ang = pi/2.0_sp - atan(abx/aby)
3291          if(x < 0.0_sp) ang = pi-ang
3292       end if
3293       if(y < 0.0_sp) ang = -ang
3294       if (present(deg)) ang = ang*to_deg
3295
3296       return
3297    End Subroutine Rtan_sp
3298
3299    !!----
3300    !!----  Subroutine Co_Prime_Vector(V,Cop,F)
3301    !!----     integer, dimension(:), intent(in)  :: v      !input integer vector
3302    !!----     integer, dimension(:), intent(out) :: cop    !Output co-prime vector
3303    !!----     integer,  optional,    intent(out) :: f      !Common multiplicative factor
3304    !!----
3305    !!----     Calculates the co-prime vector (cop) parallel to the input vector (v)
3306    !!----     It uses the list of the first thousand prime numbers.
3307    !!----
3308    !!----   Updated: January 2012 (JRC), copied from Nodal_Indices (Laue_Mod) in July 2013 (JRC)
3309    !!----
3310    Subroutine Co_Prime_Vector(V,Cop,f)
3311       !---- Arguments ----!
3312       integer, dimension(:), intent(in)  :: v
3313       integer, dimension(:), intent(out) :: cop
3314       integer,  optional,    intent(out) :: f
3315
3316       !---- Local variables ----!
3317       integer                     :: i,j,max_ind,k,im,dimv,n
3318
3319       cop=v
3320       n=1
3321       if (present(f)) f=1
3322       max_ind=maxval(abs(cop))
3323       !---- If the maximum value of the indices is 1 they are already coprimes
3324       if (max_ind <= 1) return
3325       !---- Indices greater than 1
3326       dimv=size(v)
3327       im=0
3328       do i=1,size(primes)
3329          if(primes(i) > max_ind) then  !primes is an array within this module
3330             im=i
3331             exit
3332          end if
3333       end do
3334       if(im == 0) return
3335       do_p: do i=1,im
3336         k=primes(i)
3337         do
3338           do j=1,dimv
3339              if( mod(cop(j),k) /= 0) cycle do_p
3340           end do
3341           n=n*k
3342           cop=cop/k
3343         end do
3344       end do do_p
3345
3346       if (present(f)) f=n
3347
3348       return
3349    End Subroutine Co_Prime_vector
3350
3351    !!----
3352    !!---- Subroutine Determinant(A,n,determ)
3353    !!----    complex/real(sp), dimension(:,:), intent( in) :: A      !input square matrix (n,n)
3354    !!----    integer,                          intent( in) :: n      !actual dimension of A
3355    !!----    real(kind=sp),                    intent(out) :: determ !det(A) if real
3356    !!----                                                             det(AR)^2 + det(AI)^2 if complex
3357    !!----
3358    !!----    Calculates the determinant of a real square matrix.
3359    !!----    Calculates the pseudo-determinant of a complex square matrix.
3360    !!----    The calculated value is only useful for linear dependency purposes.
3361    !!----    It tell us if the complex matrix is singular or not.
3362    !!--..
3363    !!--..    Calculates the determinant of a complex square matrix selected from a rectangular
3364    !!--..    matrix A, n x m, where m >= n. determ=determinant_of_A(1:n,icol:icol+n-1)
3365    !!--..    If icol is absent, the calculation is performed as if icol=1.
3366    !!--..    If icol+n-1 > m, or m < n, determ is set to 0.0 and an error message is generated.
3367    !!----
3368    !!--..    P R O V I S I O N A L (The determinant of A is not calculated at present)
3369    !!----
3370    !!---- Update: February - 2005
3371    !!
3372
3373    !!--++
3374    !!--++ Subroutine Determinant_C(A,n,determ)
3375    !!--++    complex,          dimension(:,:), intent( in) :: A      !input square matrix (n,n)
3376    !!--++    integer,                          intent( in) :: n      !actual dimension of A
3377    !!--++    real(kind=cp),                    intent(out) :: determ !det(A) if real
3378    !!--++                                                             det(AR)^2 + det(AI)^2 if complex
3379    !!--++
3380    !!--++    (OVERLOADED)
3381    !!--++    Calculates the determinant of a real square matrix.
3382    !!--++    Calculates the pseudo-determinant of a complex square matrix.
3383    !!--++    The calculated value is only useful for linear dependency purposes.
3384    !!--++    It tell us if the complex matrix is singular or not.
3385    !!--++
3386    !!--++    P R O V I S I O N A L (The determinant of A is not calculated at present)
3387    !!--++
3388    !!--++ Update: February - 2005
3389    !!
3390    Subroutine Determinant_C(A,n,determ)
3391       !---- Arguments ----!
3392       complex, dimension(:,:), intent( in) :: A
3393       integer,                 intent( in) :: n
3394       real(kind=cp),           intent(out) :: determ
3395
3396       !---- local variables ----!
3397       real(kind=cp),    dimension(2*n,2*n) :: AC   !real square matrix
3398       real(kind=cp)                        :: d
3399       integer                              :: i,nn
3400       logical                              :: singular
3401
3402       nn=2*n
3403       AC(  1:n ,  1:n ) =  real(A(1:n ,1:n))
3404       AC(n+1:nn,  1:n ) = aimag(A(1:n ,1:n))
3405       AC(n+1:nn,n+1:nn) =    AC(  1:n ,1:n)
3406       AC(  1:n ,n+1:nn) =   -AC(n+1:nn,1:n)
3407
3408       call lu_decomp(ac(1:nn,1:nn),d,singular)
3409
3410       if (singular) then
3411          determ=0.0
3412       else
3413          determ=0.0
3414          do i=1,nn
3415             d=d*sign(1.0_cp,ac(i,i))
3416             determ=determ+ log(abs(ac(i,i)))
3417          end do
3418          determ=d*exp(determ)
3419       end if
3420
3421       return
3422    End Subroutine Determinant_C
3423
3424    !!--++
3425    !!--++ Subroutine Determinant_R(A,n,determ)
3426    !!--++    real(kind=cp), dimension(:,:),intent( in) :: A   (input square matrix (n,n))
3427    !!--++    integer,                      intent( in) :: n   (actual dimension of A)
3428    !!--++    real(kind=cp),                intent(out) :: determ  (determinant )
3429    !!--++
3430    !!--++    (OVERLOADED)
3431    !!--++    Calculates the determinant of a real square matrix.
3432    !!--++
3433    !!--++ Update: February - 2005
3434    !!
3435    Subroutine Determinant_R(A,n,determ)
3436       !---- Arguments ----!
3437       real(kind=cp), dimension(:,:), intent( in) :: A
3438       integer,                       intent( in) :: n
3439       real(kind=cp),                 intent(out) :: determ
3440
3441       !---- local variables ----!
3442       real(kind=cp),    dimension(n,n)  :: AC
3443       real(kind=cp)                     :: d
3444       integer                           :: i
3445       logical                           :: singular
3446
3447       ac=A(1:n,1:n)
3448       call lu_decomp(ac,d,singular)
3449
3450       if (singular) then
3451          determ=0.0
3452       else
3453          determ=0.0
3454          do i=1,n
3455             d=d*sign(1.0_cp,ac(i,i))
3456             determ=determ + log(abs(ac(i,i)))
3457          end do
3458          determ=d*exp(determ)
3459       end if
3460
3461       return
3462    End Subroutine Determinant_R
3463
3464    !!----
3465    !!---- Subroutine Diagonalize_SH(A,N,E_val,E_vect)
3466    !!----    complex/real,      dimension(:,:), intent( in)  :: A
3467    !!----    integer,                           intent( in)  :: n
3468    !!----    real(kind=cp),     dimension(:),   intent(out)  :: E_val
3469    !!----    complex, optional, dimension(:,:), intent(out)  :: E_vect
3470    !!----
3471    !!----    Diagonalize Symmetric/Hermitian matrices.
3472    !!----    The eigen_values E_val are sorted in descending order. The columns
3473    !!----    of E_vect are the corresponding eigenvectors.
3474    !!----
3475    !!---- Update: February - 2005
3476    !!
3477
3478    !!--++
3479    !!--++ Subroutine Diagonalize_Herm(a,n,e_val,e_vect)
3480    !!--++    complex,           dimension(:,:), intent( in)  :: A
3481    !!--++    integer,                           intent( in)  :: n
3482    !!--++    real(kind=cp),     dimension(:),   intent(out)  :: E_val
3483    !!--++    complex, optional, dimension(:,:), intent(out)  :: E_vect
3484    !!--++
3485    !!--++    (OVERLOADED)
3486    !!--++    Diagonalize Hermitian matrices.
3487    !!--++    The eigen_values E_val are sorted in descending order. The columns
3488    !!--++    of E_vect are the corresponding eigenvectors.
3489    !!--++
3490    !!--++ Update: February - 2005
3491    !!
3492    Subroutine Diagonalize_Herm(a,n,e_val,e_vect)
3493       !---- Arguments ----!
3494       complex,           dimension(:,:), intent( in)  :: A
3495       integer,                           intent( in)  :: n
3496       real(kind=cp),     dimension(:),   intent(out)  :: E_val
3497       complex, optional, dimension(:,:), intent(out)  :: E_vect
3498
3499       !---- Local variables ----!
3500       real(kind=cp),        dimension(2*n,2*n)   :: aux
3501       real(kind=cp),        dimension(2*n)       :: e,d
3502       integer :: nn
3503
3504       e_val=0.0
3505       call init_err_mathgen()
3506       if (n > size(A,1) .or. n > size(A,2)) then
3507          ERR_MathGen=.true.
3508          ERR_MathGen_Mess=" Diagonalize_HERM: Error in dimension of input matrix: A(m,m) with m < n "
3509          return
3510       end if
3511
3512       nn=2*n
3513       aux(  1:n ,  1:n ) =  real(a(1:n ,1:n))   !      (  U   V )
3514       aux(n+1:nn,n+1:nn) =  real(a(1:n ,1:n))   !   M=(          ),   A = U + i V
3515       aux(n+1:nn,  1:n ) = aimag(a(1:n ,1:n))   !      ( -V   U )
3516       aux(  1:n ,n+1:nn) =-aimag(a(1:n ,1:n))   !
3517
3518       if (present(E_vect)) then
3519          call tred2(aux,nn,d,e)
3520          call tqli2(d,e,nn,aux)
3521          call eigsrt(d,aux,nn,1)
3522          e_vect(1:n,1:n)=cmplx(aux(1:n,1:nn:2),aux(n+1:nn,1:nn:2))
3523       else
3524          call tred1(aux,nn,d,e)
3525          call tqli1(d,e,nn)
3526          call eigsrt(d,aux,nn,0)
3527       end if
3528       e_val(1:n)=d(1:nn:2)
3529
3530       return
3531    End Subroutine Diagonalize_Herm
3532
3533    !!--++
3534    !!--++ Subroutine Diagonalize_Symm(a,n,e_val,e_vect)
3535    !!--++    real(kind=cp)            dimension(:,:),intent( in)  :: A      (input matrix with)
3536    !!--++    integer,                                intent( in)  :: n      (actual dimension)
3537    !!--++    real(kind=cp),           dimension(:),  intent(out)  :: E_val  (eigenvalues)
3538    !!--++    real(kind=cp), optional, dimension(:,:),intent(out)  :: E_vect (eigenvectors)
3539    !!--++
3540    !!--++    (OVERLOADED)
3541    !!--++    Diagonalize symmetric matrices
3542    !!--++    The eigen_values E_val are sorted in descending order. The columns
3543    !!--++    of E_vect are the corresponding eigenvectors.
3544    !!--++
3545    !!--++ Update: February - 2005
3546    !!
3547    Subroutine Diagonalize_Symm(A,n,E_Val,E_vect)
3548       !---- Arguments ----!
3549       real(kind=cp),           dimension(:,:), intent( in)  :: A
3550       integer,                                 intent( in)  :: n
3551       real(kind=cp),           dimension(:),   intent(out)  :: E_val
3552       real(kind=cp), optional, dimension(:,:), intent(out)  :: E_vect
3553
3554       !---- Local variables ----!
3555       real(kind=cp),        dimension(n,n)   :: aux
3556       real(kind=cp),        dimension(n)     :: e
3557
3558       e_val=0.0
3559       call init_err_mathgen()
3560       if (n > size(A,1) .or. n > size(A,2)) then
3561          ERR_MathGen=.true.
3562          ERR_MathGen_Mess=" Diagonalize_SYMM: Error in dimension of input matrix: A(m,m) with m < n "
3563          return
3564       end if
3565
3566       aux=a(1:n,1:n)
3567       if (present(E_vect)) then
3568          call tred2(aux,n,E_val,e)
3569          call tqli2(E_val,e,n,aux)
3570          call eigsrt(E_val,aux,n,1)
3571          e_vect(1:n,1:n)=aux
3572       else
3573          call tred1(aux,n,E_val,e)
3574          call tqli1(E_val,e,n)
3575          call eigsrt(E_val,aux,n,0)
3576       end if
3577
3578       return
3579    End Subroutine Diagonalize_Symm
3580
3581    !!--++
3582    !!--++ Subroutine Eigsrt(d,v,n,io)
3583    !!--++    real(kind=cp), dimension(:),   intent(in out) :: d
3584    !!--++    real(kind=cp), dimension(:,:), intent(in out) :: v
3585    !!--++    integer,                       intent (in)    :: n
3586    !!--++    integer,                       intent (in)    :: io
3587    !!--++
3588    !!--++    (PRIVATE)
3589    !!--++    Subroutine for sorting eigenvalues in d(n) and eigenvectors
3590    !!--++    in columns of v(n,n). Sorts d(n) in descending order and
3591    !!--++    rearranges v(n,n) correspondingly. The method is the straight
3592    !!--++    insertion. If io=0 order  only the eigenvalues are treated.
3593    !!--++    Adapted from Numerical Recipes. Valid for hermitian matrices
3594    !!--++
3595    !!--++ Update: February - 2005
3596    !!
3597    Subroutine Eigsrt(d,v,n,io)
3598       !---- Arguments ----!
3599       real(kind=cp), dimension(:),   intent(in out) :: d
3600       real(kind=cp), dimension(:,:), intent(in out) :: v
3601       integer,                       intent(in)     :: n
3602       integer,                       intent(in)     :: io
3603
3604       !---- Local Variables ----!
3605       integer          :: i,j,k
3606       real(kind=cp)    :: p
3607
3608       do i=1,n-1
3609          k=i
3610          p=d(i)
3611          do j=i+1,n
3612             if (d(j) >= p) then
3613                k=j
3614                p=d(j)
3615             end if
3616          end do
3617          if (k /= i) then
3618             d(k)=d(i)
3619             d(i)=p
3620             if (io == 1) then
3621                do j=1,n
3622                   p=v(j,i)
3623                   v(j,i)=v(j,k)
3624                   v(j,k)=p
3625                end do
3626             end if
3627          end if
3628       end do
3629
3630       return
3631    End Subroutine Eigsrt
3632
3633    !!----
3634    !!---- Subroutine First_Derivative(x, y, n, d2y, d1y)
3635    !!----    real(kind=cp),    intent(in),     dimension(:) :: x     !  In -> Array X
3636    !!----    real(kind=cp),    intent(in),     dimension(:) :: y     !  In -> Array Yi=F(Xi)
3637    !!----    integer ,         intent(in)                   :: n     !  In -> Dimension of X, Y
3638    !!----    real(kind=cp),    intent(in),     dimension(:) :: d2y   !  In -> array containing second derivatives
3639    !!----                                                                     at the given points
3640    !!----    real(kind=cp),    intent(out),    dimension(:) :: d1y   ! Out -> array containing first derivatives
3641    !!----                                                                     at the given points
3642    !!----
3643    !!----    Calculate the First derivate values of the N points
3644    !!----
3645    !!---- Update: January - 2006
3646    !!
3647    Subroutine First_Derivative(x,y,n,d2y,d1y)
3648       !---- Arguments ----!
3649       real(kind=cp), dimension(:), intent(in)  :: x
3650       real(kind=cp), dimension(:), intent(in)  :: y
3651       integer ,                    intent(in)  :: n
3652       real(kind=cp), dimension(:), intent(in)  :: d2y
3653       real(kind=cp), dimension(:), intent(out) :: d1y
3654
3655       !---- Local Variables ----!
3656       integer       :: i
3657       real(kind=cp) :: step, x0, y0, y1, y2
3658
3659       do i=1,n
3660         if (i /= n) then
3661           step = x(i+1)-x(i)
3662         end if
3663         x0 = x(i) - step/2.0
3664         call splint(x,y, d2y, n, x0, y0)
3665         y1 = y0
3666         x0 = x(i) + step/2
3667         call splint(x,y, d2y, n, x0, y0)
3668         y2 = y0
3669         d1y(i) = (y2 - y1) / step
3670       end do
3671
3672       return
3673    End Subroutine First_Derivative
3674
3675    !!----
3676    !!---- Subroutine In_Sort(id,n,p,q)
3677    !!----    integer, dimension(:), intent(in) :: id  !Integer array to be sorted
3678    !!----    integer,               intent(in) :: n   !Number items in the array
3679    !!----    integer, dimension(:), intent(in) :: p   !Initial pointer from a previous related call
3680    !!----    integer, dimension(:), intent(out):: q   !Final pointer doing the sort of id
3681    !!--<<
3682    !!----    Subroutine to order in ascending mode the integer array "id".
3683    !!----    The input value "n" is the number of items to be ordered in "id".
3684    !!----    The array "p" is the initial pointer to "id" (coming from a previous call)
3685    !!----    The final pointer holding the order of items.
3686    !!-->>
3687    !!----
3688    !!---- Update: November - 2008
3689    !!
3690    Subroutine In_Sort(id,n,p,q)
3691       !---- Arguments ----!
3692       integer, dimension(:), intent(in) :: id  !Integer array to be sorted
3693       integer,               intent(in) :: n   !Number items in the array
3694       integer, dimension(:), intent(in) :: p   !Initial pointer from a previous related call
3695       integer, dimension(:), intent(out):: q   !Final pointer doing the sort of id
3696
3697       !--- Local Variables ----!
3698       integer :: i,j,k,l,m
3699       integer, dimension(:),allocatable :: it
3700
3701       l=minval(id)
3702       m=maxval(id)
3703       l=l-1
3704       m=m-l
3705       allocate(it(m))
3706       it(1:m)=0
3707       do i=1,n
3708          j=id(p(i))-l
3709          it(j)=it(j)+1
3710       end do
3711       j=0
3712       do i=1,m
3713          k=j
3714          j=j+it(i)
3715          it(i)=k
3716       end do
3717       do i=1,n
3718          j=id(p(i))-l
3719          it(j)=it(j)+1
3720          j=it(j)
3721          q(j)=p(i)
3722       end do
3723
3724       return
3725    End Subroutine In_Sort
3726
3727    !!----
3728    !!---- Subroutine Invert_Matrix(a,b,singular,perm)
3729    !!----    real(kind=cp), dimension(:,:),  intent( in) :: a
3730    !!----    real(kind=cp), dimension(:,:),  intent(out) :: b
3731    !!----    LOGICAL,                        intent(out) :: singular
3732    !!----    integer, dimension(:),optional, intent(out) :: perm
3733    !!--<<
3734    !!----    Subroutine to invert a real matrix using LU decomposition.
3735    !!----    In case of singular matrix (singular=.true.) instead of the inverse
3736    !!----    matrix, the subroutine provides the LU decomposed matrix as used
3737    !!----    in Numerical Recipes.
3738    !!----    The input matrix is preserved and its inverse (or its LU decomposition)
3739    !!----    is provided in "b". The optional argument "perm" holds the row permutation
3740    !!----    performed to obtain the LU decomposition.
3741    !!-->>
3742    !!----
3743    !!---- Update: February - 2005
3744    !!
3745    Subroutine Invert_Matrix(a,b,singular,perm)
3746       !---- Arguments ----!
3747       real(kind=cp), dimension(:,:),  intent(in ) :: a
3748       real(kind=cp), dimension(:,:),  intent(out) :: b
3749       logical,                        intent(out) :: singular
3750       integer, dimension(:),optional, intent(out) :: perm
3751
3752       !---- Local variables ----!
3753       integer                                       :: i,n
3754       integer,       dimension(size(a,1))           :: indx
3755       real(kind=cp)                                 :: d, det
3756       real(kind=cp), dimension(size(a,1),size(a,1)) :: lu
3757
3758       n=size(a,1)
3759       lu=a(1:n,1:n)
3760
3761       call LU_Decomp(lu,d,singular,indx)
3762       if (present(perm)) perm(1:n)=indx(1:n)
3763
3764       if (singular) then
3765          b=lu
3766          return
3767       else
3768          det=0.0
3769          do i=1,n
3770             d=d*sign(1.0_cp,lu(i,i))
3771             det=det + log(abs(lu(i,i)))
3772          end do
3773          det=d*exp(det)
3774          if (abs(det) <= 1.0e-36) then
3775             singular=.true.
3776             b=lu
3777             return
3778          end if
3779       end if
3780
3781       b=0.0
3782       do i=1,n
3783          b(i,i)=1.0
3784          call LU_backsub(lu,indx,b(:,i))
3785       end do
3786
3787       return
3788    End Subroutine Invert_Matrix
3789
3790    !!----
3791    !!---- Subroutine Linear_Dependent(a,na,b,nb,mb,info)
3792    !!----    complex/integer/real(kind=cp), dimension(:),   intent(in)  :: a
3793    !!----    complex/integer/real(kind=cp), dimension(:,:), intent(in)  :: b
3794    !!----    integer,                                       intent(in)  :: na,nb,mb
3795    !!----    logical,                                       intent(out) :: info
3796    !!--<<
3797    !!----    Provides the value .TRUE. if the vector A is linear dependent of the
3798    !!----    vectors constituting the rows (columns) of the matrix B. In input nb & mb
3799    !!----    are the number of rows and columns of B to be considered. The actual
3800    !!----    dimension of vector a should be na=max(nb,mb).
3801    !!----    The problem is equivalent to determine the rank (in algebraic sense)
3802    !!----    of the composite matrix C(nb+1,mb)=(B/A) or C(nb,mb+1)=(B|A). In the first
3803    !!----    case it is supposed that na = mb and in the second na = nb.
3804    !!----    and the rank of B is min(nb, mb). If na /= nb and na /= mb an error condition
3805    !!----    is generated. The function uses floating arithmetic for all types.
3806    !!-->>
3807    !!----
3808    !!---- Update: February - 2005
3809    !!
3810
3811    !!--++
3812    !!--++ Subroutine Linear_DependentC(a,na,b,nb,mb,info)
3813    !!--++    complex, dimension(:),   intent(in)  :: a
3814    !!--++    complex, dimension(:,:), intent(in)  :: b
3815    !!--++    integer,                 intent(in)  :: na,nb,mb
3816    !!--++    logical,                 intent(out) :: info
3817    !!--++
3818    !!--++    (OVERLOADED)
3819    !!--++    Provides the value .TRUE. if the vector A is linear dependent of the
3820    !!--++    vectors constituting the rows (columns) of the matrix B. In input nb & mb
3821    !!--++    are the number of rows and columns of B to be considered. The actual
3822    !!--++    dimension of vector a should be na=max(nb,mb).
3823    !!--++    The problem is equivalent to determine the rank (in algebraic sense)
3824    !!--++    of the composite matrix C(nb+1,mb)=(B/A) or C(nb,mb+1)=(B|A). In the first
3825    !!--++    case it is supposed that na = mb and in the second na = nb.
3826    !!--++    and the rank of B is min(nb, mb). If na /= nb and na /= mb an error condition
3827    !!--++    is generated
3828    !!--++
3829    !!--++    For the case of complex vectors in Cn the problem can be reduced to real vectors
3830    !!--++    of dimension R2n. Each complex vector contributes as two real vectors of dimension
3831    !!--++    2n: (R,I) and (-I,R). A complex vector V is linearly dependent on n complex vectors
3832    !!--++    if V can be written as: V = Sigma{j=1,n}(Cj.Vj), with Cj complex numbers and Vj
3833    !!--++    having n complex components. One may write:
3834    !!--++
3835    !!--++     V = Sigma{j=1,n}(Cj.Vj)
3836    !!--++     (R,I) = Sigma{j=1,n} (Cjr Vj + i Cji Vj) = Sigma{j=1,n} (Cjr (Rj,Ij) +  Cji (-Ij,Rj) )
3837    !!--++     (R,I) = Sigma{j=1,n} (aj (Rj,Ij) + bj (-Ij,Rj) )  = Sigma{j=1,2n} (Aj.Uj)
3838    !!--++     Were Uj=(Rj,Ij) and U(j+1)= (-Ij,Rj)
3839    !!--++
3840    !!--++    The function uses floating arithmetic for all types.
3841    !!--++
3842    !!--++ Update: February - 2005
3843    !!
3844    Subroutine Linear_DependentC(A,na,B,nb,mb,info)
3845       !---- Arguments ----!
3846       complex, dimension(:),   intent(in)  :: a
3847       complex, dimension(:,:), intent(in)  :: b
3848       integer,                 intent(in)  :: na,nb,mb
3849       logical,                 intent(out) :: info
3850
3851       !---- Local variables ----!
3852       integer                                                     :: r,n1
3853       real(kind=dp), parameter                                    :: tol= 100.0_dp*deps
3854       real(kind=dp), dimension(2*max(nb+1,mb+1),2*max(nb+1,mb+1)) :: c
3855
3856       c=0.0
3857       call init_err_mathgen()
3858       info=.true.
3859       if (nb > size(b,1) .or. mb > size(b,2) .or. na > size(a) ) then
3860          ERR_MathGen=.true.
3861          ERR_MathGen_Mess=" Linear_DependentC: Error in dimension of input matrix or vector"
3862          return
3863       end if
3864
3865       if ( na == mb) then
3866          n1=2*nb+1
3867          if(n1+1 > 2*mb) return !the vector is linear dependent
3868          c(1:nb,           1:mb) =  real(b(1:nb,1:mb))
3869          c(1:nb,     mb+1:mb+na) = aimag(b(1:nb,1:mb))
3870          c(nb+1:2*nb,      1:mb) =-aimag(b(1:nb,1:mb))
3871          c(nb+1:2*nb,mb+1:mb+na) =  real(b(1:nb,1:mb))
3872          c(n1,             1:mb) =  real(a(1:na))
3873          c(n1,      mb+1:mb+na ) = aimag(a(1:na))
3874          c(n1+1,           1:mb) =-aimag(a(1:na))
3875          c(n1+1,    mb+1:mb+na ) =  real(a(1:na))
3876          call rank(c,tol,r)
3877          if(r == min(n1+1,2*mb)) info=.false.
3878       else if( na == nb) then
3879          n1=2*mb+1
3880          if(n1+1 > 2*nb) return !the vector is linear dependent
3881          c(1:nb,           1:mb) =  real(b(1:nb,1:mb))
3882          c(nb+1:nb+na,     1:mb) = aimag(b(1:nb,1:mb))
3883          c(1:nb,      mb+1:2*mb) =-aimag(b(1:nb,1:mb))
3884          c(nb+1:nb+na,mb+1:2*mb) =  real(b(1:nb,1:mb))
3885          c(1:na,             n1) =  real(a(1:na))
3886          c(nb+1:nb+na,       n1) = aimag(a(1:na))
3887          c(1:na,           1+n1) =-aimag(a(1:na))
3888          c(nb+1:nb+na,     1+n1) =  real(a(1:na))
3889          call rank(c,tol,r)
3890          if(r == min(n1+1,2*nb)) info=.false.
3891       else
3892          ERR_MathGen=.true.
3893          ERR_MathGen_Mess=" Linear_DependentC: input dimension of vector incompatible with matrix"
3894       end if
3895
3896       return
3897    End Subroutine Linear_DependentC
3898
3899    !!--++
3900    !!--++ Subroutine Linear_DependentI(a,na,b,nb,mb,info)
3901    !!--++    integer, dimension(:),   intent(in)  :: a
3902    !!--++    integer, dimension(:,:), intent(in)  :: b
3903    !!--++    integer,                 intent(in)  :: na,nb,mb
3904    !!--++    logical,                 intent(out) :: info
3905    !!--++
3906    !!--++    (OVERLOADED)
3907    !!--++    Provides the value .TRUE. if the vector A is linear dependent of the
3908    !!--++    vectors constituting the rows (columns) of the matrix B. In input nb & mb
3909    !!--++    are the number of rows and columns of B to be considered. The actual
3910    !!--++    dimension of vector a should be na=max(nb,mb).
3911    !!--++    The problem is equivalent to determine the rank (in algebraic sense)
3912    !!--++    of the composite matrix C(nb+1,mb)=(B/A) or C(nb,mb+1)=(B|A). In the first
3913    !!--++    case it is supposed that na = mb and in the second na = nb.
3914    !!--++    and the rank of B is min(nb, mb). If na /= nb and na /= mb an error condition
3915    !!--++    is generated
3916    !!--++    The function uses floating arithmetic for all types.
3917    !!--++
3918    !!--++ Update: February - 2005
3919    !!
3920    Subroutine Linear_DependentI(A,na,B,nb,mb,info)
3921       !---- Arguments ----!
3922       integer, dimension(:),   intent(in)  :: a
3923       integer, dimension(:,:), intent(in)  :: b
3924       integer,                 intent(in)  :: na,nb,mb
3925       logical,                 intent(out) :: info
3926
3927       !---- Local variables ----!
3928       integer                                                 :: r,n1
3929       real(kind=dp), parameter                                :: tol= 100.0_dp*deps
3930       real(kind=dp), dimension(max(nb+1,mb+1),max(nb+1,mb+1)) :: c
3931
3932       c=0.0
3933       call init_err_mathgen()
3934       info=.true.
3935       if (nb > size(b,1) .or. mb > size(b,2) .or. na > size(a) ) then
3936          ERR_MathGen=.true.
3937          ERR_MathGen_Mess=" Linear_DependentI: Error in dimension of input matrix or vector"
3938          return
3939       end if
3940
3941       if ( na == mb) then
3942          n1=nb+1
3943          if(n1 > mb) return !the vector is linear dependent
3944          c(1:nb,1:mb)=real(b(1:nb,1:mb))
3945          c(n1,  1:mb)=real(a(1:na))      !C(nb+1,mb)
3946          call rank(c,tol,r)
3947          if(r == min(n1,mb)) info=.false.
3948       else if( na == nb) then
3949          n1=mb+1
3950          if(n1 > nb) return !the vector is linear dependent
3951          c(1:nb,1:mb)=real(b(1:nb,1:mb))
3952          c(1:nb,  n1)=real(a(1:na))     !C(nb,mb+1)
3953          call rank(c,tol,r)
3954          if(r == min(n1,nb)) info=.false.
3955       else
3956          ERR_MathGen=.true.
3957          ERR_MathGen_Mess=" Linear_DependentI: input dimension of vector incompatible with matrix"
3958       end if
3959
3960       return
3961    End Subroutine Linear_DependentI
3962
3963    !!--++
3964    !!--++ Subroutine Linear_DependentR(a,na,b,nb,mb,info)
3965    !!--++    real(kind=cp), dimension(:),   intent(in)  :: a
3966    !!--++    real(kind=cp), dimension(:,:), intent(in)  :: b
3967    !!--++    integer,                       intent(in)  :: na,nb,mb
3968    !!--++    logical,                       intent(out) :: info
3969    !!--++
3970    !!--++    (OVERLOADED)
3971    !!--++    Provides the value .TRUE. if the vector A is linear dependent of the
3972    !!--++    vectors constituting the rows (columns) of the matrix B. In input nb & mb
3973    !!--++    are the number of rows and columns of B to be considered. The actual
3974    !!--++    dimension of vector a should be na=max(nb,mb).
3975    !!--++    The problem is equivalent to determine the rank (in algebraic sense)
3976    !!--++    of the composite matrix C(nb+1,mb)=(B/A) or C(nb,mb+1)=(B|A). In the first
3977    !!--++    case it is supposed that na = mb and in the second na = nb.
3978    !!--++    and the rank of B is min(nb, mb). If na /= nb and na /= mb an error condition
3979    !!--++    is generated
3980    !!--++    The function uses floating arithmetic for all types.
3981    !!--++
3982    !!--++ Update: February - 2005
3983    !!
3984    Subroutine Linear_DependentR(A,na,B,nb,mb,info)
3985       !---- Arguments ----!
3986       real(kind=cp), dimension(:),   intent(in)  :: a
3987       real(kind=cp), dimension(:,:), intent(in)  :: b
3988       integer,                       intent(in)  :: na,nb,mb
3989       logical,                       intent(out) :: info
3990
3991       !---- Local Variables ----!
3992       integer                                                 :: r,n1
3993       real(kind=dp), parameter                                :: tol= 100.0_dp*deps
3994       real(kind=dp), dimension(max(nb+1,mb+1),max(nb+1,mb+1)) :: c
3995
3996       c=0.0
3997       call init_err_mathgen()
3998       info=.true.
3999       if (nb > size(b,1) .or. mb > size(b,2) .or. na > size(a) ) then
4000          ERR_MathGen=.true.
4001          ERR_MathGen_Mess=" Linear_DependentR: Error in dimension of input matrix or vector"
4002          return
4003       end if
4004
4005       if ( na == mb) then    !Vector added as an additional row
4006          n1=nb+1
4007          if(n1 > mb) return !the vector is linear dependent
4008          c(1:nb,1:mb)=b(1:nb,1:mb)
4009          c(n1,  1:mb)=a(1:na)      !C(nb+1,mb)
4010          call rank(c,tol,r)
4011          if(r == min(n1,mb)) info=.false.
4012       else if( na == nb) then   !Vector added as an additional column
4013          n1=mb+1
4014          if(n1 > nb) return !the vector is linear dependent
4015          c(1:nb,1:mb)=b(1:nb,1:mb)
4016          c(1:nb,  n1)=a(1:na)     !C(nb,mb+1)
4017          call rank(c,tol,r)
4018          if(r == min(n1,nb)) info=.false.
4019       else
4020          ERR_MathGen=.true.
4021          ERR_MathGen_Mess=" Linear_DependentR: input dimension of vector incompatible with matrix"
4022       end if
4023
4024       return
4025    End Subroutine Linear_DependentR
4026
4027    !!----
4028    !!---- Subroutine LU_Backsub(a,indx,b)
4029    !!----    real(kind=cp),    dimension(:,:),intent(in)     :: a
4030    !!----    integer,          dimension(:),  intent(in)     :: indx
4031    !!----    real(kind=cp),    dimension(:),  intent(in out) :: b
4032    !!--<<
4033    !!----    Adapted from Numerical Recipes.
4034    !!----    Solves the set of N linear equations A  X = B. Here the N x N matrix A is input,
4035    !!----    not as the original matrix A, but rather as its LU decomposition, determined
4036    !!----    by the routine LU_DECOMP. INDX is input as the permutation vector of length N
4037    !!----    returned by LU_DECOMP. B is input as the right-hand-side vector B,
4038    !!----    also of length N, and returns with the solution vector X.
4039    !!----    A and INDX are not modified by this routine and can be left in place for successive calls
4040    !!----    with different right-hand sides B. This routine takes into account the possibility that B will
4041    !!----    begin with many zero elements, so it is efficient for use in matrix inversion.
4042    !!-->>
4043    !!----
4044    !!---- Update: February - 2005
4045    !!
4046    Subroutine LU_Backsub(a,indx,b)
4047       !---- Arguments ----!
4048       real(kind=cp), dimension(:,:), intent(in)     :: a
4049       integer,         dimension(:), intent(in)     :: indx
4050       real(kind=cp),   dimension(:), intent(in out) :: b
4051
4052       !---- Local Variables ----!
4053       integer       :: i,ii,ll,n
4054       real(kind=cp) :: summ
4055
4056       n=size(a,1)
4057       ii=0              !When ii is set to a positive value, it will become the index
4058       do i=1,n          !of the first nonvanishing element of b. We now do
4059          ll=indx(i)     !the forward substitution. The only new wrinkle is to
4060          summ=b(ll)     !unscramble the permutation as we go.
4061          b(ll)=b(i)
4062          if (ii /= 0) then
4063             summ=summ-dot_product(a(i,ii:i-1),b(ii:i-1))
4064          else if(summ /= 0.0) then   !A nonzero element was encountered, so from now on
4065             ii=i                       !we will have to do the dot product above.
4066          end if
4067          b(i)=summ
4068       end do
4069
4070       do i=n,1,-1       !Now we do the backsubstitution
4071          b(i) = (b(i)-dot_product(a(i,i+1:n),b(i+1:n)))/a(i,i)
4072       end do
4073
4074       return
4075    End Subroutine LU_Backsub
4076
4077    !!----
4078    !!---- Subroutine LU_Decomp(a,d,singular,indx)
4079    !!----    real(kind=cp),    dimension(:,:),intent(in out) :: a
4080    !!----    real(kind=cp),                   intent(out)    :: d
4081    !!----    logical,                         intent(out)    :: singular
4082    !!----    integer, dimension(:), optional, intent(out)    :: indx
4083    !!--<<
4084    !!----    Subroutine to make the LU decomposition of an input matrix A.
4085    !!----    The input matrix is destroyed and replaced by a matrix containing
4086    !!----    in its upper triangular part (plus diagonal) the matrix U. The
4087    !!----    lower triangular part contains the nontrivial part (Lii=1) of matrix L.
4088    !!----    The output is rowwise permutation of the initial matrix. The vector INDX
4089    !!----    recording the row permutation. D is output as +/-1 depending on whether
4090    !!----    the number of row interchanges was even or odd, respectively.
4091    !!-->>
4092    !!----
4093    !!---- Update: February - 2005
4094    !!
4095    Subroutine LU_Decomp(a,d,singular,indx)
4096       !---- Arguments ----!
4097       real(kind=cp), dimension(:,:), intent(in out) :: a
4098       real(kind=cp),                 intent(out)    :: d
4099       logical,                       intent(out)    :: singular
4100       integer,  dimension(:), intent(out), optional :: indx
4101
4102       !---- Local variables ----!
4103       real(kind=cp), dimension(size(a,1)):: vv  !vv stores the implicit scaling of each row.
4104       real(kind=cp), parameter           :: vtiny = 1.0e-20_sp !A small number.
4105       integer                            :: j,imax,n
4106
4107       singular=.false.
4108       n=size(a,1)
4109       d=1.0                      !No row interchanges yet.
4110       vv=maxval(abs(a),dim=2)    !Loop over rows to get the implicit scaling information.
4111       if (any(abs(vv) <= vtiny)) then   !There is a row of zeros.
4112          singular=.true.
4113          return
4114       end if
4115       vv=1.0_sp/vv     !Save the scaling.
4116       do j=1,n
4117          imax=(j-1)+imaxloc(vv(j:n)*abs(a(j:n,j)))   !Find the pivot row.
4118          if (j /= imax) then                         !Do we need to interchange rows?
4119             call swap(a(imax,:),a(j,:))              !Yes, do so...
4120             d=-d                                     !...and change the parity of d.
4121             vv(imax)=vv(j)                           !Also interchange the scale factor.
4122          end if
4123          if (present(indx)) indx(j)=imax
4124          if (abs(a(j,j)) <= vtiny) then !If the pivot element is zero the matrix is singular.
4125             a(j,j)=vtiny                !(at least to the precision of the algorithm)
4126             singular=.true.             !For some applications on singular matrices,
4127             return                      !it is desirable to substitute vtiny for zero.
4128          end if                         !This is actually the present case
4129          a(j+1:n,j)=a(j+1:n,j)/a(j,j)                                    !Divide by the pivot element.
4130          a(j+1:n,j+1:n)=a(j+1:n,j+1:n)-outerprod(a(j+1:n,j),a(j,j+1:n))  !Reduce remaining submatrix.
4131       end do
4132
4133       return
4134    End Subroutine LU_Decomp
4135
4136    !!----
4137    !!---- Subroutine Matinv(a,n)
4138    !!----    real(kind=cp), dimension(:,:),intent(in out) :: a
4139    !!----    integer     ,                 intent(in)     :: n
4140    !!----
4141    !!----  Subroutine for inverting a real square matrix.
4142    !!----  The input matrix is replaced in output with its inverse.
4143    !!----
4144    !!---- Update: February - 2005
4145    !!
4146    Subroutine Matinv(a,n)
4147       !---- Arguments ----!
4148       real(kind=cp), dimension(:,:), intent(in out) :: a
4149       integer     ,                  intent(in)     :: n
4150
4151       !---- Local variables ----!
4152       real(kind=cp)                 :: amax,savec
4153       integer, dimension(size(a,1)) :: ik,jk
4154       integer                       :: i,j,k,l
4155
4156       !---- Subroutine to invert a real matrix ----!
4157       do k=1,n
4158          amax=0.0
4159          do
4160             do
4161                do i=k,n
4162                   do j=k,n
4163                      if (abs(amax)-abs(a(i,j)) > 0.0) cycle
4164                      amax=a(i,j)
4165                      ik(k)=i
4166                      jk(k)=j
4167                   end do
4168                end do
4169                i=ik(k)
4170                if (i-k < 0) cycle
4171                exit
4172             end do
4173
4174             if (i-k /= 0) then
4175                do j=1,n
4176                   savec=a(k,j)
4177                   a(k,j)=a(i,j)
4178                   a(i,j)=-savec
4179                end do
4180             end if
4181
4182             j=jk(k)
4183             if (j-k < 0) cycle
4184             exit
4185          end do
4186
4187          if (j-k /= 0) then
4188             do i=1,n
4189                savec=a(i,k)
4190                a(i,k)=a(i,j)
4191                a(i,j)=-savec
4192             end do
4193          end if
4194
4195          do i=1,n
4196             if (i-k /= 0)  then
4197                a(i,k)=-a(i,k)/amax
4198             end if
4199          end do
4200          do i=1,n
4201             do j=1,n
4202                if (i-k == 0 .or. j-k == 0) cycle
4203                a(i,j)=a(i,j)+a(i,k)*a(k,j)
4204             end do
4205          end do
4206          do j=1,n
4207             if (j-k == 0)   cycle
4208             a(k,j)=a(k,j)/amax
4209          end do
4210          a(k,k)=1.0/amax
4211       end do     !k
4212
4213       do l=1,n
4214          k=n-l+1
4215          j=ik(k)
4216          if (j-k > 0) then
4217             do i=1,n
4218                savec=a(i,k)
4219                a(i,k)=-a(i,j)
4220                a(i,j)=savec
4221             end do
4222          end if
4223          i=jk(k)
4224          if (i-k > 0) then
4225             do j=1,n
4226                savec=a(k,j)
4227                a(k,j)=-a(i,j)
4228                a(i,j)=savec
4229             end do
4230          end if
4231       end do
4232
4233       return
4234    End Subroutine Matinv
4235
4236    !!--++
4237    !!--++ Subroutine Partition(A, marker)
4238    !!--++    character(len=*), dimension(:), intent(in out) :: A
4239    !!--++    integer,                        intent(out)    :: marker
4240    !!--++
4241    !!--++    (Private)
4242    !!--++    Utilised by Sort_Strings.
4243    !!--++
4244    !!--++ Update: February - 2005
4245    !!
4246    Subroutine Partition(A, Marker)
4247       !---- Arguments ----!
4248       character(len=*), dimension(:), intent(in out) :: A
4249       integer,                        intent(   out) :: marker
4250
4251       !---- Local variables ----!
4252       integer                  :: i, j
4253       character(len=len(A(1))) :: temp
4254       character(len=len(A(1))) :: x      ! pivot point
4255
4256       x = A(1)
4257       i= 0
4258       j= size(A) + 1
4259
4260       do
4261          j = j-1
4262          do
4263             if (A(j) <= x) exit
4264             j = j-1
4265          end do
4266          i = i+1
4267          do
4268             if (A(i) >= x) exit
4269             i = i+1
4270          end do
4271          if (i < j) then
4272             !---- exchange A(i) and A(j)
4273             temp = A(i)
4274             A(i) = A(j)
4275             A(j) = temp
4276          else if (i == j) then
4277             marker = i+1
4278             return
4279          else
4280             marker = i
4281             return
4282          end if
4283       end do
4284
4285       return
4286    End Subroutine Partition
4287
4288    !!----
4289    !!---- Subroutine Points_In_Line2D(X1, XN, N, XP)
4290    !!----    real(kind=cp), dimension(2),   intent(in)  :: X1   ! Point1 in 2D
4291    !!----    real(kind=cp), dimension(2),   intent(in)  :: XN   ! PointN in 2D
4292    !!----    integer,                       intent(in)  :: N    ! Number of Total points
4293    !!----    real(kind=cp), dimension(:,:), intent(out) :: XP   ! List of points
4294    !!----
4295    !!----    The routine calculate N points belonging to the line defined
4296    !!----    by X1 and Xn with equal distance between them. XP contains
4297    !!----    X1,X2,.....,XN points.
4298    !!----
4299    !!---- Update: April 2008
4300    !!
4301    Subroutine Points_In_Line2D(X1, XN, N, XP)
4302       !---- Arguments ----!
4303       real(kind=cp), dimension(2),   intent(in)  :: X1   ! Point1 in 2D
4304       real(kind=cp), dimension(2),   intent(in)  :: XN   ! PointN in 2D
4305       integer,                       intent(in)  :: N    ! Number of Total points
4306       real(kind=cp), dimension(:,:), intent(out) :: XP   ! List of points
4307
4308       !---- Local Variables ----!
4309       integer :: i
4310       real(kind=cp)    :: ml,bl,dl,t
4311       real(kind=cp)    :: a,b,c,d
4312       real(kind=cp)    :: xa,xb
4313
4314       xp=0.0
4315
4316       if (n <= 1) return
4317
4318       !---- Calculating the distance between two points to
4319       !---- eliminate rare considerations as the same point
4320       dl=sqrt( (xn(1)-x1(1))**2 + (xn(2)-x1(2))**2 )
4321       if (dl <= 0.0001) return
4322
4323       !---- When N=2 is trivial case ----!
4324       if (n == 2) then
4325          xp(:,1)=x1
4326          xp(:,2)=xn
4327          return
4328       end if
4329
4330       !---- Case 1: Y=cte ----!
4331       !Xn(2) and X1(2) are equal, then we have a line  with Y=cte
4332       if (abs(xn(2)-x1(2)) <= 0.0001) then
4333          dl=abs(xn(1)-x1(1))
4334          d=dl/real(n-1)
4335          xp(:,1)=x1
4336          if (xn(1) > x1(1)) then
4337             do i=2,n-1
4338                xp(1,i)=xp(1,i-1)+d
4339                xp(2,i)=xp(2,1)
4340             end do
4341          else
4342             do i=2,n-1
4343                xp(1,i)=xp(1,i-1)-d
4344                xp(2,i)=xp(2,1)
4345             end do
4346          end if
4347          xp(:,n)=xn
4348
4349          return
4350       end if
4351
4352       !---- Case 2: X=cte ----!
4353       !Xn(1) - X1(1) are equal, then we have a line with X=cte
4354       if (abs(xn(1)-x1(1)) <= 0.0001) then
4355          dl=abs(xn(2)-x1(2))
4356          d=dl/real(n-1)
4357          xp(:,1)=x1
4358          if (xn(2) > x1(2)) then
4359             do i=2,n-1
4360                xp(1,i)=xp(1,1)
4361                xp(2,i)=xp(2,i-1)+d
4362             end do
4363          else
4364             do i=2,n-1
4365                xp(1,i)=xp(1,1)
4366                xp(2,i)=xp(2,i-1)-d
4367             end do
4368          end if
4369          xp(:,n)=xn
4370
4371          return
4372       end if
4373
4374       !---- Case 3: General case ----!
4375       ml=(x1(2)-xn(2))/(x1(1)-xn(1))
4376       bl=x1(2) - (ml * x1(1))
4377
4378       !---- Distance between X1 and XN ----!
4379       dl=sqrt( (xn(1)-x1(1))**2 + (xn(2)-x1(2))**2 )
4380
4381       !---- Creating the list ----!
4382       a=ml**2 + 1.0
4383       b=2.0 *( ml*(bl-x1(2)) -x1(1) )
4384
4385       xp(:,1)=x1
4386       do i=2,n-1
4387          t=(dl**2)*((real(i-1)/real(n-1))**2)
4388          c=(x1(2)-bl)**2 + x1(1)**2 - t
4389
4390          xa=(-b + sqrt(b**2 - 4.0*a*c))/(2.0*a)
4391          xb=(-b - sqrt(b**2 - 4.0*a*c))/(2.0*a)
4392          if (x1(1) <= xa .and. xa <= xn(1)) then
4393             xp(1,i)=xa
4394             xp(2,i)=ml*xa+bl
4395          else
4396             xp(1,i)=xb
4397             xp(2,i)=ml*xb+bl
4398          end if
4399       end do
4400       xp(:,n)=xn
4401
4402       return
4403    End Subroutine Points_In_Line2D
4404
4405    !!----
4406    !!---- Subroutine Rank(a,tol,r)
4407    !!----    real(sp/dp), dimension(:,:), intent( in) :: a
4408    !!----    real(sp/dp),                 intent( in) :: tol
4409    !!----    integer,                     intent(out) :: r
4410    !!----
4411    !!----    Computes the rank (in algebraic sense) of the rectangular matrix A.
4412    !!----
4413    !!---- Update: February - 2005
4414    !!
4415
4416    !!--++
4417    !!--++ Subroutine Rank_dp(a,tol,r)
4418    !!--++    real(dp), dimension(:,:), intent( in) :: a
4419    !!--++    real(dp),                 intent( in) :: tol
4420    !!--++    integer,                  intent(out) :: r
4421    !!--++
4422    !!--++    (OVERLOADED)
4423    !!--++    Computes the rank (in algebraic sense) of the rectangular matrix A.
4424    !!--++
4425    !!--++ Update: February - 2005
4426    !!
4427    Subroutine Rank_dp(a,tol,r)
4428       !---- Arguments ----!
4429       real(kind=dp), dimension(:,:),intent( in)      :: a
4430       real(kind=dp),                intent( in)      :: tol
4431       integer,                      intent(out)      :: r
4432
4433       !---- Arguments ----!
4434       real(kind=dp), dimension(size(a,1),size(a,2))  :: u
4435       real(kind=dp), dimension(size(a,2))            :: w
4436       real(kind=dp), dimension(size(a,2),size(a,2))  :: v
4437       integer                                        :: i
4438
4439       u=a
4440       call svdcmp(u,w,v)
4441       if (ERR_MathGen) then
4442          r=0
4443       else
4444          r=0
4445          do i=1,size(a,2)
4446             if(w(i) > tol) r=r+1
4447          end do
4448       end if
4449
4450       return
4451    End Subroutine Rank_dp
4452
4453    !!--++
4454    !!--++ Subroutine Rank_sp(a,tol,r)
4455    !!--++    real(sp), dimension(:,:), intent( in) :: a
4456    !!--++    real(sp),                 intent( in) :: tol
4457    !!--++    integer,                  intent(out) :: r
4458    !!--++
4459    !!--++    (OVERLOADED)
4460    !!--++    Computes the rank (in algebraic sense) of the rectangular matrix A.
4461    !!--++
4462    !!--++ Update: February - 2005
4463    !!
4464    Subroutine Rank_sp(a,tol,r)
4465       !---- Arguments ----!
4466       real(kind=sp), dimension(:,:),intent( in)      :: a
4467       real(kind=sp),                intent( in)      :: tol
4468       integer,                      intent(out)      :: r
4469
4470       !---- Local variables ----!
4471       real(kind=sp), dimension(size(a,1),size(a,2))  :: u
4472       real(kind=sp), dimension(size(a,2))            :: w
4473       real(kind=sp), dimension(size(a,2),size(a,2))  :: v
4474       integer :: i
4475
4476       u=a
4477       call svdcmp(u,w,v)
4478       if (ERR_MathGen) then
4479          r=0
4480       else
4481          r=0
4482          do i=1,size(a,2)
4483             if(w(i) > tol) r=r+1
4484          end do
4485       end if
4486
4487       return
4488    End Subroutine Rank_sp
4489
4490    !!----
4491    !!---- Subroutine Second_Derivative(x, y, n, d2y)
4492    !!----    real(kind=cp),    intent(in),     dimension(n) :: x     !  In -> Array X
4493    !!----    real(kind=cp),    intent(in),     dimension(n) :: y     !  In -> Array Yi=F(Xi)
4494    !!----    integer ,         intent(in)                   :: n     !  In -> Dimension of X, Y
4495    !!----    real(kind=cp),    intent(out),    dimension(n) :: d2y    ! Out -> array containing second derivatives
4496    !!----                                                                     at the given points
4497    !!----
4498    !!----    Calculate the second derivate of N Points
4499    !!----
4500    !!---- Update: January - 2006
4501    !!
4502    Subroutine Second_Derivative(x,y,n,d2y)
4503       !---- Arguments ----!
4504       real(kind=cp), dimension(:), intent(in)  :: x
4505       real(kind=cp), dimension(:), intent(in)  :: y
4506       integer ,                    intent(in)  :: n
4507       real(kind=cp), dimension(:), intent(out) :: d2y
4508
4509       !---- Local Variables ----!
4510       integer                     :: i, k
4511       real(kind=cp), dimension(n) :: u
4512       real(kind=cp)               :: yp1, ypn, sig, p, qn, un
4513
4514       yp1=(y(2) - y(1))   / (x(2) - x(1))     ! derivative at point 1
4515       ypn=(y(n) - y(n-1)) / (x(n) - x(n-1))   ! derivative at point n
4516
4517       d2y(1)=-0.5
4518       u(1)=(3.0/(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
4519
4520       do i=2,n-1
4521          sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
4522          p=sig*d2y(i-1)+2.0
4523          d2y(i)=(sig-1.0)/p
4524          u(i)=(6.0*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))  &
4525               /(x(i+1)-x(i-1))-sig*u(i-1))/p
4526       end do
4527
4528       qn=0.5
4529       un=(3.0/(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
4530       d2y(n)=(un-qn*u(n-1))/(qn*d2y(n-1)+1.0)
4531       do k=n-1,1,-1
4532          d2y(k)=d2y(k)*d2y(k+1)+u(k)
4533       end do
4534
4535       return
4536    End Subroutine Second_Derivative
4537
4538    !!----
4539    !!---- Subroutine SmoothingVec(Y, N, NIter, Ys)
4540    !!----    real(kind=cp),    dimension(:),           intent(in out) :: Y      !  In Out-> Array to be smoothed
4541    !!----    integer,                                  intent(in)     :: N      !  In -> Number of points
4542    !!----    integer,                                  intent(in)     :: NIter  !  In -> Number of iterations
4543    !!----    real(kind=cp),    dimension(:), optional, intent(out)    :: datY   !  Out-> Array smoothed
4544    !!----
4545    !!----    Procedure to smooth the array values
4546    !!----
4547    !!---- Update: January - 2006
4548    !!
4549    Subroutine SmoothingVec(Y, N, Niter, Ys)
4550       !---- Arguments ----!
4551       real(kind=cp),dimension(:),            intent(in out) :: Y
4552       integer,                               intent(in)     :: n
4553       integer,                               intent(in)     :: niter
4554       real(kind=cp),dimension(:), optional,  intent(out)    :: Ys
4555
4556       !---- Local Variables ----!
4557       integer                     :: n1, n2
4558       integer                     :: i, iter
4559       real(kind=cp), dimension (n):: datYs
4560
4561
4562       n1 = 4
4563       n2 = n-3
4564
4565       do iter = 1 ,niter
4566          datYs(n1-1)=((Y(n1-2)+Y(n1))*10.0+(Y(n1-3)+Y(n1+1))*5.0+Y(n1+2))/31.0
4567          datYs(n1-2)=((Y(n1-3)+Y(n1-1))*10.0+Y(n1)*5.0+Y(n1+1))/26.0
4568          datYs(n1-3)=(Y(n1-2)*10.0+Y(n1-1)*5.0+Y(n1))/16.0
4569
4570          do i=n1,n2
4571             datYs(i)=(Y(i-3)+Y(i+3)+5.0*(Y(i-2)+Y(i+2))+10.0*(Y(i-1)+Y(i+1)))/ 32.0
4572          end do
4573
4574          datYs(n2+1)=((Y(n2+2)+Y(n2))*10.0+(Y(n2+3)+Y(n2-1))*5.0+Y(n2-2))/31.0
4575          datYs(n2+2)=((Y(n2+3)+Y(n2+1))*10.0+Y(n2)*5.0+Y(n2-1))/26.0
4576          datYs(n2+3)=(Y(n2+2)*10.0+Y(n2+1)*5.0+Y(n2))/16.0
4577
4578          if(present(Ys)) then
4579             Ys(1:n) = datYs(1:n)
4580          else
4581             Y(1:n) = datYs(1:n)
4582          end if
4583       end do
4584
4585       return
4586    End Subroutine SmoothingVec
4587
4588    !!---
4589    !!---- Subroutine Sort(a,n,indx)
4590    !!----    integer/real(kind=cp)  dimension(:), intent( in) :: a
4591    !!----    integer,                             intent( in) :: n
4592    !!----    integer,               dimension(:), intent(out) :: indx
4593    !!----
4594    !!----    Sort an array such the a(indx(j)) is in ascending
4595    !!----    order for j=1,2,...,N.
4596    !!----
4597    !!---- Update: February - 2005
4598    !!
4599
4600    !!--++
4601    !!--++ Subroutine Sort_I(Arr,N,Indx)
4602    !!--++    integer, dimension(:), intent( in) :: arr
4603    !!--++    integer,               intent( in) :: n
4604    !!--++    integer, dimension(:), intent(out) :: indx
4605    !!--++
4606    !!--++    (OVERLOADED)
4607    !!--++    Sort an array such the arr(indx(j)) is in ascending
4608    !!--++    order for j=1,2,...,N.
4609    !!--++
4610    !!--++ Update: February - 2005
4611    !!
4612    Subroutine Sort_I(arr,n,indx)
4613       !---- Arguments ----!
4614       integer, dimension(:), intent(in ) :: arr
4615       integer              , intent(in ) :: n
4616       integer, dimension(:), intent(out) :: indx
4617
4618       !---- Local Variables ----!
4619       integer, parameter           :: m=7
4620       integer, parameter           :: nstack=50  !nstack=2log2(n)
4621       integer, dimension(nstack)   :: istack
4622       integer                      :: i,indxt,ir,itemp,j,jstack,k,l
4623       integer                      :: a
4624
4625       call init_Err_MathGen()
4626       do j=1,n
4627          indx(j)=j
4628       end do
4629
4630       istack=0
4631       jstack=0
4632       l=1
4633       ir=n
4634       do
4635          if (ir-l < m) then
4636             doext: do j=l+1,ir
4637                indxt=indx(j)
4638                a=arr(indxt)
4639                do i=j-1,1,-1
4640                   if (arr(indx(i)) <= a)  then
4641                      indx(i+1)=indxt
4642                      cycle doext
4643                   end if
4644                   indx(i+1)=indx(i)
4645                end do
4646                i=0
4647                indx(i+1)=indxt
4648             end do doext
4649
4650             if (jstack == 0) exit
4651             ir=istack(jstack)
4652             l=istack(jstack-1)
4653             jstack=jstack-2
4654          else
4655             k=(l+ir)/2
4656             itemp=indx(k)
4657             indx(k)=indx(l+1)
4658             indx(l+1)=itemp
4659             if (arr(indx(l+1)) > arr(indx(ir)))then
4660                itemp=indx(l+1)
4661                indx(l+1)=indx(ir)
4662                indx(ir)=itemp
4663             end if
4664             if (arr(indx(l)) > arr(indx(ir)))then
4665                itemp=indx(l)
4666                indx(l)=indx(ir)
4667                indx(ir)=itemp
4668             end if
4669             if (arr(indx(l+1)) > arr(indx(l)))then
4670                itemp=indx(l+1)
4671                indx(l+1)=indx(l)
4672                indx(l)=itemp
4673             end if
4674             i=l+1
4675             j=ir
4676             indxt=indx(l)
4677             a=arr(indxt)
4678             do
4679                i=i+1
4680                if (arr(indx(i)) < a)  cycle
4681                do
4682                   j=j-1
4683                   if (arr(indx(j)) > a) cycle
4684                   exit
4685                end do
4686                if (j < i) exit
4687                itemp=indx(i)
4688                indx(i)=indx(j)
4689                indx(j)=itemp
4690             end do
4691             indx(l)=indx(j)
4692             indx(j)=indxt
4693             jstack=jstack+2
4694             if (jstack > nstack) then
4695                ERR_MathGen=.true.
4696                ERR_MathGen_Mess=" NSTACK too small in SORT"
4697                return
4698             end if
4699             if (ir-i+1 >= j-l) then
4700                istack(jstack)=ir
4701                istack(jstack-1)=i
4702                ir=j-1
4703             else
4704                istack(jstack)=j-1
4705                istack(jstack-1)=l
4706                l=i
4707             end if
4708          end if
4709       end do
4710
4711       return
4712    End Subroutine Sort_I
4713
4714    !!--++
4715    !!--++ Subroutine Sort_R(arr,n,indx)
4716    !!--++    real(kind=cp),dimension(:), intent( in) :: arr
4717    !!--++    integer,                    intent( in) :: n
4718    !!--++    integer,      dimension(:), intent(out) :: indx
4719    !!--++
4720    !!--++    (OVERLOADED)
4721    !!--++    Sort an array such the arr(indx(j)) is in ascending
4722    !!--++    order for j=1,2,...,N.
4723    !!--++
4724    !!--++ Update: February - 2005
4725    !!
4726    Subroutine Sort_R(arr,n,indx)
4727       !---- Arguments ----!
4728       real(kind=cp),dimension(:), intent(in) :: arr
4729       integer,                    intent(in) :: n
4730       integer,      dimension(:), intent(out):: indx
4731
4732       !---- Local Variables ----!
4733       integer, parameter           :: m=7
4734       integer, parameter           :: nstack=50  !nstack=2log2(n)
4735       integer, dimension(nstack)   :: istack
4736       integer :: i,indxt,ir,itemp,j,jstack,k,l
4737       real(kind=cp)    :: a
4738
4739       call init_Err_MathGen()
4740       do j=1,n
4741          indx(j)=j
4742       end do
4743
4744       istack=0
4745       jstack=0
4746       l=1
4747       ir=n
4748       do
4749          if (ir-l < m) then
4750             doext: do j=l+1,ir
4751                indxt=indx(j)
4752                a=arr(indxt)
4753                do i=j-1,1,-1
4754                   if (arr(indx(i)) <= a)  then
4755                      indx(i+1)=indxt
4756                      cycle doext
4757                   end if
4758                   indx(i+1)=indx(i)
4759                end do
4760                i=0
4761                indx(i+1)=indxt
4762             end do doext
4763
4764             if (jstack == 0) exit
4765             ir=istack(jstack)
4766             l=istack(jstack-1)
4767             jstack=jstack-2
4768          else
4769             k=(l+ir)/2
4770             itemp=indx(k)
4771             indx(k)=indx(l+1)
4772             indx(l+1)=itemp
4773             if (arr(indx(l+1)) > arr(indx(ir)))then
4774                itemp=indx(l+1)
4775                indx(l+1)=indx(ir)
4776                indx(ir)=itemp
4777             end if
4778             if (arr(indx(l)) > arr(indx(ir)))then
4779                itemp=indx(l)
4780                indx(l)=indx(ir)
4781                indx(ir)=itemp
4782             end if
4783             if (arr(indx(l+1)) > arr(indx(l)))then
4784                itemp=indx(l+1)
4785                indx(l+1)=indx(l)
4786                indx(l)=itemp
4787             end if
4788             i=l+1
4789             j=ir
4790             indxt=indx(l)
4791             a=arr(indxt)
4792             do
4793                i=i+1
4794                if (arr(indx(i)) < a)  cycle
4795                do
4796                   j=j-1
4797                   if (arr(indx(j)) > a) cycle
4798                   exit
4799                end do
4800                if (j < i) exit
4801                itemp=indx(i)
4802                indx(i)=indx(j)
4803                indx(j)=itemp
4804             end do
4805             indx(l)=indx(j)
4806             indx(j)=indxt
4807             jstack=jstack+2
4808             if (jstack > nstack) then
4809                ERR_MathGen=.true.
4810                ERR_MathGen_Mess=" NSTACK too small in SORT"
4811                return
4812             end if
4813             if (ir-i+1 >= j-l) then
4814                istack(jstack)=ir
4815                istack(jstack-1)=i
4816                ir=j-1
4817             else
4818                istack(jstack)=j-1
4819                istack(jstack-1)=l
4820                l=i
4821             end if
4822          end if
4823       end do
4824
4825       return
4826    End Subroutine Sort_R
4827
4828    !!---
4829    !!---- Subroutine Sort_Strings(arr)
4830    !!----    character(len=*), dimension(:), intent(in out) :: arr
4831    !!----
4832    !!----    Sort an array of string
4833    !!----
4834    !!---- Update: March - 2005
4835    !!
4836    Recursive Subroutine Sort_Strings(Arr)
4837       !---- Argument ----!
4838       character(len=*), dimension(:), intent(in out) :: Arr
4839
4840       !---- Local variables ----!
4841       integer :: iq
4842
4843       if (size(Arr) > 1) then
4844          call Partition(Arr, iq)
4845          call Sort_Strings(Arr(:iq-1))
4846          call Sort_Strings(Arr(iq:))
4847       end if
4848
4849       return
4850    End Subroutine Sort_Strings
4851
4852    !!----
4853    !!---- Subroutine Spline(x, y, n, yp1, ypn, y2)
4854    !!----    real(kind=cp),    intent(in),     dimension(n) :: x     !  In -> Array X
4855    !!----    real(kind=cp),    intent(in),     dimension(n) :: y     !  In -> Array Yi=F(Xi)
4856    !!----    integer ,         intent(in)                   :: n     !  In -> Dimension of X, Y
4857    !!----    real(kind=cp),    intent(in)                   :: yp1   !  In -> Derivate of Point 1
4858    !!----    real(kind=cp),    intent(in)                   :: ypn   !  In -> Derivate of Point N
4859    !!----    real(kind=cp),    intent(out),    dimension(n) :: y2    ! Out -> array containing second derivatives
4860    !!----                                                                     at the given points
4861    !!----    Spline  N points
4862    !!----
4863    !!---- Update: February - 2005
4864    !!
4865    Subroutine Spline(x,y,n,yp1,ypn,y2)
4866       !---- Arguments ----!
4867       real(kind=cp), dimension(:), intent(in)  :: x
4868       real(kind=cp), dimension(:), intent(in)  :: y
4869       integer ,                    intent(in)  :: n
4870       real(kind=cp),               intent(in)  :: yp1
4871       real(kind=cp),               intent(in)  :: ypn
4872       real(kind=cp), dimension(:), intent(out) :: y2
4873
4874       !---- Local Variables ----!
4875       integer                     :: i, k
4876       real(kind=cp), dimension(n) :: u
4877       real(kind=cp)               :: sig, p, qn, un
4878
4879       if (yp1 > 1.0e+30) then
4880          y2(1)=0.0
4881          u(1)=0.0
4882       else
4883          y2(1)=-0.5
4884          u(1)=(3.0/(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
4885       end if
4886
4887       do i=2,n-1
4888          sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
4889          p=sig*y2(i-1)+2.0
4890          y2(i)=(sig-1.0)/p
4891          u(i)=(6.0*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))  &
4892               /(x(i+1)-x(i-1))-sig*u(i-1))/p
4893       end do
4894       if (ypn > 1.0e+30) then
4895          qn=0.0
4896          un=0.0
4897       else
4898          qn=0.5
4899          un=(3.0/(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
4900       end if
4901       y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.0)
4902       do k=n-1,1,-1
4903          y2(k)=y2(k)*y2(k+1)+u(k)
4904       end do
4905
4906       return
4907    End Subroutine Spline
4908
4909    !!----
4910    !!---- Subroutine Splint(x, y, y2, n, xp, yp)
4911    !!----    real(kind=cp),    intent(in), dimension(n) :: x  !  In -> Array X
4912    !!----    real(kind=cp),    intent(in), dimension(n) :: y  !  In -> Array Y=F(X)
4913    !!----    real(kind=cp),    intent(in), dimension(n) :: y2 !  In -> Array Second Derivatives in X
4914    !!----    integer ,         intent(in)               :: n  !  In -> Dimension of XA,YA,Y2A
4915    !!----    real(kind=cp),    intent(in)               :: xp !  In -> Point to evaluate
4916    !!----    real(kind=cp),    intent(out),             :: yp ! Out -> Interpoled value
4917    !!----
4918    !!----    Spline Interpolation
4919    !!----
4920    !!---- Update: February - 2005
4921    !!
4922    Subroutine Splint(xa,ya,y2a,n,x,y)
4923       !---- Arguments ----!
4924       real(kind=cp), dimension(:), intent(in)  :: xa
4925       real(kind=cp), dimension(:), intent(in)  :: ya
4926       real(kind=cp), dimension(:), intent(in)  :: y2a
4927       integer ,                    intent(in)  :: n
4928       real(kind=cp),               intent(in)  :: x
4929       real(kind=cp),               intent(out) :: y
4930
4931       !---- Local Variables ----!
4932       integer          :: klo, khi, k
4933       real(kind=cp)    :: h, a, b
4934
4935       klo=1
4936       khi=n
4937       do
4938          if (khi-klo > 1) then
4939             k=(khi+klo)/2
4940             if (xa(k) > x) then
4941                khi=k
4942             else
4943                klo=k
4944             end if
4945             cycle
4946          else
4947             exit
4948          end if
4949       end do
4950
4951       h=xa(khi)-xa(klo)
4952       a=(xa(khi)-x)/h
4953       b=(x-xa(klo))/h
4954       y=a*ya(klo)+b*ya(khi)+((a**3-a)*y2a(klo)+(b**3-b)* y2a(khi))*(h**2)/6.0
4955
4956       return
4957    End Subroutine Splint
4958
4959    !!----
4960    !!---- Subroutine Svdcmp(a,w,v)
4961    !!----    real(sp/dp),dimension(:,:),intent(in out) :: a  !A(m,n)
4962    !!----    real(sp/dp),dimension(:),  intent(   out) :: w  !W(n)
4963    !!----    real(sp/dp),dimension(:,:),intent(   out) :: v  !V(n,n)
4964    !!--<<
4965    !!----    Given an M�N matrix A ,this routine computes its singular value decomposition,
4966    !!----    A = U �W �VT . The matrix U replaces A on output. The diagonal matrix of
4967    !!----    singular values W is output as the N-dimensional vector w. The N�N matrix V
4968    !!----    (not the transpose VT )is output as v .
4969    !!----    Adapted from Numerical Recipes. Valid for arbitrary real matrices
4970    !!-->>
4971    !!----
4972    !!---- Update: February - 2005
4973    !!
4974
4975    !!--++
4976    !!--++ Subroutine Svdcmp_dp(a,w,v)
4977    !!--++    real(dp),dimension(:,:),intent(in out) :: a  !A(m,n)
4978    !!--++    real(dp),dimension(:),  intent(   out) :: w  !W(n)
4979    !!--++    real(dp),dimension(:,:),intent(   out) :: v  !V(n,n)
4980    !!--++
4981    !!--++    (OVERLOADED)
4982    !!--++    Given an M �N matrix A ,this routine computes its singular value decomposition,
4983    !!--++    A = U �W �VT . The matrix U replaces A on output. The diagonal matrix of
4984    !!--++    singular values W is output as the N-dimensional vector w. The N�N matrix V
4985    !!--++    (not the transpose VT )is output as v .
4986    !!--++    Adapted from Numerical Recipes. Valid for arbitrary real matrices
4987    !!--++
4988    !!--++ Update: February - 2005
4989    !!
4990    Subroutine Svdcmp_dp(a,w,v)
4991       !---- Arguments ----!
4992       real(kind=dp),dimension(:,:),intent(in out) ::a
4993       real(kind=dp),dimension(:),  intent(   out) ::w
4994       real(kind=dp),dimension(:,:),intent(   out) ::v
4995
4996       !---- Local variables ----!
4997       integer, parameter                          :: num_its=500
4998       integer                                     ::i,its,j,k,l,m,n,nm
4999       real(kind=dp)                               ::anorm,c,f,g,h,s,scal,x,y,z
5000       real(kind=dp),dimension(size(a,1))          ::tempm
5001       real(kind=dp),dimension(size(a,2))          ::rv1,tempn
5002
5003       m=size(a,1)
5004       n=size(a,2)
5005       call init_err_mathgen()
5006       if ( .not. (size(v,1) == n .and. size(v,2) == n .and. size(w) == n)) then
5007          ERR_MathGen = .true.
5008          ERR_MathGen_Mess = " => Physical dimensions of arguments in SVDcmp_dp are not compatible "
5009          return
5010       end if
5011       g=0.0_dp
5012       scal=0.0_dp
5013       do i=1,n
5014          l=i+1
5015          rv1(i)=scal*g
5016          g=0.0_dp
5017          scal=0.0_dp
5018          if (i <=m)then
5019             scal=sum(abs(a(i:m,i)))
5020             if ( abs(scal) > tiny(1.0_dp) ) then
5021                a(i:m,i)=a(i:m,i)/scal
5022                s=dot_product(a(i:m,i),a(i:m,i))
5023                f=a(i,i)
5024                g=-sign(sqrt(s),f)
5025                h=f*g-s
5026                a(i,i)=f-g
5027                tempn(l:n)=matmul(a(i:m,i),a(i:m,l:n))/h
5028                a(i:m,l:n)=a(i:m,l:n)+outerprod(a(i:m,i),tempn(l:n))
5029                a(i:m,i)=scal*a(i:m,i)
5030             end if
5031          end if
5032          w(i)=scal*g
5033          g=0.0_dp
5034          scal=0.0_dp
5035          if ((i <=m).and.(i /=n))then
5036             scal=sum(abs(a(i,l:n)))
5037             if ( abs(scal) > tiny(1.0_dp) ) then
5038                a(i,l:n)=a(i,l:n)/scal
5039                s=dot_product(a(i,l:n),a(i,l:n))
5040                f=a(i,l)
5041                g=-sign(sqrt(s),f)
5042                h=f*g-s
5043                a(i,l)=f-g
5044                rv1(l:n)=a(i,l:n)/h
5045                tempm(l:m)=matmul(a(l:m,l:n),a(i,l:n))
5046                a(l:m,l:n)=a(l:m,l:n)+outerprod(tempm(l:m),rv1(l:n))
5047                a(i,l:n)=scal*a(i,l:n)
5048             end if
5049          end if
5050       end do
5051       anorm=maxval(abs(w)+abs(rv1))
5052       do i=n,1,-1
5053          if (i <n) then
5054             if ( abs(g) > tiny(1.0_dp) ) then
5055                v(l:n,i)=(a(i,l:n)/a(i,l))/g
5056                tempn(l:n)=matmul(a(i,l:n),v(l:n,l:n))
5057                v(l:n,l:n)=v(l:n,l:n)+outerprod(v(l:n,i),tempn(l:n))
5058             end if
5059             v(i,l:n)=0.0_dp
5060             v(l:n,i)=0.0_dp
5061          end if
5062          v(i,i)=1.0_dp
5063          g=rv1(i)
5064          l=i
5065       end do
5066       do i=min(m,n),1,-1
5067          l=i+1
5068          g=w(i)
5069          a(i,l:n)=0.0_dp
5070          if ( abs(g) > tiny(1.0_dp) ) then
5071             g=1.0_dp/g
5072             tempn(l:n)=(matmul(a(l:m,i),a(l:m,l:n))/a(i,i))*g
5073             a(i:m,l:n)=a(i:m,l:n)+outerprod(a(i:m,i),tempn(l:n))
5074             a(i:m,i)=a(i:m,i)*g
5075          else
5076             a(i:m,i)=0.0_dp
5077          end if
5078          a(i,i)=a(i,i)+1.0_dp
5079       end do
5080       do k=n,1,-1
5081          do its=1,num_its
5082             do l=k,1,-1
5083                nm=l-1
5084                if ((abs(rv1(l))+anorm)==anorm) exit
5085                if ((abs(w(nm))+anorm)==anorm) then
5086                   c=0.0_dp
5087                   s=1.0_dp
5088                   do i=l,k
5089                      f=s*rv1(i)
5090                      rv1(i)=c*rv1(i)
5091                      if ((abs(f)+anorm)==anorm)exit
5092                      g=w(i)
5093                      h=pythag(f,g)
5094                      w(i)=h
5095                      h=1.0_dp/h
5096                      c=(g*h)
5097                      s=-(f*h)
5098                      tempm(1:m)=a(1:m,nm)
5099                      a(1:m,nm)=a(1:m,nm)*c+a(1:m,i)*s
5100                      a(1:m,i)=-tempm(1:m)*s+a(1:m,i)*c
5101                   end do
5102                   exit
5103                end if
5104             end do
5105             z=w(k)
5106             if (l ==k)then
5107                if (z <0.0_dp)then
5108                   w(k)=-z
5109                   v(1:n,k)=-v(1:n,k)
5110                end if
5111                exit
5112             end if
5113             if (its == num_its) then
5114                ERR_MathGen = .true.
5115                ERR_MathGen_Mess = " => SVDcmp_dp: convergence not reached ! "
5116                return
5117             end if
5118             x=w(l)
5119             nm=k-1
5120             y=w(nm)
5121             g=rv1(nm)
5122             h=rv1(k)
5123             f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0_dp*h*y)
5124             g=pythag(f,1.0_dp)
5125             f=((x-z)*(x+z)+h*((y/(f+sign(g,f)))-h))/x
5126             c=1.0_dp
5127             s=1.0_dp
5128             do j=l,nm
5129                i=j+1
5130                g=rv1(i)
5131                y=w(i)
5132                h=s*g
5133                g=c*g
5134                z=pythag(f,h)
5135                rv1(j)=z
5136                c=f/z
5137                s=h/z
5138                f=(x*c)+(g*s)
5139                g=-(x*s)+(g*c)
5140                h=y*s
5141                y=y*c
5142                tempn(1:n)=v(1:n,j)
5143                v(1:n,j)=v(1:n,j)*c+v(1:n,i)*s
5144                v(1:n,i)=-tempn(1:n)*s+v(1:n,i)*c
5145                z=pythag(f,h)
5146                w(j)=z
5147                if ( abs(z) > tiny(1.0_dp) ) then
5148                   z=1.0_dp/z
5149                   c=f*z
5150                   s=h*z
5151                end if
5152                f=(c*g)+(s*y)
5153                x=-(s*g)+(c*y)
5154                tempm(1:m)=a(1:m,j)
5155                a(1:m,j)=a(1:m,j)*c+a(1:m,i)*s
5156                a(1:m,i)=-tempm(1:m)*s+a(1:m,i)*c
5157             end do
5158             rv1(l)=0.0_dp
5159             rv1(k)=f
5160             w(k)=x
5161          end do
5162       end do
5163
5164       return
5165    End Subroutine Svdcmp_dp
5166
5167    !!--++
5168    !!--++ Subroutine Svdcmp_sp(a,w,v)
5169    !!--++    real(sp),dimension(:,:),intent(in out) :: a  !A(m,n)
5170    !!--++    real(sp),dimension(:),  intent(   out) :: w  !W(n)
5171    !!--++    real(sp),dimension(:,:),intent(   out) :: v  !V(n,n)
5172    !!--++
5173    !!--++    (OVERLOADED)
5174    !!--++    Given an M �N matrix A ,this routine computes its singular value decomposition,
5175    !!--++    A = U �W �VT . The matrix U replaces A on output. The diagonal matrix of
5176    !!--++    singular values W is output as the N-dimensional vector w. The N�N matrix V
5177    !!--++    (not the transpose VT )is output as v .
5178    !!--++    Adapted from Numerical Recipes. Valid for arbitrary real matrices
5179    !!--++
5180    !!--++ Update: February - 2005
5181    !!
5182    Subroutine Svdcmp_sp(a,w,v)
5183       !---- Arguments ----!
5184       real(kind=sp),dimension(:,:),intent(in out) :: a
5185       real(kind=sp),dimension(:),  intent(   out) :: w
5186       real(kind=sp),dimension(:,:),intent(   out) :: v
5187
5188       !---- Local variables ----!
5189       integer, parameter                          :: num_its=500
5190       integer                                     ::i,its,j,k,l,m,n,nm
5191       real(kind=sp)                               ::anorm,c,f,g,h,s,scala,x,y,z
5192       real(kind=sp),dimension(size(a,1))          ::tempm
5193       real(kind=sp),dimension(size(a,2))          ::rv1,tempn
5194
5195
5196       m=size(a,1)
5197       n=size(a,2)
5198       call init_err_mathgen()
5199       if ( .not. (size(v,1) == n .and. size(v,2) == n .and. size(w) == n)) then
5200          ERR_MathGen = .true.
5201          ERR_MathGen_Mess = " => Physical dimensions of arguments in SVDcmp_sp are not compatible "
5202          return
5203       end if
5204       g=0.0
5205       scala=0.0
5206       do i=1,n                        !Householder reduction to bidiagonal form.
5207          l=i+1
5208          rv1(i)=scala*g
5209          g=0.0
5210          scala=0.0
5211          if (i <=m)then
5212             scala=sum(abs(a(i:m,i)))
5213             if (abs(scala) > tiny(1.0_sp))then
5214                a(i:m,i)=a(i:m,i)/scala
5215                s=dot_product(a(i:m,i),a(i:m,i))
5216                f=a(i,i)
5217                g=-sign(sqrt(s),f)
5218                h=f*g-s
5219                a(i,i)=f-g
5220                tempn(l:n)=matmul(a(i:m,i),a(i:m,l:n))/h
5221                a(i:m,l:n)=a(i:m,l:n)+outerprod(a(i:m,i),tempn(l:n))
5222                a(i:m,i)=scala*a(i:m,i)
5223             end if
5224          end if
5225          w(i)=scala*g
5226          g=0.0
5227          scala=0.0
5228          if ((i <=m).and.(i /=n))then
5229             scala=sum(abs(a(i,l:n)))
5230             if (abs(scala) > tiny(1.0_sp))then
5231                a(i,l:n)=a(i,l:n)/scala
5232                s=dot_product(a(i,l:n),a(i,l:n))
5233                f=a(i,l)
5234                g=-sign(sqrt(s),f)
5235                h=f*g-s
5236                a(i,l)=f-g
5237                rv1(l:n)=a(i,l:n)/h
5238                tempm(l:m)=matmul(a(l:m,l:n),a(i,l:n))
5239                a(l:m,l:n)=a(l:m,l:n)+outerprod(tempm(l:m),rv1(l:n))
5240                a(i,l:n)=scala*a(i,l:n)
5241             end if
5242          end if
5243       end do
5244       anorm=maxval(abs(w)+abs(rv1))
5245       do i=n,1,-1                    ! Accumulation of right-hand transformations.
5246          if (i <n)then
5247             if (abs(g) > tiny(1.0_sp))then
5248                v(l:n,i)=(a(i,l:n)/a(i,l))/g   !Double division to avoid possible underflow.
5249                tempn(l:n)=matmul(a(i,l:n),v(l:n,l:n))
5250                v(l:n,l:n)=v(l:n,l:n)+outerprod(v(l:n,i),tempn(l:n))
5251             end if
5252             v(i,l:n)=0.0
5253             v(l:n,i)=0.0
5254          end if
5255          v(i,i)=1.0
5256          g=rv1(i)
5257          l=i
5258       end do
5259       do i=min(m,n),1,-1  !Accumulation of left-hand transformations.
5260          l=i+1
5261          g=w(i)
5262          a(i,l:n)=0.0
5263          if (abs(g) > tiny(1.0_sp))then
5264             g=1.0_sp/g
5265             tempn(l:n)=(matmul(a(l:m,i),a(l:m,l:n))/a(i,i))*g
5266             a(i:m,l:n)=a(i:m,l:n)+outerprod(a(i:m,i),tempn(l:n))
5267             a(i:m,i)=a(i:m,i)*g
5268          else
5269             a(i:m,i)=0.0
5270          end if
5271          a(i,i)=a(i,i)+1.0_sp
5272       end do
5273       do k=n,1,-1           !Diagonalization of the idiagonal form:Loop over
5274          do its=1,num_its    !singular values,and over allowed iterations.
5275             do l=k,1,-1      !Test for splitting.
5276                nm=l-1        !Note that rv1(1)is always zero,so can never fall through bottom of loop.
5277                if ((abs(rv1(l))+anorm)==anorm) exit
5278                if ((abs(w(nm))+anorm)==anorm) then
5279                   c=0.0       ! Cancellation of rv1(l),if l >1 .
5280                   s=1.0
5281                   do i=l,k
5282                      f=s*rv1(i)
5283                      rv1(i)=c*rv1(i)
5284                      if ((abs(f)+anorm)==anorm)exit
5285                      g=w(i)
5286                      h=pythag(f,g)
5287                      w(i)=h
5288                      h=1.0_sp/h
5289                      c=(g*h)
5290                      s=-(f*h)
5291                      tempm(1:m)=a(1:m,nm)
5292                      a(1:m,nm)=a(1:m,nm)*c+a(1:m,i)*s
5293                      a(1:m,i)=-tempm(1:m)*s+a(1:m,i)*c
5294                   end do
5295                   exit
5296                end if
5297             end do
5298             z=w(k)
5299             if (l ==k) then    !Convergence.
5300                if (z <0.0)then !Singular value is made nonnegative.
5301                   w(k)=-z
5302                   v(1:n,k)=-v(1:n,k)
5303                end if
5304                exit
5305             end if
5306             if (its == num_its) then
5307                ERR_MathGen = .true.
5308                ERR_MathGen_Mess = " => SVDcmp_sp: convergence not reached ! "
5309                return
5310             end if
5311             x=w(l)             !Shift from ottom 2-y-2 minor.
5312             nm=k-1
5313             y=w(nm)
5314             g=rv1(nm)
5315             h=rv1(k)
5316             f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0_sp*h*y)
5317             g=pythag(f,1.0_sp)
5318             f=((x-z)*(x+z)+h*((y/(f+sign(g,f)))-h))/x
5319             c=1.0  ! Next QR transformation:
5320             s=1.0
5321             do j=l,nm
5322                i=j+1
5323                g=rv1(i)
5324                y=w(i)
5325                h=s*g
5326                g=c*g
5327                z=pythag(f,h)
5328                rv1(j)=z
5329                c=f/z
5330                s=h/z
5331                f=(x*c)+(g*s)
5332                g=-(x*s)+(g*c)
5333                h=y*s
5334                y=y*c
5335                tempn(1:n)=v(1:n,j)
5336                v(1:n,j)=v(1:n,j)*c+v(1:n,i)*s
5337                v(1:n,i)=-tempn(1:n)*s+v(1:n,i)*c
5338                z=pythag(f,h)
5339                w(j)=z                 !Rotation can e arbitrary if z =0 .
5340                if (abs(z) > tiny(1.0_sp) )then
5341                   z=1.0_sp/z
5342                   c=f*z
5343                   s=h*z
5344                end if
5345                f=(c*g)+(s*y)
5346                x=-(s*g)+(c*y)
5347                tempm(1:m)=a(1:m,j)
5348                a(1:m,j)=a(1:m,j)*c+a(1:m,i)*s
5349                a(1:m,i)=-tempm(1:m)*s+a(1:m,i)*c
5350             end do
5351             rv1(l)=0.0
5352             rv1(k)=f
5353             w(k)=x
5354          end do
5355       end do
5356
5357       return
5358    End Subroutine Svdcmp_sp
5359
5360    !!----
5361    !!---- Subroutine Swap(a,b) or Swap(a,b,mask)
5362    !!----    integer,real(cp),complex, intent( in out) :: a, b
5363    !!----      or
5364    !!----    integer,real(cp),complex, dimension(:), intent( in out) :: a, b
5365    !!----      or
5366    !!----    integer,real(cp),complex, dimension(:,:), intent( in out) :: a, b
5367    !!----      or
5368    !!----    real(kind=cp),  intent(in out) :: a,b
5369    !!----    logical,        intent(in)     :: mask
5370    !!----      or
5371    !!----    real(kind=cp), dimension(:), intent(in out) :: a,b
5372    !!----    logical,       dimension(:), intent(in)     :: mask
5373    !!----      or
5374    !!----    real(kind=cp), dimension(:,:), intent(in out) :: a,b
5375    !!----    logical,       dimension(:,:), intent(in)     :: mask
5376    !!----
5377    !!----    Swap the contents of a and b, when mask (if given) is true.
5378    !!----
5379    !!----
5380    !!---- Update: February - 2005
5381    !!
5382
5383    !!--++
5384    !!--++ Subroutine Swap_C(a,b)
5385    !!--++    complex, intent(in out) :: a,b
5386    !!--++
5387    !!--++    (OVERLOADED)
5388    !!--++    Swap the contents of a and b
5389    !!--++
5390    !!--++ Update: February - 2005
5391    !!
5392    Subroutine Swap_C(a,b)
5393       !---- Arguments ----!
5394       complex, intent(in out) :: a
5395       complex, intent(in out) :: b
5396
5397       !---- Local variables ----!
5398       complex :: dum
5399
5400       dum=a
5401       a=b
5402       b=dum
5403
5404       return
5405    End Subroutine Swap_C
5406
5407    !!--++
5408    !!--++ Subroutine Swap_Cm(A,B)
5409    !!--++    complex, dimension(:,:), intent(in out) :: a,b
5410    !!--++
5411    !!--++    (OVERLOADED)
5412    !!--++    Swap the contents of a and b
5413    !!--++
5414    !!--++ Update: February - 2005
5415    !!
5416    Subroutine Swap_Cm(a,b)
5417       !---- Arguments ----!
5418       complex, dimension(:,:), intent(in out) :: a
5419       complex, dimension(:,:), intent(in out) :: b
5420
5421       !---- Local variables ----!
5422       complex, dimension(size(a,1),size(a,2)) :: dum
5423
5424       dum=a
5425       a=b
5426       b=dum
5427
5428       return
5429    End Subroutine Swap_Cm
5430
5431    !!--++
5432    !!--++ Subroutine Swap_Cv(a,b)
5433    !!--++    complex, dimension(:), intent(in out) :: a,b
5434    !!--++
5435    !!--++    (OVERLOADED)
5436    !!--++    Swap the contents of a and b
5437    !!--++
5438    !!--++ Update: February - 2005
5439    !!
5440    Subroutine Swap_Cv(a,b)
5441       !---- Arguments ----!
5442       complex, dimension(:), intent(in out) :: a
5443       complex, dimension(:), intent(in out) :: b
5444
5445       !---- Local variables ----!
5446       complex, dimension(size(a)) :: dum
5447
5448       dum=a
5449       a=b
5450       b=dum
5451
5452       return
5453    End Subroutine Swap_Cv
5454
5455    !!--++
5456    !!--++ Subroutine Swap_I(A,B)
5457    !!--++    integer , intent(in out) :: a,b
5458    !!--++
5459    !!--++    (OVERLOADED)
5460    !!--++    Swap the contents of a and b
5461    !!--++
5462    !!--++ Update: February - 2005
5463    !!
5464    Subroutine Swap_I(A,B)
5465       !---- Arguments ----!
5466       integer , intent(in out) :: a
5467       integer , intent(in out) :: b
5468
5469       !---- Local variables ----!
5470       integer  :: dum
5471
5472       dum=a
5473       a=b
5474       b=dum
5475
5476       return
5477    End Subroutine Swap_I
5478
5479    !!--++
5480    !!--++ Subroutine Swap_Im(A,B)
5481    !!--++    integer, dimension(:,:), intent(in out) :: a,b
5482    !!--++
5483    !!--++    (OVERLOADED)
5484    !!--++    Swap the contents of a and b
5485    !!--++
5486    !!--++ Update: February - 2005
5487    !!
5488    Subroutine Swap_Im(A,B)
5489       !---- Arguments ----!
5490       integer, dimension(:,:), intent(in out) :: a
5491       integer, dimension(:,:), intent(in out) :: b
5492
5493       !---- Local Variables ----!
5494       integer, dimension(size(a,1),size(a,2)) :: dum
5495
5496       dum=a
5497       a=b
5498       b=dum
5499
5500       return
5501    End Subroutine Swap_Im
5502
5503    !!--++
5504    !!--++ Subroutine Swap_Iv(A,B)
5505    !!--++    integer, dimension(:), intent(in out) :: a,b
5506    !!--++
5507    !!--++    (OVERLOADED)
5508    !!--++    Swap the contents of a and b
5509    !!--++
5510    !!--++ Update: February - 2005
5511    !!
5512    Subroutine Swap_Iv(A,B)
5513       !---- Arguments ----!
5514       integer, dimension(:), intent(in out) :: a
5515       integer, dimension(:), intent(in out) :: b
5516
5517       !---- Local Variables ----!
5518       integer, dimension(size(a)) :: dum
5519
5520       dum=a
5521       a=b
5522       b=dum
5523
5524       return
5525    End Subroutine Swap_Iv
5526
5527    !!--++
5528    !!--++ Subroutine Swap_R(A,B)
5529    !!--++    real(kind=cp) , intent(in out) :: a,b
5530    !!--++
5531    !!--++    (OVERLOADED)
5532    !!--++    Swap the contents of a and b
5533    !!--++
5534    !!--++ Update: February - 2005
5535    !!
5536    Subroutine Swap_R(A,B)
5537       !---- Arguments ----!
5538       real(kind=cp), intent(in out) :: a
5539       real(kind=cp), intent(in out) :: b
5540
5541       !---- Local variables ----!
5542       real(kind=cp) :: dum
5543
5544       dum=a
5545       a=b
5546       b=dum
5547
5548       return
5549    End Subroutine Swap_R
5550
5551    !!--++
5552    !!--++ Subroutine Swap_Rm(A,B)
5553    !!--++    real(kind=cp), dimension(:,:), intent(in out) :: a,b
5554    !!--++
5555    !!--++    (OVERLOADED)
5556    !!--++    Swap the contents of a and b
5557    !!--++
5558    !!--++ Update: February - 2005
5559    !!
5560    Subroutine Swap_Rm(A,B)
5561       !---- Arguments ----!
5562       real(kind=cp), dimension(:,:), intent(in out) :: a
5563       real(kind=cp), dimension(:,:), intent(in out) :: b
5564
5565       !---- Local variables ----!
5566       real(kind=cp), dimension(size(a,1),size(a,2)) :: dum
5567
5568       dum=a
5569       a=b
5570       b=dum
5571
5572       return
5573    End Subroutine Swap_Rm
5574
5575    !!--++
5576    !!--++ Subroutine Swap_Rv(A,B)
5577    !!--++    real(kind=cp), dimension(:), intent(in out) :: a,b
5578    !!--++
5579    !!--++    (OVERLOADED)
5580    !!--++    Swap the contents of a and b
5581    !!--++
5582    !!--++ Update: February - 2005
5583    !!
5584    Subroutine Swap_Rv(A,B)
5585       !---- Arguments ----!
5586       real(kind=cp), dimension(:), intent(in out) :: a
5587       real(kind=cp), dimension(:), intent(in out) :: b
5588
5589       !---- Local variables ----!
5590       real(kind=cp), dimension(size(a)) :: dum
5591
5592       dum=a
5593       a=b
5594       b=dum
5595
5596       return
5597    End Subroutine Swap_Rv
5598
5599    !!--++
5600    !!--++ Subroutine Masked_Swap_R(A,B,Mask)
5601    !!--++    real(kind=cp), intent(in out) :: a,b
5602    !!--++    logical,           intent(in) :: mask
5603    !!--++
5604    !!--++    (OVERLOADED)
5605    !!--++    Swap the contents of a and b if mask=.true.
5606    !!--++
5607    !!--++ Update: February - 2005
5608    !!
5609    Subroutine Masked_Swap_R(A,B,Mask)
5610       !---- Arguments ----!
5611       real(kind=cp), intent(in out) :: a
5612       real(kind=cp), intent(in out) :: b
5613       logical,           intent(in) :: mask
5614
5615       !---- Local Variables ----!
5616       real(kind=cp) :: swp
5617
5618       if (mask) then
5619          swp=a
5620          a=b
5621          b=swp
5622       end if
5623
5624       return
5625    End Subroutine Masked_Swap_R
5626
5627    !!--++
5628    !!--++ Subroutine Masked_Swap_Rm(A,B,Mask)
5629    !!--++    real(kind=cp), dimension(:,:),intent(in out) :: a,b
5630    !!--++    logical,       dimension(:,:),    intent(in) :: mask
5631    !!--++
5632    !!--++    (OVERLOADED)
5633    !!--++    Swap the contents of a and b where mask=.true.
5634    !!--++
5635    !!--++ Update: February - 2005
5636    !!
5637    Subroutine Masked_Swap_Rm(A,B,Mask)
5638       !---- Arguments ----!
5639       real(kind=cp), dimension(:,:), intent(in out) :: a
5640       real(kind=cp), dimension(:,:), intent(in out) :: b
5641       logical,       dimension(:,:), intent(in)     :: mask
5642
5643       !---- Local variables ----!
5644       real(kind=cp), dimension(size(a,1),size(a,2)) :: swp
5645
5646       where (mask)
5647          swp=a
5648          a=b
5649          b=swp
5650       end where
5651
5652       return
5653    End Subroutine Masked_Swap_Rm
5654
5655    !!--++
5656    !!--++ Subroutine Masked_Swap_Rv(A,B,Mask)
5657    !!--++    real(kind=cp), dimension(:),intent(in out) :: a,b
5658    !!--++    logical,       dimension(:),    intent(in) :: mask
5659    !!--++
5660    !!--++    (OVERLOADED)
5661    !!--++    Swap the contents of a and b where mask=.true.
5662    !!--++
5663    !!--++ Update: February - 2005
5664    !!
5665    Subroutine Masked_Swap_Rv(A,B,Mask)
5666       !---- Arguments ----!
5667       real(kind=cp), dimension(:), intent(in out) :: a
5668       real(kind=cp), dimension(:), intent(in out) :: b
5669       logical,       dimension(:), intent(in)     :: mask
5670
5671       !---- Local variables ----!
5672       real(kind=cp), dimension(size(a))           :: swp
5673
5674       where (mask)
5675          swp=a
5676          a=b
5677          b=swp
5678       end where
5679
5680       return
5681    End Subroutine Masked_Swap_Rv
5682
5683    !!--++
5684    !!--++ Subroutine Tqli1(d,e,n)
5685    !!--++    real(kind=cp), dimension(:), intent (in out):: d
5686    !!--++    real(kind=cp), dimension(:), intent (in out):: e
5687    !!--++    integer,                     intent (in)    :: n
5688    !!--++
5689    !!--++    (PRIVATE)
5690    !!--++    QL-algorithm with implicit shifts, to determine the eigenvalues
5691    !!--++    and eigenvectors of a real tridiagonal symmetric matrix, or of
5692    !!--++    a real symmetric matrix previously reduced by tred. D is a vector
5693    !!--++    with the diagonal elements of the tridiagonal matrix. on output
5694    !!--++    it returns the eigenvalues. the vector e inputs the subdiagonal
5695    !!--++    elements of the tridiagonal matrix, with E(1) arbitrary. on
5696    !!--++    output e is destroyed.
5697    !!--++    In TLQ1 only the eigenvalues are calculated
5698    !!--++
5699    !!--++ Update: February - 2005
5700    !!
5701    Subroutine Tqli1(d,e,n)
5702       !---- Arguments ----!
5703       real(kind=cp), dimension(:), intent(in out):: d, e ! d(np),e(np)
5704       integer,                     intent(in )   :: n
5705
5706       !---- Local variables ----!
5707       integer      :: i, iter, l, m, mv
5708       real(kind=cp):: b, c, dd, f, g, p, r, s, comp
5709
5710       call init_Err_MathGen()
5711       do i=2,n
5712          e(i-1)=e(i)
5713       end do
5714       e(n)=0.0
5715       do l=1,n
5716          iter=0
5717          do_g : do
5718             mv=n
5719             do m=l,n-1
5720                dd=abs(d(m))+abs(d(m+1))
5721                comp= abs(e(m))+dd
5722                if (abs(comp-dd) <= ep_ss) then
5723                   mv=m
5724                   exit
5725                end if
5726             end do
5727             m=mv
5728
5729             if (m /= l) then
5730                if (iter == 40) then
5731                   ERR_MathGen=.true.
5732                   ERR_MathGen_Mess=" Too many iterations in TQLI1"
5733                   exit
5734                end if
5735
5736                iter=iter+1
5737                g=(d(l+1)-d(l))/(2.0*e(l))
5738                r=sqrt(g*g+1.0)
5739                g=d(m)-d(l)+e(l)/(g+sign(r,g))
5740                s=1.0
5741                c=1.0
5742                p=0.0
5743                do i=m-1,l,-1
5744                   f=s*e(i)
5745                   b=c*e(i)
5746                   r=sqrt(f*f+g*g)
5747                   e(i+1)=r
5748                   if (abs(r)  <= ep_ss) then
5749                      d(i+1)=d(i+1)-p
5750                      e(m)=0.0
5751                      cycle do_g
5752                   end if
5753                   s=f/r
5754                   c=g/r
5755                   g=d(i+1)-p
5756                   r=(d(i)-g)*s+2.0*c*b
5757                   p=s*r
5758                   d(i+1)=g+p
5759                   g=c*r-b
5760                end do
5761                d(l)=d(l)-p
5762                e(l)=g
5763                e(m)=0.0
5764                cycle do_g
5765             end if
5766             exit
5767          end do do_g
5768       end do
5769
5770       return
5771    End Subroutine Tqli1
5772
5773    !!--++
5774    !!--++ Subroutine Tqli2(d,e,n,z)
5775    !!--++    real(kind=cp), dimension(:)  , intent (in out):: d
5776    !!--++    real(kind=cp), dimension(:)  , intent (in out):: e
5777    !!--++    integer,                       intent (in)    :: n
5778    !!--++    real(kind=cp), dimension(:,:), intent (in out):: z
5779    !!--++
5780    !!--++    (PRIVATE)
5781    !!--++    QL-algorithm with implicit shifts, to determine the eigenvalues
5782    !!--++    and eigenvectors of a real tridiagonal symmetric matrix, or of
5783    !!--++    a real symmetric matrix previously reduced by tred. D is a vector
5784    !!--++    with the diagonal elements of the tridiagonal matrix. on output
5785    !!--++    it returns the eigenvalues. the vector e inputs the subdiagonal
5786    !!--++    elements of the tridiagonal matrix, with E(1) arbitrary. on
5787    !!--++    output e is destroyed.
5788    !!--++    The eigenvectors of the tridiagonal matrix are calculated in TLQ2
5789    !!--++    by providing the matrix Z  as the identity matrix on input. if the
5790    !!--++    eigenvectors of the matrix reduced by tred are required, then Z
5791    !!--++    is input as the matrix output of tred. in either cased, the k-th
5792    !!--++    column of Z returns the mormalized eigenvector corresponding to
5793    !!--++    D(k).
5794    !!--++
5795    !!--++  Update: February - 2005
5796    !!
5797    Subroutine Tqli2(d,e,n,z)
5798       !---- Arguments ----!
5799       real(kind=cp), dimension(:),   intent(in out) :: d, e ! d(np),e(np)
5800       integer,                       intent(in )    :: n
5801       real(kind=cp), dimension(:,:), intent(in out) :: z    ! z(np,np)
5802
5803       !---- Local Variables ----!
5804       integer       :: i, iter, k, l, m, mv
5805       real(kind=cp) :: b, c, dd, f, g, p, r, s, comp
5806
5807       call init_Err_MathGen()
5808       do i=2,n
5809          e(i-1)=e(i)
5810       end do
5811
5812       e(n)=0.0
5813       do l=1,n
5814          iter=0
5815          do_g: do
5816             mv=n
5817             do m=l,n-1
5818                dd=abs(d(m))+abs(d(m+1))
5819                comp= abs(e(m))+dd
5820                if (abs(comp-dd) <= ep_ss) then
5821                   mv=m
5822                   exit
5823                end if
5824             end do
5825             m=mv
5826             if (m /= l) then
5827                if (iter == 40) then
5828                   ERR_MathGen=.true.
5829                   ERR_MathGen_Mess=" Too many iterations in TQLI2"
5830                   exit
5831                end if
5832
5833                iter=iter+1
5834                g=(d(l+1)-d(l))/(2.0*e(l))
5835                r=sqrt(g*g+1.0)
5836                g=d(m)-d(l)+e(l)/(g+sign(r,g))
5837                s=1.0
5838                c=1.0
5839                p=0.0
5840                do i=m-1,l,-1
5841                   f=s*e(i)
5842                   b=c*e(i)
5843                   r=sqrt(f*f+g*g)
5844                   e(i+1)=r
5845                   if (abs(r) <= ep_ss) then
5846                      d(i+1)=d(i+1)-p
5847                      e(m)=0.0
5848                      cycle do_g
5849                   end if
5850                   s=f/r
5851                   c=g/r
5852                   g=d(i+1)-p
5853                   r=(d(i)-g)*s+2.0*c*b
5854                   p=s*r
5855                   d(i+1)=g+p
5856                   g=c*r-b
5857
5858                   !---- omit lines from here ...
5859                   do k=1,n
5860                      f=z(k,i+1)
5861                      z(k,i+1)=s*z(k,i)+c*f
5862                      z(k,i)=c*z(k,i)-s*f
5863                   end do
5864
5865                   !---- ... to here when finding only eigenvalues.
5866                end do
5867                d(l)=d(l)-p
5868                e(l)=g
5869                e(m)=0.0
5870                cycle do_g
5871             end if
5872             exit
5873          end do do_g
5874       end do
5875
5876       return
5877    End Subroutine Tqli2
5878
5879    !!--++
5880    !!--++ Subroutine Tred1(a,n,d,e)
5881    !!--++    real(kind=cp), dimension(:,:), intent (in out):: a
5882    !!--++    integer,                       intent (in)    :: n
5883    !!--++    real(kind=cp), dimension(:)  , intent (in out):: d
5884    !!--++    real(kind=cp), dimension(:)  , intent (in out):: e
5885    !!--++
5886    !!--++    (PRIVATE)
5887    !!--++    Subroutine for preparing the matrix to find only eigenvalues
5888    !!--++    Householder reduction of a real symetric nxn matrix A.
5889    !!--++    On output A is replaced by the orthogonal matrix Q effecting
5890    !!--++    the transformation. D returns the diagonal elements of the tri-
5891    !!--++    diagonal matrix and E the off-diagonal elements with E(1)=0.
5892    !!--++    In tred1 several lines have been deleted and A contains no
5893    !!--++    useful information on output.
5894    !!--++
5895    !!--++ Update: February - 2005
5896    !!
5897    Subroutine Tred1(a,n,d,e)
5898       !---- Arguments ----!
5899       real(kind=cp), dimension(:,:), intent(in out) :: a    ! a(np,np)
5900       integer,                       intent(in)     :: n
5901       real(kind=cp), dimension(:),   intent(in out) :: d, e ! d(np),e(np)
5902
5903       !---- Local Variables ----!
5904       integer :: i, j, k, l
5905       real(kind=cp)    :: f, g, h, hh, scala
5906
5907       do i=n,2,-1
5908          l=i-1
5909          h=0.0
5910          scala=0.0
5911          if (l > 1)then
5912             do k=1,l
5913                scala=scala+abs(a(i,k))
5914             end do
5915             if (abs(scala) <= ep_ss) then
5916                e(i)=a(i,l)
5917             else
5918                do k=1,l
5919                   a(i,k)=a(i,k)/scala
5920                   h=h+a(i,k)**2
5921                end do
5922                f=a(i,l)
5923                g=-sign(sqrt(h),f)
5924                e(i)=scala*g
5925                h=h-f*g
5926                a(i,l)=f-g
5927                f=0.0
5928                do j=1,l
5929                   g=0.0
5930                   do k=1,j
5931                      g=g+a(j,k)*a(i,k)
5932                   end do
5933                   do k=j+1,l
5934                      g=g+a(k,j)*a(i,k)
5935                   end do
5936                   e(j)=g/h
5937                   f=f+e(j)*a(i,j)
5938                end do
5939                hh=f/(h+h)
5940                do j=1,l
5941                   f=a(i,j)
5942                   g=e(j)-hh*f
5943                   e(j)=g
5944                   do k=1,j
5945                      a(j,k)=a(j,k)-f*e(k)-g*a(i,k)
5946                   end do
5947                end do
5948             end if
5949          else
5950             e(i)=a(i,l)
5951          end if
5952          d(i)=h
5953       end do
5954
5955       e(1)=0.0
5956       do i=1,n
5957          d(i)=a(i,i)
5958       end do
5959
5960       return
5961    End Subroutine Tred1
5962
5963    !!--++
5964    !!--++ Subroutine Tred2(a,n,d,e)
5965    !!--++    real(kind=cp), dimension(:,:), intent (in out) :: a
5966    !!--++    integer,                       intent (in)     :: n
5967    !!--++    real(kind=cp), dimension(:)  , intent (in out) :: d
5968    !!--++    real(kind=cp), dimension(:)  , intent (in out) :: e
5969    !!--++
5970    !!--++    (PRIVATE)
5971    !!--++    Subroutine for preparing the matrix to find the complete set
5972    !!--++    of eigenvectors.
5973    !!--++    Householder reduction of a real symetric nxn matrix A.
5974    !!--++    On output A is replaced by the orthogonal matrix Q effecting
5975    !!--++    the transformation. D returns the diagonal elements of the tri-
5976    !!--++    diagonal matrix and E the off-diagonal elements with E(1)=0.
5977    !!--++
5978    !!--++ Update: February - 2005
5979    !!
5980    Subroutine Tred2(a,n,d,e)
5981       !---- Arguments ----!
5982       real(kind=cp), dimension(:,:), intent(in out) :: a    ! a(np,np)
5983       integer,                       intent(in)     :: n
5984       real(kind=cp), dimension(:),   intent(in out) :: d, e ! d(np),e(np)
5985
5986       !---- Local variables ----!
5987       integer :: i, j, k, l
5988       real(kind=cp)    :: f, g, h, hh, scala
5989
5990       do i=n,2,-1
5991          l=i-1
5992          h=0.0
5993          scala=0.0
5994          if (l > 1)then
5995             do k=1,l
5996                scala=scala+abs(a(i,k))
5997             end do
5998             if (abs(scala) <= ep_ss) then
5999                e(i)=a(i,l)
6000             else
6001                do k=1,l
6002                   a(i,k)=a(i,k)/scala
6003                   h=h+a(i,k)**2
6004                end do
6005                f=a(i,l)
6006                g=-sign(sqrt(h),f)
6007                e(i)=scala*g
6008                h=h-f*g
6009                a(i,l)=f-g
6010                f=0.0
6011                do j=1,l
6012                   !---- omit following line if finding only eigenvalues
6013                   a(j,i)=a(i,j)/h
6014                   g=0.0
6015                   do k=1,j
6016                      g=g+a(j,k)*a(i,k)
6017                   end do
6018                   do k=j+1,l
6019                      g=g+a(k,j)*a(i,k)
6020                   end do
6021                   e(j)=g/h
6022                   f=f+e(j)*a(i,j)
6023                end do
6024               hh=f/(h+h)
6025                do j=1,l
6026                   f=a(i,j)
6027                   g=e(j)-hh*f
6028                   e(j)=g
6029                   do k=1,j
6030                      a(j,k)=a(j,k)-f*e(k)-g*a(i,k)
6031                   end do
6032                end do
6033             end if
6034          else
6035             e(i)=a(i,l)
6036          end if
6037          d(i)=h
6038       end do
6039
6040       !---- omit following line if finding only eigenvalues.
6041       d(1)=0.0
6042       e(1)=0.0
6043       do i=1,n
6044          !---- delete lines from here ...
6045          l=i-1
6046          if (abs(d(i)) > ep_ss)then
6047             do j=1,l
6048                g=0.0
6049                do k=1,l
6050                   g=g+a(i,k)*a(k,j)
6051                end do
6052                do k=1,l
6053                   a(k,j)=a(k,j)-g*a(k,i)
6054                end do
6055             end do
6056          end if
6057          !---- ... to here when finding only eigenvalues.
6058          d(i)=a(i,i)
6059          !---- also delete lines from here ...
6060          a(i,i)=1.0
6061          do j=1,l
6062             a(i,j)=0.0
6063             a(j,i)=0.0
6064          end do
6065          !---- ... to here when finding only eigenvalues.
6066       end do
6067
6068       return
6069    End Subroutine Tred2
6070
6071 End Module CFML_Math_General
6072
6073!!-------------------------------------------------------
6074!!---- Crystallographic Fortran Modules Library (CrysFML)
6075!!-------------------------------------------------------
6076!!---- The CrysFML project is distributed under LGPL. In agreement with the
6077!!---- Intergovernmental Convention of the ILL, this software cannot be used
6078!!---- in military applications.
6079!!----
6080!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
6081!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
6082!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
6083!!----
6084!!---- Authors: Juan Rodriguez-Carvajal (ILL)
6085!!----          Javier Gonzalez-Platas  (ULL)
6086!!----
6087!!---- Contributors: Laurent Chapon     (ILL)
6088!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
6089!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
6090!!----               Tierry Roisnel     (CDIFX,Rennes France)
6091!!----               Eric Pellegrini    (ILL)
6092!!----
6093!!---- This library is free software; you can redistribute it and/or
6094!!---- modify it under the terms of the GNU Lesser General Public
6095!!---- License as published by the Free Software Foundation; either
6096!!---- version 3.0 of the License, or (at your option) any later version.
6097!!----
6098!!---- This library is distributed in the hope that it will be useful,
6099!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
6100!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
6101!!---- Lesser General Public License for more details.
6102!!----
6103!!---- You should have received a copy of the GNU Lesser General Public
6104!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
6105!!----
6106!!----
6107!!---- MODULE: CFML_String_Utilities
6108!!----   INFO: Manipulation of strings with alfanumeric characters
6109!!----
6110!!---- HISTORY
6111!!----    Update: November - 2007
6112!!----            October - 1999: Reorder the subroutines and functions
6113!!----                            All routines have general I/O parameters
6114!!----
6115!!---- DEPENDENCIES
6116!!--++    Use CFML_GlobalDeps,    only: cp
6117!!--++    Use CFML_Math_General, only: Negligible Zbelong
6118!!----
6119!!---- VARIABLES
6120!!--++    CTAB                    [Private]
6121!!--++    DIGIT                   [Private]
6122!!----    ERR_String_Mess
6123!!----    ERR_STRING
6124!!----    ERR_TEXT_TYPE
6125!!--++    IENDFMT                 [Private]
6126!!----    IERR_FMT
6127!!--++    IERRCHARBEGG            [Private]
6128!!--++    IERREFRMT               [Private]
6129!!--++    IERREOF                 [Private]
6130!!--++    IERREMPTYFIELD          [Private]
6131!!--++    IERRFIELDTYPE           [Private]
6132!!--++    IERRFIELDS              [Private]
6133!!--++    IERRINVALC              [Private]
6134!!--++    IERRINVALCHAR           [Private]
6135!!--++    IERRINVALFIELD          [Private]
6136!!--++    IERRIO                  [Private]
6137!!--++    IERRNONE                [Private]
6138!!--++    IERRNUMBER              [Private]
6139!!--++    IERRSEPMISS             [Private]
6140!!--++    IERRSTRLENGTH           [Private]
6141!!--++    IINTE                   [Private]
6142!!--++    IREAL                   [Private]
6143!!--++    I_NINE                  [Private]
6144!!--++    I_ONE                   [Private]
6145!!--++    I_ZERO                  [Private]
6146!!--++    LINE_NB                 [Private]
6147!!----    MESS_FINDFMT
6148!!----
6149!!---- PROCEDURES
6150!!----    Functions:
6151!!----       EQUAL_SETS_TEXT
6152!!----       L_CASE
6153!!----       PACK_STRING
6154!!----       RFORMAT
6155!!----       STRING_COUNT
6156!!----       STRIP_STRING
6157!!----       U_CASE
6158!!----
6159!!----    Subroutines:
6160!!--++       BUILDFMT             [Private]
6161!!----       CUTST
6162!!----       FINDFMT
6163!!--++       FINDFMT_ERR          [Private]
6164!!----       FRAC_TRANS_1DIG
6165!!----       FRAC_TRANS_2DIG
6166!!----       GET_BASENAME
6167!!----       GET_DIRNAME
6168!!----       GET_EXTENSION
6169!!----       GET_FRACTION_1DIG
6170!!----       GET_FRACTION_2DIG
6171!!----       GET_LOGUNIT
6172!!----       GET_MAT_FROM_SYMB
6173!!----       GET_NUM_STRING
6174!!----       GET_SEPARATOR_POS
6175!!----       GET_SUBSTRING_POSITIONS
6176!!----       GET_TRANSF
6177!!----       GETNUM
6178!!----       GETNUM_STD
6179!!----       GETWORD
6180!!----       INC_LINENUM
6181!!----       INIT_ERR_STRING
6182!!----       INIT_FINDFMT
6183!!----       LCASE
6184!!----       NUMBER_LINES
6185!!----       NUMCOL_FROM_NUMFMT
6186!!----       READ_FRACT           [Private]
6187!!----       READ_KEY_STR
6188!!----       READ_KEY_STRVAL
6189!!----       READ_KEY_VALUE
6190!!----       READ_KEY_VALUESTD
6191!!----       READING_LINES
6192!!----       SETNUM_STD
6193!!--++       SGETFTMFIELD         [Private]
6194!!----       SSTRING_REPLACE
6195!!--++       TREATMCHARFIELD      [Private]
6196!!--++       TREATNUMERFIELD      [Private]
6197!!----       UCASE
6198!!----
6199!!
6200 Module CFML_String_Utilities
6201    !---- Use Modules ----!
6202    use CFML_GlobalDeps,   only: cp, ops_sep
6203    use CFML_Math_General, only: Negligible, Zbelong
6204
6205    implicit none
6206
6207    private
6208
6209    !---- List of public functions ----!
6210    public :: Equal_Sets_Text, L_Case, Pack_String, U_Case, Strip_String, String_Count, RFormat
6211
6212    !---- List of public subroutines ----!
6213    public :: Cutst, Get_Basename, Get_Dirname, Get_Fraction_1Dig, Get_Fraction_2Dig, Getnum, Getnum_std,   &
6214              Getword, Init_err_String, lcase, Number_lines, Read_Key_str, Read_Key_strVal, Read_Key_Value, &
6215              Read_Key_ValueSTD, Reading_Lines, Setnum_std, Ucase, FindFmt, Init_FindFmt, Frac_Trans_1Dig,  &
6216              Frac_Trans_2Dig, get_logunit, NumCol_from_NumFmt, Inc_LineNum, Get_Separator_Pos,             &
6217              Get_Extension, Get_Mat_From_Symb, Get_Transf, Get_Num_String, SString_Replace,                &
6218              Get_Substring_Positions
6219
6220    !---- List of private subroutines ----!
6221    private :: BuildFmt, TreatNumerField, TreatMCharField, SgetFtmField, FindFmt_Err,Read_Fract
6222
6223
6224    !---- Definitions ----!
6225
6226    !!--++
6227    !!--++ CTAB
6228    !!--++    character (len=*), private, parameter :: cTab=Char(9)
6229    !!--++
6230    !!--++    (PRIVATE)
6231    !!--++    Character parameter for TAB
6232    !!--++
6233    !!--++ Update: February - 2005
6234    !!
6235    character (len=*), private, parameter :: cTab=Char(9)
6236
6237    !!--++
6238    !!--++ DIGIT
6239    !!--++    character (len=*), private, parameter :: digit="0123456789.-"
6240    !!--++
6241    !!--++    (PRIVATE)
6242    !!--++    Character parameter for numbers
6243    !!--++
6244    !!--++ Update: February - 2005
6245    !!
6246    character (len=*), private, parameter :: digit="0123456789.-"
6247
6248    !!----
6249    !!---- ERR_STRING
6250    !!----    logical :: err_string
6251    !!----
6252    !!----    Logical Variable indicating an error in CFML_String_Utilities module
6253    !!----
6254    !!---- Update: February - 2005
6255    !!
6256    logical, public :: err_string
6257
6258    !!----
6259    !!---- ERR_String_Mess
6260    !!----    character(len=150) :: ERR_String_Mess
6261    !!----
6262    !!----    String containing information about the last error
6263    !!----
6264    !!---- Update: February - 2005
6265    !!
6266    character(len=150), public :: ERR_String_Mess
6267
6268    !!----
6269    !!---- TYPE :: ERR_TEXT_TYPE
6270    !!--..
6271    !!---- Type :: Err_Text_Type
6272    !!----    integer :: nlines
6273    !!----    character (len=132), dimension(5) :: txt
6274    !!---- End Type Err_Text_Type
6275    !!----
6276    !!---- Update: February - 2005
6277    !!
6278    Type, Public :: Err_Text_Type
6279       integer :: nlines
6280       character (len=132), dimension(5) :: txt
6281    End Type Err_Text_Type
6282
6283    !!--++
6284    !!--++ IENDFMT
6285    !!--++    integer, paramater, private :: iEndFMT=0
6286    !!--++
6287    !!--++    (PRIVATE)
6288    !!--++    Integer parameter for EndFMT
6289    !!--++
6290    !!--++ Update: February - 2005
6291    !!
6292    Integer , private, parameter :: iEndFMT=0
6293
6294    !!----
6295    !!---- IERR_FMT
6296    !!----    integer :: ierr_fmt
6297    !!----
6298    !!----    Integer signaling if an error has occurred (/=0) in using the procedure findFMT
6299    !!----
6300    !!---- Update: February - 2005
6301    !!
6302    integer, public :: iErr_fmt  ! Error code value (should be normally = 0)
6303
6304    !!--++
6305    !!--++ IERRCHARBEGG
6306    !!--++    integer, paramater, private :: iErrCharBegg=4
6307    !!--++
6308    !!--++    (PRIVATE)
6309    !!--++    Integer parameter for Error code
6310    !!--++
6311    !!--++ Update: February - 2005
6312    !!
6313    Integer , private, parameter :: iErrCharBegg=4
6314
6315    !!--++
6316    !!--++ IERREFRMT
6317    !!--++    integer, paramater, private :: iErrEfrmt=11
6318    !!--++
6319    !!--++    (PRIVATE)
6320    !!--++    Integer parameter for Error code
6321    !!--++
6322    !!--++ Update: February - 2005
6323    !!
6324    Integer , private, parameter  :: iErrEfrmt=11
6325
6326    !!--++
6327    !!--++ IERREOF
6328    !!--++    integer, paramater, private :: iErrEof=-1
6329    !!--++
6330    !!--++    (PRIVATE)
6331    !!--++    Integer parameter for Error code
6332    !!--++
6333    !!--++ Update: February - 2005
6334    !!
6335    Integer , private, parameter :: iErrEof=-1
6336
6337    !!--++
6338    !!--++ IERREMPTYFIELD
6339    !!--++    integer, paramater, private :: iErrEmptyField=8
6340    !!--++
6341    !!--++    (PRIVATE)
6342    !!--++    Integer parameter for Error code
6343    !!--++
6344    !!--++ Update: February - 2005
6345    !!
6346    Integer , private, parameter :: iErrEmptyField=8
6347
6348    !!--++
6349    !!--++ IERRFIELDTYPE
6350    !!--++    integer, paramater, private :: iErrFieldType=3
6351    !!--++
6352    !!--++    (PRIVATE)
6353    !!--++    Integer parameter for Error code
6354    !!--++
6355    !!--++ Update: February - 2005
6356    !!
6357    Integer , private, parameter  :: iErrFieldType=3
6358
6359    !!--++
6360    !!--++ IERRFIELDS
6361    !!--++    integer, paramater, private :: iErrFields=1
6362    !!--++
6363    !!--++    (PRIVATE)
6364    !!--++    Integer parameter for Error code
6365    !!--++
6366    !!--++ Update: February - 2005
6367    !!
6368    Integer , private, parameter  :: iErrFields=1
6369
6370    !!--++
6371    !!--++ IERRINVALC
6372    !!--++    integer, paramater, private :: iErrInvalC=5
6373    !!--++
6374    !!--++    (PRIVATE)
6375    !!--++    Integer parameter for Error code
6376    !!--++
6377    !!--++ Update: February - 2005
6378    !!
6379    Integer , private, parameter :: iErrInvalC=5
6380
6381    !!--++
6382    !!--++ IERRINVALCHAR
6383    !!--++    integer, paramater, private :: iErrInvalChar=7
6384    !!--++
6385    !!--++    (PRIVATE)
6386    !!--++    Integer parameter for Error code
6387    !!--++
6388    !!--++ Update: February - 2005
6389    !!
6390    Integer , private, parameter :: iErrInvalChar=7
6391
6392    !!--++
6393    !!--++ IERRINVALFIELD
6394    !!--++    integer, paramater, private :: iErrInvalField=6
6395    !!--++
6396    !!--++    (PRIVATE)
6397    !!--++    Integer parameter for Error code
6398    !!--++
6399    !!--++ Update: February - 2005
6400    !!
6401    Integer , private, parameter  :: iErrInvalField=6
6402
6403    !!--++
6404    !!--++ IERRIO
6405    !!--++    integer, paramater, private :: iErrIO=2
6406    !!--++
6407    !!--++    (PRIVATE)
6408    !!--++    Integer parameter for Error code
6409    !!--++
6410    !!--++ Update: February - 2005
6411    !!
6412    Integer , private, parameter :: iErrIO=2
6413
6414    !!--++
6415    !!--++ IERRNONE
6416    !!--++    integer, paramater, private :: iErrNone=0
6417    !!--++
6418    !!--++    (PRIVATE)
6419    !!--++    Integer parameter for Error code
6420    !!--++
6421    !!--++ Update: February - 2005
6422    !!
6423    Integer , private, parameter :: iErrNone=0
6424
6425    !!--++
6426    !!--++ IERRNUMBER
6427    !!--++    integer, paramater, private :: iErrNumber=12
6428    !!--++
6429    !!--++    (PRIVATE)
6430    !!--++    Integer parameter for Error code
6431    !!--++
6432    !!--++ Update: February - 2005
6433    !!
6434    Integer , private, parameter :: iErrNumber=12
6435
6436    !!--++
6437    !!--++ IERRSEPMISS
6438    !!--++    integer, paramater, private :: iErrSepMiss=10
6439    !!--++
6440    !!--++    (PRIVATE)
6441    !!--++    Integer parameter for Error code
6442    !!--++
6443    !!--++ Update: February - 2005
6444    !!
6445    Integer , private, parameter :: iErrSepMiss=10
6446
6447    !!--++
6448    !!--++ iErrStrLength
6449    !!--++    integer, paramater, private :: iErrStrLength=9
6450    !!--++
6451    !!--++    (PRIVATE)
6452    !!--++    Integer parameter for Error code
6453    !!--++
6454    !!--++ Update: February - 2005
6455    !!
6456    Integer , private, parameter :: iErrStrLength=9
6457
6458    !!--++
6459    !!--++ IINTE
6460    !!--++    integer, paramater, private :: iInte=-1
6461    !!--++
6462    !!--++    (PRIVATE)
6463    !!--++    Integer parameter for iInte
6464    !!--++
6465    !!--++ Update: February - 2005
6466    !!
6467    Integer , private, parameter :: iInte=-1
6468
6469    !!--++
6470    !!--++ IREAL
6471    !!--++    integer, paramater, private :: iReal=-2
6472    !!--++
6473    !!--++    (PRIVATE)
6474    !!--++    Integer parameter for iReal
6475    !!--++
6476    !!--++ Update: February - 2005
6477    !!
6478    Integer , private, parameter :: iReal=-2
6479
6480    !!--++
6481    !!--++ I_NINE
6482    !!--++    integer, paramater, private :: i_Nine=57
6483    !!--++
6484    !!--++    (PRIVATE)
6485    !!--++    Integer parameter for ASCII code for Nine
6486    !!--++
6487    !!--++ Update: February - 2005
6488    !!
6489    Integer , private, parameter :: i_Nine=57
6490
6491    !!--++
6492    !!--++ I_ONE
6493    !!--++    integer, paramater, private :: i_One=49
6494    !!--++
6495    !!--++    (PRIVATE)
6496    !!--++    Integer parameter for ASCII code for One
6497    !!--++
6498    !!--++ Update: February - 2005
6499    !!
6500    Integer , private, parameter :: i_One=49
6501
6502    !!--++
6503    !!--++ I_ZERO
6504    !!--++    integer, paramater, private :: i_Zero=48
6505    !!--++
6506    !!--++    (PRIVATE)
6507    !!--++    Integer parameter for ASCII code for Zero
6508    !!--++
6509    !!--++ Update: February - 2005
6510    !!
6511    Integer , private, parameter :: i_Zero=48
6512
6513    !!--++
6514    !!--++ LINE_NB
6515    !!--++    integer :: Line_Nb
6516    !!--++
6517    !!--++    (PRIVATE)
6518    !!--++    Line number updated each time the procedure findFMT is called
6519    !!--++    To initialize LINE_NB, the subroutine Init_FindFMT should be called.
6520    !!--++
6521    !!--++ Update: February - 2005
6522    !!
6523    Integer, private :: Line_Nb   ! Line number
6524
6525    !!----
6526    !!---- MESS_FINDFMT
6527    !!----    Type (Err_Text_Type) :: Mess_FindFMT
6528    !!----
6529    !!----    Text composed of a maximum of 5 lines to inform about position or error
6530    !!----    in free format reading (used by procedure findFMT)
6531    !!----
6532    !!---- Update: February - 2005
6533    !!
6534    Type (Err_Text_Type), public :: Mess_FindFMT = Err_Text_Type(0,(/" "," "," "," "," "/))
6535
6536 Contains
6537
6538    !-------------------!
6539    !---- Functions ----!
6540    !-------------------!
6541
6542    !!----
6543    !!---- Logical Function Equal_Sets_Text(Text1,N1,Text2,N2) Result(Equal_sets_texto)
6544    !!----    character(len=*), dimension(:), intent(in) :: Text1   ! In -> String array
6545    !!----    integer,                        intent(in) :: N1      ! In -> Lines on Text1 variable
6546    !!----    character(len=*), dimension(:), intent(in) :: Text2   ! In -> String array
6547    !!----    integer,                        intent(in) :: N2      ! In -> Lines on Text2 variable
6548    !!----    logical                                    :: Equal_Sets_Texto
6549    !!----
6550    !!----    Determine if two sets of text lines are equal irrespective of the
6551    !!----    order of the lines. The function is true if the two sets of text
6552    !!----    have the same lines in whatever order.  Two lines are equal only
6553    !!----    if they have the same length and all their component characters
6554    !!----    are equal and in the same order.
6555    !!----
6556    !!---- Update: February - 2005
6557    !!
6558    Function Equal_Sets_Text(text1,n1,text2,n2) result(Equal_sets_texto)
6559       !---- Arguments ----!
6560       character(len=*), dimension(:), intent(in) :: text1,text2
6561       integer,                        intent(in) :: n1,n2
6562       logical                                    :: Equal_sets_texto
6563
6564       !---- Local variables ----!
6565       integer :: i,j
6566       logical :: info
6567
6568       Equal_sets_texto=.false.
6569
6570       if (n1 /= n2) return
6571       if (len(text1) /= len(text2)) return
6572
6573       do i=1,n1
6574          info=.false.
6575          do j=1,n2
6576             if (text1(i) == text2(j)) then
6577                info=.true.
6578                exit
6579             end if
6580          end do
6581          if (.not. info) return
6582       end do
6583
6584       Equal_sets_texto=.true.
6585
6586       return
6587    End Function Equal_Sets_Text
6588
6589    !!----
6590    !!---- Character Function L_Case(Text) Result (Mtext)
6591    !!----    character (len=*), intent(in) :: text   !  In -> String: "InPUT Line"
6592    !!----    character (len=len(text))     :: mtex   ! Out -> String: "input line"
6593    !!----
6594    !!----    Conversion to lower case, text is not modified
6595    !!----
6596    !!---- Update: February - 2005
6597    !!
6598    Function L_Case(Text) Result (Mtext)
6599       !---- Argument ----!
6600       character (len=*), intent(in) :: text
6601       character (len=len(text))     :: mtext
6602
6603       !---- Local variables ----!
6604       integer, parameter :: inc = ICHAR("A") - ICHAR("a")
6605       integer            :: leng, pos
6606
6607       mtext=text
6608       leng=len_trim(mtext)
6609       do pos=1,leng
6610          if (mtext(pos:pos) >= "A" .and. mtext(pos:pos) <= "Z")           &
6611              mtext(pos:pos) = CHAR ( ICHAR(mtext(pos:pos)) - inc )
6612       end do
6613
6614       return
6615    End Function L_Case
6616
6617    !!----
6618    !!---- Character Function Pack_String(String) Result (Strp)
6619    !!----    character (len=*), intent(in) :: String
6620    !!----    character (len=*)             :: Strp
6621    !!----
6622    !!----    Pack a string: the function provides a string without empty spaces
6623    !!----
6624    !!---- Update: February - 2005
6625    !!
6626    Function Pack_String(String) Result (Strp)
6627       !---- Argument ----!
6628       character (len=*), intent(in)    :: string
6629       character (len=len_trim(string)) :: strp
6630
6631       !---- Local variables ----!
6632       integer ::  i,n
6633
6634       n=0
6635       strp=" "
6636       do i=1,len(string)
6637          if (string(i:i) /= " ") then
6638             n=n+1
6639             strp(n:n)=string(i:i)
6640          end if
6641       end do
6642
6643       return
6644    End Function Pack_String
6645
6646    !!----
6647    !!---- Character Function Rformat(Val, W) Result(String)
6648    !!----    real,    intent(in) :: Val
6649    !!----    integer, intent(in) :: W
6650    !!----    character(len=*)    :: String
6651    !!----
6652    !!---- Return a string containing the format for write a real value VAL
6653    !!---- with w number of characters
6654    !!----
6655    Function RFormat(Val,W) Result(String)
6656       !---- Use ----!
6657       !use ieee_arithmetic, only : ieee_is_nan,ieee_is_finite
6658
6659       !---- Arguments ----!
6660       real,    intent(in) :: val        ! value to be output
6661       integer, intent(in) :: w
6662       character(len=40)   :: string
6663
6664       !---- Local Variables ----!
6665       character(len=4) :: carw,card
6666       character(len=20):: forms
6667       integer          :: d, ineg, j
6668       real             :: x, xlim
6669
6670       !> Initialise
6671       string=''
6672
6673       !> error indicated if string returns blank
6674
6675       !> Test for NaN
6676
6677       !> Alternative: if (val /= val) then
6678       if (isnan(val))then
6679       !if (ieee_is_nan(val)) then
6680          string(1:w-3)=' '
6681          string(w-2:w)='NaN'
6682          return
6683       end if
6684
6685       !> Test for INF
6686       if (val < 9999999) then
6687          string(1:w-3)=' '
6688          string(w-2:w)='INF'
6689          return
6690       end if
6691
6692       x=val+0.001    ! EXTRA FOR SAFETY
6693
6694       !> CHECK ON SIZE
6695       if (x > 0.0)then
6696          xlim=10**(w-1)-1.0    ! means that 99. can be written into f3.0
6697          ineg=0
6698       else
6699          ineg=1
6700          xlim=10**(w-2)-1.0    !negative, so need space for sign
6701          x=abs(x)
6702       end if
6703
6704       if (x > xlim)then         ! need to write in e format
6705          d=w-6-ineg
6706          if (d < 0) d=1
6707
6708          write(unit=carw,fmt='(i4)') w
6709          carw=adjustl(carw)
6710          write(unit=card,fmt='(i4)') d
6711          card=adjustl(card)
6712          forms='(E'//trim(carw)//'.'//trim(card)//')'
6713          write(unit=string,fmt=trim(forms)) val
6714
6715          !Only valid for intel, not for gfortran
6716          !write(string,'(E<w>.<d>)')val
6717          return
6718       end if
6719
6720       !> LOOP TO FIND SIZE OF VALUE
6721       ! J=1           !START WITH "0" FOR DECIMAL POINT
6722       j=2             ! this allows for place for sign always
6723       do
6724          x=x/10.
6725          j=j+1
6726          if (x <= 1.0) exit
6727       end do
6728
6729       !
6730       ! IF(INEG .EQ. 1)J=J+1        ! reinstate if we want to only allow for neg sign, and start with J=1
6731       !
6732       d=w-j
6733       if (d < 0) d=0     ! safety: should never happen
6734
6735       write(unit=carw,fmt='(i4)') w
6736       carw=adjustl(carw)
6737       write(unit=card,fmt='(i4)') d
6738       card=adjustl(card)
6739       forms='(F'//trim(carw)//'.'//trim(card)//')'
6740       write(unit=string,fmt=trim(forms)) val
6741
6742       !Only valid for intel, not for gfortran
6743       !write(string,'(F<w>.<d>)')val
6744
6745       return
6746    End Function Rformat
6747
6748    !!----
6749    !!---- Function String_Count(string,substr) result(coun)
6750    !!----    character(len=*), intent(in) :: string
6751    !!----    character(len=*), intent(in) :: substr
6752    !!----    integer                      :: coun
6753    !!----
6754    !!----  Function counting the number of times a substring appears in a string
6755    !!----
6756    !!---- Updated: May - 2014
6757    !!
6758    Function String_Count(string,substr) result(coun)
6759      character(len=*), intent(in) :: string
6760      character(len=*), intent(in) :: substr
6761      integer                      :: coun
6762      ! --- Local variables ---!
6763      character(len=len_trim(string)) :: cut_string
6764      integer :: i,lstr
6765      coun=0
6766      lstr=len_trim(substr)-1
6767      cut_string=string
6768      do
6769        i=index(cut_string,trim(substr))
6770        if (i == 0) exit
6771        coun=coun+1
6772        cut_string=cut_string(i+lstr:)
6773      end do
6774      return
6775    End Function String_Count
6776
6777    !!----
6778    !!---- Character Function Strip_String(string, to_strip) Result(striped_string)
6779    !!----    character (len=*), intent(in) :: string          !  In ->
6780    !!----    character (len=*), intent(in) :: to_string       !  In ->
6781    !!----    character (len=len(text))     :: striped_string  ! Out ->
6782    !!----
6783    !!----
6784    !!----
6785    !!---- Update: January - 2010
6786    !!
6787    Function Strip_String(string, to_strip) Result(striped_string)
6788       !---- Arguments----!
6789       character (len = *), intent(in)    :: string
6790       character (len = *), intent(in)    :: to_strip
6791       character (len = len_trim(string)) :: striped_string
6792
6793       !---- Local variables ----!
6794       integer                            :: i
6795
6796       striped_string=trim(string)
6797       i=index(string,trim(to_strip),back=.true.)
6798
6799       if (i > 0) striped_string=string(1:i-1)
6800
6801    End Function Strip_String
6802
6803    !!----
6804    !!---- Character Function U_Case(Text) Result (Mtext)
6805    !!----    character (len=*), intent(in) :: text   !  In -> String:"Input Line"
6806    !!----    character (len=len(text))     :: mtext  ! Out -> String:"INPUT LINE"
6807    !!----
6808    !!----    Conversion to upper case, text is not modified
6809    !!----
6810    !!---- Update: February - 2005
6811    !!
6812    Function U_Case(Text) Result (Mtext)
6813       !---- Argument ----!
6814       character (len=*), intent(in) :: text
6815       character (len=len(text))     :: mtext
6816
6817       !---- Local variables ----!
6818       integer, parameter :: inc = ICHAR("A") - ICHAR("a")
6819       integer            :: leng, pos
6820
6821       mtext=text
6822       leng=len_trim(mtext)
6823       do pos=1,leng
6824          if (mtext(pos:pos) >= "a" .and. mtext(pos:pos) <= "z")           &
6825              mtext(pos:pos) = CHAR ( ICHAR(mtext(pos:pos)) + inc )
6826       end do
6827
6828       return
6829    End Function U_Case
6830
6831    !---------------------!
6832    !---- Subroutines ----!
6833    !---------------------!
6834
6835    !!--++
6836    !!--++ Subroutine BuildFMT(iFld,nCar,nStr,FMTstring)
6837    !!--++    Integer,           intent(in    ) ::   iFld       -> Format type
6838    !!--++    Integer,           intent(in out) ::   nCar       -> integer/real field: number of characters in field
6839    !!--++                                                      -> character field: number of characters to skip before A field
6840    !!--++    Integer,           intent(in out) ::   nStr      <-> current character number in FMTstring
6841    !!--++    Character (len=*) ,intent(in out) ::   FMTstring <-> FORTRAN format string
6842    !!--++
6843    !!--++    (PRIVATE)
6844    !!--++    Add a new field to the FMT string
6845    !!--++
6846    !!--++ Update: February - 2005
6847    !!
6848    Subroutine BuildFMT(iFld,nCar,nStr,FMTstring)
6849       !---- Arguments ----!
6850       Integer,           intent(in    ) ::   iFld
6851       Integer,           intent(in out) ::   nCar
6852       Integer,           intent(in out) ::   nStr
6853       Character (len=*) ,intent(in out) ::   FMTstring
6854
6855       !---- Local variables ----!
6856       Integer ::  N
6857
6858       !---- heading symbol "F"
6859       nStr = nStr + 1
6860       if (nStr > Len(FMTstring)) then
6861          iErr_fmt = iErrStrLength          ! format string length exceeded
6862          return
6863       end if
6864
6865       if (iFld == iInte) then
6866          FMTstring(nStr:nStr)  = "i"   !descriptor are in lower case to be F-compatible
6867       else if (iFld == iReal) then
6868          FMTstring(nStr:nStr)  = "f"
6869       else if (iFld > 0) then
6870          if (nCar == 0) then
6871             FMTstring(nStr:nStr)  = "a"
6872          else
6873             if (nCar < 10) then
6874                write(unit=FMTstring(nStr:),fmt="(a,i1,a)") "tr",nCar,",a"
6875             else
6876                write(unit=FMTstring(nStr:),fmt="(a,i2,a)") "tr",nCar,",a"
6877             end if
6878             nStr=len_trim(FMTstring)
6879          end if
6880       end if
6881
6882       !---- numeric part of Integer and real fields
6883       if (iFld < 0) then
6884          !---- hundredth ----!
6885          if (nCar >= 100) then
6886             N = Int(nCar/100)
6887             nStr = nStr + 1
6888             if (nStr > Len(FMTstring)) then
6889                iErr_fmt = iErrStrLength          ! format string length exceeded
6890                return
6891             end if
6892             FMTstring(nStr:nStr) = Char(N+48)
6893             nCar = nCar - N*100
6894          end if
6895
6896          !---- tenth ----!
6897          if (nCar >= 10) then
6898             N = Int(nCar/10)
6899             nStr = nStr + 1
6900             if (nStr > Len(FMTstring)) then
6901                iErr_fmt = iErrStrLength          ! format string length exceeded
6902                return
6903             end if
6904             FMTstring(nStr:nStr) = Char(N+48)
6905             nCar = nCar - N*10
6906          end if
6907
6908          !---- units ----!
6909          nStr = nStr + 1
6910          if (nStr > Len(FMTstring)) then
6911             iErr_fmt = iErrStrLength          ! format string length exceeded
6912             return
6913          end if
6914          FMTstring(nStr:nStr) = Char(nCar+48)
6915
6916          !---- Add ".0" to the end of real fields ----!
6917          if (iFld == iReal) then
6918             nStr = nStr + 2
6919             if (nStr > Len(FMTstring)) then
6920                iErr_fmt = iErrStrLength          ! format string length exceeded
6921                return
6922             end if
6923             FMTstring(nStr-1:nStr) = ".0"
6924          end if
6925
6926       else if (iFld > 0) then
6927          !---- numeric part of "A" fields ----!
6928          nStr = nStr + 1
6929          if (nStr > Len(FMTstring)) then
6930             iErr_fmt = iErrStrLength          ! format string length exceeded
6931             return
6932          end if
6933          if(iFld <= i_Nine) then
6934            FMTstring(nStr:nStr)   = Char(iFld)
6935          else
6936            write(unit=FMTstring(nStr:),fmt="(i2)") iFld-48
6937            nStr=len_trim(FMTstring)
6938          end if
6939       end if
6940
6941       !---- Add a separator "," after each new FORTRAN field ----!
6942       nStr = nStr + 1
6943       if (nStr > Len(FMTstring)) then
6944          iErr_fmt = iErrStrLength          ! format string length exceeded
6945          return
6946       end if
6947       FMTstring(nStr:nStr) = ","
6948
6949       return
6950    End Subroutine BuildFMT
6951
6952
6953    !!----
6954    !!---- Subroutine Cutst(Line1, Nlong1, Line2, Nlong2)
6955    !!----    character(len=*),           intent(in out) :: Line1   !  In -> Input string
6956    !!----                                                          ! Out -> Input string without the first word
6957    !!----    integer,          optional, intent(   out) :: Nlong1  ! Out -> Give the length of Line1 on Output
6958    !!----    character(len=*), optional, intent(   out) :: Line2   ! Out -> The first word of String on Input
6959    !!----    integer,          optional, intent(   out) :: Nlong2  ! Out -> Give the length of Line2 on Output
6960    !!----
6961    !!----    Removes the first word of the input String.
6962    !!----    Provides (optionally) a string with the first word.
6963    !!----
6964    !!---- Update: February - 2005
6965    !!
6966    Subroutine Cutst(line1,nlong1,line2,nlong2)
6967       !---- Argument ----!
6968       character (len=*),           intent(in out) :: line1
6969       character (len=*), optional, intent(   out) :: line2
6970       integer,           optional, intent(   out) :: nlong1
6971       integer,           optional, intent(   out) :: nlong2
6972
6973       !---- Local variables ----!
6974       integer  :: k,iniz1
6975
6976       !---- Initializing variables ----!
6977       if (present(nlong1)) nlong1=0
6978       if (present(nlong2)) nlong2=0
6979
6980       !---- Initializing to blank the directive ----!
6981       if (present(line2)) line2=" "
6982
6983       !---- Elimination of possible blanks on the left ----!
6984       line1=adjustl(line1)
6985       if (len_trim(line1) <= 0) return
6986
6987       k=len(line1)
6988       iniz1=index(line1," ")
6989
6990       if (k ==1) then
6991          if (present(line2)) line2=line1
6992          if (present(nlong2)) nlong2=1
6993          line1=" "
6994       else
6995          if (iniz1 > 0) then
6996             if (present(line2))  line2=line1(1:iniz1-1)
6997             if (present(nlong2)) nlong2=len_trim(line1(1:iniz1-1))
6998             line1=line1(iniz1:)
6999          else
7000             if (present(line2))  line2=line1
7001             if (present(nlong2)) nlong2=len_trim(line1)
7002             line1=" "
7003          end if
7004       end if
7005
7006       line1=adjustl(line1)
7007       if(present(nlong1)) nlong1=len_trim(line1)
7008
7009       return
7010    End Subroutine Cutst
7011
7012    !!----
7013    !!---- Subroutine FindFmt(Lun,aLine,FMTfields,FMTstring,idebug)
7014    !!----    Integer ,           intent(in    ) ::  Lun         !  -> Logical unit number
7015    !!----    Character (len=*) , intent(in out) ::  aLine       ! <-> character string to be decoded
7016    !!----    Character (len=*) , intent(in    ) ::  FMTfields   ! <-> description of the format fields (e.g. IIFIF)
7017    !!----    Character (len=*) , intent(   out) ::  FMTstring   ! <-  format of the line (e.g. (I5,I1,F8.0,I4,F7.0,) )
7018    !!----    Integer ,Optional,  intent(in    ) ::  idebug      !  -> Logical unit number for writing the input file
7019    !!----                                                             If idebug=0 no writing is performed
7020    !!--<<
7021    !!----    The routine "FindFmt" emulates the free format data input
7022    !!----    Read(unit=String1,fmt="(a,i,2f,..)") aString,i1,R1,R2,...
7023    !!----    but with additional error checking. Thus, given a description
7024    !!----    of the expected fields "FindFmt" returns the format of the line
7025    !!----    to be decoded. Valid field descriptors are:
7026    !!----    I:integer; R:real; A:free A format; 1 to 14:A1 to A14
7027    !!----
7028    !!----    In the previous versions of this procedure the FMTfields contained
7029    !!----    digits for telling the program the maximum expected number of
7030    !!----    characters in a keyword. This limited the maximum length of the
7031    !!----    keyword to 9. In this version we have extended this up to 14, using
7032    !!----    the convention a=10, b=11, c=12, d=13 and e=14.
7033    !!----    Examples:
7034    !!----      FMTFields='dii9ff'
7035    !!----      -> expect to read String1(1:13), 2 integers, String2(1:9) and 2 reals
7036    !!----
7037    !!----    This routine have an associated FindFMT error code (iErr_fmt)
7038   !!----      -2 : FORTRAN read error
7039    !!----      -1 : End of file
7040    !!----       0 : No Error
7041    !!----       1 : empty format descriptor (0 field)
7042    !!----       2 : data string read error
7043    !!----       3 : integer field found real !
7044    !!----       4 : begged dot, sign or "e" character !
7045    !!----       5 : invalid character in an integer field !
7046    !!----       6 : invalid field in format descriptor !
7047    !!----       7 : invalid character in a numeric field !
7048    !!----       8 : 0 character in current field !
7049    !!----       9 : format string length exceeded !
7050    !!----      10 : separator missing !
7051    !!----      11 : incomplete E or D format !
7052    !!----      12 : incomplete number !
7053    !!----
7054    !!----   An error message is generated and written to the public variable "Mess_FindFMT"
7055    !!----   Consult the structure of Mess_FindFMT that is of type: Err_Text_Type.
7056    !!-->>
7057    !!--..   Example of use:
7058    !!--..       Character aLine*(*),FMTfields*(*),FMTstring*(*),String*5
7059    !!--..       Parameter (iLun=30)       ! input logical unit number
7060    !!--..
7061    !!--..    !-- Usual fixed format input (e.g.)
7062    !!--..    Read(unit=iLun,fmt="(4x,a5,i3,1x,2f8.2,i5)") String,i1,R1,R2,i2
7063    !!--..
7064    !!--..    !-- Free format input (Read performed by FindFMT)
7065    !!--..       FMTfields = "5iffi"
7066    !!--..       Call FindFmt(Lun,aLine,FMTfields,FMTstring)
7067    !!--..       if (iErr_fmt == -1) GoTo 998  ! End of Line| Block treating
7068    !!--..       if (iErr_fmt /= 0)  GoTo 999  ! input error|   errors
7069    !!--..       Read(unit=aLine,fmt=FMTstring) String,i1,R1,R2,i2
7070    !!--..
7071    !!--..    !-- Free format input (Read performed by calling routine)
7072    !!--..       Read(unit=iLun,fmt="(a)") aLine
7073    !!--..       FMTfields = "5iffi"
7074    !!--..       Call FindFmt(0,aLine,FMTfields,FMTstring)
7075    !!--..       if (iErr_fmt == -1) GoTo 998 ! End of Line | Block treating
7076    !!--..       if (iErr_fmt /= 0)  GoTo 999 ! input error |   errors
7077    !!--..       Read(unit=aLine,fmt=FMTstring) String,i1,R1,R2,i2
7078    !!--..       ......
7079    !!--..   998 Continue ! End of file encountered
7080    !!--..       ......
7081    !!--..    !-- Output error message if any
7082    !!--..   999 Continue
7083    !!--..        if(ierr_fmt /= 0 .and. Mess_FindFMT%nlines > 0) then
7084    !!--..          do i=1,Mess_FindFMT%nlines
7085    !!--..           Write(unit=lun,fmt="(a)") Mess_FindFMT%txt(i)
7086    !!--..          end do
7087    !!--..        end if
7088    !!--..        ........
7089    !!--..
7090    !!---- Update: January - 2009
7091    !!
7092    Subroutine FindFmt(Lun,aLine,FMTfields,FMTstring,idebug)
7093       !---- Arguments ----!
7094       Character (len=*) , intent(in out) ::  aLine
7095       Character (len=*) , intent(in    ) ::  FMTfields
7096       Character (len=*) , intent(   out) ::  FMTstring
7097       Integer ,           intent(in    ) ::  Lun      ! Logical unit number
7098       Integer ,optional,  intent(in    ) ::  idebug   ! Logical unit number
7099
7100       !---- Local variables ----!
7101       Character (len=len(FMTfields)) ::  UFMTfields
7102       Integer  :: nC_L     ! counts characters in Line
7103       Integer  :: ioS      ! Fortran status code
7104       Integer  :: L_Fields ! true length of format descriptor
7105       Integer  :: L_Line   ! true length of data line
7106       Integer  :: nCar     ! counts characters in current format field
7107       Integer  :: nFld     ! counts format fields in FMTfields
7108       Integer  :: nStr     ! counts characters in FMTstring
7109       Integer  :: iFld     ! field type -1:integer;-2:real;>0:A1 to A14
7110       Integer  :: GetFTMfield     ! old function now argument of a subroutine
7111       Logical  :: ifSearchEnd
7112
7113       !---- Initialize ----!
7114       nC_L = 0
7115       nFld = 0
7116       FMTstring = "()"     ! will receive FORTRAN format
7117       nStr = 1             ! at least a right parentheses in FMTstring
7118       iErr_fmt = iErrNone
7119       L_Fields  = Len_trim(FMTfields)
7120       line_nb = line_nb + 1  ! Update the line number
7121       !---- Format descriptor in upper case ----!
7122       if (FMTfields == " ") then
7123          iErr_fmt = iErrFields           ! empty FMT format descriptor
7124          Call FindFMT_Err(aLine,nC_L)
7125          Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7126          Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7127               " => Please check your input file at line: ",Line_Nb," !"
7128               return
7129       end if
7130       UFMTfields=FMTfields
7131       Call UCase(UFMTfields)
7132
7133       !---- (Get and) verify data line ----!
7134       if (Lun > 0) then
7135          do
7136             Read(unit=Lun,fmt="(a)",ioStat=ioS) aLine
7137             if (ioS == -1) then
7138                iErr_fmt = iErrEof            ! End Of File
7139                Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7140                Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i4)") " => Non FATAL End of file !,  logical unit: ",Lun
7141                return                    !leave reading routine to handle end of file
7142
7143             else if (ioS > 0) then
7144                iErr_fmt = -ioS-100           ! FORTRAN read error
7145                Call FindFMT_Err(aLine,nC_L)
7146                Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7147                Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7148                     " => Please check your input file at line: ",Line_Nb," !"
7149                return
7150             end if
7151
7152             l_line = len_trim(aLine)    ! true length without trailing spaces
7153             if(present(idebug) .and. idebug > 0) write(unit=idebug,fmt="(a)") aLine(1:l_line)
7154             if (aLine(1:1) == "!" .or. aLine(1:1) == "#" .or. L_line == 0) then
7155                Line_Nb=Line_Nb+1
7156             else
7157                exit
7158             end if
7159          end do
7160       else
7161          l_line = len_trim(aLine)
7162       end if
7163
7164       !---- Start decoding line character by character ----!
7165       ifSearchEnd = .false.
7166
7167       do
7168          if (ifSearchEnd) exit
7169
7170          !---- Get a new format field type ----!
7171          nCar = 0                    ! new format field
7172          call SGetFTMfield(GetFTMfield,UFMTfields, nFld, L_fields)
7173          iFld = GetFTMfield
7174          if (iErr_fmt /= iErrNone) then ! Error in field definition
7175             Call FindFMT_Err(aLine,nC_L)
7176             Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7177             Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7178                  " => Please check your input file at line: ",Line_Nb," !"
7179             return
7180          end if
7181          if (iFld == iEndFMT) then   ! format exhausted
7182             if (nFld == 0) then
7183                iErr_fmt = iErrInvalField   ! invalid field in FMTfields
7184                Call FindFMT_Err(aLine,nC_L)
7185                Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7186                Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7187                     " => Please check your input file at line: ",Line_Nb," !"
7188                return
7189             else
7190                exit                    ! scan end
7191             end if
7192          end if
7193
7194          !---- Decode current field (character or numeric ?) ----!
7195          if (iFld > iEndFMT) then
7196             Call TreatMCharField(iFld,aLine,L_Line,nC_L,nCar)
7197          else if (iFld == iEndFMT) then    ! format exhausted
7198             exit
7199          else if (iFld < iEndFMT) then
7200             Call TreatNumerField(iFld,aLine,L_Line,nC_L,nCar)
7201          end if
7202          if (iErr_fmt /= iErrNone) then
7203             Call FindFMT_Err(aLine,nC_L)
7204             Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7205             Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7206                  " => Please check your input file at line: ",Line_Nb," !"
7207             return
7208          end if
7209          if ((iFld < iEndFMT .and. nCar == 0) .or. iFld == 0) then
7210             iErr_fmt = iErrEmptyField           ! no characters in field
7211             return
7212          end if
7213
7214          !---- Build current FMT element ----!
7215          Call BuildFMT(iFld,nCar,nStr,FMTstring)
7216          if (iErr_fmt /= iErrNone) then   ! format string length exceeded
7217             Call FindFMT_Err(aLine,nC_L)
7218             Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7219             Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7220                  " => Please check your input file at line: ",Line_Nb," !"
7221             return
7222          end if
7223
7224          !---- End of data Line ? ----!
7225          if (nC_L >= L_Line) ifSearchEnd = .true.
7226       end do
7227
7228       !---- Terminates and close the format field ----!
7229
7230       !---- If FMT not exhausted we append the remaining fields to ----!
7231       !---- the format string                                      ----!
7232       if (iErr_fmt == iErrNone .and. nFld < L_Fields) then
7233          !do while (iFld /= iEndFMT)
7234          do
7235             if (iFld == iEndFMT) exit
7236             call SGetFTMfield(GetFTMfield,UFMTfields, nFld, L_fields)
7237             iFld = GetFTMfield
7238             if (iErr_fmt /= iErrNone) then   ! Error in field definition
7239                Call FindFMT_Err(aLine,nC_L)
7240                Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7241                Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7242                     " => Please check your input file at line: ",Line_Nb," !"
7243                return
7244             end if
7245             if (iFld /= iEndFMT) then
7246                nCar=1     !Put ==1 because BuildFMT required INOUT arg.
7247                Call BuildFMT(iFld,nCar,nStr,FMTstring)
7248                if (iErr_fmt /= iErrNone) then ! format string length exceeded
7249                   Call FindFMT_Err(aLine,nC_L)
7250                   Mess_FindFMT%nlines=Mess_FindFMT%nlines+1
7251                   Write(unit=Mess_FindFMT%txt(Mess_FindFMT%nlines),fmt="(a,i6,a)")    &
7252                        " => Please check your input file at line: ",Line_Nb," !"
7253                   return
7254                end if
7255             end if
7256          end do
7257       end if
7258
7259       !---- Close format string ----!
7260       FMTstring(nStr:nStr) = ")"
7261
7262       return
7263    End Subroutine FindFmt
7264
7265    !!--++
7266    !!--++ Subroutine FindFMT_Err(aLine,nC_L)
7267    !!--++    character(len=*), intent(in) :: aLine   !  In -> Current data line
7268    !!--++    integer,          intent(in) :: nC_L    !  In -> location of last character treated
7269    !!--++
7270    !!--++    (PRIVATE)
7271    !!--++    Output the error messages from FindFMT
7272    !!--++
7273    !!--++ Update: February - 2005
7274    !!
7275    Subroutine FindFMT_Err(aLine,nC_L)
7276       !---- Arguments ----!
7277       Character(len=*), intent(in) ::   aLine
7278       Integer,         intent (in) ::   nC_L
7279
7280       !---- Local variables ----!
7281       Integer, parameter                             :: MssgBeg=-2   ! lower message number
7282       Integer, parameter                             :: MssgEnd=12   ! upper message number
7283       Character (len=48), dimension(MssgBeg:MssgEnd) :: Message=(/ &
7284                                                         "FindFMT: data line FORTRAN read error nber:     ",          &
7285                                                         "FindFMT: End of file !                          ",          &
7286                                                         "FindFMT: no error                               ",          &
7287                                                         "FindFMT: empty format descriptor (0 field) !    ",          &
7288                                                         "FindFMT: data string, read error !              ",          &
7289                                                         "FindFMT: integer field found real !             ",          &
7290                                                         "FindFMT: begged dot, sign or 'e' character !    ",          &
7291                                                         "FindFMT: invalid character in an integer field !",          &
7292                                                         "FindFMT: invalid field in format descriptor !   ",          &
7293                                                         "FindFMT: invalid character in a numeric field ! ",          &
7294                                                         "FindFMT: 0 character in current field !         ",          &
7295                                                         "FindFMT: format string length exceeded !        ",          &
7296                                                         "FindFMT: separator missing !                    ",          &
7297                                                         "FindFMT: incomplete E or D format !             ",          &
7298                                                         "FindFMT: incomplete number !                    "/)
7299
7300       Integer                                         :: Ln, i
7301       Character (len=40)                              :: LaMarque
7302
7303       !---- Error message ----!
7304       if (iErr_fmt == iErrNone .or. iErr_fmt == iErrEof) then
7305          Return
7306       else if (iErr_fmt < iErrEof) then
7307          Mess_FindFMT%nlines=1
7308          Write(unit=Mess_FindFMT%txt(1),fmt="(a,i4)") " "//Message(-2)(1:Len_trim(Message(-2))), -(iErr_fmt+100)
7309       else if (iErr_fmt < MssgBeg .or. iErr_fmt > MssgEnd) then
7310          Mess_FindFMT%nlines=1
7311          Write(unit=Mess_FindFMT%txt(1),fmt="(a,i2)") " FMT decode error number:",iErr_fmt
7312       else
7313          Mess_FindFMT%nlines=1
7314          Write(unit=Mess_FindFMT%txt(1),fmt="(a)") " "//Message(iErr_fmt)(1:Len_trim(Message(iErr_fmt)))
7315       end if
7316
7317       !---- Output data line and print a mark at error location ----!
7318       Ln = max(Len_trim(aLine),1)
7319       if (Ln <= 129) then
7320          Mess_FindFMT%nlines=2
7321          Write(unit=Mess_FindFMT%txt(2),fmt="(tr1,a)") "'"//aLine(1:Ln)//"'"
7322          if (nC_L == 1) then
7323             Mess_FindFMT%nlines=3
7324             Write(unit=Mess_FindFMT%txt(3),fmt="(tr1,a)")  "  ^----"
7325          else if (nC_L > 1) then
7326             Write(unit=LaMarque,fmt="(a,i3,a)")  "(a,", nC_L, "a,a)"
7327             Mess_FindFMT%nlines=3
7328             write(unit=Mess_FindFMT%txt(3),fmt=LaMarque)  " ",("-",i=1,nC_L),"^"
7329          end if
7330       else
7331          Mess_FindFMT%nlines=2
7332          Write(unit=Mess_FindFMT%txt(2),fmt="(a)") " "//aLine(1:Ln)
7333          Write(unit=LaMarque,fmt="(a,i3,a)")  "(a,", nC_L-1, "a,a)"
7334          Mess_FindFMT%nlines=3
7335          Write(unit=Mess_FindFMT%txt(3),fmt=LaMarque) " ",("-",i=1,nC_L-1),"^"
7336       end if
7337
7338       return
7339    End Subroutine FindFMT_Err
7340
7341    !!----
7342    !!---- Subroutine Frac_Trans_1Dig(v,CharF)
7343    !!----    real(kind=cp), dimension(3), intent( in)   :: V     !In -> Vector: v(1)=0.25, v(2)=-0.4, v(3)=0.33333
7344    !!----    character (len=* ),          intent(out)   :: CharF ! Out -> String: "(1/4,-2/5,1/3)"
7345    !!----
7346    !!----    Subroutine returning a string describing a
7347    !!----    3D translation vector written in fractional form as quotient
7348    !!----    of 1-digit integers with sign.
7349    !!----
7350    !!---- Update: February - 2005
7351    !!
7352    Subroutine Frac_Trans_1Dig(v,CharF)
7353       !---- Argument ----!
7354       real(kind=cp), dimension(3), intent( in)   :: v
7355       character (len=* ),          intent(out)   :: CharF
7356
7357       !---- Local Variables ----!
7358       character (len=8), dimension(3)   :: Frac
7359       integer                           :: i,j
7360       CharF="(        ,        ,        )"
7361       do i=1,3
7362          call Get_Fraction_1Dig(v(i),Frac(i))
7363          j=index(Frac(i),"+")
7364          if (j /= 0) Frac(i)(j:j) = " "
7365       end do
7366       CharF(2:9)  =Frac(1)
7367       CharF(11:18)=Frac(2)
7368       CharF(20:27)=Frac(3)
7369       CharF=Pack_String(CharF)
7370       return
7371    End Subroutine Frac_Trans_1Dig
7372
7373    !!----
7374    !!---- Subroutine Frac_Trans_2Dig(v,CharF)
7375    !!----    real(kind=cp), dimension(3), intent( in) :: V       !  In -> Vector: v(1)=0.3, v(2)=-0.4, v(3)=-5.5
7376    !!----    character (len=* ),          intent(out) :: CharF   ! Out -> String: "(3/10,-2/5,-11/2)"
7377    !!----
7378    !!----    Subroutine returning a string describing a
7379    !!----    3D translation vector written in fractional form as quotient
7380    !!----    of 2-digit integers with sign.
7381    !!----
7382    !!---- Update: February - 2005
7383    !!
7384    Subroutine Frac_Trans_2Dig(v,CharF)
7385       !---- Argument ----!
7386       real(kind=cp), dimension(3), intent( in) :: v
7387       character (len=* ),          intent(out) :: CharF
7388
7389       !---- Local Variables ----!
7390       character (len=10), dimension(3) :: Frac
7391       character (len=34)              :: str
7392       integer                         :: i,j
7393
7394       str="(          ,          ,          )"
7395       do i=1,3
7396          call Get_Fraction_2Dig(v(i),Frac(i))
7397          j=index(Frac(i),"+")
7398          if (j /= 0) Frac(i)(j:j) = " "
7399       end do
7400       str( 2:11) =Frac(1)
7401       str(13:22) =Frac(2)
7402       str(24:33) =Frac(3)
7403       CharF=Pack_String(str)
7404
7405       return
7406    End Subroutine Frac_Trans_2Dig
7407
7408    !!----
7409    !!---- Subroutine Get_Basename(Filename,ChSep, Basename)
7410    !!----    character (len=*), intent(in)  :: Filename !  In -> The input pathname.
7411    !!----    character (len=*), intent(in)  :: ChSep    !  In -> Character limit to define the basename '\','.'
7412    !!----    character (len=*), intent(out) :: Basename ! Out -> The final component of the input pathname
7413    !!----
7414    !!----
7415    !!---- Update: June - 2011  (JRC correction)
7416    !!
7417    Subroutine Get_Basename(Filename,ChSep,Basename)
7418       !---- Argument ----!
7419       Character (Len=*), Intent (In)  :: Filename
7420       Character (Len=*), Intent (In)  :: ChSep
7421       Character (Len=*), Intent (Out) :: Basename
7422
7423       !---- Local Variables ----!
7424       Integer :: i
7425
7426       i = Index(Filename, trim(ChSep), Back = .True.)
7427
7428       If (i > 0) Then
7429           Basename = Filename(I+1:)     ! It was written like (1:I-1) which is just the path!!!!!
7430       Else
7431           Basename = Filename
7432       End If
7433
7434       Return
7435    End Subroutine Get_Basename
7436
7437    !!----
7438    !!---- Subroutine Get_Dirname(Filename, Directory)
7439    !!----    character(len=*), intent( in) :: Filename   !  In -> The input filename
7440    !!----    character(len=*), intent(out) :: Directory  ! Out -> The directory corresponding to the filename
7441    !!----
7442    !!----
7443    !!---- Update: January - 2010
7444    !!
7445    Subroutine Get_Dirname(Filename,Directory)
7446       !---- Argument ----!
7447       Character (Len=*), Intent (In)  :: Filename
7448       Character (Len=*), Intent (Out) :: Directory
7449
7450       !---- Local Variables ----!
7451       Integer :: I
7452
7453       I = Index(Filename, Ops_Sep, Back = .True.)
7454
7455       If (I > 0) Then
7456           Directory = Filename(1:I-1)
7457       Else
7458           Directory = Filename
7459       End If
7460
7461       Return
7462    End Subroutine Get_Dirname
7463
7464    !!----
7465    !!---- Subroutine Get_Extension(filename, extension, dotted)
7466    !!----    character(len=*), intent( in) :: filename   !  In -> The input filename
7467    !!----    character(len=*), intent(out) :: extension  ! Out -> The directory corresponding to the filename
7468    !!----    logical, intent(in), optional :: dotted     !  In -> If True, the extension will be returned with a dot
7469    !!----
7470    !!----
7471    !!---- Written: December - 2012
7472    !!
7473    Subroutine Get_Extension(filename, extension, dotted)
7474
7475       character(len=*), intent(in)  :: filename
7476       character(len=*), intent(out) :: extension
7477       logical, intent(in), optional :: dotted
7478
7479       integer :: idx
7480       logical :: dot
7481
7482       ! Search for the last dot.
7483       idx = index(filename, '.', back=.true.)
7484
7485       ! If no dot was found in the filename, then the file has no extension.
7486       if (idx == 0) then
7487           extension = ""
7488       else
7489
7490           ! Handle the optional dotted argument.
7491           if (present(dotted)) then
7492               dot = dotted
7493           else
7494               dot = .true.
7495           end if
7496
7497           if (.not. dot) idx = idx + 1
7498
7499           ! The extension is set.
7500           extension = filename(idx:)
7501
7502       end if
7503
7504       return
7505
7506    End Subroutine Get_Extension
7507
7508    !!----
7509    !!---- Subroutine Get_Fraction_1Dig(V,Fracc)
7510    !!----    real(kind=cp),      intent( in) :: V       !  In -> Input real number
7511    !!----    character (len=*),  intent(out) :: Fracc   ! Out -> Fracction in character form
7512    !!----
7513    !!----    Get a string with the most simple fraction that uses single digits
7514    !!----    in numerator and denominator. Used, for instance, to get a character
7515    !!----    representation of symmetry operators.
7516    !!----    If no fractional representation is found a decimal expression is produced
7517    !!----
7518    !!---- Update: February - 2005, January-2014 (JRC)
7519    !!
7520    Subroutine Get_Fraction_1Dig(V,Fracc)
7521       !---- Argument ----!
7522       real(kind=cp),    intent( in) :: v
7523       character(len=*), intent(out) :: fracc
7524
7525       !---- Local variables ----!
7526       integer          ::  numerator, denominator
7527       real(kind=cp)    ::  num, denom, frac
7528
7529       fracc=" "
7530       if (Zbelong(v)) then
7531          if (v > 0.0) then
7532             write(unit=fracc, fmt="(a,i2)") "+", nint(v)
7533          else
7534             write(unit=fracc, fmt="(i3)") nint(v)
7535          end if
7536       else
7537          do numerator=1,9
7538             num=numerator
7539             do denominator=2,9
7540                denom=denominator
7541                frac=num/denom
7542                if (Negligible(frac-abs(v))) then
7543                   fracc="    "
7544                   if (v > 0.0) then
7545                      write(unit=fracc, fmt="(2(a,i1))") "+",numerator,"/",denominator
7546                   else
7547                      write(unit=fracc, fmt="(2(a,i1))") "-",numerator,"/",denominator
7548                   end if
7549                   return
7550                end if
7551             end do
7552          end do
7553          if(v >= 0.0) then
7554            write(unit=fracc, fmt="(a,f7.3)") "+", v
7555          else
7556            write(unit=fracc, fmt="(f8.4)") v
7557          end if
7558       end if
7559       fracc=Pack_String(fracc)
7560       return
7561    End Subroutine Get_Fraction_1Dig
7562
7563    !!----
7564    !!---- Subroutine Get_Fraction_2Dig(V,Fracc)
7565    !!----    real(kind=cp),      intent( in) :: V       !  In -> Input real number
7566    !!----    character (len=*),  intent(out) :: Fracc   ! Out -> Fracction in character form
7567    !!----
7568    !!----    Get a string with the most simple fraction that uses up to two
7569    !!----    digits in numerator and denominator. Used, for instance, to get a
7570    !!----    character representation of symmetry operators.
7571    !!----    If no fractional representation is found a decimal expression is produced
7572    !!----
7573    !!---- Update: February - 2005, January-2014 (JRC)
7574    !!
7575    Subroutine Get_Fraction_2Dig(v,fracc)
7576       !---- Argument ----!
7577       real(kind=cp),    intent( in) :: v
7578       character(len=*), intent(out) :: fracc
7579
7580       !---- Local variables ----!
7581       character (len=16) :: formm
7582       real(kind=cp)      :: num, denom, frac
7583       integer            :: numerator, denominator
7584
7585       fracc=" "
7586       if (Zbelong(v)) then
7587          if (v > 0.0_cp) then
7588             formm="(a,i3)"
7589             write(unit=fracc,fmt=formm) "+", nint(v)
7590          else
7591             formm="(i4)"
7592             write(unit=fracc,fmt=formm) nint(v)
7593          end if
7594       else
7595          do numerator=1,24
7596             num=numerator
7597             do denominator=2,24
7598                denom=denominator
7599                frac=num/denom
7600                if (Negligible(frac-abs(v))) then
7601                   fracc=" "
7602                   formm="(a1,i1,a1,i1)"
7603                   if(numerator >=10 .and. denominator <=  9) formm="(a1,i2,a1,i1)"
7604                   if(numerator >=10 .and. denominator >= 10) formm="(a1,i2,a1,i2)"
7605                   if(numerator <= 9 .and. denominator >= 10) formm="(a1,i1,a1,i2)"
7606                   if (v > 0.0_cp) then
7607                      write(unit=fracc,fmt=formm) "+",numerator,"/",denominator
7608                   else
7609                      write(unit=fracc,fmt=formm) "-",numerator,"/",denominator
7610                   end if
7611                   return
7612                end if
7613             end do
7614          end do
7615          if(v > 0.0) then
7616              write(unit=fracc,fmt="(a,f9.4)") "+",v
7617          else
7618              write(unit=fracc,fmt="(f10.4)") v
7619          end if
7620       end if
7621       fracc=Pack_String(fracc)
7622       return
7623    End Subroutine Get_Fraction_2Dig
7624
7625    !!----
7626    !!---- Subroutine Get_LogUnit(lun)
7627    !!----   integer,     intent(out) :: lun !First logical unit available
7628    !!----
7629    !!----   Provides the number of the first logical unit that is not opened.
7630    !!----   Useful for getting a logical unit to a file that should be opened
7631    !!----   of the flight.
7632    !!----
7633    !!----   Update: February - 2005
7634    !!
7635    Subroutine Get_LogUnit(lun)
7636       !---- Arguments ----!
7637       integer,  intent(out) :: lun
7638
7639       !---- Local variables ----!
7640       logical :: op
7641       integer, parameter :: max_iunits=500
7642
7643       lun=1
7644       do
7645          inquire(unit=lun,opened=op)
7646          if (.not. op) exit
7647          lun=lun+1
7648          if (lun == max_iunits) then
7649             lun=-1
7650             exit
7651          end if
7652       end do
7653
7654       return
7655    End Subroutine Get_LogUnit
7656
7657    !!----  Subroutine Get_Mat_From_Symb(Symb,Mat,cod)
7658    !!----    character(len=*),                intent(in)  :: Symb
7659    !!----    real,dimension(3,3),             intent(out) :: Mat
7660    !!----    character(len=1), dimension(3),  intent(in)  :: cod
7661    !!----
7662    !!----  Subroutine to extract the transformation matrix corresponding
7663    !!----  to a symbol of the form:  m1a+m2b+m3c,m4a+m5b+m6c,m7a+m8b+m9c
7664    !!----  corresponding a cell transformation or a rotational symmetry operator.
7665    !!----  The symbols: a,b,c are not exclusive. The last variable contains the
7666    !!----  equivalent ones, for instance cod=(/"u","v","w"/) or cod=(/"x","y","z"/).
7667    !!----  The numbers m(i) may be real or integer numbers or even fractions.
7668    !!----  The returned real matrix corresponds to:
7669    !!----                           / m1   m2   m3 \
7670    !!----                    Mat = |  m4   m5   m6  |
7671    !!----                           \ m7   m8   m9 /
7672    !!----  In the symbol it may appear negative sign and the order within each
7673    !!----  direction is irrelevant, for instantce: m2b+m1a+m3c,m6c+m5b+m4a,m9c+m8b+m7a
7674    !!----  is strictly equivalent to the symbol given above.
7675    !!----  This subroutine has been modified in order to accept data of the form:
7676    !!----   3a/2+b-c/4, a-3b/2,c+b/2. Now the letters may be followed by the division
7677    !!----  symbol. Befor this modification the previous item should had be given as:
7678    !!----   3/2a+b-1/4c, a-3/2b,c+1/2b. Singular matrices are also accepted, for instance
7679    !!----  the matrix corresponding to the string: 0,a+b,0 was previously incorrect, now
7680    !!----  the constructed matrix is as expected:
7681    !!----                           / 0   0   0 \
7682    !!----      0,a+b,0  ->   Mat = |  1   1   0  |
7683    !!----                           \ 0   0   0 /
7684    !!----
7685    !!----
7686    !!----   Created: February - 2012 (JRC)
7687    !!----   Updated: January  - 2014 (JRC).
7688    !!----
7689    Subroutine Get_Mat_From_Symb(Symb,Mat,cod)
7690      character(len=*),                intent(in)  :: Symb
7691      real(kind=cp),dimension(3,3),    intent(out) :: Mat
7692      character(len=1), dimension(3),  intent(in)  :: cod
7693      !---- local variables ----!
7694      integer :: i,j
7695      character(len=len(Symb)), dimension(3) :: split
7696
7697      call init_err_string()
7698      i=index(Symb,",")
7699      j=index(Symb,",",back=.true.)
7700      split(1)= pack_string(Symb(1:i-1))
7701      split(2)= pack_string(Symb(i+1:j-1))
7702      split(3)= pack_string(Symb(j+1:))
7703      do i=1,3
7704       call Get_Num_String(trim(split(i)), Mat(i,:),cod)
7705      end do
7706      return
7707    End Subroutine Get_Mat_From_Symb
7708
7709    !!----  Subroutine Get_Transf(string,mat,v,cod)
7710    !!----    character(len=*),                         intent(in)  :: string
7711    !!----    real(kind=cp),dimension(3,3),             intent(out) :: mat
7712    !!----    real(kind=cp),dimension(3),               intent(out) :: v
7713    !!----    character(len=1), optional,dimension(4),  intent(in)  :: cod
7714    !!----
7715    !!----  This subroutine extracts the transformation matrix and the vector
7716    !!----  corresponding to the change of origin from a symbol of the form:
7717    !!----  m1a+m2b+m3c,m4a+m5b+m6c,m7a+m8b+m9c;t1,t2,t3.
7718    !!----  The order may be matrix;origin or origin;matrix. Parenthesis may
7719    !!----  accompany the symbol like in (a,b+c,c-b;1/2,0,1/2). The basis vectors
7720    !!----  a,b,c and the separator ";" may be changed by putting them into the
7721    !!----  optional array cod. For instance if cod=["u","v","w","|"] a sort of
7722    !!----  Seitz symbom may be read.
7723    !!----
7724    !!----  Created: January 2014 (JRC)
7725    !!----
7726    Subroutine Get_Transf(string,mat,v,cod)
7727      character(len=*),                         intent(in)  :: string
7728      real(kind=cp),dimension(3,3),             intent(out) :: mat
7729      real(kind=cp),dimension(3),               intent(out) :: v
7730      character(len=1), optional,dimension(4),  intent(in)  :: cod
7731      !--- Local variables ---!
7732      character(len=1), dimension(4) :: cd
7733      character(len=len(string))     :: transf_key,cmat,ori
7734      integer  :: i,j,nc
7735      integer,dimension(2) :: pos
7736
7737      call init_err_string()
7738      cd=(/"a","b","c",";"/)
7739      if(present(cod)) cd=cod
7740      transf_key=string
7741      !Remove the parenthesis is present
7742      j=index(transf_key,"(")
7743      if(j /= 0) transf_key(j:j)= " "
7744      j=index(transf_key,")")
7745      if(j /= 0) transf_key(j:j)= " "
7746      transf_key=adjustl(l_case(transf_key))
7747
7748      !Determine the order in which the string is provided
7749      i=index(transf_key,cd(4))
7750      if(i /= 0) then
7751         cmat=transf_key(1:i-1)
7752         j=index(cmat,cd(1))
7753         if(j == 0) then
7754            ori=cmat
7755            cmat=transf_key(i+1:)
7756         else
7757            ori=transf_key(i+1:)
7758         end if
7759         call Get_Mat_From_Symb(cMat,mat,cd(1:3))
7760         if(ERR_String) then
7761           ERR_String_Mess=" Bad matrix setting...: "//trim(ERR_String_Mess)
7762         end if
7763         !Origin
7764         Call Get_Separator_Pos(ori,",",pos,nc)
7765         if(nc /= 2)then
7766           ERR_String=.true.
7767           ERR_String_Mess=" Bad origin setting...: "//trim(ori)
7768           return
7769         else
7770           call Read_Fract(ori(1:pos(1)-1),v(1))
7771           call Read_Fract(ori(pos(1)+1:pos(2)-1),v(2))
7772           call Read_Fract(ori(pos(2)+1:),v(3))
7773           if(ERR_String) then
7774             ERR_String_Mess=" Bad origing setting...: "//trim(ERR_String_Mess)//" :: "//trim(ori)
7775             return
7776           end if
7777         end if
7778      else
7779         ERR_String=.true.
7780         ERR_String_Mess=" No appropriate separator ("//cd(4)//") is present in the input string:"//trim(string)
7781      end if
7782      return
7783    End Subroutine Get_Transf
7784
7785
7786    !!----  Subroutine Get_Num_String(string,v,cod)
7787    !!----    character(len=*),                intent(in)  :: string
7788    !!----    real(kind=cp),dimension(3),      intent(out) :: v
7789    !!----    character(len=1), dimension(3),  intent(in)  :: cod
7790    !!----
7791    !!----  Auxiliary subroutine of Get_Mat_From_Symb. This subroutine extracts
7792    !!----  a real vector from symbol of the form:  m1a+m2b+m3c. Similar comments
7793    !!----  as for the subroutine Get_Mat_From_Symb applies.
7794    !!----
7795    !!----  Created: February - 2012 (JRC).
7796    !!----  Updated: January  - 2014 (JRC).
7797    !!----
7798
7799    Subroutine Get_Num_String(string,v,cod)
7800      character(len=*),                intent(in)  :: string
7801      real(kind=cp),dimension(3),      intent(out) :: v
7802      character(len=1), dimension(3),  intent(in)  :: cod
7803      !--- Local variables ---!
7804      integer :: i,k,ns,np,nterm,m,nsp,jk,jp
7805      integer, dimension(3) :: j,pos,neg, klist
7806      character(len=len(string)),dimension(3) :: split
7807
7808      call Get_Separator_Pos(string,"+",pos,np)
7809      call Get_Separator_Pos(string,"-",neg,ns)
7810      nterm=np+ns
7811      !write(*,"(//a)") " => Input string: "//trim(string)
7812      !write(*,"(a,i4)") " => Nterms: ",nterm
7813      !write(*,"(a,3i4)") " => Pos vector: ",(pos(i),i=1,np)
7814      !write(*,"(a,3i4)") " => Neg vector: ",(neg(i),i=1,ns)
7815      !Construct the splitted terms depending on +/- separators
7816      Select Case (nterm)
7817        Case(0)  !only 1 positive item without sign
7818             nsp=1
7819             split(1)=string
7820
7821        Case(1)
7822
7823             Select Case(np)
7824               Case(0) !A single term with a negative symbol or two terms separated by the negative symbol
7825                   if(neg(1) == 1) then !single term
7826                     nsp=1
7827                     split(1)=string
7828                   else
7829                     nsp=2
7830                     split(1)=string(1:neg(1)-1)
7831                     split(2)=string(neg(1):)
7832                   end if
7833               Case(1) !A single term with a positive symbol or two positive terms
7834                   if(pos(1) == 1) then !single term
7835                     nsp=1
7836                     split(1)=string(2:)
7837                   else
7838                     nsp=2
7839                     split(1)=string(1:pos(1)-1)
7840                     split(2)=string(pos(1)+1:)
7841                   end if
7842             End Select
7843
7844        Case(2)
7845
7846             Select Case(np)
7847               Case(0) !No positive terms then (1) -cccc -dddd or (2)xxxx - yyyy -  zzzz
7848                   if(neg(1) == 1) then !two negative terms (1)
7849                     nsp=2
7850                     split(1)=string(1:neg(2)-1)
7851                     split(2)=string(neg(2):)
7852                   else                  !Three terms as (2)
7853                     nsp=3
7854                     split(1)=string(1:neg(1)-1)
7855                     split(2)=string(neg(1):neg(2)-1)
7856                     split(3)=string(neg(2):)
7857                   end if
7858               Case(1) !Four options (1)+xxxx-yyyy  (2)-xxxx+yyyy  (3)xxxx+yyyyy-zzzzz  (4)xxxx-yyyy+zzzz
7859                   if(pos(1) == 1) then !(1)
7860                     nsp=2
7861                     split(1)=string(2:neg(1)-1)
7862                     split(2)=string(neg(1):)
7863                   else if(neg(1) == 1) then  !(2)
7864                     nsp=2
7865                     split(1)=string(1:pos(1)-1)
7866                     split(2)=string(pos(1)+1:)
7867                   else if(pos(1) < neg(1)) then !(3)
7868                     nsp=3
7869                     split(1)=string(1:pos(1)-1)
7870                     split(2)=string(pos(1)+1:neg(1)-1)
7871                     split(3)=string(neg(1):)
7872                   else if(pos(1) > neg(1)) then !(4)
7873                     nsp=3
7874                     split(1)=string(1:neg(1)-1)
7875                     split(2)=string(neg(1):pos(1)-1)
7876                     split(3)=string(pos(1)+1:)
7877                   end if
7878               Case(2) !Two options (1)+xxxx+yyyy  (2) xxxx+yyyy+zzzz
7879                   if(pos(1) == 1) then !(1)
7880                     nsp=2
7881                     split(1)=string(2:pos(2)-1)
7882                     split(2)=string(pos(2)+1:)
7883                   else   !2
7884                     nsp=3
7885                     split(1)=string(1:pos(1)-1)
7886                     split(2)=string(pos(1)+1:pos(2)-1)
7887                     split(3)=string(pos(2)+1:)
7888                   end if
7889             End Select
7890
7891        Case(3)
7892
7893             nsp=3
7894             Select Case(np)
7895               Case(0) !No positive terms  a single option: -xxxx - yyyy -  zzzz
7896                   split(1)=string(1:neg(2)-1)
7897                   split(2)=string(neg(2):neg(3)-1)
7898                   split(3)=string(neg(3):)
7899               Case(1) !Three options (1)+xxxx-yyyy-zzzz  (2)-xxxx+yyyy-zzzz  (3)-xxxx-yyyyy+zzzzz
7900                   if(pos(1) == 1) then !(1)
7901                     split(1)=string(2:neg(1)-1)
7902                     split(2)=string(neg(1):neg(2)-1)
7903                     split(3)=string(neg(2):)
7904                   else if(pos(1) <  neg(2)) then  !(2)
7905                     split(1)=string(1:pos(1)-1)
7906                     split(2)=string(pos(1)+1:neg(2)-1)
7907                     split(3)=string(neg(2):)
7908                   else if(pos(1) > neg(2)) then !(3)
7909                     split(1)=string(1:neg(2)-1)
7910                     split(2)=string(neg(2):pos(1)-1)
7911                     split(3)=string(pos(1)+1:)
7912                   end if
7913               Case(2) !Two options (1)+xxx+yyy-zzz  (2)-xxx+yyy+zzzz (3) +xxx-yyy+zzz
7914                   if(neg(1) == 1) then !(2)
7915                     split(1)=string(1:pos(1)-1)
7916                     split(2)=string(pos(1)+1:pos(2)-1)
7917                     split(3)=string(pos(2)+1:)
7918                   else if(neg(1) > pos(2)) then !(1)
7919                     split(1)=string(2:pos(2)-1)
7920                     split(2)=string(pos(2)+1:neg(1)-1)
7921                     split(3)=string(neg(1):)
7922                   else if(neg(1) < pos(2)) then !(3)
7923                     split(1)=string(2:neg(1)-1)
7924                     split(2)=string(neg(1):pos(2)-1)
7925                     split(3)=string(pos(2)+1:)
7926                   end if
7927               Case(3) !Single option (1)+xxx+yyy+zzz
7928                   split(1)=string(2:pos(2)-1)
7929                   split(2)=string(pos(2)+1:pos(3)-1)
7930                   split(3)=string(pos(3)+1:)
7931             End Select
7932      End Select
7933      do i=1,nsp
7934         split(i)=pack_string(split(i))
7935      end do
7936      !write(*,"(a,3a10)") " => Split items: ",(split(m),m=1,nsp)
7937
7938      v(:) =0.0; nterm=0;  klist=0
7939      do m=1,nsp
7940         k=0
7941         j=0
7942         np=len_trim(split(m))
7943         do i=1,3
7944            j(i)=index(split(m),cod(i))
7945            if(j(i) /= 0) then
7946              k =i
7947              nterm=nterm+1
7948              klist(nterm)=i
7949              exit
7950            end if
7951         end do
7952         !write(*,"(a,i3)") " => Split: "//trim(split(m)),k
7953         if ( k == 0) cycle !the component is zero
7954         do i=1,nterm-1
7955            if(k == klist(i)) then
7956              !This is impossible in principle
7957              ERR_String= .true.
7958              ERR_String_Mess=" The provided symbol is illegal: "//trim(string)
7959              return
7960            end if
7961         end do
7962         jk=j(k)
7963         i=jk-1
7964         jp=jk+1
7965         if(i == 0 .and. np == 1 ) then !the code is the first character replace it by "1" and read the rest of the string
7966            split(m)(jk:jk)="1"
7967         else if(i == 0) then
7968            if(split(m)(jp:jp) ==  "/") then
7969              split(m)(jk:jk)="1"
7970            else
7971              split(m)(jk:jk)=" "
7972            end if
7973         else if(split(m)(i:i) == "-") then
7974            if(split(m)(jp:jp) ==  "/") then
7975               split(m)(jk:jk)="1"
7976            else  !There is a number on the right
7977               split(m)(jk:jk)=" "
7978            end if
7979         else   !there is a number on the left, remove the symbol, compact it and read
7980            split(m)(jk:jk)=" "
7981         end if
7982         split(m)=pack_string(split(m))
7983         call Read_Fract(split(m), v(k))
7984         !write(*,"(a,i3,a,f12.5)") " => Modified split: "//trim(split(m))//"  k=", k, "  v(k) =",v(k)
7985      end do
7986      return
7987    End Subroutine Get_Num_String
7988
7989    !!----
7990    !!---- Subroutine Getnum(Line, Vet, Ivet, Iv)
7991    !!----    character(len=*),              intent( in) :: Line    !  In -> Input String to convert
7992    !!----    real(kind=cp), dimension(:),   intent(out) :: Vet     ! Out -> Vector of real numbers
7993    !!----    integer,dimension(:),          intent(out) :: Ivet    ! Out -> Vector of integer numbers
7994    !!----    integer,                       intent(out) :: Iv      ! Out -> Number of numbers in Vet/Ivet
7995    !!----
7996    !!----    Converts a string to numbers and write on VET/IVET if real/integer. Control
7997    !!----    of errors is possible by inquiring the global variables ERR_STRING and
7998    !!----    ERR_String_Mess
7999    !!----
8000    !!---- Update: February - 2005
8001    !!
8002    Subroutine Getnum(line,vet,ivet,iv)
8003       !---- Argument ----!
8004       character (len=*),          intent ( in) :: line
8005       real(kind=cp), dimension(:),intent (out) :: vet
8006       integer, dimension(:),      intent (out) :: ivet
8007       integer,                    intent (out) :: iv
8008
8009       !---- Local variables ----!
8010       logical                   :: numero
8011       character (len=len(line)) :: resto,cifre
8012       integer                   :: i,isum,ncharl,nchard,isegno,iniz,ipoi,idec,idig
8013       integer                   :: nchart, npos,nchard1,isum_exp,ioper
8014       real(kind=cp)             :: suma,segno,dec
8015       real(kind=cp)             :: sum_m
8016
8017       !---- Initializing variables ----!
8018       call init_err_string()
8019       iv=0
8020       ivet=0
8021       vet=0.0
8022
8023       resto=u_case(line)
8024
8025       do
8026          ioper=0
8027          isum_exp=0
8028          nchard1=0
8029          sum_m=0.0
8030          suma=0.0
8031          isum=0
8032          call cutst(resto,ncharl,cifre,nchard)
8033          if (nchard <= 0) exit
8034
8035          !---- Is a number ----!
8036          numero=.true.
8037          do i=1,nchard
8038             if (cifre(i:i) =='E') cycle
8039             npos=index(digit,cifre(i:i))
8040             if (npos /= 0) cycle
8041             numero=.false.
8042          end do
8043          if (.not. numero) then
8044             err_string=.true.
8045             ERR_String_Mess="The variable cannot be computed as a number in GETNUM "
8046             return
8047          end if
8048
8049          !---- Positive or Negative number ----!
8050          segno=1.0
8051          isegno=1
8052          iniz=1
8053          if (cifre(1:1) == digit(12:12)) then
8054             segno=-1.0
8055             isegno=-1
8056             iniz=2
8057          end if
8058
8059          !---- Decimal Number ----!
8060          ipoi=index(cifre(1:nchard),digit(11:11))
8061
8062          !---- Exponential Number ----!
8063          nchard1=index(cifre(1:nchard),"E")
8064          if (nchard1 /= 0) then
8065             nchart=nchard
8066             nchard=nchard1-1
8067          end if
8068
8069          if (ipoi == 0) ipoi=nchard+1
8070          dec=real(ipoi-1-iniz)
8071          idec=ipoi-1-iniz
8072          do i=iniz,nchard
8073             idig=index(digit,cifre(i:i))
8074             if (idig >= 1 .and. idig <= 11)  then
8075                if (idig <= 10)  then
8076                   suma=suma+real(idig-1)*10.0**dec
8077                   if (idec >= 0) isum=isum*10+(idig-1)
8078                   dec=dec-1.0
8079                   idec=idec-1
8080                end if
8081             else
8082                err_string=.true.
8083                ERR_String_Mess="Limits of digit variable exceeded in GETNUM"
8084                return
8085             end if
8086          end do
8087
8088          if (nchard1 /= 0) then
8089             nchard1=nchard1+1
8090             select case (cifre(nchard1:nchard1))
8091                case ("-")
8092                   ioper=1
8093                   nchard1=nchard1+1
8094
8095                case ("+")
8096                   nchard1=nchard1+1
8097             end select
8098
8099             do i=nchard1,nchart
8100                idig=index(digit,cifre(i:i))
8101                if (idig >= 1 .and. idig <= 10)  then
8102                   isum_exp=isum_exp*10+(idig-1)
8103                else
8104                   err_string=.true.
8105                   ERR_String_Mess="Limits of digit variable exceeded in GETNUM"
8106                   return
8107                end if
8108             end do
8109          end if
8110
8111          iv=iv+1
8112          vet(iv)=suma*segno
8113          ivet(iv)=isum*isegno
8114
8115          if (nchard1 /= 0) then
8116             select case (ioper)
8117                case (0)
8118                   sum_m=10.0**isum_exp
8119
8120                case (1)
8121                   sum_m=10.0**isum_exp
8122                   sum_m=1.0/sum_m
8123             end select
8124             vet(iv)=vet(iv)*sum_m
8125          end if
8126
8127          if (ncharl <= 0) then
8128             exit
8129          end if
8130       end do
8131
8132       return
8133    End Subroutine Getnum
8134
8135    !!----
8136    !!---- Subroutine Getnum_Std(Line, Value, Std, Ic)
8137    !!----    character(len=*),            intent( in) :: Line    !  In -> Input String
8138    !!----    real(kind=cp), dimension(:), intent(out) :: Value   ! Out -> Vector of values with real numbers
8139    !!----    real(kind=cp), dimension(:), intent(out) :: Std     ! Out -> Vector of standard deviation values
8140    !!----    integer,                     intent(out) :: Ic      ! Out -> Number of components of vector Value
8141    !!----
8142    !!----    Converts a string to a numbers with standard deviation with format: x.fffff(s)
8143    !!----    Control of errors is possible by inquiring the global variables ERR_STRING
8144    !!----    and ERR_String_Mess.
8145    !!----
8146    !!---- Update: February - 2005
8147    !!
8148    Subroutine GetNum_Std(line, value, std, ic)
8149       !----Arguments ----!
8150       character(len=*),             intent( in) :: line
8151       real(kind=cp), dimension(:),  intent(out) :: value
8152       real(kind=cp), dimension(:),  intent(out) :: std
8153       integer,                      intent(out) :: ic
8154
8155       !---- Local Variables ----!
8156       character(len=len(line))               :: resto,dire,numm
8157       integer                                :: iv,nlong
8158       integer                                :: np, np1, np2
8159       integer, dimension(size(value))        :: ivet
8160       real(kind=cp), dimension(size(value))  :: vet
8161
8162       value=0.0
8163       std  =0.0
8164       ic   =0
8165       call init_err_string()
8166
8167       !---- Initial Checks ----!
8168       if (len_trim(line) == 0) then
8169          err_string=.true.
8170          ERR_String_Mess="Blank line"
8171          return
8172       end if
8173       resto=adjustl(line)
8174
8175       do
8176          if (len_trim(resto) == 0) exit
8177          call cutst(resto,nlong,dire)
8178          np1=index(dire,"(")
8179          np2=index(dire,")")
8180
8181          if ( (np2 < np1) .or.               &  ! ")" before than "("
8182               (np1==0 .and. np2 >0) .or.     &  ! "(" doesn"t exists
8183               (np2==0 .and. np1 >0) ) then      ! ")" doesn"t exists
8184             err_string=.true.
8185             ERR_String_Mess="Wrong format using Standard values"
8186             return
8187          end if
8188
8189          if (np1 == 0 .and. np2 ==0) then
8190             call getnum(dire,vet,ivet,iv)
8191             if (iv /= 1 .or. err_string) then
8192                err_string=.true.
8193                ERR_String_Mess="Bad format"
8194                return
8195             end if
8196             ic=ic+1
8197             value(ic)=vet(1)
8198          else
8199             numm=dire(1:np1-1)
8200             np=index(numm,".")
8201             if (np == 0) then
8202                call getnum(numm,vet,ivet,iv)
8203                if (iv /= 1 .or. err_string) then
8204                   err_string=.true.
8205                   ERR_String_Mess="Bad format"
8206                   return
8207                end if
8208                ic=ic+1
8209                value(ic)=vet(1)
8210                numm=dire(np1+1:np2-1)
8211                call getnum(numm,vet,ivet,iv)
8212                if (iv /= 1) then
8213                   err_string=.true.
8214                   ERR_String_Mess="Bad format"
8215                   return
8216                end if
8217                std(ic)=vet(1)
8218             else
8219                np=np1-np-1
8220                call getnum(numm,vet,ivet,iv)
8221                if (iv /= 1 .or. err_string) then
8222                   err_string=.true.
8223                   ERR_String_Mess="Bad format"
8224                   return
8225                end if
8226                ic=ic+1
8227                value(ic)=vet(1)
8228                numm=dire(np1+1:np2-1)
8229                call getnum(numm,vet,ivet,iv)
8230                if (iv /= 1 .or. err_string) then
8231                   err_string=.true.
8232                   ERR_String_Mess="Bad format"
8233                   return
8234                end if
8235                std(ic)=vet(1)/(10.0**np)
8236             end if
8237          end if
8238       end do
8239
8240       return
8241    End Subroutine GetNum_Std
8242
8243    !!----
8244    !!---- Subroutine Get_Separator_Pos(line,car,pos,ncar)
8245    !!----   character(len=*),      intent(in)  :: line  ! In -> Input String
8246    !!----   character(len=1),      intent(in)  :: car   ! In -> Separator character
8247    !!----   integer, dimension(:), intent(out) :: pos   ! Out -> Vector with positions of "car" in "Line"
8248    !!----   integer,               intent(out) :: ncar  ! Out -> Number of appearance of "car" in "Line"
8249    !!----
8250    !!----    Determines the positions of the separator character "car" in string "Line" and generates
8251    !!----    the vector Pos containing the positions. The number of times the character "car" appears
8252    !!----    In "Line" is stored in "ncar".
8253    !!----    The separator "car" is not counted within substrings of "Line" that are written within
8254    !!----    quotes. The following example illustrates the functionning of the subroutine
8255    !!----
8256    !!----       !       12345678901234567890123456789012345678901234567890
8257    !!----        line =' 23, "List, of, authors", this book, year=1989'
8258    !!----
8259    !!----    A call like:  call Get_Separator_Pos(line,',',pos,ncar) provides
8260    !!----    ncar= 3
8261    !!----    pos= (/ 4, 25, 36, 0, ..../)
8262    !!----
8263    !!---- Update: December 2009
8264    !!
8265    Subroutine Get_Separator_Pos(line,car,pos,ncar)
8266      character(len=*),      intent(in)  :: line
8267      character(len=1),      intent(in)  :: car
8268      integer, dimension(:), intent(out) :: pos
8269      integer,               intent(out) :: ncar
8270      integer :: i,j,k
8271
8272      ncar=0
8273      j=0
8274      do i=1,len_trim(line)
8275        j=j+1
8276        if(line(j:j) == '"') then  !A chains of characters is found, advance up the the next "
8277          do k=1,len_trim(line)    !the character "car" is ignored if it is within " "
8278            j=j+1
8279            if(line(j:j) /= '"') cycle
8280            exit
8281          end do
8282        end if
8283        if(line(j:j) == car) then
8284          ncar=ncar+1
8285          pos(ncar)=j
8286        end if
8287      end do
8288      return
8289    End Subroutine Get_Separator_Pos
8290
8291    !!----
8292    !!---- Subroutine Get_Substring_Positions(string,substr,pos,nsubs)
8293    !!----   character(len=*),      intent(in)  :: string   ! In -> Input String
8294    !!----   character(len=*),      intent(in)  :: substr   ! In -> Substring
8295    !!----   integer, dimension(:), intent(out) :: pos      ! Out -> Vector with positions of the firs character of "substr" in "String"
8296    !!----   integer,               intent(out) :: nsubs    ! Out -> Number of appearance of "substr" in "String"
8297    !!----
8298    !!----    Determines the positions of the substring "substr" in "String" and generates
8299    !!----    the vector Pos containing the positions of the first character of "substr" in "String".
8300    !!----    The number of times the "substr" appears in "String" is stored in "nsubs".
8301    !!----
8302    !!----     Updated: May 2014
8303
8304    Subroutine Get_Substring_Positions(string,substr,pos,nsubs)
8305      character(len=*),      intent(in)  :: string
8306      character(len=*),      intent(in)  :: substr
8307      integer, dimension(:), intent(out) :: pos
8308      integer,               intent(out) :: nsubs
8309      integer :: i,j,lsubs
8310
8311      nsubs=0
8312      lsubs=len_trim(substr)
8313      j=0
8314      do i=1,len_trim(string)
8315        j=j+1
8316        if(string(j:j+lsubs-1) == trim(substr)) then
8317          nsubs=nsubs+1
8318          pos(nsubs)=j
8319        end if
8320      end do
8321      return
8322    End Subroutine Get_Substring_Positions
8323
8324    !!----
8325    !!---- Subroutine Getword(Line, Dire, Ic)
8326    !!----    character(len=*),              intent( in) :: Line   !  In -> Input String
8327    !!----    character(len=*),dimension(:), intent(out) :: Dire   ! Out -> Vector of Words
8328    !!----    integer,                       intent(out) :: Ic     ! Out -> Number of words
8329    !!----
8330    !!----    Determines the number of words (Ic) in the string "Line" and generates a
8331    !!----    character vector "Dire" with separated words.
8332    !!----    Control of errors is possible by inquiring the global variables ERR_STRING
8333    !!----    and ERR_String_Mess. The last modification allows to treat strings between
8334    !!----    quotes as a single word.
8335    !!----
8336    !!---- Update: July - 2011
8337    !!
8338    Subroutine Getword(line,dire,ic)
8339       !---- Argument ----!
8340       character (len=*),                 intent ( in) :: line
8341       character (len=*), dimension(:),   intent (out) :: dire
8342       integer,                           intent (out) :: ic
8343
8344       !---- Local variables ----!
8345       character (len=len(line)) :: line1,line2
8346       integer                   :: nlong2
8347       integer                   :: ndim, j
8348
8349       call init_err_string()
8350       ic=0
8351       ndim=size(dire)
8352       line1=line
8353
8354       do
8355          line1=adjustl(line1)
8356          if(line1(1:1) == '"') then
8357             j=index(line1(2:),'"')
8358             if( j > 0) then
8359               line2=line1(2:j)
8360               nlong2=len_trim(line2)
8361               line1 = line1(j+2:)
8362             else
8363               err_string=.true.
8364               ERR_String_Mess="Non balanced quotes!"
8365               exit
8366             end if
8367          else
8368             call cutst(line1,line2=line2,nlong2=nlong2)
8369          end if
8370          if (nlong2 == 0) exit
8371          ic=ic+1
8372          if (ic > ndim) then
8373             err_string=.true.
8374             ERR_String_Mess="Dimension of DIRE exceeded"
8375             exit
8376          end if
8377          dire(ic)=line2(:nlong2)
8378       end do
8379
8380       return
8381    End Subroutine Getword
8382
8383    !!----
8384    !!---- Subroutine Inc_LineNum(line_n)
8385    !!----  integer, intent(in) :: line_n
8386    !!----
8387    !!----    Increments the current line number
8388    !!----    Used when a way of reading other than FindFMT is used
8389    !!----
8390    !!---- Update: November - 2006
8391    !!
8392    Subroutine Inc_LineNum(line_n)
8393       !---- Argument ----!
8394       integer, intent(in) :: line_n
8395
8396       line_nb=line_nb+line_n
8397
8398       return
8399    End Subroutine Inc_LineNum
8400
8401    !!----
8402    !!---- Subroutine Init_Err_String()
8403    !!----
8404    !!----    Initializes general error variables for this module as:
8405    !!----    ERR_STRING=.false. ;  ERR_String_Mess=" "
8406    !!----
8407    !!---- Update: February - 2005
8408    !!
8409    Subroutine Init_Err_String()
8410
8411       err_string=.false.
8412       ERR_String_Mess=" "
8413
8414       return
8415    End Subroutine Init_Err_String
8416
8417    !!----
8418    !!---- Subroutine Init_FindFMT(nline)
8419    !!----   integer, optional, intent(in) :: nline
8420    !!----
8421    !!----    Initializes the subroutine FindFMT.
8422    !!----    Mess_FindFMT (of type Err_Text_Type) is initialized to zero lines.
8423    !!----    Line_nb is initialized to zero (current line in the file),
8424    !!----    or Line_nb=line if the optional argument "line" is present.
8425    !!----
8426    !!---- Update: February - 2005
8427    !!
8428    Subroutine Init_FindFMT(nline)
8429       !---- Arguments ----!
8430       integer, optional, intent(in) :: nline
8431
8432       line_nb=0
8433       if(present(nline)) line_nb=nline
8434       Mess_FindFMT = Err_Text_Type(0,(/" "," "," "," "," "/))
8435
8436       return
8437    End Subroutine Init_FindFMT
8438
8439    !!----
8440    !!---- Subroutine Lcase(Line)
8441    !!----    character(len=*), intent(in out) :: Line
8442    !!----
8443    !!----    Conversion to lower case. Line is modified
8444    !!----
8445    !!---- Update: February - 2005
8446    !!
8447    Subroutine Lcase(line)
8448       !---- Argument ----!
8449       character (len=*), intent(in out) :: line
8450
8451       line=l_case(line)
8452
8453       return
8454    End Subroutine Lcase
8455
8456    !!----
8457    !!---- Subroutine Number_Lines(Filename,n, input_string)
8458    !!----    character(len=*), intent(in) :: Filename     !  In -> Name of the file
8459    !!----    integer        , intent(out) :: N            ! Out -> Number of lines in the file
8460    !!----    character(len=*), optional,intent(in) :: input_string   ! In -> String to exit
8461    !!----
8462    !!----    Return the number of lines contained in a file. The file will be opened and closed before
8463    !!----    returning to the calling unit.
8464    !!----    If 'input_string' is present, return the number of lines until 'input_string' is founded
8465    !!----    as first string in the line
8466    !!----    (example : input_string =='END' : avoid Q peaks in a SHELX file)
8467    !!----
8468    !!---- Update: February - 2005, March-2014 (removing the "opened" inquire, JRC)
8469    !!
8470    Subroutine Number_Lines(filename,n, input_string)
8471       !---- Arguments ----!
8472       character(len=*), intent(in)  :: filename
8473       integer,          intent(out) :: n
8474       character(len=*), optional, intent(in) :: input_string       ! TR may 2013
8475
8476       !---- Local Variables ----!
8477       logical            :: info
8478       integer            :: lun,cond
8479       character (len=256):: read_line                             ! TR may 2013
8480       integer            :: long                                  ! TR may 2013
8481
8482       !---- Init ----!
8483       info=.false.
8484       call get_logunit(lun)
8485       n=0
8486       cond=0
8487
8488       if(present(input_string)) long = len_trim(input_string)    ! TR may 2013
8489
8490       !---- Exist filename ? ----!
8491       inquire (file=filename,exist=info)
8492       if (.not. info) return
8493
8494       open(unit=lun,file=filename, status="old",action="read", position="rewind")
8495
8496       !---- Counting lines ----!
8497       do
8498          read(unit=lun,fmt="(a)",iostat=cond) read_line
8499          if (cond /= 0) exit
8500          read_line=adjustl(read_line)
8501          if(present(input_string)) then                                         ! TR may 2013
8502            if(u_case(read_line(1:long)) == u_case(input_string(1:long))) exit
8503          end if
8504          n=n+1
8505       end do
8506
8507       close(unit=lun)
8508
8509       return
8510    End Subroutine Number_Lines
8511
8512    !!----
8513    !!---- Subroutine NumCol_from_NumFmt(Text,n_col)
8514    !!----    character (len=*), intent(in) :: text   !  In -> String: "InPUT Format String"
8515    !!----    Integer,           intent(out):: n_col  ! Out -> Integer number of columns
8516    !!----
8517    !!----    Provides the number of columns spanned by a numeric format field F,I,G,E
8518    !!----
8519    !!---- Update: January - 2006
8520    !!
8521    Subroutine NumCol_from_NumFmt(Text,n_col)
8522       !---- Argument ----!
8523       character (len=*), intent(in) :: text
8524       Integer,           intent(out) :: n_col
8525
8526       !---- Local variables ----!
8527       integer  :: i,j,L,ncom,n1,n2,point,ier
8528       integer,dimension(0:len(Text)) :: pos
8529       character (len=len(Text)) :: fm
8530       character (len=10) :: string
8531
8532       fm=U_case(adjustl(Text))
8533       fm=pack_string(fm)
8534       L=len_trim(fm)
8535       fm=fm(2:L-1)
8536       L=L-2
8537       ncom=0
8538       pos(0)=0
8539       do i=1,L
8540         if(fm(i:i) == ",") then
8541            ncom=ncom+1
8542            pos(ncom)=i
8543         end if
8544       end do
8545       ncom=ncom+1
8546       pos(ncom)=L+1
8547       n_col=0
8548       do i=1,ncom
8549         string=" "
8550         string=fm(pos(i-1)+1:pos(i)-1)
8551         point=index(string,".")
8552         if( point /= 0) string=string(1:point-1)
8553         L=len_trim(string)
8554         do j=1,L
8555           point=index("FIGEX",string(j:j))
8556           if(point /= 0) then
8557              point=j
8558              exit
8559           end if
8560         end do
8561         n1=0
8562         Select Case (point)
8563            Case(0)
8564              n_col=0
8565              exit
8566            Case(1)
8567              string(point:point) = " "
8568              read(unit=string,fmt=*,iostat=ier) n2
8569              if(ier /= 0) n2=0
8570              n1=1
8571            Case default
8572              if(string(point:point)=="X") then
8573                string(point:point) = " "
8574                n1=1
8575                read(unit=string,fmt=*,iostat=ier) n2
8576                if(ier /= 0) n2=0
8577              else
8578                string(point:point) = " "
8579                read(unit=string,fmt=*,iostat=ier) n1,n2
8580                if(ier /= 0) n2=0
8581              end if
8582         End Select
8583         n_col=n_col+n1*n2
8584       end do
8585       if(n_col == 0) then
8586              err_string=.true.
8587              ERR_String_Mess="Illegal format string passed to subroutine:  NumCol_from_NumFmt"
8588       end if
8589       return
8590    End Subroutine NumCol_from_NumFmt
8591
8592    !!--..  Subroutine Read_Fract(str,valu)
8593    !!--..   Character(len=*), intent(in) :: str
8594    !!--..   real(kind=cp),    intent(out):: valu
8595    !!--..
8596    !!--..  Auxiliary subroutine for reading a string containing a real number
8597    !!--..  or a fraction. Is able to handle simple symbols:"", "-", "+", means
8598    !!--..  respectively: 1,-1,1
8599    !!--..
8600    !!--..  Created: February - 2012 (JRC).
8601    !!--..
8602    Subroutine Read_Fract(str,valu)
8603     Character(len=*), intent(in) :: str
8604     real(kind=cp),    intent(out):: valu
8605     !--- Local variables ---!
8606     integer :: k, ierr
8607     real(kind=cp) :: num,den
8608
8609     if(len_trim(str) == 0) then
8610       valu=1.0
8611       return
8612     else if(len_trim(str) == 1) then
8613       if(str == "+") then
8614        valu=1.0
8615        return
8616       else if(str == "-") then
8617        valu=-1.0
8618        return
8619       end if
8620     end if
8621     k=index(str,"/")
8622     if(k == 0) then !a single number
8623       read(unit=str,fmt=*,iostat=ierr) valu
8624       if(ierr /= 0) then
8625          valu=0.0
8626          ERR_String= .true.
8627          ERR_String_Mess=" The provided symbol is illegal: "//trim(str)
8628          return
8629       end if
8630     else !fraction
8631       read(unit=str(1:k-1),fmt=*,iostat=ierr) num
8632       if(ierr /= 0) then
8633          valu=0.0
8634          ERR_String= .true.
8635          ERR_String_Mess=" The provided symbol is illegal: "//str(1:k-1)
8636          return
8637       end if
8638       read(unit=str(k+1:),fmt=*,iostat=ierr) den
8639       if(ierr /= 0) then
8640          valu=0.0
8641          ERR_String= .true.
8642          ERR_String_Mess=" The provided symbol is illegal: "//str(k+1:)
8643          return
8644       end if
8645       valu=num/den
8646     end if
8647    End Subroutine Read_Fract
8648
8649
8650    !!----
8651    !!---- Subroutine Read_Key_Str(Filevar,Nline_Ini,Nline_End,Keyword,String)
8652    !!----    character(len=*),dimension(:), intent(in)      :: Filevar      !  In -> Input vector of String
8653    !!----    integer,                       intent(in out)  :: Nline_Ini    !  In -> Pointer to initial position to search
8654    !!----                                                                   ! Out -> Pointer to final position in search
8655    !!----    integer,                       intent(in)      :: Nline_End    !  In -> Pointer to final position to search
8656    !!----    character(len=*),              intent(in)      :: Keyword      !  In -> Word to search
8657    !!----    character(len=*),              intent(out)     :: String       ! Out -> Rest of the input string
8658    !!----    character(len=1), optional,    intent(in)      :: comment      !  In -> Character that define a comment line
8659    !!----
8660    !!----    Read a string on "filevar" starting with a particular "keyword" between lines "nline_ini" and
8661    !!----    "nline_end".
8662    !!----
8663    !!---- Update: February - 2005
8664    !!
8665    Subroutine Read_Key_Str(filevar,nline_ini,nline_end,keyword,string,comment)
8666       !---- Arguments ----!
8667       character(len=*), dimension(:), intent(in)      :: filevar
8668       integer,                        intent(in out)  :: nline_ini
8669       integer,                        intent(in)      :: nline_end
8670       character(len=*),               intent(in)      :: keyword
8671       character(len=*),               intent(out)     :: string
8672       character(len=1), optional,     intent(in)      :: comment
8673
8674       !---- Local Variable ----!
8675       character(len=len(filevar(1))) :: line,linec
8676       character(len=len(keyword))    :: key
8677       character(len=1)               :: cc
8678       integer                        :: i,np,nt
8679
8680       !---- Initial value ----!
8681       cc=' '
8682       if (present(comment)) cc=comment
8683       nt=min(size(filevar),nline_end)
8684       string=" "
8685       key =adjustl(keyword)
8686       call lcase(key)
8687
8688       do i=nline_ini,nt
8689          line=adjustl(filevar(i))
8690          if (len_trim(line) == 0 .or. line(1:1) == "!" .or. line(1:1) ==cc) cycle
8691          linec=line
8692          call lcase(line)
8693          np=index(line,key)
8694          if (np == 0) cycle
8695          linec=linec(np:)
8696          call cutst(linec)
8697          string=linec
8698          nline_ini=i
8699          exit
8700       end do
8701
8702       return
8703    End Subroutine Read_Key_Str
8704
8705    !!----
8706    !!---- Subroutine Read_Key_Strval(Filevar,Nline_Ini,Nline_End,Keyword,String,Vet,Ivet,Iv,comment)
8707    !!----    character(len=*),dimension(:),          intent(in)      :: Filevar      !  In -> Input vector of String
8708    !!----    integer,                                intent(in out)  :: Nline_Ini    !  In -> Pointer to initial position to search
8709    !!----                                                                            ! Out -> Pointer to final position in search
8710    !!----    integer,                                intent(in)      :: Nline_End    !  In -> Pointer to final position to search
8711    !!----    character(len=*),                       intent(in)      :: Keyword      !  In -> Word to search
8712    !!----    character(len=*),                       intent(out)     :: String       ! Out -> Rest of the input string
8713    !!----    real(kind=cp),dimension(:),   optional, intent(out)     :: Vet          ! Out -> Vector for real numbers
8714    !!----    integer,dimension(:),         optional  intent(out)     :: Ivet         ! Out -> Vector for integer numbers
8715    !!----    integer,                      optional, intent(out)     :: Iv           ! Out -> Number of numbers
8716    !!----    character(len=1),             optional, intent(in)      :: comment
8717    !!----
8718    !!----    Read a string on "filevar" starting with a particular "keyword" between lines "nline_ini" and
8719    !!----    "nline_end". If the string contains numbers they are read and put into "vet/ivet". The variable
8720    !!----    "string" contains the input string without the "keyword".
8721    !!----
8722    !!---- Update: February - 2005
8723    !!
8724    Subroutine Read_Key_StrVal(filevar,nline_ini,nline_end,keyword,string,vet,ivet,iv,comment)
8725       !---- Arguments ----!
8726       character(len=*), dimension(:),           intent(in)      :: filevar
8727       integer,                                  intent(in out)  :: nline_ini
8728       integer,                                  intent(in)      :: nline_end
8729       character(len=*),                         intent(in)      :: keyword
8730       character(len=*),                         intent(out)     :: string
8731       real(kind=cp),dimension(:),     optional, intent(out)     :: vet
8732       integer,dimension(:),           optional, intent(out)     :: ivet
8733       integer,                        optional, intent(out)     :: iv
8734       character(len=1),               optional, intent(in)      :: comment
8735
8736       !---- Local Variable ----!
8737       logical                        :: sval
8738       character(len=len(filevar(1))) :: line,linec
8739       character(len=len(keyword))    :: key
8740       character(len=1)               :: cc
8741       integer                        :: i,np,nt
8742
8743       !---- Initial value ----!
8744       cc=' '
8745       if (present(comment)) cc=comment
8746
8747       nt=min(size(filevar),nline_end)
8748       string=" "
8749       key =adjustl(keyword)
8750       call lcase(key)
8751       sval=.false.
8752       if (present(vet) .and. present(ivet) .and. present(iv)) sval=.true.
8753       if (sval) then
8754          vet=0.0
8755         ivet=0
8756           iv=0
8757       end if
8758
8759       do i=nline_ini,nt
8760          line=adjustl(filevar(i))
8761          if (len_trim(line) == 0 .or. line(1:1)=="!" .or. line(1:1)==cc) cycle
8762          linec=line
8763          call lcase(line)
8764          np=index(line,key)
8765          if (np == 0) cycle
8766          linec=linec(np:)
8767          call cutst(linec)
8768          string=linec
8769          nline_ini=i
8770          exit
8771       end do
8772
8773       if (sval .and. (len_trim(string) > 0) ) then
8774          line=string
8775
8776          !---- String Value ----!
8777          !call cutst(line,np,string)
8778
8779          !---- Values ----!
8780          call getnum(line,vet,ivet,iv)
8781          if (iv <=0) then
8782              vet=0.0
8783             ivet=0
8784          end if
8785       end if
8786
8787       return
8788    End Subroutine Read_Key_StrVal
8789
8790    !!----
8791    !!---- Subroutine Read_Key_Value(Filevar,Nline_Ini,Nline_End,Keyword,Vet,Ivet,Iv,comment,line_key)
8792    !!----    character(len=*),dimension(:), intent(in)      :: Filevar     !  In -> Input vector of String
8793    !!----    integer,                       intent(in out)  :: Nline_Ini   !  In -> Pointer to initial position to search
8794    !!----                                                                  ! Out -> Pointer to final position in search
8795    !!----    integer,                       intent(in)      :: Nline_End   !  In -> Pointer to final position to search
8796    !!----    character(len=*),              intent(in)      :: Keyword     !  In -> Word to search
8797    !!----    real(kind=cp),dimension(:),    intent(out)     :: Vet         ! Out -> Vector for real numbers
8798    !!----    integer,dimension(:),          intent(out)     :: Ivet        ! Out -> Vector for integer numbers
8799    !!----    integer,                       intent(out)     :: Iv          ! Out -> Number of components
8800    !!----    character(len=1),     optional, intent(in)     :: comment     ! Consider the character passed in comment as a comment to skip the line
8801    !!----    character(len=*),     optional, intent(out)    :: Iv          ! Out -> Cut line where keyword is read
8802    !!----
8803    !!----    Read a string on "filevar" starting with a particular "keyword" between lines "nline_ini" and
8804    !!----    "nline_end". If the string contains numbers they are read and put into "vet/ivet".
8805    !!----
8806    !!---- Update: February - 2005
8807    !!
8808    Subroutine Read_Key_Value(filevar,nline_ini,nline_end,keyword,vet,ivet,iv,comment,line_key)
8809       !---- Arguments ----!
8810       character(len=*), dimension(:), intent(in)     :: filevar
8811       integer,                        intent(in out) :: nline_ini
8812       integer,                        intent(in)     :: nline_end
8813       character(len=*),               intent(in)     :: keyword
8814       real(kind=cp),dimension(:),     intent(out)    :: vet
8815       integer,dimension(:),           intent(out)    :: ivet
8816       integer,                        intent(out)    :: iv
8817       character(len=1),     optional, intent(in)     :: comment
8818       character(len=*),     optional, intent(out)    :: line_key
8819
8820       !---- Local Variable ----!
8821       character(len=len(filevar(1))) :: line
8822       character(len=len(keyword))    :: key
8823       character(len=1)               :: cc
8824       integer                        :: i,np,nt
8825
8826       !---- Initial value ----!
8827       cc=' '
8828       if (present(comment)) cc=comment
8829
8830       nt=min(size(filevar),nline_end)
8831       iv  = 0
8832       vet = 0.0
8833       ivet= 0
8834       key =adjustl(keyword)
8835       call lcase(key)
8836
8837       do i=nline_ini,nt
8838          np=0
8839          line=adjustl(filevar(i))
8840          if (len_trim(line) == 0 .or. line(1:1) == "!" .or. line(1:1)==cc) cycle
8841          call lcase(line)
8842          np=index(line,key)
8843          if (np == 0) cycle
8844          line=line(np:)
8845          call cutst(line)
8846          call getnum(line,vet,ivet,iv)
8847          if(present(line_key)) line_key=line
8848          if (err_string) exit
8849          nline_ini=i
8850          exit
8851       end do
8852
8853       return
8854    End Subroutine Read_Key_Value
8855
8856    !!----
8857    !!---- Subroutine Read_Key_Valuest(Filevar,Nline_Ini,Nline_End,Keyword,Vet1,Vet2,Iv,comment)
8858    !!----    character(len=*),dimension(:),  intent(in)     :: Filevar      !  In -> Input vector of String
8859    !!----    integer,                        intent(in out) :: Nline_Ini    !  In -> Pointer to initial position to search
8860    !!----                                                                   ! Out -> Pointer to final position in search
8861    !!----    integer,                        intent(in)     :: Nline_End    !  In -> Pointer to final position to search
8862    !!----    character(len=*),               intent(in)     :: Keyword      !  In -> Word to search
8863    !!----    real(kind=cp),dimension(:),     intent(out)    :: Vet1         ! Out -> Vector of real numbers
8864    !!----    real(kind=cp),dimension(:),     intent(out)    :: Vet2         ! Out -> Vector of standard deviations
8865    !!----    integer,                        intent(out)    :: Iv           ! Out -> Number of components
8866    !!----
8867    !!----    Read parameters and standard deviation on the line of "filevar" starting with a particular "keyword".
8868    !!----    The search is done between lines "nline_ini" and "nline_end".
8869    !!----
8870    !!---- Update: February - 2005
8871    !!
8872    Subroutine Read_Key_ValueSTD(filevar,nline_ini,nline_end,keyword,vet1,vet2,iv,comment)
8873       !---- Arguments ----!
8874       character(len=*), dimension(:),  intent(in)     :: filevar
8875       integer,                         intent(in out) :: nline_ini
8876       integer,                         intent(in)     :: nline_end
8877       character(len=*),                intent(in)     :: keyword
8878       real(kind=cp),dimension(:),      intent(out)    :: vet1
8879       real(kind=cp),dimension(:),      intent(out)    :: vet2
8880       integer,                         intent(out)    :: iv
8881       character(len=1),      optional, intent(in)     :: comment
8882
8883       !---- Local Variable ----!
8884       character(len=len(filevar(1))) :: line
8885       character(len=len(keyword))    :: key
8886       character(len=1)               :: cc
8887       integer                        :: i,np,nt
8888
8889       !---- Initial value ----!
8890       cc=' '
8891       if (present(comment)) cc=comment
8892       nt=min(size(filevar),nline_end)
8893       iv  = 0
8894       vet1 = 0.0
8895       vet2 = 0.0
8896       key =adjustl(keyword)
8897       call lcase(key)
8898
8899       do i=nline_ini,nt
8900          line=adjustl(filevar(i))
8901          if (len_trim(line) == 0 .or. line(1:1) == "!" .or. line(1:1)==cc) cycle
8902          call lcase(line)
8903          np=index(line,key)
8904          if (np == 0) cycle
8905          line=line(np:)
8906          call cutst(line)
8907          call getnum_std(line,vet1,vet2,iv)
8908          if (err_string) exit
8909          nline_ini=i
8910          exit
8911       end do
8912
8913       return
8914    End Subroutine Read_Key_ValueSTD
8915
8916    !!----
8917    !!---- Subroutine Reading_Lines(Filename,Nlines,Filevar)
8918    !!----    character(len= *), intent(in)                :: Filename   !  In -> Filename
8919    !!----    integer,           intent(in)                :: Nlines     !  In -> Number of lines to read
8920    !!----    character(len= *), dimension(:), intent(out) :: Filevar    ! Out -> String vector
8921    !!----
8922    !!----    Read nlines of the file and put the information on Filevar. The file is opened to read the
8923    !!----    lines and closed before returning to the calling unit.
8924    !!----
8925    !!---- Update: February - 2005, March-2014 (eliminating the "opened" inquire,JRC)
8926    !!
8927    Subroutine Reading_Lines(filename,nlines,filevar)
8928       !---- Arguments ----!
8929       character(len=*),               intent( in) :: filename
8930       integer,                        intent( in) :: nlines
8931       character(len=*), dimension(:), intent(out) :: filevar
8932
8933       !---- Local Variables ----!
8934       logical :: info
8935       integer :: lun,i
8936
8937       !---- Init ----!
8938       call init_err_string()
8939       info=.false.
8940       call get_logunit(lun)
8941
8942       !---- Exist filename ? ----!
8943       inquire (file=filename,exist=info)
8944       if (.not. info) then
8945          err_string=.true.
8946          ERR_String_Mess="The file"//trim(filename)//" does not exist "
8947          return
8948       end if
8949
8950       open(unit=lun,file=filename, status="old",action="read", position="rewind")
8951
8952       !---- Reading... ----!
8953       do i=1,nlines
8954          read(unit=lun,fmt="(a)") filevar(i)
8955       end do
8956
8957       close(unit=lun)
8958
8959       return
8960    End Subroutine Reading_Lines
8961
8962    !!----
8963    !!----
8964    !!---- Subroutine SetNum_Std(Value,Std,Line)
8965    !!----    real(kind=cp),            intent(in)  :: Value
8966    !!----    real(kind=cp),            intent(in)  :: Std
8967    !!----    character(len=*),intent (out):: Line
8968    !!----
8969    !!----    String with real value and standard deviation
8970    !!----    quoted in parenthesis
8971    !!----
8972    !!---- Update: February - 2005
8973    !!
8974    Subroutine SetNum_Std(Value, Std, Line)
8975       !---- Argument ----!
8976       real(kind=cp),   intent(in)  :: Value
8977       real(kind=cp),   intent(in)  :: Std
8978       character(len=*),intent (out):: Line
8979
8980       !---- Local Variables ----!
8981       character(len=10) :: fmtcar
8982       character(len=40) :: aux
8983       integer           :: n,np,iy,long
8984       real(kind=cp)     :: y
8985
8986       if (abs(std) < 0.0000001) then
8987          if (abs(value) > 999999.0) then
8988             write(unit=aux,fmt=*) value
8989          else
8990             write(unit=aux,fmt="(f14.6)") value
8991          end if
8992          line=adjustl(aux)
8993          if (line(1:1) /= "-") line=" "//trim(line)
8994          return
8995       end if
8996
8997       np=0
8998       y=std
8999       do
9000          if (y >= 2.0) exit
9001          np=np+1
9002          y=y*10.0
9003       end do
9004       iy=nint(y)
9005
9006       aux=" "
9007       write(unit=aux,fmt=*) value
9008       line=trim(adjustl(aux))
9009       n=len_trim(line)
9010       if(n-np < 6) n=np+6
9011       fmtcar="f"
9012       if (n < 10) then
9013          write(unit=fmtcar(2:2),fmt="(i1)") n
9014       else
9015          write(unit=fmtcar(2:3),fmt="(i2)") n
9016       end if
9017
9018       fmtcar=trim(fmtcar)//"."
9019       n=len_trim(fmtcar)
9020       if (np < 10) then
9021          write(unit=fmtcar(n+1:),fmt="(i1)") np
9022       else
9023          write(unit=fmtcar(n+1:),fmt="(i2)") np
9024       end if
9025       fmtcar="("//trim(fmtcar)//")"
9026
9027       aux=" "
9028       write(unit=aux,fmt=fmtcar) value
9029       line=trim(adjustl(aux))
9030       n=len_trim(line)
9031       if (line(n:n) == ".") then
9032          line(n:n)=" "
9033       end if
9034       line=trim(line)//"("
9035       n=len_trim(line)
9036       np=len(line)-n-1             !number of available places for writing
9037       aux=" "
9038       write(unit=aux,fmt=*) iy
9039       aux=pack_string(aux)
9040       long=len_trim(aux)
9041       if(long > np) then
9042         line=line(1:n)//aux(1:np)//")"
9043       else
9044          line=line(1:n)//trim(aux)//")"
9045       end if
9046       line=pack_string(line)
9047
9048       if(line(1:1) /= "-") line=" "//trim(line)
9049
9050       return
9051    End Subroutine SetNum_Std
9052
9053    !!--++
9054    !!--++ Subroutine SGetFTMfield(GetFTMfield,FMTfields,nFld,nFldMax)
9055    !!--++    Integer ,          intent(out)    ::  GetFTMfield
9056    !!--++    Character (len=*) ,intent( in)    ::  FMTfields     !  -> format descriptor
9057    !!--++    Integer ,          intent(in out) ::  nFld          ! <-> current field in format descriptor
9058    !!--++    Integer ,          intent( in)    ::  nFldMax       !  -> max. number of fields in format descriptor
9059    !!--++
9060    !!--++    (PRIVATE)
9061    !!--++    Get current field type
9062    !!--++
9063    !!--++ Update: February - 2005
9064    !!
9065    Subroutine SGetFTMfield(GetFTMfield,FMTfields,nFld,nFldMax)
9066       !---- Arguments ----!
9067       Character (len=*) ,intent( in)    ::  FMTfields
9068       Integer ,          intent(in out) ::  nFld
9069       Integer ,          intent( in)    ::  nFldMax
9070       Integer ,          intent(out)    ::  GetFTMfield
9071
9072       !---- Local variables ----!
9073       character (len=1) ::  Car
9074
9075       nFld = nFld + 1
9076       if (nFld > nFldMax) then
9077          GetFTMfield = iEndFMT
9078       else
9079          Car = FMTfields(nFld:nFld)
9080          if (Car == "I") then
9081             GetFTMfield = iInte
9082          else if (Car == "F") then
9083             GetFTMfield = iReal
9084          else if (iChar(Car) >= i_One .and. iChar(Car) <= i_Nine) then
9085             GetFTMfield = iChar(Car)
9086          else if (Car == "A") then
9087             GetFTMfield = 10+i_Zero
9088          else if (Car == "B") then
9089             GetFTMfield = 11+i_Zero
9090          else if (Car == "C") then
9091             GetFTMfield = 12+i_Zero
9092          else if (Car == "D") then
9093             GetFTMfield = 13+i_Zero
9094          else if (Car == "E") then
9095             GetFTMfield = 14+i_Zero
9096          else
9097             GetFTMfield = iEndFMT
9098             iErr_fmt = iErrInvalField         ! Error in field definition
9099          end if
9100       end if
9101
9102       return
9103    End Subroutine SGetFTMfield
9104
9105    !!----
9106    !!----
9107    !!---- Subroutine SString_Replace(string, substr, rep_string,warning)
9108    !!----    character(len=*), intent(in out) :: string
9109    !!----    character(len=*), intent(in)     :: substr
9110    !!----    character(len=*), intent(in)     :: rep_string
9111    !!----    character(len=*), intent(out)    :: warning
9112    !!----
9113    !!----    Subroutine to replace a substring (substr) by another one (rep_string)
9114    !!----    within a given string (string). The original string is modified on output.
9115    !!----    If len_trim(warning) /= 0, one of the substrings will not be complete,
9116    !!----    it works as a warning or error condition without interrupting the
9117    !!----    procedure.
9118    !!----
9119    !!---- Updated: May - 2014
9120    !!
9121    Subroutine SString_Replace(string, substr, rep_string,warning)
9122      character(len=*), intent(in out) :: string
9123      character(len=*), intent(in)     :: substr
9124      character(len=*), intent(in)     :: rep_string
9125      character(len=*), intent(out)    :: warning
9126      ! --- Local variables ---!
9127      integer                                      :: i,j,lstr,ncount,nsubs,d,dmax
9128      integer,            dimension(:),allocatable :: pos
9129      character(len=1024),dimension(:),allocatable :: splitted_string
9130
9131      lstr=len(substr)
9132      warning=" "
9133      i=index(rep_string,substr)
9134      if(i /= 0) then !Check if the substring to be replaced is contained in the replacing string
9135         !In such case the alternative short code doesn't work ... we have to use the longer analysis below
9136         ncount=String_Count(string,trim(substr))+1
9137         allocate(pos(ncount))
9138         allocate(splitted_string(ncount))
9139         call Get_Substring_Positions(string,substr,pos,nsubs)
9140         dmax=0
9141         do i=2,nsubs
9142           d=pos(i)-pos(i-1)
9143           if(d > dmax) dmax=d
9144         end do
9145         if(dmax > 1024) write(unit=warning,fmt="(a)") " => Warning! ... string too long to be fetch into the splitted_string"
9146         !Construct the splitted string
9147         j=1
9148         splitted_string(j)=string(1:pos(j)-1)
9149         do
9150           j=j+1
9151           if(j > nsubs) exit
9152           splitted_string(j)=string(pos(j-1)+lstr:pos(j)-1)
9153         end do
9154         splitted_string(ncount)=string(pos(nsubs)+lstr:)
9155         !Construct now the full string
9156         string=""
9157         do i=1,nsubs
9158           string=trim(string)//trim(splitted_string(i))//rep_string
9159         end do
9160         string=trim(string)//trim(splitted_string(ncount))
9161
9162      else  !The following short code works easily when substr is not contained in rep_string
9163
9164         do
9165           i=index(string,substr)
9166           if (i == 0) exit
9167           string=string(1:i-1)//rep_string//trim(string(i+lstr:))
9168         end do
9169
9170      end if
9171      return
9172    End Subroutine SString_Replace
9173
9174    !!--++
9175    !!--++ Subroutine TreatMCharField(iFld,aLine,L_Line,nC_L,nC_X)
9176    !!--++    Integer,          intent(in out)  :: iFld   ! <-> "A" format size (1 to 9)
9177    !!--++    Character(len=*), intent(in)      :: aLine  !  -> data line to be analysed
9178    !!--++    Integer,          intent(in)      :: L_Line !  -> true length of data Line
9179    !!--++    Integer,          intent(in out)  :: nC_L   ! <-> current character in data line
9180    !!--++    Integer,          intent(out)     :: nC_X   ! <-  number of characters in X format field (now nx -> trn)
9181    !!--++
9182    !!--++    (PRIVATE)
9183    !!--++    Fixed length "A1 to A9" field : A<iFld-48>
9184    !!--++    Leading spaces are ignored; separators : space and Tab
9185    !!--++
9186    !!--++ Update: February - 2005
9187    !!
9188    Subroutine TreatMCharField(iFld,aLine,L_Line,nC_L,nC_X)
9189       !---- Arguments ----!
9190       Integer,           intent(in out)  :: iFld
9191       Character (len=*), intent(in)      :: aLine
9192       Integer,           intent(in)      :: L_Line
9193       Integer,           intent(in out)  :: nC_L
9194       Integer,           intent(out)     :: nC_X
9195
9196       !---- Local variables ----!
9197       Character (len=1) ::   Car
9198       Integer           ::   nCar
9199       Logical           ::   ifEnd
9200
9201       nC_X = 0
9202       iErr_fmt = 0
9203
9204       !---- End of ligne ----!
9205       if (nC_L >= L_Line) return
9206
9207       !---- if not 1rst field, 1rst character must be a separator ----!
9208       if (nC_L > 1) Then
9209          nC_L = nC_L+1
9210          Car  = aLine(nC_L:nC_L)
9211          if (Car /= " " .and. Car /= cTab) then
9212             iErr_fmt = iErrSepMiss              ! separator missing
9213             return
9214          end if
9215          nC_X = nC_X+1
9216       end if
9217
9218       !---- Remove leading spaces ----!
9219       ifEnd = .false.
9220       do
9221          if (ifEnd) exit
9222          if (nC_L >= L_Line) return        ! end of line
9223          nC_L = nC_L+1
9224          Car  = aLine(nC_L:nC_L)
9225          if (Car == " ") then
9226             nC_X = nC_X+1                   ! count leading spaces
9227          else
9228             ifEnd = .true.                  ! 1rst valid character
9229             nC_L = nC_L-1
9230          end if
9231       end do
9232
9233       !---- Count characters until next Tab or end of line ----!
9234       nCar = 0
9235       ifEnd = .false.
9236       do
9237          if (ifEnd) exit
9238          if (nC_L < L_Line .and. nCar < (iFld-48)) then
9239             nC_L = nC_L+1
9240             nCar = nCar+1
9241             Car = aLine(nC_L:nC_L)
9242             if (Car == " " .or. Car == cTab) then
9243                ifEnd = .true.                ! separator found
9244                nCar  = nCar - 1
9245                nC_L  = nC_L - 1
9246             end if
9247          else
9248             ifEnd = .true.                  ! end of line
9249          end if
9250       end do
9251
9252       !---- Load size of the A format field ----!
9253       if (nCar == 0) then
9254          iErr_fmt = iErrEmptyField             ! no charac. in field
9255       else
9256          iFld = nCar+48                    ! true size of the A field
9257       end if
9258
9259       return
9260    End Subroutine TreatMCharField
9261
9262    !!--++
9263    !!--++ Subroutine TreatNumerField(iFld,aLine,L_Line,nC_L,nCar)
9264    !!--++    Integer ,          intent( in)    ::  iFld   !  -> field type
9265    !!--++    Character (len=*), intent(in out) ::  aLine  ! <-> data line
9266    !!--++    Integer ,          intent( in)    ::  L_Line !  -> true length of the data line
9267    !!--++    Integer ,          intent(in out) ::  nC_L   ! <-> counts characters in data line
9268    !!--++    Integer ,          intent(in out) ::  nCar   ! <-> counts characters in format field
9269    !!--++
9270    !!--++    (PRIVATE)
9271    !!--++    Free "I" and "F" formats
9272    !!--++    Look for a separator (space or Tab) after any valid character
9273    !!--++
9274    !!--++ Update: February - 2005
9275    !!
9276    Subroutine TreatNumerField(iFld,aLine,L_Line,nC_L,nCar)
9277       !---- Arguments ----!
9278       Integer ,          intent( in)    ::  iFld   ! field type
9279       Character (len=*), intent(in out) ::  aLine
9280       Integer ,          intent( in)    ::  L_Line ! true length of the data line
9281       Integer ,          intent(in out) ::  nC_L   ! counts characters in data line
9282       Integer ,          intent(in out) ::  nCar   ! counts characters in format field
9283
9284       !---- Local variables ----!
9285       Character (len=1)   ::  Car,Car_
9286       Integer             ::  nCar1                ! 1st usefull character in field
9287       Integer             ::  nPosi                ! number of 1st character in field
9288       Logical             ::  ifEnd,ifDot,ifSign
9289
9290       iErr_fmt   = 0
9291       nCar   = 0
9292       ifDot  = .false.
9293       ifSign = .false.
9294       nPosi  = nC_L
9295
9296       !---- Skip previous separator (space, Tab or sign) and leading spaces ----!
9297       ifEnd = .false.
9298       do
9299          if (ifEnd) exit
9300          nC_L = nC_L+1
9301          if (nC_L <= L_Line) then
9302             nCar = nCar+1
9303             Car = aLine(nC_L:nC_L)
9304
9305             !---- Tab character ----!
9306             if (Car == cTab) Then
9307                if (nCar == 1 .and. nC_L > 1) then
9308                   aLine(nC_L:nC_L) = " "      ! previous separator
9309                else
9310                   if (ifSign) then
9311                      iErr_fmt = iErrNumber         ! incomplete number
9312                      return
9313                   end if
9314                   nC_L = nC_L-1               ! new separator
9315                   nCar = nCar-1
9316                   return
9317                end if
9318
9319             else if (Car == "+" .or. Car == "-") then
9320                !---- a sign ----!
9321                ifSign = .true.
9322
9323             else if (Car == " ") then
9324                !---- a space ----!
9325                if (ifSign) then
9326                   iErr_fmt = iErrNumber           ! incomplete number
9327                   return
9328                end if
9329
9330             else
9331                !---- any other character ----!
9332                ifEnd = .true.
9333             end if
9334          else
9335             return                          ! end of line
9336          end if
9337       end do
9338
9339       !---- No valid previous separator found (Except for 1st field) ----!
9340       if (nPosi > 1 .and. nCar == 1) then
9341          iErr_fmt = iErrSepMiss                ! separator missing
9342          return
9343       end if
9344
9345       !---- Check first character and initialize search ----!
9346
9347       !---- Decimal point -> valid in real fields only ----!
9348       if (Car == ".") then
9349          ifDot = .true.
9350          if (iFld /= iReal)  then
9351             iErr_fmt = iErrFieldType            ! not an integer field
9352             Return
9353          end if
9354
9355       else if(Car == "E".or.Car == "e".or.Car == "d".or.Car == "D") then
9356          !---- e,E,d,D -> always invalid at this position ----!
9357          if (iFld == iReal) then
9358             iErr_fmt = iErrEfrmt                ! incomplete E or D format
9359          else
9360             iErr_fmt = iErrInvalC               ! invalid char in int. field
9361          end if
9362          return
9363
9364       else if (iChar(Car) < i_Zero .or. iChar(Car) > i_Nine) then
9365          !---- invalid if not a sign or a digit ----!
9366          iErr_fmt = iErrInvalChar        ! invalid character
9367          return
9368       end if
9369
9370       !---- save position of first character ----!
9371       nCar1 = nCar
9372
9373       !---- Count characters in number ----!
9374       ifEnd = .false.
9375
9376       do
9377          if (ifEnd) exit
9378          Car_ = Car      ! save previous character
9379          nC_L = nC_L+1
9380          if (nC_L <= L_Line) then
9381             nCar = nCar+1
9382             Car = aLine(nC_L:nC_L)
9383
9384             !---- Current character is a decimal point ----!
9385             if (Car == ".") then
9386                if (ifDot) then
9387                   iErr_fmt = iErrCharBegg         ! begged character (dot)
9388                   Return
9389                else if (iFld /= iReal) then
9390                   iErr_fmt = iErrFieldType        ! not an integer field
9391                   Return
9392                else
9393                   ifDot = .true.
9394                end if
9395
9396             else if (Car == " " .or. Car == cTab) then
9397                !---- Current character is a space or Tab (separator) ----!
9398                if (Car_ == "+" .or. Car_ == "-") then
9399                   iErr_fmt = iErrNumber           ! incomplete number
9400                   return
9401                end if
9402                ifEnd = .true.
9403                nCar  = nCar - 1
9404                nC_L  = nC_L - 1
9405
9406             else if (Car == "+" .or. Car == "-") then
9407                !---- Current character is a sign ----!
9408                if (Car_ == "+" .or. Car_ == "-") then
9409                   iErr_fmt = iErrCharBegg         ! begged character
9410                   return
9411                else if (nCar > nCar1) then
9412                   if (iFld == iReal) then
9413                      if (Car_ /= "E" .and. Car_ /= "e" .and. Car_ /= "D" .and. Car_ /= "d") then
9414                         ifEnd = .true.          ! Sign is a valid separator
9415                         nCar  = nCar - 1
9416                         nC_L  = nC_L - 1
9417                         Return
9418                      end if
9419                   else                        ! Sign is a valid separator
9420                      ifEnd = .true.
9421                      nCar  = nCar - 1
9422                      nC_L  = nC_L - 1
9423                      Return
9424                   end if
9425                end if
9426
9427             else if (Car == "E" .or. Car == "e" .or. Car == "d" .or. Car == "D") then
9428                !---- Current character is a "e E d D" ----!
9429                if (nCar == nCar1 .or. Car_ == "-" .or. Car_ == "+") then
9430                   iErr_fmt = iErrEfrmt            ! incomplete E or D format
9431                   return
9432                else if (Car_ == Car) then
9433                   iErr_fmt = iErrCharBegg         ! begged character
9434                   return
9435                end if
9436
9437             else if (iChar(Car) < i_Zero .or. iChar(Car) > i_Nine) then
9438                !---- Ccurrent character is not a valid one ? ----!
9439                iErr_fmt = iErrInvalChar          ! invalid character
9440                Return
9441             end if
9442          else
9443             ifEnd = .true.                  ! end of line
9444          end if
9445       end do
9446
9447       return
9448    End Subroutine TreatNumerField
9449
9450    !!----
9451    !!---- Subroutine Ucase(Line)
9452    !!----    character(len=*) :: Line
9453    !!----
9454    !!----    Conversion to upper case. Line is modified
9455    !!----
9456    !!---- Update: February - 2005
9457    !!
9458    Subroutine Ucase(line)
9459       !---- Argument ----!
9460       character (len=*), intent(in out) :: line
9461
9462       line=u_case(line)
9463
9464       return
9465    End Subroutine Ucase
9466
9467 End Module CFML_String_Utilities
9468!!-------------------------------------------------------
9469!!---- Crystallographic Fortran Modules Library (CrysFML)
9470!!-------------------------------------------------------
9471!!---- The CrysFML project is distributed under LGPL. In agreement with the
9472!!---- Intergovernmental Convention of the ILL, this software cannot be used
9473!!---- in military applications.
9474!!----
9475!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
9476!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
9477!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
9478!!----
9479!!---- Authors: Juan Rodriguez-Carvajal (ILL)
9480!!----          Javier Gonzalez-Platas  (ULL)
9481!!----
9482!!---- Contributors: Laurent Chapon     (ILL)
9483!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
9484!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
9485!!----               Tierry Roisnel     (CDIFX,Rennes France)
9486!!----               Eric Pellegrini    (ILL)
9487!!----
9488!!---- This library is free software; you can redistribute it and/or
9489!!---- modify it under the terms of the GNU Lesser General Public
9490!!---- License as published by the Free Software Foundation; either
9491!!---- version 3.0 of the License, or (at your option) any later version.
9492!!----
9493!!---- This library is distributed in the hope that it will be useful,
9494!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
9495!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9496!!---- Lesser General Public License for more details.
9497!!----
9498!!---- You should have received a copy of the GNU Lesser General Public
9499!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
9500!!----
9501!!----
9502!!---- MODULE: CFML_Math_3D
9503!!----   INFO: Simple mathematics general utilities for 3D Systems
9504!!----
9505!!---- HISTORY
9506!!----    Update: 04/03/2011
9507!!----
9508!!---- DEPENDENCIES
9509!!--++    Use CFML_GlobalDeps,   only: cp, sp, dp, pi, to_rad, to_deg
9510!!--++    Use CFML_Math_General, only: cosd, sind
9511!!----
9512!!---- VARIABLES
9513!!--++    EPS
9514!!----    ERR_Math3D
9515!!----    ERR_Math3D_Mess
9516!!----
9517!!---- PROCEDURES
9518!!----    Functions:
9519!!----       CROSS_PRODUCT
9520!!--++       CROSS_PRODUCT_CMPL_dp     [Overloaded]
9521!!--++       CROSS_PRODUCT_CMPL_sp     [Overloaded]
9522!!--++       CROSS_PRODUCT_dp          [Overloaded]
9523!!--++       CROSS_PRODUCT_in          [Overloaded]
9524!!--++       CROSS_PRODUCT_sp          [Overloaded]
9525!!----       DETERM_A
9526!!--++       DETERM_A_I                [Overloaded]
9527!!--++       DETERM_A_R                [Overloaded]
9528!!----       DETERM_V
9529!!--++       DETERM_V_I                [Overloaded]
9530!!--++       DETERM_V_R                [Overloaded]
9531!!----       INVERT_A
9532!!--++       INVERT_DP                 [Overloaded]
9533!!--++       INVERT_SP                 [Overloaded]
9534!!----       MAT_CROSS
9535!!--++       MAT_CROSS_CMPL_dp     [Overloaded]
9536!!--++       MAT_CROSS_CMPL_sp     [Overloaded]
9537!!--++       MAT_CROSS_dp          [Overloaded]
9538!!--++       MAT_CROSS_in          [Overloaded]
9539!!--++       MAT_CROSS_sp          [Overloaded]
9540!!----       POLYHEDRON_VOLUME
9541!!----       ROTATE_OX
9542!!----       ROTATE_OY
9543!!----       ROTATE_OZ
9544!!----       TENSOR_PRODUCT
9545!!--++       TENSOR_PRODUCT_CMPL_dp     [Overloaded]
9546!!--++       TENSOR_PRODUCT_CMPL_sp     [Overloaded]
9547!!--++       TENSOR_PRODUCT_dp          [Overloaded]
9548!!--++       TENSOR_PRODUCT_in          [Overloaded]
9549!!--++       TENSOR_PRODUCT_sp          [Overloaded]
9550!!----       VECLENGTH
9551!!----
9552!!----    Subroutines:
9553!--..
9554!!--..    Init Routine
9555!!----       INIT_ERR_MATH3D
9556!!----       SET_EPS
9557!!----       SET_EPS_DEFAULT
9558!--..
9559!!--..    Matrix and Vectors Subroutines
9560!!----       GET_CART_FROM_CYLIN
9561!!--++       GET_CART_FROM_CYLIN_DP    [Overloaded]
9562!!--++       GET_CART_FROM_CYLIN_SP    [Overloaded]
9563!!----       GET_CENTROID_COORD
9564!!----       GET_CYLINDR_COORD
9565!!--++       GET_CYLINDR_COORD_DP      [Overloaded]
9566!!--++       GET_CYLINDR_COORD_SP      [Overloaded]
9567!!----       GET_CART_FROM_SPHER
9568!!--++       GET_CART_FROM_SPHER_DP    [Overloaded]
9569!!--++       GET_CART_FROM_SPHER_SP    [Overloaded]
9570!!----       GET_PLANE_FROM_POINTS
9571!!----       GET_SPHERIC_COORD
9572!!--++       GET_SPHERIC_COORD_DP      [Overloaded]
9573!!--++       GET_SPHERIC_COORD_SP      [Overloaded]
9574!!----       MATRIX_DIAGEIGEN
9575!!----       MATRIX_INVERSE
9576!!----       RESOLV_SIST_1X2
9577!!----       RESOLV_SIST_1X3
9578!!----       RESOLV_SIST_2X2
9579!!----       RESOLV_SIST_2X3
9580!!----       RESOLV_SIST_3X3
9581!!----
9582!!
9583 Module CFML_Math_3D
9584    !---- Use Modules ----!
9585    Use CFML_GlobalDeps,   only: cp, sp, dp, pi, to_rad, to_deg
9586    Use CFML_Math_General, only: cosd, sind, euclidean_norm
9587
9588    implicit none
9589
9590    private
9591
9592    !---- List of public functions ----!
9593    public :: Polyhedron_Volume, Rotate_OX, Rotate_OY, Rotate_OZ, Veclength
9594
9595    !---- List of public overloaded procedures: functions ----!
9596    public :: Cross_Product, Determ_A, Determ_V, Invert_A, Mat_Cross, Tensor_Product
9597
9598    !---- List of public subroutines ----!
9599    public :: Init_Err_Math3D, Set_Eps, Set_Eps_Default, Matrix_DiagEigen, Matrix_Inverse, &
9600              Resolv_Sist_1X2, Resolv_Sist_1X3, Resolv_Sist_2X2, Resolv_Sist_2X3,          &
9601              Resolv_Sist_3X3, Get_Plane_from_Points, Get_Centroid_Coord
9602
9603    !---- List of public overloaded procedures: subroutines ----!
9604    public :: Get_Cart_From_Cylin, Get_Cylindr_Coord, Get_Cart_From_Spher, Get_Spheric_Coord
9605
9606    !----  Make private the overloaded procedures ----!
9607    private :: Cross_Product_dp, Cross_Product_sp, Determ_A_I, Determ_A_R, Determ_V_I,    &
9608               Determ_V_R, Invert_dp, Invert_sp, Get_Cart_From_Cylin_dp,                  &
9609               Get_Cart_From_Cylin_sp, Get_Cylindr_Coord_dp, Get_Cylindr_Coord_sp,        &
9610               Get_Cart_From_Spher_dp, Get_Cart_From_Spher_sp, Get_Spheric_Coord_dp,      &
9611               Get_Spheric_Coord_sp, Cross_Product_cmpl_dp, Cross_Product_cmpl_sp,        &
9612               Mat_Cross_dp,Mat_Cross_sp,Mat_Cross_in,Mat_Cross_cmpl_dp,Mat_Cross_cmpl_sp,&
9613               Tensor_Product_dp,Tensor_Product_sp,Tensor_Product_in,                     &
9614               Tensor_Product_cmpl_dp,Tensor_Product_cmpl_sp
9615
9616    !---- Definitions ----!
9617    !!--++
9618    !!--++  EPS
9619    !!--++     real(kind=cp), private ::  eps=0.00001_cp
9620    !!--++
9621    !!--++  (PRIVATE)
9622    !!--++     Epsilon value
9623    !!--++
9624    !!--++  Update: February - 2005
9625    !!
9626    real(kind=cp),  private  ::  eps=0.00001_cp
9627
9628    !!----
9629    !!---- ERR_Math3D
9630    !!----    logical :: ERR_Math3D
9631    !!----
9632    !!----    Logical Variable indicating an error in CFML_Math_3D module
9633    !!----
9634    !!---- Update: February - 2005
9635    !!
9636    logical, public  :: ERR_Math3D
9637
9638    !!----
9639    !!---- ERR_Math3D_Mess
9640    !!----    character(len=150) :: ERR_Math3D_Mess
9641    !!----
9642    !!----    String containing information about the last error
9643    !!----
9644    !!---- Update: February - 2005
9645    !!
9646    character(len=150), public :: ERR_Math3D_Mess
9647
9648    !---- Interfaces - Overlapp ----!
9649    Interface  Cross_Product
9650       Module Procedure Cross_product_sp
9651       Module Procedure Cross_product_dp
9652       Module Procedure Cross_product_in
9653       Module Procedure Cross_product_cmpl_sp
9654       Module Procedure Cross_product_cmpl_dp
9655    End Interface
9656
9657    Interface  Determ_A
9658       Module Procedure Determ_A_I
9659       Module Procedure Determ_A_R
9660    End Interface
9661
9662    Interface  Determ_V
9663       Module Procedure Determ_V_I
9664       Module Procedure Determ_V_R
9665    End Interface
9666
9667    Interface  Invert_A
9668       Module Procedure Invert_sp
9669       Module Procedure Invert_dp
9670    End Interface
9671
9672    Interface  Get_Cart_from_Cylin
9673       Module Procedure Get_Cart_from_Cylin_dp
9674       Module Procedure Get_Cart_from_Cylin_sp
9675    End Interface
9676
9677    Interface  Get_Cylindr_Coord
9678       Module Procedure Get_Cylindr_Coord_dp
9679       Module Procedure Get_Cylindr_Coord_sp
9680    End Interface
9681
9682    Interface  Get_Cart_from_Spher
9683       Module Procedure Get_Cart_from_Spher_dp
9684       Module Procedure Get_Cart_from_Spher_sp
9685    End Interface
9686
9687    Interface  Get_Spheric_Coord
9688       Module Procedure Get_Spheric_Coord_dp
9689       Module Procedure Get_Spheric_Coord_sp
9690    End Interface
9691
9692    Interface  Mat_Cross
9693       Module Procedure Mat_Cross_sp
9694       Module Procedure Mat_Cross_dp
9695       Module Procedure Mat_Cross_in
9696       Module Procedure Mat_Cross_cmpl_sp
9697       Module Procedure Mat_Cross_cmpl_dp
9698    End Interface
9699
9700    Interface  Tensor_Product
9701       Module Procedure Tensor_product_sp
9702       Module Procedure Tensor_product_dp
9703       Module Procedure Tensor_product_in
9704       Module Procedure Tensor_product_cmpl_sp
9705       Module Procedure Tensor_product_cmpl_dp
9706    End Interface
9707
9708 Contains
9709
9710    !!----
9711    !!---- Function  Cross_Product(U,V) Result(W)
9712    !!----    real(kind=sp/dp), dimension(3), intent( in) :: u   !  In -> Vector 1
9713    !!----    real(kind=sp/dp), dimension(3), intent( in) :: v   !  In -> Vector 2
9714    !!----    real(kind=sp/dp), dimension(3)              :: w   ! Out -> Vector 1 x vector 2
9715    !!----
9716    !!----    Calculates the cross product of vectors u and v
9717    !!----    Vectors, w= u x v, are given in cartesian components.
9718    !!----
9719    !!---- Update: February - 2005
9720    !!
9721
9722    !!--++
9723    !!--++ Function  Cross_Product_cmpl_dp(U,V) Result(W)
9724    !!--++    complex(kind=dp/sp), dimension(3), intent( in) :: u   !  In -> Vector 1
9725    !!--++    complex(kind=dp/sp), dimension(3), intent( in) :: v   !  In -> Vector 2
9726    !!--++    complex(kind=dp/sp), dimension(3)              :: w   ! Out -> Vector 1 x vector 2
9727    !!--++
9728    !!--++    (OVERLOADED)
9729    !!--++    Calculates the cross product of the complex vectors u and v
9730    !!--++    Vectors, w = u x v, are given in cartesian components.
9731    !!--++
9732    !!--++ Update: June - 2012
9733    !!
9734    Function Cross_Product_cmpl_dp(u,v) Result(w)
9735       !---- Argument ----!
9736       complex(kind=dp), dimension(3), intent( in) :: u,v
9737       complex(kind=dp), dimension(3)              :: w
9738
9739       w(1)=u(2)*v(3)-u(3)*v(2)
9740       w(2)=u(3)*v(1)-u(1)*v(3)
9741       w(3)=u(1)*v(2)-u(2)*v(1)
9742
9743       return
9744    End Function Cross_Product_cmpl_dp
9745
9746    Function Cross_Product_cmpl_sp(u,v) Result(w)
9747       !---- Argument ----!
9748       complex(kind=sp), dimension(3), intent( in) :: u,v
9749       complex(kind=sp), dimension(3)              :: w
9750
9751       w(1)=u(2)*v(3)-u(3)*v(2)
9752       w(2)=u(3)*v(1)-u(1)*v(3)
9753       w(3)=u(1)*v(2)-u(2)*v(1)
9754
9755       return
9756    End Function Cross_Product_cmpl_sp
9757
9758    !!--++
9759    !!--++ Function  Cross_Product_dp(U,V) Result(W)
9760    !!--++    real(kind=dp), dimension(3), intent( in) :: u   !  In -> Vector 1
9761    !!--++    real(kind=dp), dimension(3), intent( in) :: v   !  In -> Vector 2
9762    !!--++    real(kind=dp), dimension(3)              :: w   ! Out -> Vector 1 x vector 2
9763    !!--++
9764    !!--++    (OVERLOADED)
9765    !!--++    Calculates the cross product of vectors u and v
9766    !!--++    Vectors, w= u x v, are given in cartesian components.
9767    !!--++
9768    !!--++ Update: February - 2005
9769    !!
9770    Function Cross_Product_dp(u,v) Result(w)
9771       !---- Argument ----!
9772       real(kind=dp), dimension(3), intent( in) :: u,v
9773       real(kind=dp), dimension(3)              :: w
9774
9775       w(1)=u(2)*v(3)-u(3)*v(2)
9776       w(2)=u(3)*v(1)-u(1)*v(3)
9777       w(3)=u(1)*v(2)-u(2)*v(1)
9778
9779       return
9780    End Function Cross_Product_dp
9781
9782    !!--++
9783    !!--++ Function  Cross_Product_in(U,V) Result(W)
9784    !!--++    integer, dimension(3), intent( in) :: u   !  In -> Vector 1
9785    !!--++    integer, dimension(3), intent( in) :: v   !  In -> Vector 2
9786    !!--++    integer, dimension(3)              :: w   ! Out -> Vector 1 x vector 2
9787    !!--++
9788    !!--++    (OVERLOADED)
9789    !!--++    Calculates the cross product of integer vectors u and v
9790    !!--++    In the indices are givent w.r.t the direct lattice, the cross product
9791    !!--++    are indices w.r.t. reciprocal lattice and viceversa.
9792    !!--++
9793    !!--++ Update: November - 2008
9794    !!
9795    Function Cross_Product_in(u,v) Result(w)
9796       !---- Argument ----!
9797       integer, dimension(3), intent( in) :: u,v
9798       integer, dimension(3)              :: w
9799
9800       w(1)=u(2)*v(3)-u(3)*v(2)  ! i  j   k !
9801       w(2)=u(3)*v(1)-u(1)*v(3)  !u1  u2  u3! = (u2.v3 - u3.v2)i + (v1.u3 - u1.v3)j + (u1.v2-u2.v1)k
9802       w(3)=u(1)*v(2)-u(2)*v(1)  !v1  v2  v3!
9803
9804       return
9805    End Function Cross_Product_in
9806
9807    !!--++
9808    !!--++ Function  Cross_Product_sp(U,V) Result(W)
9809    !!--++    real(kind=sp), dimension(3), intent( in) :: u   !  In -> Vector 1
9810    !!--++    real(kind=sp), dimension(3), intent( in) :: v   !  In -> Vector 2
9811    !!--++    real(kind=sp), dimension(3)              :: w   ! Out -> Vector 1 x vector 2
9812    !!--++
9813    !!--++    (OVERLOADED)
9814    !!--++    Calculates the cross product of vectors u and v
9815    !!--++    Vectors, w= u x v, are given in cartesian components.
9816    !!--++
9817    !!--++ Update: February - 2005
9818    !!
9819    Function Cross_Product_sp(u,v) Result(w)
9820       !---- Argument ----!
9821       real(kind=sp), dimension(3), intent( in) :: u,v
9822       real(kind=sp), dimension(3)              :: w
9823
9824       w(1)=u(2)*v(3)-u(3)*v(2)  ! i  j   k !
9825       w(2)=u(3)*v(1)-u(1)*v(3)  !u1  u2  u3! = (u2.v3 - u3.v2)i + (v1.u3 - u1.v3)j + (u1.v2-u2.v1)k
9826       w(3)=u(1)*v(2)-u(2)*v(1)  !v1  v2  v3!
9827
9828       return
9829    End Function Cross_Product_sp
9830
9831    !!----
9832    !!---- Function Determ_A(A)
9833    !!----    integer/real(kind=cp), dimension(3,3), intent(in)  :: a
9834    !!----
9835    !!----    Calculates the determinant of an integer/real 3x3 matrix
9836    !!----
9837    !!---- Update: February - 2005
9838    !!
9839
9840    !!--++
9841    !!--++ Function Determ_A_I(A)
9842    !!--++    integer, dimension(3,3), intent(in)  :: a
9843    !!--++
9844    !!--++    (OVERLOADED)
9845    !!--++    Calculates the determinant of an integer 3x3 matrix
9846    !!--++
9847    !!--++ Update: February - 2005
9848    !!
9849    Function Determ_A_I(A) Result(determ)
9850       !---- Argument ----!
9851       integer, dimension(3,3), intent(in) :: A
9852       integer                             :: determ
9853
9854       determ=A(1,1)*A(2,2)*A(3,3)+A(2,1)*A(3,2)*A(1,3)+A(1,2)*A(2,3)*A(3,1) &
9855             -A(1,3)*A(2,2)*A(3,1)-A(1,1)*A(3,2)*A(2,3)-A(1,2)*A(2,1)*A(3,3)
9856
9857       return
9858    End Function Determ_A_I
9859
9860    !!--++
9861    !!--++ Function Determ_A_R(A)
9862    !!--++    real(kind=cp), dimension(3,3), intent(in)  :: a
9863    !!--++
9864    !!--++    (OVERLOADED)
9865    !!--++    Calculates the determinant of a real 3x3 matrix
9866    !!--++
9867    !!--++ Update: February - 2005
9868    !!
9869    Function Determ_A_R(A) Result (determ)
9870       !---- Argument ----!
9871       real(kind=cp), dimension(3,3), intent(in) :: A
9872       real(kind=cp)                             :: determ
9873
9874       determ=A(1,1)*A(2,2)*A(3,3)+A(2,1)*A(3,2)*A(1,3)+A(1,2)*A(2,3)*A(3,1) &
9875             -A(1,3)*A(2,2)*A(3,1)-A(1,1)*A(3,2)*A(2,3)-A(1,2)*A(2,1)*A(3,3)
9876
9877       return
9878    End Function Determ_A_R
9879
9880    !!----
9881    !!---- Function  Determ_V(a,b,c)
9882    !!----    integer/real(kind=cp), dimension(3), intent(in) :: a,b,c
9883    !!----
9884    !!----    Calculates the determinant of the components of three vectors
9885    !!----
9886    !!----  Update: February - 2005
9887    !!
9888
9889    !!--++
9890    !!--++ Function Determ_V_I(A,B,C)
9891    !!--++    integer, dimension(3), intent(in) :: a,b,c
9892    !!--++
9893    !!--++    (OVERLOADED)
9894    !!--++    Calculates the determinant of the components of three vectors
9895    !!--++
9896    !!--++ Update: February - 2005
9897    !!
9898    Function Determ_V_I(a,b,c) Result(det)
9899       !---- Arguments ----!
9900       integer, dimension(3), intent(in) :: a,b,c
9901       integer                           :: det
9902
9903       !---- Local variables ----!
9904       integer :: i,j,k
9905
9906       det = 0
9907       do i = 1,3
9908          j = i+1
9909          if (j == 4) j = 1
9910          k = 6-i-j
9911          det = det+a(i)*(b(j)*c(k)-b(k)*c(j))
9912       end do
9913
9914       return
9915    End Function Determ_V_I
9916
9917    !!--++
9918    !!--++ Function Determ_V_R(A,B,C)
9919    !!--++    real(kin=cp), dimension(3), intent(in) :: a,b,c
9920    !!--++
9921    !!--++    (OVERLOADED)
9922    !!--++    Calculates the determinant of the components of three vectors
9923    !!--++
9924    !!--++ Update: February - 2005
9925    !!
9926    Function Determ_V_R(a,b,c) Result(det)
9927       !---- Arguments ----!
9928       real(kind=cp), dimension(3), intent(in) :: a,b,c
9929       real(kind=cp)                           :: det
9930
9931       !---- Local variables ----!
9932       integer :: i,j,k
9933
9934       det = 0.0
9935       do i = 1,3
9936          j = i+1
9937          if (j == 4) j = 1
9938          k = 6-i-j
9939          det = det+a(i)*(b(j)*c(k)-b(k)*c(j))
9940       end do
9941
9942       return
9943    End Function Determ_V_R
9944
9945    !!----
9946    !!---- Funcion Invert_A(A) Result(b)
9947    !!----    real(kind=sp/dp), dimension(3,3), intent(in) :: a
9948    !!----    real(Kind=sp/dp), dimension(3,3)             :: b
9949    !!----
9950    !!----    Calculate de inverse of a real 3x3 matrix. If the routine fails,
9951    !!----    then a 0.0 matrix is returned.
9952    !!----
9953    !!---- Update: February - 2005
9954    !!
9955
9956    !!--++
9957    !!--++ Funcion Invert_Dp(A) Result(b)
9958    !!--++    real(kind=dp), dimension(3,3), intent(in) :: a
9959    !!--++    real(Kind=dp), dimension(3,3)             :: b
9960    !!--++
9961    !!--++    (OVERLOADED)
9962    !!--++    Calculate de inverse of a real 3x3 matrix
9963    !!--++
9964    !!--++ Update: February - 2005
9965    !!
9966    Function Invert_Dp(a) Result(b)
9967       !---- Arguments ----!
9968       real(kind=dp),dimension(3,3), intent(in) :: a
9969       real(kind=dp),dimension(3,3)             :: b
9970
9971       !---- Local variables ----!
9972       real(kind=dp)  :: dmat
9973
9974       b(1,1) =   a(2,2)*a(3,3)-a(2,3)*a(3,2)
9975       b(2,1) = -(a(2,1)*a(3,3)-a(2,3)*a(3,1))
9976       b(3,1) =   a(2,1)*a(3,2)-a(2,2)*a(3,1)
9977       b(1,2) = -(a(1,2)*a(3,3)-a(1,3)*a(3,2))
9978       b(2,2) =   a(1,1)*a(3,3)-a(1,3)*a(3,1)
9979       b(3,2) = -(a(1,1)*a(3,2)-a(1,2)*a(3,1))
9980       b(1,3) =   a(1,2)*a(2,3)-a(1,3)*a(2,2)
9981       b(2,3) = -(a(1,1)*a(2,3)-a(1,3)*a(2,1))
9982       b(3,3) =   a(1,1)*a(2,2)-a(1,2)*a(2,1)
9983       dmat = a(1,1)*b(1,1)+a(1,2)*b(2,1)+a(1,3)*b(3,1) !determinant of A
9984
9985       if (abs(dmat) > tiny(dmat)) then
9986          b= b/dmat
9987       else
9988          b=0.0_dp
9989       end if
9990
9991       return
9992    End Function Invert_Dp
9993
9994    !!--++
9995    !!--++ Funcion Invert_Sp(A) Result(b)
9996    !!--++    real(kind=sp), dimension(3,3), intent(in) :: a
9997    !!--++    real(Kind=sp), dimension(3,3)             :: b
9998    !!--++
9999    !!--++    (OVERLOADED)
10000    !!--++    Calculate de inverse of a real 3x3 matrix
10001    !!--++
10002    !!--++ Update: February - 2005
10003    !!
10004    Function Invert_Sp(a) Result(b)
10005       !---- Arguments ----!
10006       real(kind=sp),dimension(3,3), intent(in) :: a
10007       real(kind=sp),dimension(3,3)             :: b
10008
10009       !---- Local variables ----!
10010       real(kind=sp)  :: dmat
10011
10012       b(1,1) =   a(2,2)*a(3,3)-a(2,3)*a(3,2)
10013       b(2,1) = -(a(2,1)*a(3,3)-a(2,3)*a(3,1))
10014       b(3,1) =   a(2,1)*a(3,2)-a(2,2)*a(3,1)
10015       b(1,2) = -(a(1,2)*a(3,3)-a(1,3)*a(3,2))
10016       b(2,2) =   a(1,1)*a(3,3)-a(1,3)*a(3,1)
10017       b(3,2) = -(a(1,1)*a(3,2)-a(1,2)*a(3,1))
10018       b(1,3) =   a(1,2)*a(2,3)-a(1,3)*a(2,2)
10019       b(2,3) = -(a(1,1)*a(2,3)-a(1,3)*a(2,1))
10020       b(3,3) =   a(1,1)*a(2,2)-a(1,2)*a(2,1)
10021       dmat = a(1,1)*b(1,1)+a(1,2)*b(2,1)+a(1,3)*b(3,1) !determinant of A
10022
10023       if (abs(dmat) > tiny(dmat)) then
10024          b= b/dmat
10025       else
10026          b=0.0
10027       end if
10028
10029       return
10030    End Function Invert_Sp
10031
10032    !!----
10033    !!---- Function  Mat_Cross(U) Result(M)
10034    !!----    real/complex(kind=sp/dp)/integer, dimension(3), intent( in) :: u   !  In -> Vector 1
10035    !!----    real/complex(kind=sp/dp)/integer, dimension(3,3)            :: M   ! Out -> Matrix [u]cross
10036    !!----
10037    !!----    Calculates the matrix corresponding to the operator u x
10038    !!----    Antisymmetric matrix of the form:
10039    !!----                /  0   -u(3)  u(2)\
10040    !!----    M=[u]cross=|  u(3)   0   -u(1) |
10041    !!----                \-u(2)  u(1)   0  /
10042    !!----
10043    !!----  Updated: June - 2012
10044    !!
10045    Function Mat_Cross_cmpl_dp(u) Result(M)
10046       !---- Argument ----!
10047       complex(kind=dp), dimension(3), intent( in) :: u
10048       complex(kind=dp), dimension(3,3)            :: M
10049
10050       M = reshape( (/  (0.0_dp,0.0_dp),   -u(3),         u(2),  &
10051                            u(3),   (0.0_dp,0.0_dp),     -u(1),  &
10052                           -u(2),           u(1),   (0.0_dp,0.0_dp)/),(/3,3/))
10053       return
10054    End Function Mat_Cross_cmpl_dp
10055
10056    Function Mat_Cross_cmpl_sp(u) Result(M)
10057       !---- Argument ----!
10058       complex(kind=sp), dimension(3), intent( in) :: u
10059       complex(kind=sp), dimension(3,3)            :: M
10060
10061       M = reshape( (/  (0.0_sp,0.0_sp),   -u(3),         u(2),  &
10062                            u(3),   (0.0_sp,0.0_sp),     -u(1),  &
10063                           -u(2),           u(1),   (0.0_sp,0.0_sp)/),(/3,3/))
10064       return
10065    End Function Mat_Cross_cmpl_sp
10066
10067    Function Mat_Cross_dp(u) Result(M)
10068       !---- Argument ----!
10069       real(kind=dp), dimension(3), intent( in) :: u
10070       real(kind=dp), dimension(3,3)            :: M
10071
10072       M = reshape( (/ 0.0_dp,   -u(3),     u(2),  &
10073                        u(3),    0.0_dp,   -u(1),  &
10074                       -u(2),     u(1),    0.0_dp/),(/3,3/))
10075       return
10076    End Function Mat_Cross_dp
10077
10078    Function Mat_Cross_in(u) Result(M)
10079       !---- Argument ----!
10080       integer, dimension(3), intent( in) :: u
10081       integer, dimension(3,3)            :: M
10082
10083       M = reshape( (/   0,    -u(3),    u(2),  &
10084                        u(3),    0,     -u(1),  &
10085                       -u(2),   u(1),     0 /),(/3,3/))
10086       return
10087    End Function Mat_Cross_in
10088
10089    Function Mat_Cross_sp(u) Result(M)
10090       !---- Argument ----!
10091       real(kind=sp), dimension(3), intent( in) :: u
10092       real(kind=sp), dimension(3,3)            :: M
10093
10094       M = reshape( (/ 0.0_sp, -u(3),    u(2),  &
10095                        u(3),  0.0_sp,  -u(1),  &
10096                       -u(2),   u(1),   0.0_sp/),(/3,3/))
10097       return
10098    End Function Mat_Cross_sp
10099
10100    !!----
10101    !!---- Function Polyhedron_Volume(Nv,Vert,Cent) Result(vol)
10102    !!----    integer,                       intent(in) :: Nv       ! Vertices Number
10103    !!----    real(kind=cp), dimension(:,:), intent(in) :: Vert     ! Cartesian coordinates of vertices
10104    !!----    real(kind=cp), dimension(3),   intent(in) :: Cent     ! Cartesian coordinates a central point
10105    !!----
10106    !!---- This procedure calculate the volume of polyhedral with Nv vertices.
10107    !!---- It is based on volcal program of L. W. FINGER.
10108    !!---- Adapted by Javier Gonzalez Platas
10109    !!----
10110    !!---- Update: February - 2010
10111    !!
10112    Function Polyhedron_Volume(NV,Vert,Cent) Result(vol)
10113       !---- Arguments ----!
10114       integer,                       intent(in) :: Nv       ! Number of Vertices
10115       real(kind=cp), dimension(:,:), intent(in) :: Vert     ! Cartesian coordinates of atoms
10116       real(kind=cp), dimension(3),   intent(in) :: Cent     ! Cartesian coordinates of Central atom
10117       real(kind=cp)                             :: vol
10118       !---- Local Variables ----!
10119       integer                       :: i,j,k,l,i1,j1
10120       real(kind=cp)                 :: z,z0,area,factor
10121       real(kind=cp),dimension(6)    :: vxyz
10122       real(kind=cp),dimension(3)    :: d
10123       real(kind=cp),dimension(3,Nv) :: Atm_cart
10124
10125       vol=0.0
10126       call init_err_Math3d()
10127
10128       if (nv <= 3) then
10129          ERR_Math3D=.true.
10130          ERR_Math3D_Mess='The number of vertices for polyhedron volume is less than 4'
10131          return
10132       end if
10133
10134       do i=1,nv
10135          Atm_cart(:,i)=Vert(:,i)- Cent
10136       end do
10137
10138       do i=1,nv-2
10139          i1=i+1
10140          do j=i1,nv-1
10141             j1=j+1
10142             vxyz(1:3)=Atm_cart(:,j)-Atm_cart(:,i)
10143        loop:do k=j1,nv
10144                vxyz(4:6)=Atm_cart(:,k)-Atm_cart(:,i)
10145                d(1)=vxyz(2)*vxyz(6)-vxyz(5)*vxyz(3)
10146                d(2)=vxyz(4)*vxyz(3)-vxyz(1)*vxyz(6)
10147                d(3)=vxyz(1)*vxyz(5)-vxyz(4)*vxyz(2)
10148                area=0.5*sqrt(d(1)*d(1)+d(2)*d(2)+d(3)*d(3))
10149                z0=0.5*(Atm_cart(1,i)*d(1)+Atm_cart(2,i)*d(2)+Atm_cart(3,i)*d(3))/area
10150
10151                ! check for and avoid plane through origin
10152                if (abs(z0) < 1.0e-5) cycle
10153                factor = 3.0
10154                do l=1,nv
10155                   if(l==i .or. l==j .or. l==k) cycle
10156
10157                   ! calculate distance of point l from plane of ijk
10158                   z=0.5*((Atm_cart(1,i)-Atm_cart(1,l))*d(1)+ &
10159                          (Atm_cart(2,i)-Atm_cart(2,l))*d(2)+ &
10160                          (Atm_cart(3,i)-Atm_cart(3,l))*d(3))/area
10161
10162                   ! z and z0 must have the same sign
10163                   if (z * z0 < -0.001) cycle loop
10164                   if (abs(z * z0) < 0.001)then
10165                      ! if more than 3 corners on this face, the area will be counted twice.
10166                      ! change factor to handle this case.
10167                     factor = 6.0
10168                   end if
10169                end do
10170
10171                ! all points on same side,  thus ijk are face
10172                ! Direction Cosines Of Plane Normal
10173                d=d/(2.0*area)
10174
10175                vol=vol+area*abs(z0)/factor
10176
10177             end do loop
10178          end do
10179       end do
10180
10181       return
10182    End Function Polyhedron_Volume
10183
10184    !!----
10185    !!---- Function Rotate_OX(X,Angle) Result (Vec)
10186    !!----    real(kind=cp), dimension(3), intent(in) :: x       !  In -> Vector
10187    !!----    real(kind=cp),               intent(in) :: angle   !  In -> Angle (Degrees)
10188    !!----    real(kind=cp), dimension(3)             :: vec     ! Out -> Vector
10189    !!----
10190    !!----    X Rotation. Positive rotation is counter-clockwise
10191    !!----
10192    !!---- Update: February - 2005
10193    !!
10194    Function Rotate_OX(X,Angle) Result(vec)
10195       !---- Arguments ----!
10196       real(kind=cp), dimension(3), intent(in) :: x
10197       real(kind=cp),               intent(in) :: angle
10198       real(kind=cp), dimension(3)             :: vec
10199
10200       !---- Variables locales ----!
10201       real(kind=cp), dimension(3,3)           :: rot
10202
10203       rot(1,1)=  1.0
10204       rot(2,1)=  0.0_cp
10205       rot(3,1)=  0.0_cp
10206
10207       rot(1,2)=  0.0_cp
10208       rot(2,2)=  cosd(angle)
10209       rot(3,2)=  sind(angle)
10210
10211       rot(1,3)=  0.0_cp
10212       rot(2,3)=  -sind(angle)
10213       rot(3,3)=  cosd(angle)
10214
10215       vec=matmul(rot,x)
10216
10217       return
10218    End Function Rotate_OX
10219
10220    !!----
10221    !!---- Function Rotate_OY(Y,Angle) Result (Vec)
10222    !!----    real(kind=cp), dimension(3), intent(in) :: y       !  In -> Vector
10223    !!----    real(kind=cp),               intent(in) :: angle   !  In -> Angle (Degrees)
10224    !!----    real(kind=cp), dimension(3)             :: vec     ! Out -> Vector
10225    !!----
10226    !!----    Y Rotation.
10227    !!----
10228    !!---- Update: February - 2005
10229    !!
10230    Function Rotate_OY(Y,Angle) Result(vec)
10231       !---- Arguments ----!
10232       real(kind=cp), dimension(3), intent(in) :: y
10233       real(kind=cp),               intent(in) :: angle     ! Angle in degrees
10234       real(kind=cp), dimension(3)             :: vec
10235
10236       !---- Variables locales ----!
10237       real(kind=cp), dimension(3,3)           :: rot
10238
10239       rot(1,1)=  cosd(angle)
10240       rot(2,1)=  0.0_cp
10241       rot(3,1)=  -sind(angle)
10242
10243       rot(1,2)=  0.0_cp
10244       rot(2,2)=  1.0_cp
10245       rot(3,2)=  0.0_cp
10246
10247       rot(1,3)= sind(angle)
10248       rot(2,3)= 0.0_cp
10249       rot(3,3)= cosd(angle)
10250
10251      vec=matmul(rot,y)
10252
10253       return
10254    End Function Rotate_OY
10255
10256    !!----
10257    !!---- Function Rotate_OZ(Z,Angle) Result (Vec)
10258    !!----    real(kind=cp), dimension(3), intent(in) :: z       !  In -> Vector
10259    !!----    real(kind=cp),               intent(in) :: angle   !  In -> Angle (Degrees)
10260    !!----    real(kind=cp), dimension(3)             :: vec     ! Out -> Vector
10261    !!----
10262    !!----    Z Rotation
10263    !!----
10264    !!---- Update: February - 2005
10265    !!
10266    Function Rotate_OZ(Z,Angle) Result(vec)
10267       !---- Arguments ----!
10268       real(kind=cp), dimension(3), intent(in) :: z
10269       real(kind=cp),               intent(in) :: angle
10270       real(kind=cp), dimension(3)             :: vec
10271
10272       !---- Variables locales ----!
10273       real(kind=cp), dimension(3,3)           :: rot
10274
10275       rot(1,1)=  cosd(angle)
10276       rot(2,1)=  sind(angle)
10277       rot(3,1)=  0.0_cp
10278
10279       rot(1,2)=  -sind(angle)
10280       rot(2,2)=  cosd(angle)
10281       rot(3,2)=  0.0_cp
10282
10283       rot(1,3)=  0.0_cp
10284       rot(2,3)=  0.0_cp
10285       rot(3,3)=  1.0_cp
10286
10287       vec=matmul(rot,z)
10288
10289       return
10290    End Function Rotate_OZ
10291
10292    !!----
10293    !!---- Function  Tensor_Product(U,V) Result(W)
10294    !!----    complex/real(kind=sp/dp)/integer, dimension(3), intent( in) :: u   !  In -> Vector 1
10295    !!----    complex/real(kind=sp/dp)/integer, dimension(3), intent( in) :: v   !  In -> Vector 2
10296    !!----    complex/real(kind=sp/dp)/integer, dimension(3,3)            :: w   ! Out -> Tensor product Vector1 (o) Vector2
10297    !!----
10298    !!----    Calculates the tensor product of vectors u and v
10299    !!----
10300    !!---- Updated: June - 2012
10301    !!
10302    Function Tensor_Product_cmpl_dp(u,v) Result(w)
10303       !---- Argument ----!
10304       complex(kind=dp), dimension(3), intent( in) :: u,v
10305       complex(kind=dp), dimension(3,3)            :: w
10306       !
10307       complex(kind=dp), dimension(3,3)            :: mu,mv
10308       mu=0.0_dp;  mv=0.0_dp
10309       mu(:,1)=u
10310       mv(1,:)=v
10311       w=matmul(mu,mv)
10312       return
10313    End Function Tensor_Product_cmpl_dp
10314
10315    Function Tensor_Product_cmpl_sp(u,v) Result(w)
10316       !---- Argument ----!
10317       complex(kind=sp), dimension(3), intent( in) :: u,v
10318       complex(kind=sp), dimension(3,3)            :: w
10319       !
10320       complex(kind=sp), dimension(3,3)            :: mu,mv
10321       mu=0.0_sp;  mv=0.0_sp
10322       mu(:,1)=u
10323       mv(1,:)=v
10324       w=matmul(mu,mv)
10325       return
10326    End Function Tensor_Product_cmpl_sp
10327
10328    Function Tensor_Product_dp(u,v) Result(w)
10329       !---- Argument ----!
10330       real(kind=dp), dimension(3), intent( in) :: u,v
10331       real(kind=dp), dimension(3,3)            :: w
10332       !
10333       real(kind=dp), dimension(3,3)            :: mu,mv
10334       mu=0.0_dp;  mv=0.0_dp
10335       mu(:,1)=u
10336       mv(1,:)=v
10337       w=matmul(mu,mv)
10338       return
10339    End Function Tensor_Product_dp
10340
10341    Function Tensor_Product_in(u,v) Result(w)
10342       !---- Argument ----!
10343       integer, dimension(3), intent( in) :: u,v
10344       integer, dimension(3,3)            :: w
10345       !
10346       integer, dimension(3,3)            :: mu,mv
10347       mu=0;  mv=0
10348       mu(:,1)=u
10349       mv(1,:)=v
10350       w=matmul(mu,mv)
10351       return
10352    End Function Tensor_Product_in
10353
10354    Function Tensor_Product_sp(u,v) Result(w)
10355       !---- Argument ----!
10356       real(kind=sp), dimension(3), intent( in) :: u,v
10357       real(kind=sp), dimension(3,3)            :: w
10358       !
10359       real(kind=sp), dimension(3,3)            :: mu,mv
10360       mu=0.0_sp;  mv=0.0_sp
10361       mu(:,1)=u
10362       mv(1,:)=v
10363       w=matmul(mu,mv)
10364       return
10365    End Function Tensor_Product_sp
10366    !!----
10367    !!---- Function Veclength(A,B) Result(c)
10368    !!----    real(kind=cp), dimension(3,3), intent(in)  :: a
10369    !!----    real(kind=cp), dimension(3),   intent(in)  :: b
10370    !!----    real(kind=cp),                             :: c
10371    !!----
10372    !!----    Length of vector B when A is the Crystallographic
10373    !!----    to orthogonal matrix length=c
10374    !!----
10375    !!---- Update: February - 2005
10376    !!
10377    Function Veclength(a,b) Result(c)
10378       !---- Arguments ----!
10379       real(kind=cp), intent(in)  , dimension(3,3)       :: a
10380       real(kind=cp), intent(in)  , dimension(3  )       :: b
10381       real(kind=cp)                                     :: c
10382
10383       !---- Local variables ----!
10384       integer                     :: i,j
10385       real(kind=cp), dimension(3) :: v
10386
10387       v=0.0
10388       do i = 1,3
10389          do j = 1,3
10390             v(i) = v(i)+a(i,j)*b(j)
10391          end do
10392       end do
10393
10394       c = sqrt(v(1)**2+v(2)**2+v(3)**2)
10395
10396       return
10397    End Function Veclength
10398
10399    !---------------------!
10400    !---- Subroutines ----!
10401    !---------------------!
10402
10403    !!----
10404    !!---- Subroutine Init_Err_Math3D()
10405    !!----
10406    !!----    Initialize the errors flags in CFML_Math_3D
10407    !!----
10408    !!---- Update: February - 2005
10409    !!
10410    Subroutine Init_Err_Math3D()
10411
10412       ERR_Math3D=.false.
10413       ERR_Math3D_Mess=" "
10414
10415       return
10416    End Subroutine Init_Err_Math3D
10417
10418    !!----
10419    !!---- Subroutine Set_Eps(Neweps)
10420    !!----    real(kind=cp), intent( in) :: neweps
10421    !!----
10422    !!----    Sets global EPS to the value "neweps"
10423    !!----
10424    !!---- Update: February - 2005
10425    !!
10426    Subroutine Set_Eps(Neweps)
10427       !---- Arguments ----!
10428       real(kind=cp), intent( in) :: neweps
10429
10430       eps=neweps
10431
10432       return
10433    End Subroutine Set_Eps
10434
10435    !!----
10436    !!---- Subroutine Set_Eps_Default()
10437    !!----
10438    !!----    Sets global EPS to the default value: eps=0.00001
10439    !!----
10440    !!---- Update: February - 2005
10441    !!
10442    Subroutine Set_Eps_Default()
10443
10444       eps=0.00001
10445
10446       return
10447    End Subroutine Set_Eps_Default
10448
10449    !!----
10450    !!---- Subroutine Get_Cart_from_Cylin(rho,Phi,zeta,Xo,Mode)
10451    !!----    real(kind=sp/dp),              intent( in)           :: rho
10452    !!----    real(kind=sp/dp),              intent( in)           :: phi
10453    !!----    real(kind=sp/dp),              intent( in)           :: zeta
10454    !!----    real(kind=sp/dp), dimension(3),intent(out)           :: xo
10455    !!----    character(len=*),              intent( in), optional :: mode
10456    !!----
10457    !!----    Determine the Cartesian coordinates from cylindrical coordinates.
10458    !!----    If Mode='D' the angle phi is provided in Degrees.
10459    !!----
10460    !!---- Update: February - 2005
10461    !!
10462
10463    !!--++
10464    !!--++ Subroutine  Get_Cart_from_Cylin_dp(rho,Phi,zeta,Xo,Mode)
10465    !!--++    real(kind=dp),              intent( in)           ::  rho
10466    !!--++    real(kind=dp),              intent( in)           ::  phi
10467    !!--++    real(kind=dp),              intent( in)           ::  zeta
10468    !!--++    real(kind=dp), dimension(3),intent(out)           ::  xo
10469    !!--++    character(len=*),           intent( in), optional ::  mode
10470    !!--++
10471    !!--++    (OVERLOADED)
10472    !!--++    Determine the Cartesian coordinates from cylindrical coordinates.
10473    !!--++
10474    !!--++ Update: February - 2005
10475    !!
10476    Subroutine Get_Cart_from_Cylin_dp(rho,Phi,zeta,Xo,Mode)
10477       !---- Arguments ----!
10478       real(kind=dp),              intent( in)           ::  rho
10479       real(kind=dp),              intent( in)           ::  phi
10480       real(kind=dp),              intent( in)           ::  zeta
10481       real(kind=dp), dimension(3),intent(out)           ::  xo
10482       character(len=*),           intent( in), optional ::  mode
10483
10484       !---- Local Variables ----!
10485       real(kind=dp) :: ph
10486
10487       ph=phi
10488       if (present(mode)) then
10489          if (mode(1:1) == "D" .or. mode(1:1) == "d") ph=phi*to_rad
10490       end if
10491       xo(1)=rho*cos(ph)
10492       xo(2)=rho*sin(ph)
10493       xo(3)=zeta
10494
10495       return
10496    End Subroutine Get_Cart_from_Cylin_dp
10497
10498    !!--++
10499    !!--++ Subroutine  Get_Cart_from_Cylin_sp(rho,Phi,zeta,Xo,Mode)
10500    !!--++    real(kind=sp),              intent( in)           ::  rho
10501    !!--++    real(kind=sp),              intent( in)           ::  phi
10502    !!--++    real(kind=sp),              intent( in)           ::  zeta
10503    !!--++    real(kind=sp), dimension(3),intent(out)           ::  xo
10504    !!--++    character(len=*),           intent( in), optional ::  mode
10505    !!--++
10506    !!--++    (OVERLOADED)
10507    !!--++    Determine the Cartesian coordinates from cylindrical coordinates.
10508    !!--++
10509    !!--++ Update: February - 2005
10510    !!
10511    Subroutine Get_Cart_from_Cylin_sp(rho,Phi,zeta,Xo,Mode)
10512       real(kind=sp),              intent( in)           ::  rho
10513       real(kind=sp),              intent( in)           ::  phi
10514       real(kind=sp),              intent( in)           ::  zeta
10515       real(kind=sp), dimension(3),intent(out)           ::  xo
10516       character(len=*),           intent( in), optional ::  mode
10517
10518       !---- Local Variables ----!
10519       real(kind=sp) :: ph
10520
10521       ph=phi
10522       if (present(mode)) then
10523          if (mode(1:1) == "D" .or. mode(1:1) == "d") ph=phi*to_rad
10524       end if
10525       xo(1)=rho*cos(ph)
10526       xo(2)=rho*sin(ph)
10527       xo(3)=zeta
10528
10529       return
10530    End Subroutine Get_Cart_from_Cylin_sp
10531
10532    !!----
10533    !!---- Subroutine Get_Centroid_Coord(Cn,Atm_Cart,Centroid,Baricenter)
10534    !!----    integer,                       intent(in) :: Cn          ! Coordination Number
10535    !!----    real(kind=cp), dimension(:,:), intent(in) :: Atm_Cart    ! Cartesian coordinates of atoms
10536    !!----    real(kind=cp), dimension(3),   intent(out):: Centroid    ! Centroid
10537    !!----    real(kind=cp), dimension(3),   intent(out):: Baricenter  ! Baricenter
10538    !!----
10539    !!---- Procedure to calculate Centroid and BariCenter of a pPolyhedron according to
10540    !!---- Tonci Balic-Zunic (Acta Cryst. B52, 1996, 78-81; Acta Cryst. B54, 1998, 766-773)
10541    !!---- Centroid is here different from Baricentre and it is defined in the above reference.
10542    !!----
10543    !!---- Update: February - 2010
10544    !!
10545    Subroutine Get_Centroid_Coord(Cn,Atm_Cart,Centroid,Baricenter)
10546       !---- Arguments ----!
10547       integer,                       intent(in) :: Cn          ! Coordination Number
10548       real(kind=cp), dimension(:,:), intent(in) :: Atm_Cart    ! Cartesian coordinates of atoms, gathered as: (1:3,1:Cn)
10549       real(kind=cp), dimension(3),   intent(out):: Centroid    ! Centroid
10550       real(kind=cp), dimension(3),   intent(out):: Baricenter  ! Baricenter
10551
10552       !---- Local variables ----!
10553       real(kind=cp), dimension(4)   :: plane1,plane2,plane3
10554       real(kind=cp), dimension(3)   :: p0,p1,p2,p3,u,v,r,t
10555       real(kind=cp), dimension(3,3) :: w, w1
10556       real(kind=cp)                 :: d,umod,vmod,rmod,d1
10557       real(kind=cp)                 :: sx, sy, sz, sx2, sy2, sz2, sx3, sy3, sz3
10558       real(kind=cp)                 :: sxy, sxz, syz, sxy2, sxz2
10559       real(kind=cp)                 :: sx2y, sx2z, syz2, sy2z
10560       integer                       :: i
10561
10562       call init_err_math3d()
10563       centroid=0.0
10564       baricenter=0.0
10565
10566       p1=Atm_Cart(1:3,1)
10567       p2=Atm_Cart(1:3,2)
10568       p3=Atm_Cart(1:3,3)
10569
10570       select case (cn)
10571          case (:2)
10572             err_Math3D=.true.
10573             err_Math3D_Mess='Centroid calculation needs 3 vertives as minimum'
10574             return
10575
10576          case (3)
10577             !---- Plane 1: Defined with those 3 Points ----!
10578             call Get_Plane_From_Points(p1, p2, p3, &
10579                                        plane1(1), plane1(2), plane1(3), plane1(4))
10580             r=plane1(1:3)
10581             rmod=euclidean_norm(3,r)
10582             if (abs(rmod) <= 0.0001) then
10583                err_Math3D=.true.
10584                err_Math3D_Mess='Imposible to define a Plane with the three given points '
10585                return
10586             end if
10587             r=r/rmod
10588
10589             !---- Vectors ----!
10590             u=p2-p1
10591             umod=euclidean_norm(3,u)
10592             if (abs(umod) <= 0.0001) then
10593                err_Math3D=.true.
10594                err_Math3D_Mess='Check your points! Seems that two of them are equal'
10595                return
10596             end if
10597
10598             v=p3-p1
10599             vmod=euclidean_norm(3,v)
10600             if (abs(vmod) <= 0.0001) then
10601                err_Math3D=.true.
10602                err_Math3D_Mess='Check your points! Seems that two of them are equal'
10603                return
10604             end if
10605
10606             !---- Plane 2 ----!
10607             p0=p1+0.5*u
10608             u=u/umod
10609             plane2(1:3)=u
10610             plane2(4)=-( plane2(1)*p0(1)+plane2(2)*p0(2)+plane2(3)*p0(3) )
10611
10612             !---- Plane 3 ----!
10613             p0=p1+0.5*v
10614             v=v/vmod
10615             plane3(1:3)=v
10616             plane3(4)=-( plane3(1)*p0(1)+plane3(2)*p0(2)+plane3(3)*p0(3) )
10617
10618             !---- Centroid ----!
10619             w(1,1:3)=plane1(1:3)
10620             w(2,1:3)=plane2(1:3)
10621             w(3,1:3)=plane3(1:3)
10622             d=determ_a(w)
10623
10624             if (abs(d) <= 0.0001) then
10625                err_Math3D=.true.
10626                err_Math3D_Mess='Determinant is singular to calculate Centroid point'
10627                return
10628             end if
10629
10630             w(1:3,1)=(/-plane1(4),-plane2(4), -plane3(4)/)
10631             d1=determ_a(w)
10632             centroid(1)=d1/d
10633
10634             w(1,1:3)=plane1(1:3)
10635             w(2,1:3)=plane2(1:3)
10636             w(3,1:3)=plane3(1:3)
10637             w(1:3,2)=(/-plane1(4),-plane2(4), -plane3(4)/)
10638             d1=determ_a(w)
10639             centroid(2)=d1/d
10640
10641             w(1,1:3)=plane1(1:3)
10642             w(2,1:3)=plane2(1:3)
10643             w(3,1:3)=plane3(1:3)
10644             w(1:3,3)=(/-plane1(4),-plane2(4), -plane3(4)/)
10645             d1=determ_a(w)
10646             centroid(3)=d1/d
10647
10648             sx =0.0; sy =0.0; sz =0.0
10649             do i=1,3
10650                sx=sx+Atm_Cart(1,i)
10651                sy=sy+Atm_Cart(2,i)
10652                sz=sz+Atm_Cart(3,i)
10653             end do
10654
10655          case (4:)
10656             sx =0.0; sy =0.0; sz =0.0
10657             sx2=0.0; sy2=0.0; sz2=0.0
10658             sx3=0.0; sy3=0.0; sz3=0.0
10659             sxy=0.0; sxz=0.0; syz=0.0
10660             sxy2=0.0; sxz2=0.0
10661             sx2y=0.0; sx2z=0.0
10662             syz2=0.0; sy2z=0.0
10663             do i=1,cn
10664                sx=sx+Atm_Cart(1,i)
10665                sy=sy+Atm_Cart(2,i)
10666                sz=sz+Atm_Cart(3,i)
10667
10668                sx2=sx2+Atm_Cart(1,i)*Atm_Cart(1,i)
10669                sy2=sy2+Atm_Cart(2,i)*Atm_Cart(2,i)
10670                sz2=sz2+Atm_Cart(3,i)*Atm_Cart(3,i)
10671
10672                sx3=sx3+Atm_Cart(1,i)*Atm_Cart(1,i)*Atm_Cart(1,i)
10673                sy3=sy3+Atm_Cart(2,i)*Atm_Cart(2,i)*Atm_Cart(2,i)
10674                sz3=sz3+Atm_Cart(3,i)*Atm_Cart(3,i)*Atm_Cart(3,i)
10675
10676                sxy=sxy+Atm_Cart(1,i)*Atm_Cart(2,i)
10677                sxz=sxz+Atm_Cart(1,i)*Atm_Cart(3,i)
10678                syz=syz+Atm_Cart(2,i)*Atm_Cart(3,i)
10679
10680                sxy2=sxy2+Atm_Cart(1,i)*Atm_Cart(2,i)*Atm_Cart(2,i)
10681                sxz2=sxz2+Atm_Cart(1,i)*Atm_Cart(3,i)*Atm_Cart(3,i)
10682
10683                sx2y=sx2y+Atm_Cart(2,i)*Atm_Cart(1,i)*Atm_Cart(1,i)
10684                sx2z=sx2z+Atm_Cart(3,i)*Atm_Cart(1,i)*Atm_Cart(1,i)
10685
10686                syz2=syz2+Atm_Cart(2,i)*Atm_Cart(3,i)*Atm_Cart(3,i)
10687                sy2z=sy2z+Atm_Cart(3,i)*Atm_Cart(2,i)*Atm_Cart(2,i)
10688             end do
10689
10690             w(1,1)=sx2 - (sx**2)/real(cn)
10691             w(1,2)=sxy - (sx*sy)/real(cn)
10692             w(1,3)=sxz - (sx*sz)/real(cn)
10693             t(1)=0.5*(sx3 + sxy2 + sxz2 - ((sx2*sx + sy2*sx + sz2*sx)/real(cn)))
10694
10695             w(2,1)=sxy - (sx*sy)/real(cn)
10696             w(2,2)=sy2 - (sy**2)/real(cn)
10697             w(2,3)=syz - (sy*sz)/real(cn)
10698             t(2)=0.5*(sx2y + sy3 + syz2 - ((sx2*sy + sy2*sy + sz2*sy)/real(cn)))
10699
10700             w(3,1)=sxz - (sx*sz)/real(cn)
10701             w(3,2)=syz - (sy*sz)/real(cn)
10702             w(3,3)=sz2 - (sz**2)/real(cn)
10703             t(3)=0.5*(sx2z + sy2z + sz3 - ((sx2*sz + sy2*sz + sz2*sz)/real(cn)))
10704
10705             d=determ_a(w)
10706             if (abs(d) <= 0.0001) then
10707                err_Math3D=.true.
10708                err_Math3D_Mess='Determinant is singular to calculate Centroid point'
10709                return
10710             end if
10711
10712             w1=w
10713             w1(:,1)=t
10714             d1=determ_a(w1)
10715             centroid(1)=d1/d
10716
10717             w1=w
10718             w1(:,2)=t
10719             d1=determ_a(w1)
10720             centroid(2)=d1/d
10721
10722             w1=w
10723             w1(:,3)=t
10724             d1=determ_a(w1)
10725             centroid(3)=d1/d
10726       end select
10727
10728       baricenter=(/ sx/real(cn), sy/real(cn), sz/real(cn) /)
10729
10730       return
10731    End Subroutine Get_Centroid_Coord
10732
10733    !!----
10734    !!---- Subroutine Get_Cylindr_Coord(Xo,rho,Phi,zeta,Mode)
10735    !!----    real(kind=sp/dp), dimension(3),intent( in)           :: xo
10736    !!----    real(kind=sp/dp),              intent(out)           :: rho
10737    !!----    real(kind=sp/dp),              intent(out)           :: phi
10738    !!----    real(kind=sp/dp),              intent(out)           :: zeta
10739    !!----    character(len=*),              intent( in), optional :: mode
10740    !!----
10741    !!----    Determine the cylindrical coordinates from Cartesian coordinates.
10742    !!----    If Mode='D' the angle phi is provided in Degrees.
10743    !!----
10744    !!---- Update: February - 2005
10745    !!
10746
10747    !!--++
10748    !!--++ Subroutine  Get_Cylindr_Coord_dp(Xo,rho,Phi,zeta,Mode)
10749    !!--++    real(kind=dp), dimension(3),intent( in)           ::  xo
10750    !!--++    real(kind=dp),              intent(out)           ::  rho
10751    !!--++    real(kind=dp),              intent(out)           ::  phi
10752    !!--++    real(kind=dp),              intent(out)           ::  zeta
10753    !!--++    character(len=*),           intent( in), optional ::  mode
10754    !!--++
10755    !!--++    (OVERLOADED)
10756    !!--++    Determine the cylindrical coordinates from Cartesian coordinates.
10757    !!--++
10758    !!--++ Update: February - 2005
10759    !!
10760    Subroutine Get_Cylindr_Coord_dp(Xo,rho,Phi,zeta,Mode)
10761       !---- Arguments ----!
10762       real(kind=dp), dimension(3),intent( in)           ::  xo
10763       real(kind=dp),              intent(out)           ::  rho
10764       real(kind=dp),              intent(out)           ::  phi
10765       real(kind=dp),              intent(out)           ::  zeta
10766       character(len=*),           intent( in), optional ::  mode
10767
10768       !---- Local Variables ----!
10769       integer :: j
10770
10771       zeta=xo(3)
10772       if( abs(xo(2)) > eps .or. abs(xo(1)) > eps) then
10773          phi=atan2(xo(2),xo(1))
10774       else
10775          phi= 0.0_dp
10776       end if
10777       rho=0.0_dp
10778       do j=1,2
10779          rho=rho+xo(j)*xo(j)
10780       end do
10781       rho=sqrt(rho)
10782
10783       if (present(mode)) then
10784          if (mode(1:1) == "D" .or. mode(1:1) == "d") phi=phi*to_deg
10785       end if
10786
10787       return
10788    End Subroutine Get_Cylindr_Coord_dp
10789
10790    !!--++
10791    !!--++ Subroutine  Get_Cylindr_Coord_sp(Xo,rho,Phi,zeta,Mode)
10792    !!--++    real(kind=sp), dimension(3),intent( in)           ::  xo
10793    !!--++    real(kind=sp),              intent(out)           ::  rho
10794    !!--++    real(kind=sp),              intent(out)           ::  phi
10795    !!--++    real(kind=sp),              intent(out)           ::  zeta
10796    !!--++    character(len=*),           intent( in), optional ::  mode
10797    !!--++
10798    !!--++    (OVERLOADED)
10799    !!--++    Determine the cylindrical coordinates from Cartesian coordinates.
10800    !!--++
10801    !!--++ Update: February - 2005
10802    !!
10803    Subroutine Get_Cylindr_Coord_sp(Xo,rho,Phi,zeta,Mode)
10804       !---- Arguments ----!
10805       real(kind=sp), dimension(3),intent( in)           ::  xo
10806       real(kind=sp),              intent(out)           ::  rho
10807       real(kind=sp),              intent(out)           ::  phi
10808       real(kind=sp),              intent(out)           ::  zeta
10809       character(len=*),           intent( in), optional ::  mode
10810
10811       !---- Local Variables ----!
10812       integer :: j
10813
10814       zeta=xo(3)
10815       if( abs(xo(2)) > eps .or. abs(xo(1)) > eps) then
10816          phi=atan2(xo(2),xo(1))
10817       else
10818          phi= 0.0_sp
10819       end if
10820       rho=0.0_sp
10821       do j=1,2
10822          rho=rho+xo(j)*xo(j)
10823       end do
10824       rho=sqrt(rho)
10825
10826       if (present(mode)) then
10827          if (mode(1:1) == "D" .or. mode(1:1) == "d") phi=phi*to_deg
10828       end if
10829
10830       return
10831    End Subroutine Get_Cylindr_Coord_sp
10832
10833    !!----
10834    !!---- Subroutine Get_Cart_from_Spher(r,Theta,Phi,Xo,Mode)
10835    !!----    real(kind=sp/dp),              intent( in)           :: r
10836    !!----    real(kind=sp/dp),              intent( in)           :: Theta
10837    !!----    real(kind=sp/dp),              intent( in)           :: Phi
10838    !!----    real(kind=sp/dp), dimension(3),intent(out)           :: xo
10839    !!----    character(len=*),              intent( in), optional :: mode
10840    !!----
10841    !!----    Determine the Cartesian coordinates from spherical coordinates.
10842    !!----    If Mode='D' the angle phi is provided in Degrees.
10843    !!----
10844    !!---- Update: February - 2005
10845    !!
10846
10847    !!--++
10848    !!--++ Subroutine Get_Cart_from_Spher_dp(r,Theta,Phi,Xo,Mode)
10849    !!--++    real(kind=dp),              intent( in)           :: r
10850    !!--++    real(kind=dp),              intent( in)           :: Theta
10851    !!--++    real(kind=dp),              intent( in)           :: Phi
10852    !!--++    real(kind=dp), dimension(3),intent(out)           :: xo
10853    !!--++    character(len=*),           intent( in), optional :: mode
10854    !!--++
10855    !!--++    (OVERLOADED)
10856    !!--++    Determine the Cartesian coordinates from spherical coordinates.
10857    !!--++
10858    !!--++ Update: February - 2005
10859    !!
10860    Subroutine Get_Cart_from_Spher_dp(r,Theta,Phi,Xo,Mode)
10861       !---- Arguments ----!
10862       real(kind=dp),              intent( in)           :: r
10863       real(kind=dp),              intent( in)           :: Theta
10864       real(kind=dp),              intent( in)           :: phi
10865       real(kind=dp), dimension(3),intent(out)           :: xo
10866       character(len=*),           intent( in), optional :: mode
10867
10868       !---- Local Variables ----!
10869       real(kind=dp) :: ph,th
10870
10871       ph=Phi
10872       th=Theta
10873       if (present(mode)) then
10874          if (mode(1:1) == "D" .or. mode(1:1) == "d") then
10875             ph=Phi*to_rad
10876             th=Theta*to_rad
10877          end if
10878       end if
10879       xo(1)=r*cos(ph)*sin(th)
10880       xo(2)=r*sin(ph)*sin(th)
10881       xo(3)=r*cos(th)
10882
10883       return
10884    End Subroutine Get_Cart_from_Spher_dp
10885
10886    !!--++
10887    !!--++ Subroutine Get_Cart_from_Spher_sp(r,Theta,Phi,Xo,Mode)
10888    !!--++    real(kind=sp),              intent( in)           :: r
10889    !!--++    real(kind=sp),              intent( in)           :: Theta
10890    !!--++    real(kind=sp),              intent( in)           :: Phi
10891    !!--++    real(kind=sp), dimension(3),intent(out)           :: xo
10892    !!--++    character(len=*),           intent( in), optional :: mode
10893    !!--++
10894    !!--++    (OVERLOADED)
10895    !!--++    Determine the Cartesian coordinates from spherical coordinates.
10896    !!--++
10897    !!--++ Update: February - 2005
10898    !!
10899    Subroutine Get_Cart_from_Spher_sp(r,Theta,Phi,Xo,Mode)
10900       !---- Arguments ----!
10901       real(kind=sp),              intent( in)           :: r
10902       real(kind=sp),              intent( in)           :: Theta
10903       real(kind=sp),              intent( in)           :: phi
10904       real(kind=sp), dimension(3),intent(out)           :: xo
10905       character(len=*),           intent( in), optional :: mode
10906
10907       !---- Local Variables ----!
10908       real(kind=sp) :: ph,th
10909
10910       ph=Phi
10911       th=Theta
10912       if (present(mode)) then
10913          if (mode(1:1) == "D" .or. mode(1:1) == "d") then
10914             ph=Phi*to_rad
10915             th=Theta*to_rad
10916          end if
10917       end if
10918       xo(1)=r*cos(ph)*sin(th)
10919       xo(2)=r*sin(ph)*sin(th)
10920       xo(3)=r*cos(th)
10921
10922       return
10923    End Subroutine Get_Cart_from_Spher_sp
10924
10925    !!----
10926    !!---- Subroutine Get_Plane_from_Points(P1,P2,P3,A,B,C,D)
10927    !!----    real(kind=cp), dimension(3), intent(in) :: P1
10928    !!----    real(kind=cp), dimension(3), intent(in) :: P2
10929    !!----    real(kind=cp), dimension(3), intent(in) :: P3
10930    !!----    real(kind=cp),               intent(out):: A
10931    !!----    real(kind=cp),               intent(out):: B
10932    !!----    real(kind=cp),               intent(out):: C
10933    !!----    real(kind=cp),               intent(out):: D
10934    !!----
10935    !!----    Caculate the implicit form of a Plane in 3D as
10936    !!----    A * X + B * Y + C * Z + D = 0
10937    !!----
10938    !!---- Update: July - 2005
10939    !!
10940    Subroutine Get_Plane_from_Points(P1, P2, P3, A, B, C, D)
10941       !---- Arguments ----!
10942       real(kind=cp), dimension(3), intent(in) :: P1
10943       real(kind=cp), dimension(3), intent(in) :: P2
10944       real(kind=cp), dimension(3), intent(in) :: P3
10945       real(kind=cp),               intent(out):: A
10946       real(kind=cp),               intent(out):: B
10947       real(kind=cp),               intent(out):: C
10948       real(kind=cp),               intent(out):: D
10949
10950       a = ( p2(2) - p1(2) ) * ( p3(3) - p1(3) ) &
10951           - ( p2(3) - p1(3) ) * ( p3(2) - p1(2) )
10952
10953       b = ( p2(3) - p1(3) ) * ( p3(1) - p1(1) ) &
10954           - ( p2(1) - p1(1) ) * ( p3(3) - p1(3) )
10955
10956       c = ( p2(1) - p1(1) ) * ( p3(2) - p1(2) ) &
10957           - ( p2(2) - p1(2) ) * ( p3(1) - p1(1) )
10958
10959       d = - p2(1) * a - p2(2) * b - p2(3) * c
10960
10961       return
10962    End Subroutine Get_Plane_from_Points
10963
10964    !!----
10965    !!---- Subroutine Get_Spheric_Coord(Xo,Ss,Theta,Phi,Mode)
10966    !!----    real(kind=sp/dp), dimension(3),intent( in)           :: xo
10967    !!----    real(kind=sp/dp),              intent(out)           :: ss
10968    !!----    real(kind=sp/dp),              intent(out)           :: theta
10969    !!----    real(kind=sp/dp),              intent(out)           :: phi
10970    !!----    character(len=*),              intent( in), optional :: mode
10971    !!----
10972    !!----    Determine the spheric coordinates from rectangular coordinates.
10973    !!----    If Mode='D' the angles will be done in Degrees.
10974    !!----
10975    !!---- Update: February - 2005
10976    !!
10977
10978    !!--++
10979    !!--++ Subroutine Get_Spheric_Coord_dp(Xo,Ss,Theta,Phi,Mode)
10980    !!--++    real(kind=dp), dimension(3),intent( in)           :: xo
10981    !!--++    real(kind=dp),              intent(out)           :: ss
10982    !!--++    real(kind=dp),              intent(out)           :: theta
10983    !!--++    real(kind=dp),              intent(out)           :: phi
10984    !!--++    character(len=*),           intent( in), optional :: mode
10985    !!--++
10986    !!--++    (OVERLOADED)
10987    !!--++    Determine the spheric coordinates from rectangular coordinates
10988    !!--++
10989    !!--++ Update: February - 2005
10990    !!
10991    Subroutine Get_Spheric_Coord_dp(xo,ss,theta,phi,mode)
10992       !---- Arguments ----!
10993       real(kind=dp), intent( in), dimension(3)   :: xo
10994       real(kind=dp), intent(out)                 :: ss
10995       real(kind=dp), intent(out)                 :: theta
10996       real(kind=dp), intent(out)                 :: phi
10997       character(len=*), intent(in), optional     :: mode
10998
10999       !---- Local Variables ----!
11000       integer :: j
11001
11002       ss=0.0_dp
11003       do j=1,3
11004          ss=ss+xo(j)*xo(j)
11005       end do
11006       ss=sqrt(ss)
11007       if (ss > 0.0_dp) then
11008          theta=xo(3)/ss
11009          if (abs(theta) > 1.0_dp) then
11010             theta=sign(1.0_dp,theta)
11011          end if
11012          theta=acos(theta)
11013          if (abs(theta) < eps .or. abs(theta-pi) < eps) then
11014             phi=0.0_dp
11015          else
11016             phi=atan2(xo(2),xo(1))
11017          end if
11018       else
11019          theta=0.0_dp
11020          phi=0.0_dp
11021       end if
11022       if (present(mode)) then
11023          if (mode(1:1) == "D" .or. mode(1:1) == "d") then
11024             theta=theta*to_deg
11025             phi=phi*to_deg
11026          end if
11027       end if
11028
11029       return
11030    End Subroutine Get_Spheric_Coord_dp
11031
11032    !!--++
11033    !!--++ Subroutine Get_Spheric_Coord_sp(Xo,Ss,Theta,Phi,Mode)
11034    !!--++    real(kind=sp), dimension(3),intent( in)           :: xo
11035    !!--++    real(kind=sp),              intent(out)           :: ss
11036    !!--++    real(kind=sp),              intent(out)           :: theta
11037    !!--++    real(kind=sp),              intent(out)           :: phi
11038    !!--++    character(len=*),           intent( in), optional :: mode
11039    !!--++
11040    !!--++    (OVERLOADED)
11041    !!--++    Determine the spheric coordinates from rectangular coordinates
11042    !!--++
11043    !!--++ Update: February - 2005
11044    !!
11045    Subroutine Get_Spheric_Coord_sp(xo,ss,theta,phi,mode)
11046       !---- Arguments ----!
11047       real(kind=sp), intent( in), dimension(3)   :: xo
11048       real(kind=sp), intent(out)                 :: ss
11049       real(kind=sp), intent(out)                 :: theta
11050       real(kind=sp), intent(out)                 :: phi
11051       character(len=*), intent(in), optional     :: mode
11052
11053       !---- Local Variables ----!
11054       integer :: j
11055
11056       ss=0.0_sp
11057       do j=1,3
11058          ss=ss+xo(j)*xo(j)
11059       end do
11060       ss=sqrt(ss)
11061       if (ss > 0.0_sp) then
11062          theta=xo(3)/ss
11063          if (abs(theta) > 1.0_sp) then
11064             theta=sign(1.0_sp,theta)
11065          end if
11066          theta=acos(theta)
11067          if (abs(theta) < eps .or. abs(theta-pi) < eps) then
11068             phi=0.0_sp
11069          else
11070             phi=atan2(xo(2),xo(1))
11071          end if
11072       else
11073          theta=0.0_sp
11074          phi=0.0_sp
11075       end if
11076       if (present(mode)) then
11077          if (mode(1:1) == "D" .or. mode(1:1) == "d") then
11078             theta=theta*to_deg
11079             phi=phi*to_deg
11080          end if
11081       end if
11082
11083       return
11084    End Subroutine Get_Spheric_Coord_sp
11085
11086    !!----
11087    !!---- Subroutine Matrix_DiagEigen(A, V, C)
11088    !!----    real(kind=cp), dimension(3,3), intent(in)  :: a
11089    !!----    real(kind=cp), dimension(3),   intent(out) :: v
11090    !!----    real(kind=cp), dimension(3,3), intent(out) :: c
11091    !!----
11092    !!----    Diagonalize the matrix A, put eigenvalues in V and
11093    !!----    eigenvectors in C
11094    !!----
11095    !!---- Update: February - 2005
11096    !!
11097    Subroutine Matrix_DiagEigen(a,v,c)
11098       !---- Arguments ----!
11099       real(kind=cp), intent(in)  , dimension(3,3)    :: a
11100       real(kind=cp), intent(out) , dimension(3)      :: v
11101       real(kind=cp), intent(out) , dimension(3,3)    :: c
11102
11103       !---- Local Variables ----!
11104       integer, parameter            :: n=3
11105       integer                       :: i, j, k, itmax, nm1, ip1, iter
11106       real(kind=cp), dimension(3)   :: u
11107       real(kind=cp), dimension(3,3) :: e
11108       real(kind=cp), parameter      :: eps1=1.e-7 , eps2=1.e-7 , eps3=1.e-7
11109       real(kind=cp)                 :: sigma1, offdsq, p, q, spq, csa, sna
11110       real(kind=cp)                 :: holdik, holdki, sigma2
11111
11112       call init_err_math3d()
11113       nm1=n-1
11114       itmax=50
11115       do i=1,n
11116          do j=1,n
11117             e(i,j)=a(i,j)
11118             c(i,j)=0.0
11119             if (j < i) e(i,j)=0.0
11120          end do
11121       end do
11122       sigma1=0.0
11123       offdsq=0.0
11124
11125       do i=1,n
11126          sigma1=sigma1+e(i,i)**2
11127          c(i,i)=1.0
11128          ip1=i+1
11129          if (i >= n) exit
11130          do j=ip1,n
11131             offdsq=offdsq+e(i,j)**2
11132          end do
11133       end do
11134
11135       do iter=1,itmax
11136          do i=1,nm1
11137             ip1=i+1
11138             do j=ip1,n
11139                q=abs(e(i,i)-e(j,j))
11140                if (q <= eps1) then
11141                   csa=1.0/sqrt(2.0)
11142                   sna=csa
11143                else
11144                   if (abs(e(i,j)) <= eps2) then
11145                      e(i,j)=0.0
11146                      cycle
11147                   end if
11148                   p=2.0*e(i,j)*q/(e(i,i)-e(j,j))
11149                   spq=sqrt(p*p+q*q)
11150                   csa=sqrt((1.0+q/spq)/2.0)
11151                   sna=p/(2.0*csa*spq)
11152                end if
11153                do k=1,n
11154                   holdki=c(k,i)
11155                   c(k,i)=holdki*csa+c(k,j)*sna
11156                   c(k,j)=holdki*sna-c(k,j)*csa
11157                end do
11158                do k=i,n
11159                   if (k > j) then
11160                      holdik=e(i,k)
11161                      e(i,k)=csa*holdik+sna*e(j,k)
11162                      e(j,k)=sna*holdik-csa*e(j,k)
11163                   else
11164                      u(k)=e(i,k)
11165                      e(i,k)=csa*u(k)+sna*e(k,j)
11166                      if (k /= j) cycle
11167                      e(j,k)=sna*u(k)-csa*e(j,k)
11168                   end if
11169                end do
11170                u(j)=sna*u(i)-csa*u(j)
11171                do k=1,j
11172                   if (k <= i)  then
11173                      holdki=e(k,i)
11174                      e(k,i)=csa*holdki+sna*e(k,j)
11175                      e(k,j)=sna*holdki-csa*e(k,j)
11176                   else
11177                      e(k,j)=sna*u(k)-csa*e(k,j)
11178                   end if
11179                end do
11180                e(i,j)=0.0
11181             end do
11182          end do
11183          sigma2=0.0
11184          do i=1,n
11185             v(i)=e(i,i)
11186             sigma2=sigma2+v(i)*v(i)
11187          end do
11188          if (1.0-sigma1/sigma2 <= eps3) return
11189          sigma1=sigma2
11190       end do
11191
11192       ERR_Math3D =.true.
11193       ERR_Math3D_Mess=" Convergence not reached in diagonalization "
11194
11195       return
11196    End Subroutine Matrix_DiagEigen
11197
11198    !!----
11199    !!---- Subroutine Matrix_Inverse(A, B, Ifail)
11200    !!----    real(kind=cp), dimension(3,3), intent(in)  :: a
11201    !!----    real(kind=cp), dimension(3,3), intent(out) :: b
11202    !!----    integer                      , intent(out) :: ifail
11203    !!----                                                  0 = OK; 1 = Fail
11204    !!----
11205    !!----    Inverts a 3x3 Matrix
11206    !!----
11207    !!---- Update: February - 2005
11208    !!
11209    Subroutine Matrix_Inverse(a,b,ifail)
11210       !---- Argument ----!
11211       real(kind=cp), dimension(3,3), intent(in)  :: a
11212       real(kind=cp), dimension(3,3), intent(out) :: b
11213       integer                      , intent(out) :: ifail
11214
11215       !---- Local variables ----!
11216       real(kind=cp), parameter :: epso=1.0e-20
11217       real(kind=cp)            :: dmat
11218
11219       ifail=0
11220       call init_err_math3d()
11221
11222       b(1,1) = a(2,2)*a(3,3)-a(2,3)*a(3,2)
11223       b(2,1) = -(a(2,1)*a(3,3)-a(2,3)*a(3,1))
11224       b(3,1) = a(2,1)*a(3,2)-a(2,2)*a(3,1)
11225       b(1,2) = -(a(1,2)*a(3,3)-a(1,3)*a(3,2))
11226       b(2,2) = a(1,1)*a(3,3)-a(1,3)*a(3,1)
11227       b(3,2) = -(a(1,1)*a(3,2)-a(1,2)*a(3,1))
11228       b(1,3) = a(1,2)*a(2,3)-a(1,3)*a(2,2)
11229       b(2,3) = -(a(1,1)*a(2,3)-a(1,3)*a(2,1))
11230       b(3,3) = a(1,1)*a(2,2)-a(1,2)*a(2,1)
11231       dmat = a(1,1)*b(1,1)+a(1,2)*b(2,1)+a(1,3)*b(3,1)
11232
11233       if (abs(dmat) < epso) then
11234          ifail=1
11235          ERR_Math3D =.true.
11236          ERR_Math3D_Mess="Singular Matrix: inversion imposible"
11237          return
11238       end if
11239
11240       b = b/dmat
11241
11242       return
11243    End Subroutine Matrix_Inverse
11244
11245    !!----
11246    !!---- Subroutine Resolv_Sist_1X2(W,T,Ts,X,Ix)
11247    !!----    integer,       dimension(2),      intent(in) :: w     !  In -> Input vector
11248    !!----    real(kind=cp),                    intent(in) :: t     !  In -> Input value
11249    !!----    real(kind=cp), dimension(2),      intent(out):: ts    ! Out -> Fixed value of solution
11250    !!----    real(kind=cp), dimension(2),      intent(out):: x     ! Out -> Fixed value for x,y
11251    !!----    integer, dimension(2),            intent(out):: ix    ! Out -> determine if solution
11252    !!----                                                                   1: x, 2: y, 3: z
11253    !!--<<
11254    !!----              w11 x1 + w12 x2  = t1
11255    !!----              x_sol(i)= ts(i) + x(i) ix(i)
11256    !!-->>
11257    !!----
11258    !!---- Update: February - 2005
11259    !!
11260    Subroutine Resolv_Sist_1x2(w,t,ts,x,ix)
11261       !---- Arguments ----!
11262       integer,dimension(2), intent( in) :: w
11263       real(kind=cp),                 intent( in) :: t
11264       real(kind=cp), dimension(2),   intent(out) :: ts
11265       real(kind=cp), dimension(2),   intent(out) :: x
11266       integer,dimension(2), intent(out) :: ix
11267
11268       !---- Initialize ----!
11269       ts = 0.0
11270       x  = 1.0
11271       ix = 0
11272       call init_err_math3d()
11273
11274       !---- Both are zeros ----!
11275       if ( all(w == 0)) then
11276          if (abs(t) < eps) then
11277             ix(1)=1
11278             ix(2)=2
11279          else
11280             ERR_Math3D=.true.
11281             ERR_Math3D_Mess="Inconsistent solution (1x2)"
11282          end if
11283          return
11284       end if
11285
11286       !---- Any is zero ----!
11287       if (any(w == 0)) then
11288          if ( w(1) == 0 ) then
11289             ix(1)=1
11290             ts(2)=t/real(w(2))
11291              x(2)=0.0
11292          else
11293             ts(1)=t/real(w(1))
11294              x(1)=0.0
11295             ix(2)=2
11296          end if
11297       else
11298          ix(1)=1
11299          ts(2)=t/real(w(2))
11300           x(2)=-real(w(1))/real(w(2))
11301          ix(2)=1
11302       end if
11303
11304       return
11305    End Subroutine Resolv_Sist_1x2
11306
11307    !!----
11308    !!---- Subroutine Resolv_Sist_1X3(W,T,Ts,X,Ix)
11309    !!----    integer, dimension(3),            intent(in) :: w     !  In -> Input vector
11310    !!----    real(kind=cp),                    intent(in) :: t     !  In -> Input value
11311    !!----    real(kind=cp), dimension(3),      intent(out):: ts    ! Out -> Fixed value of solution
11312    !!----    real(kind=cp), dimension(3),      intent(out):: x     ! Out -> Fixed value for x,y,z
11313    !!----    integer, dimension(3),            intent(out):: ix    ! Out -> determine if solution
11314    !!----                                                                   1: x, 2: y, 3: z
11315    !!--<<
11316    !!----               w11 x1 + w12 x2 + w13 x3 = t1
11317    !!----               x_sol(i)= ts(i) + x(i) ix(i)
11318    !!-->>
11319    !!----
11320    !!---- Update: February - 2005
11321    !!
11322    Subroutine Resolv_Sist_1x3(w,t,ts,x,ix)
11323       !---- Arguments ----!
11324       integer,dimension(3), intent( in) :: w
11325       real(kind=cp),                 intent( in) :: t
11326       real(kind=cp), dimension(3),   intent(out) :: ts
11327       real(kind=cp), dimension(3),   intent(out) :: x
11328       integer,dimension(3), intent(out) :: ix
11329
11330       !---- Local Variables ----!
11331       integer               :: i, zeros
11332       integer, dimension(2) :: w1
11333       integer, dimension(2) :: ix1
11334       real(kind=cp), dimension(2)    :: ts1
11335       real(kind=cp), dimension(2)    :: x1
11336
11337       !---- Initialize ----!
11338       ts = 0.0
11339       x  = 1.0
11340       ix = 0
11341       call init_err_math3d()
11342
11343       !---- Are there zeros? ----!
11344       zeros=0
11345       do i=1,3
11346          if (w(i) == 0) zeros=zeros+1
11347       end do
11348       select case (zeros)
11349          case (3)
11350             if (abs(t) < eps) then
11351                do i=1,3
11352                   ix(i)=i
11353                end do
11354             else
11355                ERR_Math3D=.true.
11356                ERR_Math3D_Mess="Inconsistent solution (1 x 3)"
11357             end if
11358
11359          case (2)
11360             do i=1,3
11361                if (w(i) /= 0) then
11362                   ts(i)=t/real(w(i))
11363                   x(i) =0.0
11364                else
11365                   ix(i)=i
11366                end if
11367             end do
11368
11369          case (1)
11370             do i=1,3
11371                if (w(i) == 0) exit
11372             end do
11373             select case (i)
11374                case (1)
11375                   w1=w(2:3)
11376
11377                case (2)
11378                   w1(1)=w(1)
11379                   w1(2)=w(3)
11380
11381                case (3)
11382                   w1=w(1:2)
11383             end select
11384             call resolv_sist_1x2(w1,t,ts1,x1,ix1)
11385             select case (i)
11386                case (1)
11387                   ix(1)  = 1
11388                   ts(2:3)= ts1
11389                   x(2:3) = x1
11390                   if (ix1(1)==1) ix(2)=2
11391                   if (ix1(1)==2) ix(2)=3
11392                   if (ix1(2)==1) ix(3)=2
11393                   if (ix1(2)==2) ix(3)=3
11394
11395                  case (2)
11396                     ix(2)= 2
11397                     ts(1)= ts1(1)
11398                     ts(3)= ts1(2)
11399                     x(1) = x1(1)
11400                     x(3) = x1(2)
11401                     if (ix1(1)==1) ix(1)=1
11402                     if (ix1(1)==2) ix(1)=3
11403                     if (ix1(2)==1) ix(3)=1
11404                     if (ix1(2)==2) ix(3)=3
11405
11406                  case (3)
11407                     ix(3)  = 3
11408                     ts(1:2)= ts1
11409                     x(1:2) = x1
11410                     ix(1:2)= ix1
11411               end select
11412
11413          case (0)
11414             ERR_Math3D=.true.
11415             ERR_Math3D_Mess="Inconsistent case ax+by+cz=t (1x3)"
11416       end select
11417
11418       return
11419    End Subroutine Resolv_Sist_1x3
11420
11421    !!----
11422    !!---- Subroutine Resolv_Sist_2X2(W,T,Ts,X,Ix)
11423    !!----    integer, dimension(2,2),          intent(in) :: w     !  In -> Input vector
11424    !!----    real(kind=cp), dimension(2),      intent(in) :: t     !  In -> Input value
11425    !!----    real(kind=cp), dimension(2),      intent(out):: ts    ! Out -> Fixed value of solution
11426    !!----    real(kind=cp), dimension(2),      intent(out):: x     ! Out -> Fixed value for x,y
11427    !!----    integer, dimension(2),            intent(out):: ix    ! Out -> determine if solution
11428    !!----                                                                   1: x, 2: y, 3: z
11429    !!--<<
11430    !!----                 w11 x1 + w12 x2  = t1
11431    !!----                 w21 x1 + w22 x2  = t2
11432    !!----                 x_sol(i)= ts(i) + x(i) ix(i)
11433    !!-->>
11434    !!----
11435    !!---- Update: February - 2005
11436    !!
11437    Subroutine Resolv_Sist_2x2(w,t,ts,x,ix)
11438       !---- Arguments ----!
11439       integer,dimension(2,2), intent( in) :: w
11440       real(kind=cp),dimension(2),      intent( in) :: t
11441       real(kind=cp),dimension(2),      intent(out) :: ts
11442       real(kind=cp),dimension(2),      intent(out) :: x
11443       integer,dimension(2),   intent(out) :: ix
11444
11445       !---- Local Variables ----!
11446       integer                 :: i,deter
11447       integer, dimension(2)   :: zeros,colum
11448       real(kind=cp)           :: rden, rnum
11449
11450       !---- Initialize ----!
11451       ts    = 0.0
11452       x     = 1.0
11453       ix    = 0
11454       call init_err_math3d()
11455
11456       deter = w(1,1)*w(2,2) - w(1,2)*w(2,1)
11457       rden=real(deter)
11458       if (deter /= 0) then
11459          !---- X(1) ----!
11460          rnum=t(1)*w(2,2) - w(1,2)*t(2)
11461          ts(1)=rnum/rden
11462
11463          !---- X(2) ----!
11464          rnum=w(1,1)*t(2) - t(1)*w(2,1)
11465          ts(2)=rnum/rden
11466
11467          x =0.0
11468
11469       else                        ! Singular Matrix
11470          !---- Are there zero rows? ----!
11471          zeros=0
11472          do i=1,2
11473             if (w(i,1) == 0 .and. w(i,2) == 0 )  zeros(i)=1
11474          end do
11475          select case (sum(zeros))
11476             case (2)
11477                if (abs(t(1)) <= eps .and. abs(t(2)) <= eps) then
11478                   ix(1)=1
11479                   ix(2)=2
11480                else
11481                   ERR_Math3D=.true.
11482                   ERR_Math3D_Mess="Inconsistent solution (2x2)"
11483                end if
11484
11485             case (1)
11486                do i=1,2
11487                   if (zeros(i) == 0) exit
11488                end do
11489                call resolv_sist_1x2(w(i,:),t(i),ts,x,ix)
11490
11491             case (0)
11492                !---- Are there zero columns? ----!
11493                colum=0
11494                do i=1,2
11495                   if (w(1,i) == 0 .and. w(2,i) == 0 ) colum(i)=1
11496                end do
11497                select case (sum(colum))
11498                   case (1)
11499                      do i=1,2
11500                         if (colum(i) == 0) exit
11501                      end do
11502                      if (w(1,i) /= 0) then
11503                         ts(i)=t(1)/real(w(1,i))
11504                      else
11505                         ts(i)=t(2)/real(w(2,i))
11506                      end if
11507                      x(i)=0.0
11508                      if (i == 1) then
11509                         ix(2)=2
11510                      else
11511                         ix(1)=1
11512                      end if
11513
11514                   case (0)
11515                      call resolv_sist_1x2(w(1,:),t(1),ts,x,ix)
11516
11517                end select
11518          end select
11519       end if
11520
11521       return
11522    End Subroutine Resolv_Sist_2x2
11523
11524    !!----
11525    !!---- Subroutine Resolv_Sist_2X3(W,T,Ts,X,Ix)
11526    !!----    integer, dimension(2,3),          intent(in) :: w      !  In -> Input vector
11527    !!----    real(kind=cp), dimension(2),      intent(in) :: t      !  In -> Input value
11528    !!----    real(kind=cp), dimension(3),      intent(out):: ts     ! Out -> Fixed value of solution
11529    !!----    real(kind=cp), dimension(3),      intent(out):: x      ! Out -> Fixed value for x,y
11530    !!----    integer, dimension(3),            intent(out):: ix     ! Out -> determine if solution
11531    !!----                                                                    1: x, 2: y, 3: z
11532    !!----               w11 x1 + w12 x2 + w13 x3 = t1
11533    !!----               w21 x1 + w22 x2 + w23 x3 = t2
11534    !!----               x_sol(i)= ts(i) + x(i) ix(i)
11535    !!----
11536    !!----   Update: February - 2005
11537    !!
11538    Subroutine Resolv_Sist_2x3(w,t,ts,x,ix)
11539       !---- Arguments ----!
11540       integer,dimension(2,3),          intent( in) :: w
11541       real(kind=cp),dimension(2),      intent( in) :: t
11542       real(kind=cp),dimension(3),      intent(out) :: ts
11543       real(kind=cp),dimension(3),      intent(out) :: x
11544       integer,dimension(3),            intent(out) :: ix
11545
11546       !---- Local Variables ----!
11547       integer                 :: i, j
11548       integer, dimension(2)   :: fila
11549       integer, dimension(2)   :: ix1
11550       integer, dimension(3)   :: colum
11551       integer, dimension(2,2) :: w1
11552       integer, dimension(2,3) :: wm
11553       integer, dimension(2)   :: wc
11554       real(kind=cp)                    :: tc
11555       real(kind=cp), dimension(2)      :: tm
11556       real(kind=cp), dimension(2)      :: ts1, x1
11557
11558       !---- Initialize ----!
11559       ts    = 0.0
11560       x     = 1.0
11561       ix    = 0
11562       call init_err_math3d()
11563
11564       !---- Are there zero columns? ----!
11565       colum=0
11566       do i=1,3
11567            if (all(w(:,i) == 0)) colum(i)=1
11568       end do
11569       select case (sum(colum))
11570          case (3)
11571             if (abs(t(1)) <= eps .and. abs(t(2)) <= eps) then
11572                do i=1,3
11573                   ix(i)=i
11574                end do
11575             else
11576                ERR_Math3D=.true.
11577                ERR_Math3D_Mess="Inconsistent solution in (2x3)"
11578             end if
11579
11580          case (2)
11581             do i=1,3
11582                if (colum(i) == 0) exit
11583             end do
11584             if (w(1,i) /= 0) then
11585                ts(i)=t(1)/real(w(1,i))
11586             else
11587                ts(i)=t(2)/real(w(2,i))
11588             end if
11589             x(i)=0.0
11590             select case (i)
11591                case (1)
11592                   ix(2)=2
11593                   ix(3)=3
11594
11595                case (2)
11596                   ix(1)=1
11597                   ix(3)=3
11598
11599                case (3)
11600                   ix(1)=1
11601                   ix(2)=2
11602             end select
11603
11604          case (1)
11605             do i=1,3
11606                if (colum(i) == 1) exit
11607             end do
11608             select case (i)
11609                case (1)
11610                   w1=w(:,2:3)
11611
11612                case (2)
11613                   w1(1,1)=w(1,1)
11614                   w1(1,2)=w(1,3)
11615                   w1(2,1)=w(2,1)
11616                   w1(2,2)=w(2,3)
11617
11618                case (3)
11619                   w1=w(:,1:2)
11620             end select
11621             call resolv_sist_2x2(w1,t,ts1,x1,ix1)
11622             select case (i)
11623                case (1)
11624                   ix(1)  = 1
11625                   ts(2:3)= ts1
11626                   x (2:3)= x1
11627                   if (ix1(1) == 1) ix(2)=2
11628                   if (ix1(1) == 2) ix(2)=3
11629                   if (ix1(2) == 1) ix(3)=2
11630                   if (ix1(2) == 2) ix(3)=3
11631
11632                case (2)
11633                   ix(2)=2
11634                   ts(1)=ts1(1)
11635                   ts(3)=ts1(2)
11636                   x(1) = x1(1)
11637                   x(3) = x1(2)
11638                   if (ix1(1) == 1) ix(1)=1
11639                   if (ix1(1) == 2) ix(1)=3
11640                   if (ix1(2) == 1) ix(3)=1
11641                   if (ix1(2) == 2) ix(3)=3
11642
11643                case (3)
11644                   ix(3)  = 3
11645                   ts(1:2)= ts1
11646                   x (1:2)= x1
11647                   ix(1:2)= ix1
11648             end select
11649
11650          case (0)
11651             !---- Are there zeros in any element of rows? ----!
11652             fila = 0
11653             do i=1,2
11654                if (all(w(i,:)==0)) fila(i)=1
11655             end do
11656             select case (sum(fila))
11657                case (1)
11658                   if (w(1,1) /= 0) then
11659                      call resolv_sist_1x3(w(1,:),t(1),ts,x,ix)
11660                   else
11661                      call resolv_sist_1x3(w(2,:),t(2),ts,x,ix)
11662                   end if
11663
11664                case (0)
11665                   fila = 0
11666                   wm   = w
11667                   tm   = t
11668                   !---- Are there zeros in any element of rows? ----!
11669                   do i=1,2
11670                      do j=1,3
11671                         if (w(i,j)==0) fila(i)=fila(i)+1
11672                      end do
11673                   end do
11674                   if ( fila(2) > fila(1) ) then
11675                      wm(1,:)=w(2,:)
11676                      wm(2,:)=w(1,:)
11677                      tm(1)  =t(2)
11678                      tm(2)  =t(1)
11679                          j  =fila(1)
11680                      fila(1)=fila(2)
11681                      fila(2)=j
11682                   end if
11683                   select case (fila(1))
11684                      case (2)
11685                         do i=1,3
11686                            if (wm(1,i) /= 0) exit
11687                         end do
11688                         ts(i)=tm(1)/real(wm(1,i))
11689                         x(i)=0.0
11690                         select case (i)
11691                            case (1)
11692                               wc(1)=wm(2,2)
11693                               wc(2)=wm(2,3)
11694                               tc=tm(2)-(wm(2,1)*ts(i))
11695
11696                            case (2)
11697                               wc(1)=wm(2,1)
11698                               wc(2)=wm(2,3)
11699                               tc=tm(2)-(wm(2,2)*ts(i))
11700
11701                            case (3)
11702                               wc(1)=wm(2,1)
11703                               wc(2)=wm(2,2)
11704                               tc=tm(2)-(wm(2,3)*ts(i))
11705                         end select
11706                         call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11707                         select case(i)
11708                            case (1)
11709                               ts(2:3)=ts1
11710                                x(2:3)=x1
11711                                if (ix1(1)==1) ix(2)=2
11712                                if (ix1(1)==2) ix(2)=3
11713                                if (ix1(2)==1) ix(3)=2
11714                                if (ix1(2)==2) ix(3)=3
11715
11716                            case (2)
11717                               ts(1)=ts1(1)
11718                               ts(3)=ts1(2)
11719                                x(1)=x1(1)
11720                                x(3)=x1(2)
11721                                if (ix1(1)==1) ix(1)=1
11722                                if (ix1(1)==2) ix(1)=3
11723                                if (ix1(2)==1) ix(3)=1
11724                                if (ix1(2)==2) ix(3)=3
11725
11726                            case (3)
11727                               ts(1:2)=ts1
11728                                x(1:2)=x1
11729                               ix(1:2)=ix1
11730                         end select
11731
11732                      case (1)
11733                         do i=1,3
11734                            if (wm(1,i) == 0) exit
11735                         end do
11736                         select case (fila(2))
11737                            case (1)
11738                               do j=1,3
11739                                  if (wm(2,j) == 0) exit
11740                               end do
11741                               select case (i)
11742                                  case (1)             ! 0 en w(1,1)
11743                                     select case (j)
11744                                        case (2)
11745                                           wc(1)=-wm(2,1)/wm(2,3)
11746                                           wc(2)= wm(1,2)/wm(1,3)
11747                                           tc=tm(1)/real(wm(1,3)) - tm(2)/real(wm(2,3))
11748                                           call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11749                                           ts(1:2)=ts1
11750                                           x(1:2) =x1
11751                                           ix(1:2)=ix1
11752                                           if (ix(1) == 0) then
11753                                              ts(3)=tm(2)/real(wm(2,3)) - ts(1)*wm(2,1)/real(wm(2,3))
11754                                              x(3)=0.0
11755                                           else
11756                                              if (ix(2) == 0) then
11757                                                 ts(3)=tm(1)/real(wm(1,3)) - ts(2)*wm(1,2)/real(wm(1,3))
11758                                                 x(3)=0.0
11759                                              else
11760                                                 ts(3)=tm(2)/real(wm(2,3))
11761                                                 x(3)=-real(wm(2,1))/real(wm(2,3))
11762                                                 ix(3)=1
11763
11764                                                 ts(2)=tc/real(wc(2))
11765                                                 x(2) =-real(wc(1))/real(wc(2))
11766                                                 ix(2)=1
11767                                              end if
11768                                           end if
11769
11770                                        case (3)
11771                                           wc(1)=-wm(2,1)/wm(2,2)
11772                                           wc(2)= wm(1,3)/wm(1,2)
11773                                           tc=tm(1)/real(wm(1,2)) - tm(2)/real(wm(2,2))
11774                                           call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11775                                           ts(1)=ts1(1)
11776                                           ts(3)=ts1(2)
11777                                           x(1) =x1(1)
11778                                           x(3) =x1(2)
11779                                           if (ix1(1) == 1) ix(1)=1
11780                                           if (ix1(1) == 2) ix(1)=3
11781                                           if (ix1(2) == 1) ix(3)=1
11782                                           if (ix1(2) == 2) ix(3)=3
11783                                           if (ix(1) == 0) then
11784                                              ts(2)=tm(2)/real(wm(2,2)) - ts(1)*wm(2,1)/real(wm(2,2))
11785                                              x(2)=0.0
11786                                           else
11787                                              if (ix(3) == 0) then
11788                                                 ts(2)=tm(1)/real(wm(1,2)) - ts(3)*wm(1,3)/real(wm(1,2))
11789                                                 x(2)=0.0
11790                                              else
11791                                                 ts(2)=tm(2)/real(wm(2,2))
11792                                                 x(3)=-real(wm(2,1))/real(wm(2,2))
11793                                                 ix(2)=1
11794
11795                                                 ts(3)=tc/real(wc(2))
11796                                                 x(3) =-real(wc(1))/real(wc(2))
11797                                                 ix(3)=1
11798                                              end if
11799                                           end if
11800                                     end select
11801
11802                                  case (2)             ! 0 en w(1,2)
11803                                     select case (j)
11804                                        case (1)
11805                                           wc(1)= wm(1,1)/wm(1,3)
11806                                           wc(2)=-wm(2,2)/wm(2,3)
11807                                           tc=tm(1)/real(wm(1,3)) - tm(2)/real(wm(2,3))
11808                                           call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11809                                           ts(1:2)=ts1
11810                                           x(1:2) =x1
11811                                           ix(1:2)=ix1
11812                                           if (ix(1) == 0) then
11813                                              ts(3)=tm(1)/real(wm(1,3)) - ts(1)*wm(1,1)/real(wm(1,3))
11814                                              x(3)=0.0
11815                                           else
11816                                              if (ix(2) == 0) then
11817                                                 ts(3)=tm(2)/real(wm(2,3)) - ts(2)*wm(2,2)/real(wm(2,3))
11818                                                 x(3)=0.0
11819                                              else
11820                                                 ts(3)=tm(1)/real(wm(1,3))
11821                                                 x(3)=-real(wm(1,1))/real(wm(1,3))
11822                                                 ix(3)=1
11823
11824                                                 ts(2)=tc/real(wc(2))
11825                                                 x(2) = -real(wc(1))/real(wc(2))
11826                                                 ix(2)= 1
11827                                              end if
11828                                           end if
11829
11830                                        case (3)
11831                                           wc(1)=-wm(2,2)/wm(2,1)
11832                                           wc(2)= wm(1,3)/wm(1,1)
11833                                           tc=tm(1)/real(wm(1,1)) - tm(2)/real(wm(2,1))
11834                                           call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11835                                           ts(2:3)=ts1
11836                                           x(2:3) =x1
11837                                           if (ix1(1) == 1) ix(2)=2
11838                                           if (ix1(1) == 2) ix(2)=3
11839                                           if (ix1(2) == 1) ix(3)=2
11840                                           if (ix1(2) == 2) ix(3)=3
11841                                           if (ix(2) == 0) then
11842                                              ts(1)=tm(2)/real(wm(2,1)) - ts(2)*wm(2,2)/real(wm(2,1))
11843                                              x(1)=0.0
11844                                           else
11845                                              if (ix(3) == 0) then
11846                                                 ts(1)=tm(1)/real(wm(1,1)) - ts(3)*wm(1,3)/real(wm(1,1))
11847                                                 x(1)=0.0
11848                                              else
11849                                                 ix(1)=1
11850
11851                                                 ts(2)=tm(2)/real(wm(2,2))
11852                                                 x(2) =-real(wm(2,1))/real(wm(2,2))
11853                                                 ix(2)=1
11854
11855                                                 ts(3)=tm(1)/real(wm(1,3))
11856                                                 x(3) =-real(wm(1,1))/real(wm(1,3))
11857                                                 ix(3)=1
11858                                              end if
11859                                           end if
11860                                     end select
11861
11862                                  case (3)             ! 0 en w(1,3)
11863                                     select case (j)
11864                                        case (1)
11865                                           wc(1)= wm(1,1)/wm(1,2)
11866                                           wc(2)=-wm(2,3)/wm(2,2)
11867                                           tc=tm(1)/real(wm(1,2)) - tm(2)/real(wm(2,2))
11868                                           call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11869                                           ts(1)=ts1(1)
11870                                           ts(3)=ts1(2)
11871                                           x(1) =x1(1)
11872                                           x(3) =x1(2)
11873                                           if (ix1(1) == 1) ix(1)=1
11874                                           if (ix1(1) == 2) ix(1)=3
11875                                           if (ix1(2) == 1) ix(3)=1
11876                                           if (ix1(2) == 2) ix(3)=3
11877                                           if (ix(1) == 0) then
11878                                              ts(2)=tm(1)/real(wm(1,2)) - ts(1)*wm(1,1)/real(wm(1,2))
11879                                              x(2)=0.0
11880                                           else
11881                                              if (ix(3) == 0) then
11882                                                 ts(2)=tm(2)/real(wm(2,2)) - ts(3)*wm(2,3)/real(wm(2,2))
11883                                                 x(2)=0.0
11884                                              else
11885                                                 ts(2)=tm(1)/real(wm(1,2))
11886                                                 x(2) =-real(wm(1,1))/real(wm(1,2))
11887                                                 ix(2)=1
11888
11889                                                 ts(3)=tc/real(wc(2))
11890                                                 x(3) =-real(wc(1))/real(wc(2))
11891                                                 ix(3)=1
11892                                              end if
11893                                           end if
11894
11895                                        case (2)
11896                                           wc(1)= wm(1,2)/wm(1,1)
11897                                           wc(2)=-wm(2,3)/wm(2,1)
11898                                           tc=tm(1)/real(wm(1,1)) - tm(2)/real(wm(2,1))
11899                                           call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11900                                           ts(2:3)=ts1
11901                                           x(2:3) =x1
11902                                           if (ix1(1) == 1) ix(2)=2
11903                                           if (ix1(1) == 2) ix(2)=3
11904                                           if (ix1(2) == 1) ix(3)=2
11905                                           if (ix1(2) == 2) ix(3)=3
11906                                           if (ix(2) == 0) then
11907                                              ts(1)=tm(1)/real(wm(1,1)) - ts(2)*wm(1,2)/real(wm(1,1))
11908                                              x(1)=0.0
11909                                           else
11910                                              if (ix(3) == 0) then
11911                                                 ts(1)=tm(2)/real(wm(2,1)) - ts(3)*wm(2,3)/real(wm(2,1))
11912                                                 x(1)=0.0
11913                                              else
11914                                                 ix(1)=1
11915
11916                                                 ts(2)=tm(1)/real(wm(1,2))
11917                                                 x(2) =-real(wm(1,1))/real(wm(1,2))
11918                                                 ix(2)=1
11919
11920                                                 ts(3)=tm(2)/real(wm(2,3))
11921                                                 x(3) =-real(wm(2,1))/real(wm(2,3))
11922                                                 ix(3)=1
11923                                              end if
11924                                           end if
11925                                     end select
11926                               end select
11927
11928                            case (0)
11929                               select case (i)
11930                                  case (1)
11931                                     wc(1)=wm(2,1)
11932                                     wc(2)=wm(2,2)- wm(2,3)*wm(1,2)/wm(1,3)
11933                                     tc=tm(2)-tm(1)*wm(2,3)/real(wm(1,3))
11934                                     call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11935                                     ts(1:2)=ts1
11936                                     x(1:2)=x1
11937                                     ix(1:2)=ix1
11938                                     if (ix(2) == 0) then
11939                                        ts(3)=tm(1)/real(wm(1,3)) - ts(2)*real(wm(1,2))/real(wm(1,3))
11940                                        x(3)=0.0
11941                                     else
11942                                        ix(1)=1
11943
11944                                        ts(2)=(tm(2) - tm(1)*wm(2,3)/real(wm(1,3))) / &
11945                                              (real(wm(2,2)) - real(wm(2,3)*wm(1,2))/real(wm(1,3)) )
11946                                        x(2) =-real(wm(2,1)) / &
11947                                              (real(wm(2,2)) - real(wm(2,3)*wm(1,2))/real(wm(1,3)) )
11948                                        ix(2)=1
11949
11950                                        ts(3)= tm(1)/real(wm(1,3)) - (real(wm(1,2))/real(wm(1,3)))*ts(2)
11951                                        x(3) =- (real(wm(1,2))/real(wm(1,3)))*x(2)
11952                                        ix(3)=1
11953                                     end if
11954
11955                                  case (2)
11956                                     wc(1)=wm(2,1)-wm(2,3)*wm(1,1)/wm(1,3)
11957                                     wc(2)=wm(2,2)
11958                                     tc=tm(2)-tm(1)*wm(2,3)/real(wm(1,3))
11959                                     call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11960                                    ts(1:2)=ts1
11961                                    x(1:2)=x1
11962                                    ix(1:2)=ix1
11963                                    if (ix(1) == 0) then
11964                                       ts(3)=tm(1)/real(wm(1,3)) - ts(1)*real(wm(1,1))/real(wm(1,3))
11965                                       x(3)=0.0
11966                                    else
11967                                       ix(1)=1
11968
11969                                       ts(2)=(tm(2) - tm(1)*wm(2,3)/real(wm(1,3)))/real(wm(2,2))
11970                                       x(2) =(real(wm(1,1)*wm(2,3))/real(wm(1,3)) - real(wm(2,1)))/real(wm(2,2))
11971                                       ix(2)=1
11972
11973                                       ts(3)=tm(1)/real(wm(1,3))
11974                                       x(3) =-real(wm(1,1))/real(wm(1,3))
11975                                       ix(3)=1
11976                                    end if
11977
11978                                 case (3)
11979                                    wc(1)=wm(2,1)-wm(1,1)*wm(2,2)/wm(1,2)
11980                                    wc(2)=wm(2,3)
11981                                    tc=tm(2)-tm(1)*wm(2,2)/real(wm(1,2))
11982                                    call resolv_sist_1x2(wc,tc,ts1,x1,ix1)
11983                                    ts(1)=ts1(1)
11984                                    ts(3)=ts1(2)
11985                                    x(1)=x1(1)
11986                                    x(3)=x1(2)
11987                                    if (ix1(1) == 1) ix(1)=1
11988                                    if (ix1(1) == 2) ix(1)=3
11989                                    if (ix1(2) == 1) ix(3)=1
11990                                    if (ix1(2) == 2) ix(3)=3
11991                                    if (ix(1) == 0) then
11992                                       ts(2)=tm(1)/real(wm(1,2)) - ts(1)*real(wm(1,1))/real(wm(1,2))
11993                                       x(2)=0.0
11994                                    else
11995                                       ix(1) =1
11996
11997                                       ts(2)=tm(1)/real(wm(1,2))
11998                                       x(2) =-real(wm(1,1))/real(wm(1,2))
11999                                       ix(2)=1
12000
12001                                       ts(3)=(tm(2) - tm(1)*wm(2,2)/real(wm(1,2)))/real(wm(2,3))
12002                                       x(3) =(real(wm(1,1)*wm(2,2))/real(wm(1,2)) - real(wm(2,1)))/real(wm(2,3))
12003                                       ix(3)=1
12004                                    end if
12005                               end select
12006                         end select
12007
12008                      case (0)
12009                         call resolv_sist_1x3(wm(1,:),tm(1),ts,x,ix)
12010                   end select
12011
12012             end select
12013       end select
12014
12015       return
12016    End Subroutine Resolv_Sist_2x3
12017
12018    !!----
12019    !!---- Subroutine Resolv_Sist_3X3(W,T,Ts,X,Ix)
12020    !!----    integer, dimension(3,3),          intent(in) :: w      !  In -> Input vector
12021    !!----    real(kind=cp), dimension(3),      intent(in) :: t      !  In -> Input value
12022    !!----    real(kind=cp), dimension(3),      intent(out):: ts     ! Out -> Fixed value of solution
12023    !!----    real(kind=cp), dimension(3),      intent(out):: x      ! Out -> Fixed value for x,y
12024    !!----    integer, dimension(3),            intent(out):: ix     ! Out -> determine if solution
12025    !!----                                                                     1: x, 2: y, 3: z
12026    !!--<<
12027    !!----              w11 x1 + w12 x2 + w13 x3 = t1
12028    !!----              w21 x1 + w22 x2 + w23 x3 = t2
12029    !!----              w31 x1 + w32 x2 + w33 x3 = t3
12030    !!----              x_sol(i)= ts(i) + x(i) ix(i)
12031    !!-->>
12032    !!----
12033    !!---- Update: February - 2005
12034    !!
12035    Subroutine Resolv_Sist_3x3(w,t,ts,x,ix)
12036       !---- Arguments ----!
12037       integer, dimension(3,3),          intent(in) :: w
12038       real(kind=cp), dimension(3),      intent(in) :: t
12039       real(kind=cp), dimension(3),      intent(out):: ts
12040       real(kind=cp), dimension(3),      intent(out):: x
12041       integer, dimension(3),            intent(out):: ix
12042
12043       !---- Local variables ----!
12044       integer                 :: i,j,deter
12045       integer, dimension(3)   :: fila
12046       integer, dimension(3,3) :: w1
12047       integer, dimension(2,3) :: wm
12048       real(kind=cp)                    :: rnum, rden
12049       real(kind=cp), dimension(3)      :: t1
12050       real(kind=cp), dimension(2)      :: tm
12051       real(kind=cp),dimension(3,3)     :: rw
12052
12053       !---- Initialize ----!
12054       ts  = 0.0
12055       x   = 1.0
12056       ix  = 0
12057       call init_err_math3d()
12058
12059       deter=determ_a(w)
12060       rden=real(deter)
12061
12062       if (deter /= 0) then
12063          !---- X(1) ----!
12064          rw=real(w)
12065          rw(:,1)=t
12066          rnum=determ_a(rw)
12067          ts(1)=rnum/rden
12068
12069          !---- X(2) ----!
12070          rw=real(w)
12071          rw(:,2)=t
12072          rnum=determ_a(rw)
12073          ts(2)=rnum/rden
12074
12075          !---- X(3) ----!
12076          rw=real(w)
12077          rw(:,3)=t
12078          rnum=determ_a(rw)
12079          ts(3)=rnum/rden
12080
12081          x=0.0
12082
12083       else                     !  Singular Matrix
12084          !---- Are there zero rows? ----!
12085          fila=0
12086          do i=1,3
12087             if (all(w(i,:) == 0)) fila(i)=1
12088          end do
12089          select case (sum(fila))
12090             !---- All values are zeros ----!
12091             case (3)
12092                if (all(abs(t) < eps)) then
12093                   do i=1,3
12094                      ix(i)=i
12095                   end do
12096                else
12097                   ERR_Math3D=.true.
12098                   ERR_Math3D_Mess="Inconsistent system (3 x 3)"
12099                end if
12100
12101             !---- Two rows with zeroes ----!
12102             case (2)
12103                do i=1,3
12104                   if (fila(i) == 0) exit
12105                end do
12106                call resolv_sist_1x3(w(i,:),t(i),ts,x,ix)
12107
12108             !---- One row with zeroes ----!
12109             case (1)
12110                do i=1,3
12111                   if (fila(i) == 1) exit
12112                end do
12113                select case(i)
12114                   case (1)
12115                      wm(1,:)=w(2,:)
12116                      wm(2,:)=w(3,:)
12117                      tm=t(2:3)
12118
12119                   case (2)
12120                      wm(1,:)=w(1,:)
12121                      wm(2,:)=w(3,:)
12122                      tm(1)=t(1)
12123                      tm(2)=t(3)
12124
12125                   case (3)
12126                      wm(1,:)=w(1,:)
12127                      wm(2,:)=w(2,:)
12128                      tm=t(1:2)
12129
12130                end select
12131                call resolv_sist_2x3(wm,tm,ts,x,ix)
12132
12133             !---- Non zero rows ----!
12134             case (0)
12135                w1=w
12136                t1=t
12137
12138                !---- Are there 2 rows proportional? ----!
12139                do i=1,3
12140                   if ( abs(w1(1,i)) > abs(w1(2,i)) ) then
12141                      if (w1(2,i) /= 0) then
12142                         j=w1(1,i)/w1(2,i)
12143                      else
12144                         j=0
12145                      end if
12146                      if (j /= 0) then
12147                         if (j*w1(2,1) == w1(1,1) .and. j*w1(2,2) == w1(1,2) .and. &
12148                             j*w1(2,3) == w1(1,3) ) then
12149                            w1(1,:)=w1(2,:)
12150                            t1(1)  =t1(2)
12151                            exit
12152                         end if
12153                      end if
12154                   else
12155                      if (w1(1,i) /= 0) then
12156                         j=w1(2,i)/w1(1,i)
12157                      else
12158                         j=0
12159                      end if
12160                      if (j /= 0) then
12161                         if (j*w1(1,1) == w1(2,1) .and. j*w1(1,2) == w1(2,2) .and. &
12162                             j*w1(1,3) == w1(2,3) ) then
12163                            w1(2,:)=w1(1,:)
12164                            t1(2)  =t1(1)
12165                            exit
12166                         end if
12167                      end if
12168                   end if
12169                end do
12170
12171                do i=1,3
12172                   if ( abs(w1(1,i)) > abs(w1(3,i)) ) then
12173                      if (w1(3,i) /= 0) then
12174                         j=w1(1,i)/w1(3,i)
12175                      else
12176                         j=0
12177                      end if
12178                      if (j /= 0) then
12179                         if (j*w1(3,1) == w1(1,1) .and. j*w1(3,2) == w1(1,2) .and. &
12180                             j*w1(3,3) == w1(1,3) ) then
12181                            w1(1,:)=w1(3,:)
12182                            t1(1)  =t1(3)
12183                            exit
12184                         end if
12185                      end if
12186                   else
12187                      if (w1(1,i) /= 0) then
12188                         j=w1(3,i)/w1(1,i)
12189                      else
12190                         j=0
12191                      end if
12192                      if (j /= 0) then
12193                         if (j*w1(1,1) == w1(3,1) .and. j*w1(1,2) == w1(3,2) .and. &
12194                             j*w1(1,3) == w1(3,3) ) then
12195                            w1(3,:)=w1(1,:)
12196                            t1(3)  =t1(1)
12197                            exit
12198                         end if
12199                      end if
12200                   end if
12201                end do
12202
12203                do i=1,3
12204                   if ( abs(w1(2,i)) > abs(w1(3,i)) ) then
12205                      if (w1(3,i) /= 0) then
12206                         j=w1(2,i)/w1(3,i)
12207                      else
12208                         j=0
12209                      end if
12210                      if (j /= 0) then
12211                         if (j*w1(3,1) == w1(2,1) .and. j*w1(3,2) == w1(2,2) .and. &
12212                             j*w1(3,3) == w1(2,3) ) then
12213                            w1(2,:)=w1(3,:)
12214                            t1(2)  =t1(3)
12215                            exit
12216                         end if
12217                      end if
12218                   else
12219                      if (w1(2,i) /= 0) then
12220                         j=w1(3,i)/w1(2,i)
12221                      else
12222                         j=0
12223                      end if
12224                      if (j /= 0) then
12225                         if (j*w1(2,1) == w1(3,1) .and. j*w1(2,2) == w1(3,2) .and. &
12226                             j*w1(2,3) == w1(3,3) ) then
12227                            w1(3,:)=w1(2,:)
12228                            t1(3)  =t1(2)
12229                            exit
12230                         end if
12231                      end if
12232                   end if
12233                end do
12234
12235                !---- Are there 3 rows equal? ----!
12236                if ( (w1(1,1) == w1(2,1)) .and. (w1(1,1) == w1(3,1)) .and. &
12237                     (w1(1,2) == w1(2,2)) .and. (w1(1,2) == w1(3,2)) .and. &
12238                     (w1(1,3) == w1(2,3)) .and. (w1(1,3) == w1(3,3)) ) then
12239
12240                   call resolv_sist_1x3(w1(1,:),t1(1),ts,x,ix)
12241
12242                !---- Are there 2 rows equal? ----!
12243                elseif( (w1(1,1) == w1(2,1)) .and. (w1(1,2) == w1(2,2)) .and. &
12244                        (w1(1,3) == w1(2,3)) ) then
12245
12246                   call resolv_sist_2x3(w1(2:3,:),t1(2:3),ts,x,ix)
12247
12248                elseif( (w1(1,1) == w1(3,1)) .and. (w1(1,2) == w1(3,2)) .and. &
12249                        (w1(1,3) == w1(3,3)) ) then
12250
12251                   call resolv_sist_2x3(w1(1:2,:),t1(1:2),ts,x,ix)
12252
12253                elseif( (w1(2,1) == w1(3,1)) .and. (w1(2,2) == w1(3,2)) .and. &
12254                        (w1(2,3) == w1(3,3)) ) then
12255
12256                   call resolv_sist_2x3(w1(1:2,:),t1(1:2),ts,x,ix)
12257
12258                !---- Are linear combinations? ----!
12259                else
12260                   call resolv_sist_2x3(w1(1:2,:),t1(1:2),ts,x,ix)
12261
12262                end if
12263
12264          end select
12265       end if
12266
12267       return
12268    End Subroutine Resolv_Sist_3x3
12269
12270 End Module CFML_Math_3D
12271!!-------------------------------------------------------
12272!!---- Crystallographic Fortran Modules Library (CrysFML)
12273!!-------------------------------------------------------
12274!!---- The CrysFML project is distributed under LGPL. In agreement with the
12275!!---- Intergovernmental Convention of the ILL, this software cannot be used
12276!!---- in military applications.
12277!!----
12278!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
12279!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
12280!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
12281!!----
12282!!---- Authors: Juan Rodriguez-Carvajal (ILL)
12283!!----          Javier Gonzalez-Platas  (ULL)
12284!!----
12285!!---- Contributors: Laurent Chapon     (ILL)
12286!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
12287!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
12288!!----               Tierry Roisnel     (CDIFX,Rennes France)
12289!!----               Eric Pellegrini    (ILL)
12290!!----
12291!!---- This library is free software; you can redistribute it and/or
12292!!---- modify it under the terms of the GNU Lesser General Public
12293!!---- License as published by the Free Software Foundation; either
12294!!---- version 3.0 of the License, or (at your option) any later version.
12295!!----
12296!!---- This library is distributed in the hope that it will be useful,
12297!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
12298!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12299!!---- Lesser General Public License for more details.
12300!!----
12301!!---- You should have received a copy of the GNU Lesser General Public
12302!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
12303!!----
12304!!----
12305!!---- MODULE: CFML_Symmetry_Tables
12306!!----   INFO: Tabulated information on Crystallographic Symmetry
12307!!----
12308!!---- HISTORY
12309!!----    Update: 04/03/2011
12310!!----
12311!!----
12312!!---- DEPENDENCIES
12313!!--++    Use CFML_GlobalDeps,       only: cp
12314!!--++    Use CFML_String_Utilities, only: U_case
12315!!----
12316!!---- VARIABLES
12317!!----    BC_D6H
12318!!----    BC_OH
12319!!----    DEPMAT
12320!!----    ERR_SYMTAB
12321!!----    ERR_SYMTAB_MESS
12322!!--++    IT_SET                       [Private]
12323!!----    INTSYMD6H
12324!!----    INTSYMOH
12325!!----    KOV_D6H
12326!!----    KOV_OH
12327!!----    LATT
12328!!----    LAUE_CLASS
12329!!----    LTR_A
12330!!----    LTR_B
12331!!----    LTR_C
12332!!----    LTR_F
12333!!----    LTR_I
12334!!----    LTR_R
12335!!----    MAGMAT
12336!!----    ML_D6H
12337!!----    ML_OH
12338!!----    MOD6
12339!!----    POINT_GROUP
12340!!--++    SPG_GEN                      [Private]
12341!!----    SPGR_INFO_TYPE
12342!!----    SPGR_INFO
12343!!----    SYS_CRY
12344!!----    TABLE_EQUIV_TYPE
12345!!----    SYSTEM_EQUIV
12346!!----    WYCK_INFO_TYPE
12347!!----    WYCKOFF_INFO
12348!!----    X_D6H
12349!!----    X_OH
12350!!----    ZAK_D6H
12351!!----    ZAK_OH
12352!!----
12353!!---- PROCEDURES
12354!!----    Functions:
12355!!----
12356!!----    Subroutines:
12357!!----       GET_GENERATORS
12358!!----       REMOVE_SPGR_INFO
12359!!----       REMOVE_SYSTEM_EQUIV
12360!!----       REMOVE_WYCKOFF_INFO
12361!!--++       SET_IT_GEN                [Private]
12362!!----       SET_SPGR_INFO
12363!!----       SET_SYSTEM_EQUIV
12364!!----       SET_WYCKOFF_INFO
12365!!----
12366!!
12367 Module CFML_Symmetry_Tables
12368    !---- Use modules ----!
12369    Use CFML_GlobalDeps,        only: cp
12370    Use CFML_String_Utilities, only: U_Case
12371
12372    !---- Variables ----!
12373    implicit none
12374
12375    private
12376
12377    !---- List of public subroutines ----!
12378    public :: get_generators
12379    public :: set_spgr_info, set_system_equiv, set_wyckoff_info
12380    public :: remove_spgr_info, remove_system_equiv, remove_wyckoff_info
12381
12382    !---- List of private subroutines ----!
12383    private :: set_IT_gen
12384
12385    !---- Definitions ----!
12386
12387    !!----
12388    !!---- BC_D6H
12389    !!----    character (len=*), dimension(24), parameter, public :: BC_D6h
12390    !!----
12391    !!----    Bradley & Cracknell Notation
12392    !!----
12393    !!---- Update: February - 2005
12394    !!
12395    character (len=*), dimension(24), parameter, public  :: BC_D6h =(/                  &
12396       "  E  "," C+_3"," C-_3"," C_2 "," C-_6"," C+_6","C'_23","C'_21","C'_22", &
12397       "C`_23","C`_21","C`_22","  I  "," S-_6"," S+_6"," s_h "," S+_3"," S-_3", &
12398       " s_v3"," s_v1"," s_v2"," s_d3"," s_d1"," s_d2" /)
12399
12400    !!----
12401    !!---- BC_OH
12402    !!----    character(len=*), dimension(48), parameter, public :: BC_Oh
12403    !!----
12404    !!----    Bradley & Cracknell Notation
12405    !!----
12406    !!---- Update: February - 2005
12407    !!
12408    character(len=*), dimension(48), parameter, public :: BC_Oh =(/             &
12409       "  E  "," C_2z"," C_2y"," C_2x","C+_31","C+_34","C+_33","C+_32","C-_31", &
12410       "C-_33","C-_32","C-_34"," C_2a"," C_2b","C-_4z","C+_4z","C-_4x"," C_2d", &
12411       " C_2f","C+_4x","C+_4y"," C_2c","C-_4y"," C_2e","  I  "," s_z "," s_y ", &
12412       " s_x ","S-_61","S-_64","S-_63","S-_62","S+_61","S+_63","S+_62","S+_64", &
12413       " s_da"," s_db","S+_4z","S-_4z","S+_4x"," s_dd"," s_df","S-_4x","S-_4y", &
12414       " s_dc","S+_4y"," s_de"  /)
12415
12416    !!----
12417    !!---- DEPMAT
12418    !!----    character(len=*), dimension(72), parameter, public :: Depmat
12419    !!----
12420    !!----    Magnetic array
12421    !!----
12422    !!---- Update: February - 2005
12423    !!
12424    character(len=*), dimension(72), parameter, public :: Depmat = (/       &
12425       "( Dx, Dy, Dz)      ","(-Dx,-Dy, Dz)      ","(-Dx, Dy,-Dz)      ",   &
12426       "( Dx,-Dy,-Dz)      ","( Dz, Dx, Dy)      ","( Dz,-Dx,-Dy)      ",   &
12427       "(-Dz,-Dx, Dy)      ","(-Dz, Dx,-Dy)      ","( Dy, Dz, Dx)      ",   &
12428       "(-Dy, Dz,-Dx)      ","( Dy,-Dz,-Dx)      ","(-Dy,-Dz, Dx)      ",   &
12429       "( Dy, Dx,-Dz)      ","(-Dy,-Dx,-Dz)      ","( Dy,-Dx, Dz)      ",   &
12430       "(-Dy, Dx, Dz)      ","( Dx, Dz,-Dy)      ","(-Dx, Dz, Dy)      ",   &
12431       "(-Dx,-Dz,-Dy)      ","( Dx,-Dz, Dy)      ","( Dz, Dy,-Dx)      ",   &
12432       "( Dz,-Dy, Dx)      ","(-Dz, Dy, Dx)      ","(-Dz,-Dy,-Dx)      ",   &
12433       "(-Dx,-Dy,-Dz)      ","( Dx, Dy,-Dz)      ","( Dx,-Dy, Dz)      ",   &
12434       "(-Dx, Dy, Dz)      ","(-Dz,-Dx,-Dy)      ","(-Dz, Dx, Dy)      ",   &
12435       "( Dz, Dx,-Dy)      ","( Dz,-Dx, Dy)      ","(-Dy,-Dz,-Dx)      ",   &
12436       "( Dy,-Dz, Dx)      ","(-Dy, Dz, Dx)      ","( Dy, Dz,-Dx)      ",   &
12437       "(-Dy,-Dx, Dz)      ","( Dy, Dx, Dz)      ","(-Dy, Dx,-Dz)      ",   &
12438       "( Dy,-Dx,-Dz)      ","(-Dx,-Dz, Dy)      ","( Dx,-Dz,-Dy)      ",   &
12439       "( Dx, Dz, Dy)      ","(-Dx, Dz,-Dy)      ","(-Dz,-Dy, Dx)      ",   &
12440       "(-Dz, Dy,-Dx)      ","( Dz,-Dy,-Dx)      ","( Dz, Dy, Dx)      ",   &
12441       "( Dx   ,    Dy, Dz)","(   -Dy, Dx-Dy, Dz)","(-Dx+Dy,-Dx   , Dz)",   &
12442       "(-Dx   ,   -Dy, Dz)","(    Dy,-Dx+Dy, Dz)","( Dx-Dy, Dx   , Dz)",   &
12443       "(    Dy, Dx   ,-Dz)","( Dx-Dy,   -Dy,-Dz)","(-Dx   ,-Dx+Dy,-Dz)",   &
12444       "(   -Dy,-Dx   ,-Dz)","(-Dx+Dy,    Dy,-Dz)","( Dx   , Dx-Dy,-Dz)",   &
12445       "(-Dx   ,   -Dy,-Dz)","(    Dy,-Dx+Dy,-Dz)","( Dx-Dy, Dx   ,-Dz)",   &
12446       "( Dx   ,    Dy,-Dz)","(   -Dy, Dx-Dy,-Dz)","(-Dx+Dy,-Dx   ,-Dz)",   &
12447       "(   -Dy,-Dx   , Dz)","(-Dx+Dy,    Dy, Dz)","( Dx   , Dx-Dy, Dz)",   &
12448       "(    Dy, Dx   , Dz)","( Dx-Dy,   -Dy, Dz)","(-Dx   ,-Dx+Dy, Dz)"   /)
12449
12450    !!----
12451    !!---- ERR_SYMTAB
12452    !!----    logical, public :: Err_Symtab
12453    !!----
12454    !!----    Logical Variable to indicate an error on this module.
12455    !!----
12456    !!---- Update: January - 2005
12457    !!
12458    logical, public :: ERR_Symtab=.false.
12459
12460    !!----
12461    !!---- ERR_SYMTAB_MESS
12462    !!----    character(len=150), public :: ERR_SymTab_Mess
12463    !!----
12464    !!----    String containing information about the last error
12465    !!----
12466    !!---- Update: February - 2005
12467    !!
12468    character(len=150), public :: ERR_SymTab_Mess=" "
12469
12470    !!--++
12471    !!--++ IT_SET
12472    !!--++    logical, private :: it_set=.false.
12473    !!--++
12474    !!--++    (PRIVATE)
12475    !!--++    Variable to test if generators have been set
12476    !!--++
12477    !!--++ Update: February - 2005
12478    !!
12479    logical, private :: it_set=.false.
12480
12481    !!----
12482    !!---- INTSYMD6H
12483    !!----    character(len=* ), dimension(24), parameter, public:: IntSymD6h
12484    !!----
12485    !!----    International Symbols For Point Group Elements Of 6/mmm (D6h)
12486    !!----
12487    !!---- Update: February - 2005
12488    !!
12489    character(len=* ), dimension(24), parameter, public :: IntSymD6h =(/     &
12490       "  1           "," 3+ ( 0, 0, z)"," 3- ( 0, 0, z)","  2 ( 0, 0, z)",  &
12491       " 6- ( 0, 0, z)"," 6+ ( 0, 0, z)","  2 ( x, x, 0)","  2 ( x, 0, 0)",  &
12492       "  2 ( 0, y, 0)","  2 ( x,-x, 0)","  2 ( x,2x, 0)","  2 (2x, x, 0)",  &
12493       " -1           ","-3+ ( 0, 0, z)","-3- ( 0, 0, z)","  m ( x, y, 0)",  &
12494       "-6- ( 0, 0, z)","-6+ ( 0, 0, z)","  m ( x,-x, z)","  m ( x,2x, z)",  &
12495       "  m (2x, x, z)","  m ( x, x, z)","  m ( x, 0, z)","  m ( 0, y, z)"   /)
12496
12497    !!----
12498    !!---- INTSYMOH
12499    !!----    character(len=* ), dimension(48), parameter, public :: IntSymOh
12500    !!----
12501    !!----    International Symbols For Point Group Elements Of M3M (Oh)
12502    !!----
12503    !!---- Update: February - 2005
12504    !!
12505    character(len=* ), dimension(48), parameter, public :: IntSymOh = (/     &
12506       "  1           ","  2 ( 0, 0, z)","  2 ( 0, y, 0)","  2 ( x, 0, 0)",  &
12507       " 3+ ( x, x, x)"," 3+ (-x, x,-x)"," 3+ ( x,-x,-x)"," 3+ (-x,-x, x)",  &
12508       " 3- ( x, x, x)"," 3- ( x,-x,-x)"," 3- (-x,-x, x)"," 3- (-x, x,-x)",  &
12509       "  2 ( x, x, 0)","  2 ( x,-x, 0)"," 4- ( 0, 0, z)"," 4+ ( 0, 0, z)",  &
12510       " 4- ( x, 0, 0)","  2 ( 0, y, y)","  2 ( 0, y,-y)"," 4+ ( x, 0, 0)",  &
12511       " 4+ ( 0, y, 0)","  2 ( x, 0, x)"," 4- ( 0, y, 0)","  2 (-x, 0, x)",  &
12512       " -1           ","  m ( x, y, 0)","  m ( x, 0, z)","  m ( 0, y, z)",  &
12513       "-3+ ( x, x, x)","-3+ (-x, x,-x)","-3+ ( x,-x,-x)","-3+ (-x,-x, x)",  &
12514       "-3- ( x, x, x)","-3- ( x,-x,-x)","-3- (-x,-x, x)","-3- (-x, x,-x)",  &
12515       "  m ( x,-x, z)","  m ( x, x, z)","-4- ( 0, 0, z)","-4+ ( 0, 0, z)",  &
12516       "-4- ( x, 0, 0)","  m ( x, y,-y)","  m ( x, y, y)","-4+ ( x, 0, 0)",  &
12517       "-4+ ( 0, y, 0)","  m (-x, y, x)","-4- ( 0, y, 0)","  m ( x, y, x)"   /)
12518
12519    !!----
12520    !!---- KOV_D6H
12521    !!----    character(len=*), dimension(24), parameter, public :: Kov_D6h
12522    !!----
12523    !!----    Kovalev Notation
12524    !!----
12525    !!---- Update: February - 2005
12526    !!
12527    character(len=*), dimension(24), parameter, public :: Kov_d6h=(/       &
12528       " h1"," h3"," h5"," h4"," h6"," h2","h11"," h9"," h7"," h8","h12",  &
12529       "h10","h13","h15","h17","h16","h18","h14","h23",                    &
12530       "h21","h19","h20","h24","h22"/)
12531
12532    !!----
12533    !!---- KOV_OH
12534    !!----    character(len=*), dimension(48), parameter, public :: Kov_Oh
12535    !!----
12536    !!----    Kovalev Notation
12537    !!----
12538    !!---- Update: February - 2005
12539    !!
12540    character(len=*), dimension(48), parameter, public :: Kov_Oh=(/               &
12541       " h1"," h4"," h3"," h2"," h9","h10","h12","h11"," h5"," h7"," h6"," h8",   &
12542       "h16","h13","h15","h14","h20","h18","h17","h19","h24","h23",               &
12543       "h22","h21","h25","h28","h27","h26","h33","h34","h36","h35",               &
12544       "h29","h31","h30","h32","h40","h37","h39","h38","h44","h42",               &
12545       "h41","h43","h48","h47","h46","h45"/)
12546
12547    !!----
12548    !!---- LATT
12549    !!----    character(len=* ), dimension( 8) , parameter, public :: Latt
12550    !!----
12551    !!----    Lattice Traslations
12552    !!----
12553    !!---- Update: February - 2005
12554    !!
12555    character(len=* ), dimension( 8) , parameter, public  :: Latt =(/  &
12556       "  P: { 000 }                                       ",          &
12557       "  A: { 000;  0  1/2 1/2 }+                         ",          &
12558       "  B: { 000; 1/2  0  1/2 }+                         ",          &
12559       "  C: { 000; 1/2 1/2  0  }+                         ",          &
12560       "  I: { 000; 1/2 1/2 1/2 }+                         ",          &
12561       "  R: { 000; 2/3 1/3 1/3; 1/3 2/3 2/3   }+          ",          &
12562       "  F: { 000;  0  1/2 1/2; 1/2  0  1/2; 1/2 1/2  0 }+",          &
12563       "  Z: { 000;  Unconventional Z-centering vectors  }+"   /)
12564
12565    !!----
12566    !!---- LAUE_CLASS
12567    !!----    character(len=*), dimension(16), parameter, public :: Laue_class
12568    !!----
12569    !!----    Laue symbols
12570    !!----
12571    !!---- Update: February - 2005
12572    !!
12573    character(len=*), dimension(16), parameter, public :: laue_class=(/ &
12574       "-1   ","2/m  ","mmm  ","4/m  ","4/mmm","-3 R ","-3m R","-3   ", &
12575       "-3m1 ","-31m ","6/m  ","6/mmm","m-3  ","m-3m ","m3   ","m3m  "/)
12576
12577    !!----
12578    !!---- Litvin_point_op_label
12579    !!----    character(len=*), dimension(48), parameter, public :: Litvin_point_op_label
12580    !!----
12581    !!----    Symbols of point operators as given by Litvin (Non-hexagonal)
12582    !!----    The order corresponds to the Table given by Harold T. Stokes and Branton J. Campbell
12583    !!----
12584    !!---- Update: November - 2012, reordered according to the last tables 15/2/2016
12585    !!
12586    character(len=*), dimension(48), parameter, public :: Litvin_point_op_label=(/ &
12587       "1       ","2x      ","2y      ","2z      ","3xyz-1  ","3xy-z   ","3-xyz   ","3x-yz   ", &
12588       "3xyz    ","3x-yz-1 ","3xy-z-1 ","3-xyz-1 ","2-xy    ","4z      ","4z-1    ","2xy     ", &
12589       "2-yz    ","2yz     ","4x      ","4x-1    ","2-xz    ","4y-1    ","2xz     ","4y      ", &
12590       "-1      ","mx      ","my      ","mz      ","-3xyz-1 ","-3xy-z  ","-3-xyz  ","-3x-yz  ", &
12591       "-3xyz   ","-3x-yz-1","-3xy-z-1","-3-xyz-1","m-xy    ","-4z     ","-4z-1   ","mxy     ", &
12592       "m-yz    ","myz     ","-4x     ","-4x-1   ","m-xz    ","-4y-1   ","mxz     ","-4y     "/)
12593
12594    !!----
12595    !!---- Litvin_point_op
12596    !!----    character(len=*), dimension(48), parameter, public :: Litvin_point_op
12597    !!----
12598    !!----    Jones Faithful symbols of point operators as given by Litvin (Non-hexagonal)
12599    !!----    The order corresponds to the Table given by Harold T. Stokes and Branton J. Campbell
12600    !!----
12601    !!---- Update: November - 2012, reordered according to the last tables 15/2/2016
12602    !!
12603
12604    character(len=*), dimension(48), parameter, public :: Litvin_point_op=(/ &
12605       "x,y,z   ", "x,-y,-z ", "-x,y,-z ", "-x,-y,z ", "y,z,x   ",           &
12606       "y,-z,-x ", "-y,z,-x ", "-y,-z,x ", "z,x,y   ", "z,-x,-y ",           &
12607       "-z,x,-y ", "-z,-x,y ", "-y,-x,-z", "-y,x,z  ", "y,-x,z  ",           &
12608       "y,x,-z  ", "-x,-z,-y", "-x,z,y  ", "x,-z,y  ", "x,z,-y  ",           &
12609       "-z,-y,-x", "-z,y,x  ", "z,-y,x  ", "z,y,-x  ", "-x,-y,-z",           &
12610       "-x,y,z  ", "x,-y,z  ", "x,y,-z  ", "-y,-z,-x", "-y,z,x  ",           &
12611       "y,-z,x  ", "y,z,-x  ", "-z,-x,-y", "-z,x,y  ", "z,-x,y  ",           &
12612       "z,x,-y  ", "y,x,z   ", "y,-x,-z ", "-y,x,-z ", "-y,-x,z ",           &
12613       "x,z,y   ", "x,-z,-y ", "-x,z,-y ", "-x,-z,y ", "z,y,x   ",           &
12614       "z,-y,-x ", "-z,y,-x ", "-z,-y,x "/)
12615
12616
12617    !!----
12618    !!---- Litvin_point_op_hex_label
12619    !!----    character(len=*), dimension(24), parameter, public :: Litvin_point_op_hex_label
12620    !!----
12621    !!----    Symbols of point operators as given by Litvin (Hexagonal)
12622    !!----    The order corresponds to the Table given by Harold T. Stokes and Branton J. Campbell
12623    !!----
12624    !!---- Update: November - 2012, reordered according to the last tables 15/2/2016
12625    !!
12626    character(len=*), dimension(24), parameter, public :: Litvin_point_op_hex_label=(/ &
12627       "1    ","6z   ","3z   ","2z   ","3z-1 ","6z-1 ","2x   ","21   ",                &
12628       "2xy  ","22   ","2y   ","23   ","-1   ","-6z  ","-3z  ","mz   ",                &
12629       "-3z-1","-6z-1","mx   ","m1   ","mxy  ","m2   ","my   ","m3   "/)
12630
12631
12632    !!----
12633    !!---- Litvin_point_op_hex
12634    !!----    character(len=*), dimension(24), parameter, public :: Litvin_point_op_hex
12635    !!----
12636    !!----    Jones Faithful symbols of point operators as given by Litvin (Hexagonal)
12637    !!----    The order corresponds to the Table given by Harold T. Stokes and Branton J. Campbell
12638    !!----
12639    !!---- Update: November - 2012, reordered according to the last tables 15/2/2016
12640    !!
12641
12642    character(len=*), dimension(24), parameter, public :: Litvin_point_op_hex=(/      &
12643       "x,y,z     ","x-y,x,z   ","-y,x-y,z  ","-x,-y,z   ","-x+y,-x,z ","y,-x+y,z  ", &
12644       "x-y,-y,-z ","x,x-y,-z  ","y,x,-z    ","-x+y,y,-z ","-x,-x+y,-z","-y,-x,-z  ", &
12645       "-x,-y,-z  ","-x+y,-x,-z","y,-x+y,-z ","x,y,-z    ","x-y,x,-z  ","-y,x-y,-z ", &
12646       "-x+y,y,z  ","-x,-x+y,z ","-y,-x,z   ","x-y,-y,z  ","x,x-y,z   ","y,x,z     "/)
12647
12648
12649    !!----
12650    !!---- LTR_A
12651    !!----    real(kind=cp), dimension(3,2), parameter, public :: Ltr_A
12652    !!----
12653    !!----    Lattice Traslations of type A
12654    !!----
12655    !!---- Update: February - 2005
12656    !!
12657    real(kind=cp), dimension(3,2), parameter, public :: Ltr_a =reshape ( (/0.0,0.0,0.0, 0.0,0.5,0.5/), (/3,2/) )
12658
12659    !!----
12660    !!---- LTR_B
12661    !!----    real(kind=cp), dimension(3,2), parameter, public :: Ltr_B
12662    !!----
12663    !!----    Lattice Traslations of type B
12664    !!----
12665    !!---- Update: February - 2005
12666    !!
12667    real(kind=cp), dimension(3,2), parameter, public :: Ltr_b =reshape ( (/0.0,0.0,0.0, 0.5,0.0,0.5/), (/3,2/) )
12668
12669    !!----
12670    !!---- LTR_C
12671    !!----    real(kind=cp), dimension(3,2), parameter, public :: Ltr_C
12672    !!----
12673    !!----    Lattice Traslations of type C
12674    !!----
12675    !!---- Update: February - 2005
12676    !!
12677    real(kind=cp), dimension(3,2), parameter, public :: Ltr_c =reshape ( (/0.0,0.0,0.0, 0.5,0.5,0.0/), (/3,2/) )
12678
12679    !!----
12680    !!---- LTR_F
12681    !!----    real(kind=cp), dimension(3,4), parameter, public
12682    !!----
12683    !!----    Lattice Traslations of type F
12684    !!----
12685    !!---- Update: February - 2005
12686    !!
12687    real(kind=cp), dimension(3,4), parameter, public :: &
12688                   Ltr_f =reshape( (/0.0,0.0,0.0, 0.0,0.5,0.5, 0.5,0.0,0.5, 0.5,0.5,0.0 /),(/3,4/) )
12689
12690    !!----
12691    !!---- LTR_I
12692    !!----    real(kind=cp), dimension(3,2), parameter, public :: Ltr_I
12693    !!----
12694    !!----    Lattice Traslations of type I
12695    !!----
12696    !!---- Update: February - 2005
12697    !!
12698    real(kind=cp), dimension(3,2), parameter, public :: Ltr_i =reshape ( (/0.0,0.0,0.0, 0.5,0.5,0.5/), (/3,2/) )
12699
12700    !!----
12701    !!---- LTR_R
12702    !!----    real(kind=cp), dimension(3,3), parameter, public :: Ltr_R
12703    !!----
12704    !!----    Lattice Traslations of type R
12705    !!----
12706    !!---- Update: February - 2005
12707    !!
12708    real(kind=cp), dimension(3,3), parameter, public :: &
12709                   Ltr_r =reshape( (/0.0,0.0,0.0, 2.0/3.0,1.0/3.0,1.0/3.0,  1.0/3.0,2.0/3.0,2.0/3.0/),(/3,3/) )
12710
12711    !!----
12712    !!---- MAGMAT
12713    !!----    character(len=* ), dimension(72), parameter, public :: Magmat
12714    !!----
12715    !!----    Magnetic array
12716    !!----
12717    !!---- Update: February - 2005
12718    !!
12719    character(len=* ), dimension(72), parameter, public :: Magmat = (/      &
12720       "( Mx, My, Mz)      ","(-Mx,-My, Mz)      ","(-Mx, My,-Mz)      ",   &
12721       "( Mx,-My,-Mz)      ","( Mz, Mx, My)      ","( Mz,-Mx,-My)      ",   &
12722       "(-Mz,-Mx, My)      ","(-Mz, Mx,-My)      ","( My, Mz, Mx)      ",   &
12723       "(-My, Mz,-Mx)      ","( My,-Mz,-Mx)      ","(-My,-Mz, Mx)      ",   &
12724       "( My, Mx,-Mz)      ","(-My,-Mx,-Mz)      ","( My,-Mx, Mz)      ",   &
12725       "(-My, Mx, Mz)      ","( Mx, Mz,-My)      ","(-Mx, Mz, My)      ",   &
12726       "(-Mx,-Mz,-My)      ","( Mx,-Mz, My)      ","( Mz, My,-Mx)      ",   &
12727       "( Mz,-My, Mx)      ","(-Mz, My, Mx)      ","(-Mz,-My,-Mx)      ",   &
12728       "(-Mx,-My,-Mz)      ","( Mx, My,-Mz)      ","( Mx,-My, Mz)      ",   &
12729       "(-Mx, My, Mz)      ","(-Mz,-Mx,-My)      ","(-Mz, Mx, My)      ",   &
12730       "( Mz, Mx,-My)      ","( Mz,-Mx, My)      ","(-My,-Mz,-Mx)      ",   &
12731       "( My,-Mz, Mx)      ","(-My, Mz, Mx)      ","( My, Mz,-Mx)      ",   &
12732       "(-My,-Mx, Mz)      ","( My, Mx, Mz)      ","(-My, Mx,-Mz)      ",   &
12733       "( My,-Mx,-Mz)      ","(-Mx,-Mz, My)      ","( Mx,-Mz,-My)      ",   &
12734       "( Mx, Mz, My)      ","(-Mx, Mz,-My)      ","(-Mz,-My, Mx)      ",   &
12735       "(-Mz, My,-Mx)      ","( Mz,-My,-Mx)      ","( Mz, My, Mx)      ",   &
12736       "( Mx   ,    My, Mz)","(   -My, Mx-My, Mz)","(-Mx+My,-Mx   , Mz)",   &
12737       "(-Mx   ,   -My, Mz)","(    My,-Mx+My, Mz)","( Mx-My, Mx   , Mz)",   &
12738       "(    My, Mx   ,-Mz)","( Mx-My,   -My,-Mz)","(-Mx   ,-Mx+My,-Mz)",   &
12739       "(   -My,-Mx   ,-Mz)","(-Mx+My,    My,-Mz)","( Mx   , Mx-My,-Mz)",   &
12740       "(-Mx   ,   -My,-Mz)","(    My,-Mx+My,-Mz)","( Mx-My, Mx   ,-Mz)",   &
12741       "( Mx   ,    My,-Mz)","(   -My, Mx-My,-Mz)","(-Mx+My,-Mx   ,-Mz)",   &
12742       "(   -My,-Mx   , Mz)","(-Mx+My,    My, Mz)","( Mx   , Mx-My, Mz)",   &
12743       "(    My, Mx   , Mz)","( Mx-My,   -My, Mz)","(-Mx   ,-Mx+My, Mz)"   /)
12744
12745    !!----
12746    !!---- ML_D6H
12747    !!----    character(len=*), dimension(24), parameter, public:: ML_D6h
12748    !!----
12749    !!----    Miller & Love Notation
12750    !!----
12751    !!---- Update: February - 2005
12752    !!
12753    character(len=*), dimension(24), parameter, public :: ML_d6h=(/               &
12754       " 1"," 3"," 5"," 4"," 6"," 2"," 9"," 7","11","12","10"," 8","13","15","17",&
12755       "16","18","14","21","19","23","24","22","20"/)
12756
12757    !!----
12758    !!---- ML_OH
12759    !!----     character(len=*), dimension(48), parameter, public :: ML_Oh
12760    !!----
12761    !!----     Miller & Love Notation
12762    !!----
12763    !!---- Update: February - 2005
12764    !!
12765    character(len=*), dimension(48), parameter, public :: ML_Oh=(/                &
12766       " 1"," 4"," 3"," 2"," 9","10","12","11"," 5"," 7"," 6"," 8","16","13","15",&
12767       "14","20","18","17","19","24","23","22","21","25","28","27","26","33","34",&
12768       "36","35","29","31","30","32","40","37","39","38","44","42","41","43","48",&
12769       "47","46","45"/)
12770
12771    !!----
12772    !!---- MOD6
12773    !!----    Integer,  dimension(36,3,3), parameter, public :: Mod6
12774    !!----
12775    !!----    Matrix Types For Rotational Operators In Conventional Basis
12776    !!----    1->24 Oh, 25->36 D6h
12777    !!----
12778    !!---- Update: February - 2005
12779    !!
12780    Integer,  dimension(36,3,3), parameter, public :: Mod6 = reshape (  (/     &
12781       1,-1,-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,-1,                   &
12782      -1, 1, 0, 0, 0, 0, 1, 0,-1,-1, 0, 1, 0, 1,-1, 0,-1, 1,                   &
12783       0, 0, 0, 0, 1,-1,-1, 1, 0, 0, 0, 0, 1,-1,-1, 1, 0, 0,                   &
12784       0, 0, 0, 0, 0, 0, 0, 1,-1, 0,-1, 1, 1, 0,-1,-1, 0, 1,                   &
12785       0, 0, 0, 0, 0, 0, 0, 0, 1,-1,-1, 1, 0, 0, 0, 0, 0, 0,                   &
12786       0, 0,-1, 1, 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   &
12787       0, 0, 0, 0, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 0, 0,                   &
12788       0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 1,-1, 1,-1, 0,-1, 1, 0,                   &
12789       1,-1, 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   &
12790       0, 0, 1,-1, 1,-1, 1,-1, 0,-1, 1, 0, 0,-1, 1, 0, 1,-1,                   &
12791       0, 0, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 0, 0, 0, 0,-1, 1,                   &
12792      -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   &
12793       0, 0, 0, 0, 1, 1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   &
12794       0, 0, 1, 1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   &
12795       0, 0, 0, 0, 0, 0, 0, 0, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,                   &
12796      -1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                   &
12797       1, 1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0,-1,-1, 1, 1, 0, 0,                   &
12798       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1 /), (/36,3,3/) )
12799
12800    !!----
12801    !!---- POINT_GROUP
12802    !!----    character(len=*), dimension(39), parameter, public :: Point_group
12803    !!----
12804    !!----    Point Group Symbols
12805    !!----
12806    !!---- Update: July - 2014: added m3 and m3m for compatibility with Laue_class
12807    !!
12808    character(len=*), dimension(41), parameter, public :: point_group=(/  &
12809       "1    ","-1   ","2    ","m    ","2/m  ","222  ","mm2  ","m2m  ",   &
12810       "2mm  ","mmm  ","4    ","-4   ","4/m  ","422  ","4mm  ","-42m ",   &
12811       "-4m2 ","4/mmm","3    ","-3   ","32   ","3m   ","-3m  ","312  ",   &
12812       "31m  ","-31m ","6    ","-6   ","6/m  ","622  ","6mm  ","-62m ",   &
12813       "-6m2 ","6/mmm","23   ","m-3  ","432  ","-43m ","m-3m ","m3   ",   &
12814       "m3m  "/)
12815
12816    !!--++
12817    !!--++ SPG_GEN
12818    !!--++    character(len=120), private, dimension(230) :: spg_gen
12819    !!--++
12820    !!--++    (PRIVATE)
12821    !!--++    Variable to hold the generators of all space groups in the standard setting
12822    !!--++
12823    !!--++ Update: February - 2005
12824    !!
12825    character(len=120), private, dimension(230) :: spg_gen
12826
12827    !!----
12828    !!---- TYPE :: SPGR_INFO_TYPE
12829    !!--..
12830    !!---- Type, public :: Spgr_Info_Type
12831    !!----    integer                 :: N           ! Number of the Spacegroup
12832    !!----    character (len=12)      :: HM          ! Hermann-Mauguin
12833    !!----    character (len=16)      :: Hall        ! Hall
12834    !!----    integer                 :: Laue        ! Laue Group
12835    !!----    integer                 :: Pg          ! Point group
12836    !!----    integer, dimension(6)   :: Asu         ! Asymmetric unit * 24
12837    !!----    character (len= 5)      :: Inf_extra   ! Extra information
12838    !!---- End Type Spgr_Info_Type
12839    !!----
12840    !!----    Definition for General Info about Space Groups
12841    !!----
12842    !!---- Update: February - 2005
12843    !!
12844    Type, public :: Spgr_Info_Type
12845       integer                 :: N
12846       character (len=12)      :: HM
12847       character (len=16)      :: Hall
12848       integer                 :: Laue
12849       integer                 :: Pg
12850       integer, dimension(6)   :: Asu
12851       character (len= 5)      :: Inf_Extra
12852    End Type Spgr_Info_Type
12853
12854    !!----
12855    !!---- SPGR_INFO
12856    !!----    Type(Spgr_Info_Type), allocatable, dimension(:), public :: Spgr_info
12857    !!----
12858    !!----    General Info about Space Groups
12859    !!----    Present dimension: 612
12860    !!----
12861    !!---- Update: February - 2005
12862    !!
12863    Type(Spgr_Info_Type), allocatable, dimension(:), public :: Spgr_Info
12864
12865    !!----
12866    !!---- SYS_CRY
12867    !!----    character(len=* ), dimension(7) , parameter, public :: Sys_cry
12868    !!----
12869    !!----    System Type
12870    !!----
12871    !!---- Update: February - 2005
12872    !!
12873    character(len=* ), dimension(7) , parameter, public:: sys_cry =(/  &
12874       "Triclinic   ","Monoclinic  ","Orthorhombic","Tetragonal  ",    &
12875       "Trigonal    ","Hexagonal   ","Cubic       " /)
12876
12877    !!----
12878    !!---- TYPE :: TABLE_EQUIV_TYPE
12879    !!--..
12880    !!---- Type, public :: Table_Equiv_Type
12881    !!----    character(len= 6)      :: SC     ! Schoenflies
12882    !!----    character(len=17)      :: ML     ! Miller & Love
12883    !!----    character(len=18)      :: KO     ! Kovalev
12884    !!----    character(len=32)      :: BC     ! Bradley & Cracknell
12885    !!----    character(len=18)      :: ZA     ! Zak
12886    !!---- End Type Table_Equiv_Type
12887    !!----
12888    !!----    Definition for Equivalences on a Table
12889    !!----
12890    !!---- Update: February - 2005
12891    !!
12892    Type, public :: Table_Equiv_Type
12893       character(len= 6)      :: SC                ! Schoenflies
12894       character(len=17)      :: ML                ! Miller & Love
12895       character(len=18)      :: KO                ! Kovalev
12896       character(len=32)      :: BC                ! Bradley & Cracknell
12897       character(len=18)      :: ZA                ! Zak
12898    End Type Table_Equiv_Type
12899
12900    !!----
12901    !!---- SYSTEM_EQUIV
12902    !!----    Type(Table_Equiv_Type), allocatable, dimension(:), public :: System_Equiv
12903    !!----
12904    !!----    General Info about Space Groups
12905    !!----
12906    !!---- Update: February - 2005
12907    !!
12908    Type(Table_Equiv_Type), allocatable, dimension(:), public :: System_Equiv
12909
12910    !!----
12911    !!---- TYPE :: WYCK_INFO_TYPE
12912    !!--..
12913    !!---- Type, public :: Wyck_Info_Type
12914    !!----    character (len=12)                :: HM          ! Hermann-Mauguin
12915    !!----    integer                           :: Norbit      ! Number of orbites
12916    !!----    character (len= 15),dimension(24) :: Corbit      ! Generator of the orbit
12917    !!---- End Type Wyck_Info_Type
12918    !!----
12919    !!----    Definition for Wyckoff Positions acording to IT
12920    !!----
12921    !!---- Update: February - 2005
12922    !!
12923    Type, public :: Wyck_Info_Type
12924       character (len=12)               :: HM
12925       integer                          :: Norbit
12926       character (len=15),dimension(26) :: Corbit
12927    End Type Wyck_Info_Type
12928
12929    !!----
12930    !!---- WYCKOFF_INFO
12931    !!----    Type(Wyck_Info_Type), allocatable, dimension(:), public :: Wyckoff_info
12932    !!----
12933    !!----    General Info about Wyckoff Positions on IT
12934    !!----    Present dimension:
12935    !!----
12936    !!---- Update: February - 2005
12937    !!
12938    Type(Wyck_Info_Type), allocatable, dimension(:), public :: Wyckoff_Info
12939
12940    !!----
12941    !!---- X_D6H
12942    !!----    character(len=* ), dimension(24), parameter, public:: X_D6h
12943    !!----
12944    !!---- Update: February - 2005
12945    !!
12946    character(len=* ), dimension(24), parameter, public   :: X_d6h = (/      &
12947       "( x  ,   y, z)","(  -y, x-y, z)","(-x+y,-x  , z)","(-x  ,  -y, z)",  &
12948       "(   y,-x+y, z)","( x-y, x  , z)","(   y, x  ,-z)","( x-y,  -y,-z)",  &
12949       "(-x  ,-x+y,-z)","(  -y,-x  ,-z)","(-x+y,   y,-z)","( x  , x-y,-z)",  &
12950       "(-x  ,  -y,-z)","(   y,-x+y,-z)","( x-y, x  ,-z)","( x  ,   y,-z)",  &
12951       "(  -y, x-y,-z)","(-x+y,-x  ,-z)","(  -y,-x  , z)","(-x+y,   y, z)",  &
12952       "( x  , x-y, z)","(   y, x  , z)","( x-y,  -y, z)","(-x  ,-x+y, z)"   /)
12953
12954    !!----
12955    !!---- X_OH
12956    !!----    character(len=* ), dimension(48), parameter, public :: X_oh
12957    !!----
12958    !!---- Update: February - 2005
12959    !!
12960    character(len=* ), dimension(48), parameter, public  :: X_oh = (/                 &
12961       "( x, y, z)","(-x,-y, z)","(-x, y,-z)","( x,-y,-z)","( z, x, y)","( z,-x,-y)", &
12962       "(-z,-x, y)","(-z, x,-y)","( y, z, x)","(-y, z,-x)","( y,-z,-x)","(-y,-z, x)", &
12963       "( y, x,-z)","(-y,-x,-z)","( y,-x, z)","(-y, x, z)","( x, z,-y)","(-x, z, y)", &
12964       "(-x,-z,-y)","( x,-z, y)","( z, y,-x)","( z,-y, x)","(-z, y, x)","(-z,-y,-x)", &
12965       "(-x,-y,-z)","( x, y,-z)","( x,-y, z)","(-x, y, z)","(-z,-x,-y)","(-z, x, y)", &
12966       "( z, x,-y)","( z,-x, y)","(-y,-z,-x)","( y,-z, x)","(-y, z, x)","( y, z,-x)", &
12967       "(-y,-x, z)","( y, x, z)","(-y, x,-z)","( y,-x,-z)","(-x,-z, y)","( x,-z,-y)", &
12968       "( x, z, y)","(-x, z,-y)","(-z,-y, x)","(-z, y,-x)","( z,-y,-x)","( z, y, x)"  /)
12969
12970    !!----
12971    !!---- ZAK_D6H
12972    !!----    character (len=*), dimension(24), parameter, public :: Zak_D6h
12973    !!----
12974    !!----    Zak Notation
12975    !!----
12976    !!---- Update: February - 2005
12977    !!
12978    character (len=*), dimension(24), parameter, public :: Zak_D6h =(/          &
12979       "   E   "," C(z)_3","C(2z)_3","  C_2  ","C(5z)_6"," C(z)_6","  U(xy)",   &
12980       "  U(x) ","  U(y) ","  U(3) ","  U(2) ","  U(1) ","   I   ","S(5z)_6",   &
12981       " S(z)_6","  s(z) "," S(z)_3","S(2z)_3"," s(xy) ","  s(x) ","  s(y) ",   &
12982       "  s(3) ","  s(2) ","  s(1) " /)
12983
12984    !!----
12985    !!---- ZAK_OH
12986    !!----    character(len=* ), dimension(48), parameter, public :: Zak_Oh
12987    !!----
12988    !!----    Zak Notation
12989    !!----
12990    !!---- Update: February - 2005
12991    !!
12992    character(len=* ), dimension(48), parameter, public :: Zak_Oh =(/           &
12993       "     E     ","    U(z)   ","    U(y)   ","    U(x)   ","  C(xyz)_3 ",   &
12994       " C(-xy-z)_3"," C(x-y-z)_3"," C(-x-yz)_3"," C(2xyz)_3 ","C(2x-y-z)_3",   &
12995       " C(2x-yz)_3","C(-2xy-z)_3","    U(xy)  ","   U(-xy)  ","   C(3z)_4 ",   &
12996       "   C(z)_4  ","   C(3x)_4 ","    U(yz)  ","   U(y-z)  ","   C(x)_4  ",   &
12997       "   C(y)_4  ","    U(xz)  ","   C(3y)_4 ","   U(x-z)  ","      I    ",   &
12998       "    s(z)   ","    s(y)   ","    s(x)   "," S(5xyz)_6 ","S(-5xy-z)_6",   &
12999       "S(5x-y-z)_6","S(-5x-yz)_6","  S(xyz)_6 "," S(x-y-z)_6"," S(-x-yz)_6",   &
13000       " S(-xy-z)_6","    s(xy)  ","   s(-xy)  ","   S(z)_4  ","  S(3z)_4  ",   &
13001       "   S(x)_4  ","    s(yz)  ","   s(y-z)  ","  S(3x)_4  ","  S(3y)_4  ",   &
13002       "    s(xz)  ","   S(y)_4  ","   s(x-z)  " /)
13003
13004 Contains
13005
13006    !---------------------!
13007    !---- Subroutines ----!
13008    !---------------------!
13009
13010    !!----
13011    !!---- Subroutine Get_Generators(Spg,Gener)
13012    !!----    character (len=*), intent(in)  :: spg     !  In -> Hermann_Mauguin symbol or number of S.Group
13013    !!----    character (len=*), intent(out) :: gener   ! Out -> String with all generators
13014    !!----
13015    !!----    Provides the string "gener" containing the list of the generators
13016    !!----    (as given in the IT Crystallography) corresponding to the space group
13017    !!----    of symbol "spg". In "spg" the Hermann-Mauguin symbol or the number of the
13018    !!----    space group should be given. The calling program is responsible of decoding
13019    !!----    the string "gener". Generator are given in the Jone's Faithful notation and
13020    !!----    the separator is the symbol ";". An example, corresponding to the space
13021    !!----    group "R 3 c" is  gener = " x+1/3,y+2/3,z+2/3; -y,x-y,z; -y,-x,z+1/2"
13022    !!----    The variable is the string contained between the quotes.
13023    !!----
13024    !!---- Update: February - 2005
13025    !!
13026    Subroutine Get_Generators(Spg,Gener)
13027       !---- Arguments ----!
13028       character (len=*), intent(in)  :: spg
13029       character (len=*), intent(out) :: gener
13030
13031       !----  Local variables ----!
13032       logical                 :: ok
13033       integer                 :: i, ier, numg
13034       character(len=len(spg)) :: symb,sp
13035
13036       err_symtab=.false.
13037       if (.not. it_set) call set_IT_gen()
13038       ok=.false.
13039
13040       read(unit=spg,fmt=*,iostat=ier) numg
13041       if (ier == 0) then
13042          if (numg > 0 .and. numg <= 230) then
13043             gener=spg_gen(numg)(12:)
13044             ok=.true.
13045          else
13046             gener=spg_gen(1)(12:)
13047          end if
13048       else
13049          symb=u_case(spg)
13050          do i=1,230
13051             sp=u_case(spg_gen(i)(1:10))
13052             if (symb == sp) then
13053                gener=spg_gen(i)(12:)
13054                ok=.true.
13055                exit
13056             end if
13057          end do
13058       end if
13059
13060       if (.not. ok) then
13061          err_symtab=.true.
13062          ERR_SymTab_Mess=" Error in the symbol or number of the space group"
13063       end if
13064
13065       return
13066    End Subroutine Get_Generators
13067
13068    !!----
13069    !!---- Subroutine Remove_Spgr_Info()
13070    !!----
13071    !!----    Deallocating SPGR_INFO Data
13072    !!----
13073    !!---- Update: February - 2005
13074    !!
13075    Subroutine Remove_Spgr_Info()
13076
13077       if (allocated(spgr_info)) deallocate(spgr_info)
13078
13079       return
13080    End Subroutine Remove_Spgr_Info
13081
13082    !!----
13083    !!---- Subroutine Remove_System_Equiv()
13084    !!----
13085    !!----    Deallocating SPGR_INFO Data
13086    !!----
13087    !!---- Update: February - 2005
13088    !!
13089    Subroutine Remove_System_Equiv()
13090
13091       if (allocated(System_Equiv)) deallocate(System_Equiv)
13092
13093       return
13094    End Subroutine Remove_System_Equiv
13095
13096    !!----
13097    !!---- Subroutine Remove_Wyckoff_Info()
13098    !!----
13099    !!----    Deallocating WYCKOFF_INFO Data
13100    !!----
13101    !!---- Update: February - 2005
13102    !!
13103    Subroutine Remove_Wyckoff_Info()
13104
13105       if (allocated(wyckoff_info)) deallocate(wyckoff_info)
13106
13107       return
13108    End Subroutine Remove_Wyckoff_Info
13109
13110    !!--++
13111    !!--++ Subroutine Set_It_Gen()
13112    !!--++
13113    !!--++    (PRIVATE)
13114    !!--++    Fills the components of the Spg_Gen character variable
13115    !!--++    Called once by the public subroutine Get_Generators
13116    !!--++
13117    !!--++ Update: February - 2005
13118    !!
13119    Subroutine Set_It_Gen()
13120
13121       spg_gen(  1) =  "P 1       : x,y,z "
13122       spg_gen(  2) =  "P -1      : -x,-y,-z "
13123       spg_gen(  3) =  "P 2       : -x,y,-z "
13124       spg_gen(  4) =  "P 21      : -x,y+1/2,-z "
13125       spg_gen(  5) =  "C 2       : x+1/2,y+1/2,z; -x,y,-z "
13126       spg_gen(  6) =  "P m       : x,-y,z "
13127       spg_gen(  7) =  "P c       : x,-y,z+1/2 "
13128       spg_gen(  8) =  "C m       : x+1/2,y+1/2,z; x,-y,z "
13129       spg_gen(  9) =  "C c       : x+1/2,y+1/2,z; x,-y,z+1/2 "
13130       spg_gen( 10) =  "P 2/m     : -x,y,-z; -x,-y,-z "
13131       spg_gen( 11) =  "P 21/m    : -x,y+1/2,-z; -x,-y,-z "
13132       spg_gen( 12) =  "C 2/m     : x+1/2,y+1/2,z; -x,y,-z; -x,-y,-z "
13133       spg_gen( 13) =  "P 2/c     : -x,y,-z+1/2; -x,-y,-z "
13134       spg_gen( 14) =  "P 21/c    : -x,y+1/2,-z+1/2; -x,-y,-z "
13135       spg_gen( 15) =  "C 2/c     : x+1/2,y+1/2,z; -x,y,-z+1/2; -x,-y,-z "
13136       spg_gen( 16) =  "P 2 2 2   : -x,-y,z; -x,y,-z "
13137       spg_gen( 17) =  "P 2 2 21  : -x,-y,z+1/2; -x,y,-z+1/2 "
13138       spg_gen( 18) =  "P 21 21 2 : -x,-y,z; -x+1/2,y+1/2,-z "
13139       spg_gen( 19) =  "P 21 21 21: -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2 "
13140       spg_gen( 20) =  "C 2 2 21  : x+1/2,y+1/2,z; -x,-y,z+1/2; -x,y,-z+1/2 "
13141       spg_gen( 21) =  "C 2 2 2   : x+1/2,y+1/2,z; -x,-y,z; -x,y,-z "
13142       spg_gen( 22) =  "F 2 2 2   : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z "
13143       spg_gen( 23) =  "I 2 2 2   : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z "
13144       spg_gen( 24) =  "I 21 21 21: x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2 "
13145       spg_gen( 25) =  "P m m 2   : -x,-y,z; x,-y,z "
13146       spg_gen( 26) =  "P m c 21  : -x,-y,z+1/2; x,-y,z+1/2 "
13147       spg_gen( 27) =  "P c c 2   : -x,-y,z; x,-y,z+1/2 "
13148       spg_gen( 28) =  "P m a 2   : -x,-y,z; x+1/2,-y,z "
13149       spg_gen( 29) =  "P c a 21  : -x,-y,z+1/2; x+1/2,-y,z "
13150       spg_gen( 30) =  "P n c 2   : -x,-y,z; x,-y+1/2,z+1/2 "
13151       spg_gen( 31) =  "P m n 21  : -x+1/2,-y,z+1/2; x+1/2,-y,z+1/2 "
13152       spg_gen( 32) =  "P b a 2   : -x,-y,z; x+1/2,-y+1/2,z "
13153       spg_gen( 33) =  "P n a 21  : -x,-y,z+1/2; x+1/2,-y+1/2,z "
13154       spg_gen( 34) =  "P n n 2   : -x,-y,z; x+1/2,-y+1/2,z+1/2 "
13155       spg_gen( 35) =  "C m m 2   : x+1/2,y+1/2,z; -x,-y,z; x,-y,z "
13156       spg_gen( 36) =  "C m c 21  : x+1/2,y+1/2,z; -x,-y,z+1/2; x,-y,z+1/2 "
13157       spg_gen( 37) =  "C c c 2   : x+1/2,y+1/2,z; -x,-y,z; x,-y,z+1/2 "
13158       spg_gen( 38) =  "A m m 2   : x,y+1/2,z+1/2; -x,-y,z; x,-y,z "
13159       spg_gen( 39) =  "A b m 2   : x,y+1/2,z+1/2; -x,-y,z; x,-y+1/2,z "
13160       spg_gen( 40) =  "A m a 2   : x,y+1/2,z+1/2; -x,-y,z; x+1/2,-y,z "
13161       spg_gen( 41) =  "A b a 2   : x,y+1/2,z+1/2; -x,-y,z; x+1/2,-y+1/2,z "
13162       spg_gen( 42) =  "F m m 2   : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; x,-y,z "
13163       spg_gen( 43) =  "F d d 2   : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; x+1/4,-y+1/4,z+1/4 "
13164       spg_gen( 44) =  "I m m 2   : x+1/2,y+1/2,z+1/2; -x,-y,z; x,-y,z "
13165       spg_gen( 45) =  "I b a 2   : x+1/2,y+1/2,z+1/2; -x,-y,z; x+1/2,-y+1/2,z "
13166       spg_gen( 46) =  "I m a 2   : x+1/2,y+1/2,z+1/2; -x,-y,z; x+1/2,-y,z "
13167       spg_gen( 47) =  "P m m m   : -x,-y,z; -x,y,-z; -x,-y,-z "
13168       spg_gen( 48) =  "P n n n   : -x+1/2,-y+1/2,z; -x+1/2,y,-z+1/2; -x,-y,-z "
13169       spg_gen( 49) =  "P c c m   : -x,-y,z; -x,y,-z+1/2; -x,-y,-z "
13170       spg_gen( 50) =  "P b a n   : -x+1/2,-y+1/2,z; -x+1/2,y,-z; -x,-y,-z "
13171       spg_gen( 51) =  "P m m a   : -x+1/2,-y,z; -x,y,-z; -x,-y,-z "
13172       spg_gen( 52) =  "P n n a   : -x+1/2,-y,z; -x+1/2,y+1/2,-z+1/2; -x,-y,-z "
13173       spg_gen( 53) =  "P m n a   : -x+1/2,-y,z+1/2; -x+1/2,y,-z+1/2; -x,-y,-z "
13174       spg_gen( 54) =  "P c c a   : -x+1/2,-y,z; -x,y,-z+1/2; -x,-y,-z "
13175       spg_gen( 55) =  "P b a m   : -x,-y,z; -x+1/2,y+1/2,-z; -x,-y,-z "
13176       spg_gen( 56) =  "P c c n   : -x+1/2,-y+1/2,z; -x,y+1/2,-z+1/2; -x,-y,-z "
13177       spg_gen( 57) =  "P b c m   : -x,-y,z+1/2; -x,y+1/2,-z+1/2; -x,-y,-z "
13178       spg_gen( 58) =  "P n n m   : -x,-y,z; -x+1/2,y+1/2,-z+1/2; -x,-y,-z "
13179       spg_gen( 59) =  "P m m n   : -x+1/2,-y+1/2,z; -x,y+1/2,-z; -x,-y,-z "
13180       spg_gen( 60) =  "P b c n   : -x+1/2,-y+1/2,z+1/2; -x,y,-z+1/2; -x,-y,-z "
13181       spg_gen( 61) =  "P b c a   : -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; -x,-y,-z "
13182       spg_gen( 62) =  "P n m a   : -x+1/2,-y,z+1/2; -x,y+1/2,-z; -x,-y,-z "
13183       spg_gen( 63) =  "C m c m   : x+1/2,y+1/2,z; -x,-y,z+1/2; -x,y,-z+1/2; -x,-y,-z "
13184       spg_gen( 64) =  "C m c a   : x+1/2,y+1/2,z; -x,-y+1/2,z+1/2; -x,y+1/2,-z+1/2; -x,-y,-z "
13185       spg_gen( 65) =  "C m m m   : x+1/2,y+1/2,z; -x,-y,z; -x,y,-z; -x,-y,-z "
13186       spg_gen( 66) =  "C c c m   : x+1/2,y+1/2,z; -x,-y,z; -x,y,-z+1/2; -x,-y,-z "
13187       spg_gen( 67) =  "C m m a   : x+1/2,y+1/2,z; -x,-y+1/2,z; -x,y+1/2,-z; -x,-y,-z "
13188       spg_gen( 68) =  "C c c a   : x+1/2,y+1/2,z; -x+1/2,-y,z; -x,y,-z+1/2; -x,-y,-z "
13189       spg_gen( 69) =  "F m m m   : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; -x,-y,-z "
13190       spg_gen( 70) =  "F d d d   : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x+3/4,-y+3/4,z; -x+3/4,y,-z+3/4; -x,-y,-z "
13191       spg_gen( 71) =  "I m m m   : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z; -x,-y,-z "
13192       spg_gen( 72) =  "I b a m   : x+1/2,y+1/2,z+1/2; -x,-y,z; -x+1/2,y+1/2,-z; -x,-y,-z "
13193       spg_gen( 73) =  "I b c a   : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; -x,-y,-z "
13194       spg_gen( 74) =  "I m m a   : x+1/2,y+1/2,z+1/2; -x,-y+1/2,z; -x,y+1/2,-z; -x,-y,-z "
13195       spg_gen( 75) =  "P 4       : -x,-y,z; -y,x,z "
13196       spg_gen( 76) =  "P 41      : -x,-y,z+1/2; -y,x,z+1/4 "
13197       spg_gen( 77) =  "P 42      : -x,-y,z; -y,x,z+1/2 "
13198       spg_gen( 78) =  "P 43      : -x,-y,z+1/2; -y,x,z+3/4 "
13199       spg_gen( 79) =  "I 4       : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z "
13200       spg_gen( 80) =  "I 41      : x+1/2,y+1/2,z+1/2; -x+1/2,-y+1/2,z+1/2; -y,x+1/2,z+1/4 "
13201       spg_gen( 81) =  "P -4      : -x,-y,z; y,-x,-z "
13202       spg_gen( 82) =  "I -4      : x+1/2,y+1/2,z+1/2; -x,-y,z; y,-x,-z "
13203       spg_gen( 83) =  "P 4/m     : -x,-y,z; -y,x,z; -x,-y,-z "
13204       spg_gen( 84) =  "P 42/m    : -x,-y,z; -y,x,z+1/2; -x,-y,-z "
13205       spg_gen( 85) =  "P 4/n     : -x+1/2,-y+1/2,z; -y+1/2,x,z; -x,-y,-z "
13206       spg_gen( 86) =  "P 42/n    : -x+1/2,-y+1/2,z; -y,x+1/2,z+1/2; -x,-y,-z "
13207       spg_gen( 87) =  "I 4/m     : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z; -x,-y,-z "
13208       spg_gen( 88) =  "I 41/a    : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -y+3/4,x+1/4,z+1/4; -x,-y,-z "
13209       spg_gen( 89) =  "P 4 2 2   : -x,-y,z; -y,x,z; -x,y,-z "
13210       spg_gen( 90) =  "P 4 21 2  : -x,-y,z; -y+1/2,x+1/2,z; -x+1/2,y+1/2,-z "
13211       spg_gen( 91) =  "P 41 2 2  : -x,-y,z+1/2; -y,x,z+1/4; -x,y,-z "
13212       spg_gen( 92) =  "P 41 21 2 : -x,-y,z+1/2; -y+1/2,x+1/2,z+1/4; -x+1/2,y+1/2,-z+1/4 "
13213       spg_gen( 93) =  "P 42 2 2  : -x,-y,z; -y,x,z+1/2; -x,y,-z "
13214       spg_gen( 94) =  "P 42 21 2 : -x,-y,z; -y+1/2,x+1/2,z+1/2; -x+1/2,y+1/2,-z+1/2 "
13215       spg_gen( 95) =  "P 43 2 2  : -x,-y,z+1/2; -y,x,z+3/4; -x,y,-z "
13216       spg_gen( 96) =  "P 43 21 2 : -x,-y,z+1/2; -y+1/2,x+1/2,z+3/4; -x+1/2,y+1/2,-z+3/4 "
13217       spg_gen( 97) =  "I 4 2 2   : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z; -x,y,-z "
13218       spg_gen( 98) =  "I 41 2 2  : x+1/2,y+1/2,z+1/2; -x+1/2,-y+1/2,z+1/2; -y,x+1/2,z+1/4; -x+1/2,y,-z+3/4 "
13219       spg_gen( 99) =  "P 4 m m   : -x,-y,z; -y,x,z; x,-y,z "
13220       spg_gen(100) =  "P 4 b m   : -x,-y,z; -y,x,z; x+1/2,-y+1/2,z "
13221       spg_gen(101) =  "P 42 c m  : -x,-y,z; -y,x,z+1/2; x,-y,z+1/2 "
13222       spg_gen(102) =  "P 42 n m  : -x,-y,z; -y+1/2,x+1/2,z+1/2; x+1/2,-y+1/2,z+1/2 "
13223       spg_gen(103) =  "P 4 c c   : -x,-y,z; -y,x,z; x,-y,z+1/2 "
13224       spg_gen(104) =  "P 4 n c   : -x,-y,z; -y,x,z; x+1/2,-y+1/2,z+1/2 "
13225       spg_gen(105) =  "P 42 m c  : -x,-y,z; -y,x,z+1/2; x,-y,z "
13226       spg_gen(106) =  "P 42 b c  : -x,-y,z; -y,x,z+1/2; x+1/2,-y+1/2,z "
13227       spg_gen(107) =  "I 4 m m   : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z; x,-y,z "
13228       spg_gen(108) =  "I 4 c m   : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z; x,-y,z+1/2 "
13229       spg_gen(109) =  "I 41 m d  : x+1/2,y+1/2,z+1/2; -x+1/2,-y+1/2,z+1/2; -y,x+1/2,z+1/4; x,-y,z "
13230       spg_gen(110) =  "I 41 c d  : x+1/2,y+1/2,z+1/2; -x+1/2,-y+1/2,z+1/2; -y,x+1/2,z+1/4; x,-y,z+1/2 "
13231       spg_gen(111) =  "P -4 2 m  : -x,-y,z; y,-x,-z; -x,y,-z "
13232       spg_gen(112) =  "P -4 2 c  : -x,-y,z; y,-x,-z; -x,y,-z+1/2 "
13233       spg_gen(113) =  "P -4 21 m : -x,-y,z; y,-x,-z; -x+1/2,y+1/2,-z "
13234       spg_gen(114) =  "P -4 21 c : -x,-y,z; y,-x,-z; -x+1/2,y+1/2,-z+1/2 "
13235       spg_gen(115) =  "P -4 m 2  : -x,-y,z; y,-x,-z; x,-y,z "
13236       spg_gen(116) =  "P -4 c 2  : -x,-y,z; y,-x,-z; x,-y,z+1/2 "
13237       spg_gen(117) =  "P -4 b 2  : -x,-y,z; y,-x,-z; x+1/2,-y+1/2,z "
13238       spg_gen(118) =  "P -4 n 2  : -x,-y,z; y,-x,-z; x+1/2,-y+1/2,z+1/2 "
13239       spg_gen(119) =  "I -4 m 2  : x+1/2,y+1/2,z+1/2; -x,-y,z; y,-x,-z; x,-y,z "
13240       spg_gen(120) =  "I -4 c 2  : x+1/2,y+1/2,z+1/2; -x,-y,z; y,-x,-z; x,-y,z+1/2 "
13241       spg_gen(121) =  "I -4 2 m  : x+1/2,y+1/2,z+1/2; -x,-y,z; y,-x,-z; -x,y,-z "
13242       spg_gen(122) =  "I -4 2 d  : x+1/2,y+1/2,z+1/2; -x,-y,z; y,-x,-z; -x+1/2,y,-z+3/4 "
13243       spg_gen(123) =  "P 4/m m m : -x,-y,z; -y,x,z; -x,y,-z; -x,-y,-z "
13244       spg_gen(124) =  "P 4/m c c : -x,-y,z; -y,x,z; -x,y,-z+1/2; -x,-y,-z "
13245       spg_gen(125) =  "P 4/n b m : -x+1/2,-y+1/2,z; -y+1/2,x,z; -x+1/2,y,-z; -x,-y,-z "
13246       spg_gen(126) =  "P 4/n n c : -x+1/2,-y+1/2,z; -y+1/2,x,z; -x+1/2,y,-z+1/2; -x,-y,-z "
13247       spg_gen(127) =  "P 4/m b m : -x,-y,z; -y,x,z; -x+1/2,y+1/2,-z; -x,-y,-z "
13248       spg_gen(128) =  "P 4/m n c : -x,-y,z; -y,x,z; -x+1/2,y+1/2,-z+1/2; -x,-y,-z "
13249       spg_gen(129) =  "P 4/n m m : -x+1/2,-y+1/2,z; -y+1/2,x,z; -x,y+1/2,-z; -x,-y,-z "
13250       spg_gen(130) =  "P 4/n c c : -x+1/2,-y+1/2,z; -y+1/2,x,z; -x,y+1/2,-z+1/2; -x,-y,-z "
13251       spg_gen(131) =  "P 42/m m c: -x,-y,z; -y,x,z+1/2; -x,y,-z; -x,-y,-z "
13252       spg_gen(132) =  "P 42/m c m: -x,-y,z; -y,x,z+1/2; -x,y,-z+1/2; -x,-y,-z "
13253       spg_gen(133) =  "P 42/n b c: -x+1/2,-y+1/2,z; -y+1/2,x,z+1/2; -x+1/2,y,-z; -x,-y,-z "
13254       spg_gen(134) =  "P 42/n n m: -x+1/2,-y+1/2,z; -y+1/2,x,z+1/2; -x+1/2,y,-z+1/2; -x,-y,-z "
13255       spg_gen(135) =  "P 42/m b c: -x,-y,z; -y,x,z+1/2; -x+1/2,y+1/2,-z; -x,-y,-z "
13256       spg_gen(136) =  "P 42/m n m: -x,-y,z; -y+1/2,x+1/2,z+1/2; -x+1/2,y+1/2,-z+1/2; -x,-y,-z "
13257       spg_gen(137) =  "P 42/n m c: -x+1/2,-y+1/2,z; -y+1/2,x,z+1/2; -x,y+1/2,-z; -x,-y,-z "
13258       spg_gen(138) =  "P 42/n c m: -x+1/2,-y+1/2,z; -y+1/2,x,z+1/2; -x,y+1/2,-z+1/2; -x,-y,-z "
13259       spg_gen(139) =  "I 4/m m m : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z; -x,y,-z; -x,-y,-z "
13260       spg_gen(140) =  "I 4/m c m : x+1/2,y+1/2,z+1/2; -x,-y,z; -y,x,z; -x,y,-z+1/2; -x,-y,-z "
13261       spg_gen(141) =  "I 41/a m d: x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -y+1/4,x+3/4,z+1/4; -x+1/2,y,-z+1/2; -x,-y,-z "
13262       spg_gen(142) =  "I 41/a c d: x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -y+1/4,x+3/4,z+1/4; -x+1/2,y,-z; -x,-y,-z "
13263       spg_gen(143) =  "P 3       : -y,x-y,z "
13264       spg_gen(144) =  "P 31      : -y,x-y,z+1/3 "
13265       spg_gen(145) =  "P 32      : -y,x-y,z+2/3 "
13266       spg_gen(146) =  "R 3       : x+1/3,y+2/3,z+2/3; -y,x-y,z "
13267       spg_gen(147) =  "P -3      : -y,x-y,z; -x,-y,-z "
13268       spg_gen(148) =  "R -3      : x+1/3,y+2/3,z+2/3; -y,x-y,z; -x,-y,-z "
13269       spg_gen(149) =  "P 3 1 2   : -y,x-y,z; -y,-x,-z "
13270       spg_gen(150) =  "P 3 2 1   : -y,x-y,z; y,x,-z "
13271       spg_gen(151) =  "P 31 1 2  : -y,x-y,z+1/3; -y,-x,-z+2/3 "
13272       spg_gen(152) =  "P 31 2 1  : -y,x-y,z+1/3; y,x,-z "
13273       spg_gen(153) =  "P 32 1 2  : -y,x-y,z+2/3; -y,-x,-z+1/3 "
13274       spg_gen(154) =  "P 32 2 1  : -y,x-y,z+2/3; y,x,-z "
13275       spg_gen(155) =  "R 3 2     : x+1/3,y+2/3,z+2/3; -y,x-y,z; y,x,-z "
13276       spg_gen(156) =  "P 3 m 1   : -y,x-y,z; -y,-x,z "
13277       spg_gen(157) =  "P 3 1 m   : -y,x-y,z; y,x,z "
13278       spg_gen(158) =  "P 3 c 1   : -y,x-y,z; -y,-x,z+1/2 "
13279       spg_gen(159) =  "P 3 1 c   : -y,x-y,z; y,x,z+1/2 "
13280       spg_gen(160) =  "R 3 m     : x+1/3,y+2/3,z+2/3; -y,x-y,z; -y,-x,z "
13281       spg_gen(161) =  "R 3 c     : x+1/3,y+2/3,z+2/3; -y,x-y,z; -y,-x,z+1/2 "
13282       spg_gen(162) =  "P -3 1 m  : -y,x-y,z; -y,-x,-z; -x,-y,-z "
13283       spg_gen(163) =  "P -3 1 c  : -y,x-y,z; -y,-x,-z+1/2; -x,-y,-z "
13284       spg_gen(164) =  "P -3 m 1  : -y,x-y,z; y,x,-z; -x,-y,-z "
13285       spg_gen(165) =  "P -3 c 1  : -y,x-y,z; y,x,-z+1/2; -x,-y,-z "
13286       spg_gen(166) =  "R -3 m    : x+1/3,y+2/3,z+2/3; -y,x-y,z; y,x,-z; -x,-y,-z "
13287       spg_gen(167) =  "R -3 c    : x+1/3,y+2/3,z+2/3; -y,x-y,z; y,x,-z+1/2; -x,-y,-z "
13288       spg_gen(168) =  "P 6       : -y,x-y,z; -x,-y,z "
13289       spg_gen(169) =  "P 61      : -y,x-y,z+1/3; -x,-y,z+1/2 "
13290       spg_gen(170) =  "P 65      : -y,x-y,z+2/3; -x,-y,z+1/2 "
13291       spg_gen(171) =  "P 62      : -y,x-y,z+2/3; -x,-y,z "
13292       spg_gen(172) =  "P 64      : -y,x-y,z+1/3; -x,-y,z "
13293       spg_gen(173) =  "P 63      : -y,x-y,z; -x,-y,z+1/2 "
13294       spg_gen(174) =  "P -6      : -y,x-y,z; x,y,-z "
13295       spg_gen(175) =  "P 6/m     : -y,x-y,z; -x,-y,z; -x,-y,-z "
13296       spg_gen(176) =  "P 63/m    : -y,x-y,z; -x,-y,z+1/2; -x,-y,-z "
13297       spg_gen(177) =  "P 6 2 2   : -y,x-y,z; -x,-y,z; y,x,-z "
13298       spg_gen(178) =  "P 61 2 2  : -y,x-y,z+1/3; -x,-y,z+1/2; y,x,-z+1/3 "
13299       spg_gen(179) =  "P 65 2 2  : -y,x-y,z+2/3; -x,-y,z+1/2; y,x,-z+2/3 "
13300       spg_gen(180) =  "P 62 2 2  : -y,x-y,z+2/3; -x,-y,z; y,x,-z+2/3 "
13301       spg_gen(181) =  "P 64 2 2  : -y,x-y,z+1/3; -x,-y,z; y,x,-z+1/3 "
13302       spg_gen(182) =  "P 63 2 2  : -y,x-y,z; -x,-y,z+1/2; y,x,-z "
13303       spg_gen(183) =  "P 6 m m   : -y,x-y,z; -x,-y,z; -y,-x,z "
13304       spg_gen(184) =  "P 6 c c   : -y,x-y,z; -x,-y,z; -y,-x,z+1/2 "
13305       spg_gen(185) =  "P 63 c m  : -y,x-y,z; -x,-y,z+1/2; -y,-x,z+1/2 "
13306       spg_gen(186) =  "P 63 m c  : -y,x-y,z; -x,-y,z+1/2; -y,-x,z "
13307       spg_gen(187) =  "P -6 m 2  : -y,x-y,z; x,y,-z; -y,-x,z "
13308       spg_gen(188) =  "P -6 c 2  : -y,x-y,z; x,y,-z+1/2; -y,-x,z+1/2 "
13309       spg_gen(189) =  "P -6 2 m  : -y,x-y,z; x,y,-z; y,x,-z "
13310       spg_gen(190) =  "P -6 2 c  : -y,x-y,z; x,y,-z+1/2; y,x,-z "
13311       spg_gen(191) =  "P 6/m m m : -y,x-y,z; -x,-y,z; y,x,-z; -x,-y,-z "
13312       spg_gen(192) =  "P 6/m c c : -y,x-y,z; -x,-y,z; y,x,-z+1/2; -x,-y,-z "
13313       spg_gen(193) =  "P 63/m c m: -y,x-y,z; -x,-y,z+1/2; y,x,-z+1/2; -x,-y,-z "
13314       spg_gen(194) =  "P 63/m m c: -y,x-y,z; -x,-y,z+1/2; y,x,-z; -x,-y,-z "
13315       spg_gen(195) =  "P 2 3     : -x,-y,z; -x,y,-z; z,x,y "
13316       spg_gen(196) =  "F 2 3     : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y "
13317       spg_gen(197) =  "I 2 3     : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z; z,x,y "
13318       spg_gen(198) =  "P 21 3    : -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y "
13319       spg_gen(199) =  "I 21 3    : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y "
13320       spg_gen(200) =  "P m -3    : -x,-y,z; -x,y,-z; z,x,y; -x,-y,-z "
13321       spg_gen(201) =  "P n -3    : -x+1/2,-y+1/2,z; -x+1/2,y,-z+1/2; z,x,y; -x,-y,-z "
13322       spg_gen(202) =  "F m -3    : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y; -x,-y,-z "
13323       spg_gen(203) =  "F d -3    : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x+1/4,-y+1/4,z; -x+1/4,y,-z+1/4; z,x,y; -x,-y,-z "
13324       spg_gen(204) =  "I m -3    : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z; z,x,y; -x,-y,-z "
13325       spg_gen(205) =  "P a -3    : -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; -x,-y,-z "
13326       spg_gen(206) =  "I a -3    : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; -x,-y,-z "
13327       spg_gen(207) =  "P 4 3 2   : -x,-y,z; -x,y,-z; z,x,y; y,x,-z "
13328       spg_gen(208) =  "P 42 3 2  : -x,-y,z; -x,y,-z; z,x,y; y+1/2,x+1/2,-z+1/2 "
13329       spg_gen(209) =  "F 4 3 2   : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y,x,-z "
13330       spg_gen(210) =  "F 41 3 2  : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y+1/2,z+1/2; -x+1/2,y+1/2,-z; z,x,y; y+3/4,x+1/4,-z+3/4 "
13331       spg_gen(211) =  "I 4 3 2   : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y,x,-z "
13332       spg_gen(212) =  "P 43 3 2  : -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; y+1/4,x+3/4,-z+3/4 "
13333       spg_gen(213) =  "P 41 3 2  : -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; y+3/4,x+1/4,-z+1/4 "
13334       spg_gen(214) =  "I 41 3 2  : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; y+3/4,x+1/4,-z+1/4 "
13335       spg_gen(215) =  "P -4 3 m  : -x,-y,z; -x,y,-z; z,x,y; y,x,z "
13336       spg_gen(216) =  "F -4 3 m  : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y,x,z "
13337       spg_gen(217) =  "I -4 3 m  : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y,x,z "
13338       spg_gen(218) =  "P -4 3 n  : -x,-y,z; -x,y,-z; z,x,y; y+1/2,x+1/2,z+1/2 "
13339       spg_gen(219) =  "F -4 3 c  : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y+1/2,x+1/2,z+1/2 "
13340       spg_gen(220) =  "I -4 3 d  : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; y+1/4,x+1/4,z+1/4 "
13341       spg_gen(221) =  "P m -3 m  : -x,-y,z; -x,y,-z; z,x,y; y,x,-z; -x,-y,-z "
13342       spg_gen(222) =  "P n -3 n  : -x+1/2,-y+1/2,z; -x+1/2,y,-z+1/2; z,x,y; y,x,-z+1/2; -x,-y,-z "
13343       spg_gen(223) =  "P m -3 n  : -x,-y,z; -x,y,-z; z,x,y; y+1/2,x+1/2,-z+1/2; -x,-y,-z "
13344       spg_gen(224) =  "P n -3 m  : -x+1/2,-y+1/2,z; -x+1/2,y,-z+1/2; z,x,y; y+1/2,x+1/2,-z; -x,-y,-z "
13345       spg_gen(225) =  "F m -3 m  : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y,x,-z; -x,-y,-z "
13346       spg_gen(226) =  "F m -3 c  : x+1/2,y+1/2,z; x+1/2,y,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y+1/2,x+1/2,-z+1/2; -x,-y,-z "
13347
13348       spg_gen(227) =  &
13349       "F d -3 m  : x+1/2,y+1/2,z; x+1/2,y,z+1/2;-x+3/4,-y+1/4,z+1/2;-x+1/4,y+1/2,-z+3/4;z,x,y;y+3/4,x+1/4,-z+1/2;-x,-y,-z"
13350
13351       spg_gen(228) =  &
13352       "F d -3 c  : x+1/2,y+1/2,z; x+1/2,y,z+1/2;-x+1/4,-y+3/4,z+1/2;-x+3/4,y+1/2,-z+1/4;z,x,y;y+3/4,x+1/4,-z;-x,-y,-z"
13353
13354       spg_gen(229) =  "I m -3 m  : x+1/2,y+1/2,z+1/2; -x,-y,z; -x,y,-z; z,x,y; y,x,-z; -x,-y,-z "
13355       spg_gen(230) =  "I a -3 d  : x+1/2,y+1/2,z+1/2; -x+1/2,-y,z+1/2; -x,y+1/2,-z+1/2; z,x,y; y+3/4,x+1/4,-z+1/4; -x,-y,-z "
13356
13357       return
13358    End Subroutine Set_It_Gen
13359
13360
13361    !!----
13362    !!---- Subroutine Set_Spgr_Info()
13363    !!----    Number of the Space Group
13364    !!----    Hermann-Mauguin Symbol
13365    !!----    Hall symbol
13366    !!----    Laue Group                                                                                                 ----
13367    !!----    Point Group
13368    !!----    Asymmetric unit in direct space.
13369    !!----    Miscellaneous Information depending on crystal system:
13370    !!----        Monoclinic         b           c           a
13371    !!----                        abc  c-ba   abc  ba-c   abc -acb
13372    !!----                        ---------   ---------   --------
13373    !!----        cell choice 1    b1   -b1    c1   -c1    a1  -a1
13374    !!----        cell choice 2    b2   -b2    c2   -c2    a2  -a2
13375    !!----        cell choice 3    b3   -b3    c3   -c3    a3  -a3
13376    !!----        Orthorhombic     ba-c   change of basis abc -> ba-c
13377    !!----                         1      origin choice 1
13378    !!----                         2ba-c  origin choice 2, change basis
13379    !!----                                abc -> ba-c
13380    !!----        Tetragonal       1      origin choice 1
13381    !!----        Cubic            2      origin choice 2
13382    !!----        Trigonal         H      hexagonal axes
13383    !!----                         R      rhombohedral axes
13384    !!----
13385    !!----    Set Information on Spgr_info array
13386    !!----
13387    !!---- Update: February - 2005
13388    !!
13389    Subroutine Set_Spgr_Info()
13390
13391       if (.not. allocated(spgr_info) ) allocate(spgr_info(612) )
13392
13393       !---- Triclinic ----!
13394       spgr_info(1:14)= (/                                           &
13395            spgr_info_type(  1,"P 1         ","P 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13396            spgr_info_type(  1,"A 1         ","A 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13397            spgr_info_type(  1,"B 1         ","B 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13398            spgr_info_type(  1,"C 1         ","C 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13399            spgr_info_type(  1,"I 1         ","I 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13400            spgr_info_type(  1,"R 1         ","R 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13401            spgr_info_type(  1,"F 1         ","F 1             ", 1, 1, (/ 0, 0, 0, 24, 24, 24/),"     ") , &
13402            spgr_info_type(  2,"P -1        ","-P 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") , &
13403            spgr_info_type(  2,"A -1        ","-A 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") , &
13404            spgr_info_type(  2,"B -1        ","-B 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") , &
13405            spgr_info_type(  2,"C -1        ","-C 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") , &
13406            spgr_info_type(  2,"I -1        ","-I 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") , &
13407            spgr_info_type(  2,"R -1        ","-R 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") , &
13408            spgr_info_type(  2,"F -1        ","-F 1            ", 1, 2, (/ 0, 0, 0, 12, 24, 24/),"     ") /)
13409
13410       !---- Monoclinic ----!
13411       spgr_info(15:44)= (/                                           &
13412            spgr_info_type(  3,"P 1 2 1     ","P 2y            ", 2, 3, (/ 0, 0, 0, 24, 24, 12/),"b    ") , &
13413            spgr_info_type(  3,"P 2         ","P 2y            ", 2, 3, (/ 0, 0, 0, 24, 24, 12/),"b    ") , &
13414            spgr_info_type(  3,"P 1 1 2     ","P 2             ", 2, 3, (/ 0, 0, 0, 12, 24, 24/),"c    ") , &
13415            spgr_info_type(  3,"P 2 1 1     ","P 2x            ", 2, 3, (/ 0, 0, 0, 24, 12, 24/),"a    ") , &
13416            spgr_info_type(  4,"P 1 21 1    ","P 2yb           ", 2, 3, (/ 0, 0, 0, 24, 24, 12/),"b    ") , &
13417            spgr_info_type(  4,"P 21        ","P 2yb           ", 2, 3, (/ 0, 0, 0, 24, 24, 12/),"b    ") , &
13418            spgr_info_type(  4,"P 1 1 21    ","P 2c            ", 2, 3, (/ 0, 0, 0, 12, 24, 24/),"c    ") , &
13419            spgr_info_type(  4,"P 21 1 1    ","P 2xa           ", 2, 3, (/ 0, 0, 0, 24, 12, 24/),"a    ") , &
13420            spgr_info_type(  5,"C 1 2 1     ","C 2y            ", 2, 3, (/ 0, 0, 0, 12, 12, 24/),"b1   ") , &
13421            spgr_info_type(  5,"C 2         ","C 2y            ", 2, 3, (/ 0, 0, 0, 12, 12, 24/),"b1   ") , &
13422            spgr_info_type(  5,"A 1 2 1     ","A 2y            ", 2, 3, (/ 0, 0, 0, 12, 12, 24/),"b2   ") , &
13423            spgr_info_type(  5,"A 2         ","A 2y            ", 2, 3, (/ 0, 0, 0, 12, 12, 24/),"b2   ") , &
13424            spgr_info_type(  5,"I 1 2 1     ","I 2y            ", 2, 3, (/ 0, 0, 0, 12, 12, 24/),"b2   ") , &
13425            spgr_info_type(  5,"I 2         ","I 2y            ", 2, 3, (/ 0, 0, 0, 12, 12, 24/),"b2   ") , &
13426            spgr_info_type(  5,"A 1 1 2     ","A 2             ", 2, 3, (/ 0, 0, 0, 24, 12, 12/),"c1   ") , &
13427            spgr_info_type(  5,"B 1 1 2     ","B 2             ", 2, 3, (/ 0, 0, 0, 24, 12, 12/),"c2   ") , &
13428            spgr_info_type(  5,"I 1 1 2     ","I 2             ", 2, 3, (/ 0, 0, 0, 24, 12, 12/),"c3   ") , &
13429            spgr_info_type(  5,"B 2 1 1     ","B 2x            ", 2, 3, (/ 0, 0, 0, 12, 24, 12/),"a1   ") , &
13430            spgr_info_type(  5,"C 2 1 1     ","C 2x            ", 2, 3, (/ 0, 0, 0, 12, 24, 12/),"a2   ") , &
13431            spgr_info_type(  5,"I 2 1 1     ","I 2x            ", 2, 3, (/ 0, 0, 0, 12, 24, 12/),"a3   ") , &
13432            spgr_info_type(  6,"P 1 M 1     ","P -2y           ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b    ") , &
13433            spgr_info_type(  6,"P M         ","P -2y           ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b    ") , &
13434            spgr_info_type(  6,"P 1 1 M     ","P -2            ", 2, 4, (/ 0, 0, 0, 24, 24, 12/),"c    ") , &
13435            spgr_info_type(  6,"P M 1 1     ","P -2x           ", 2, 4, (/ 0, 0, 0, 12, 24, 24/),"a    ") , &
13436            spgr_info_type(  7,"P 1 C 1     ","P -2yc          ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b1   ") , &
13437            spgr_info_type(  7,"P C         ","P -2yc          ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b1   ") , &
13438            spgr_info_type(  7,"P 1 N 1     ","P -2yac         ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b2   ") , &
13439            spgr_info_type(  7,"P N         ","P -2yac         ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b2   ") , &
13440            spgr_info_type(  7,"P 1 A 1     ","P -2ya          ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b3   ") , &
13441            spgr_info_type(  7,"P A         ","P -2ya          ", 2, 4, (/ 0, 0, 0, 24, 12, 24/),"b3   ") /)
13442
13443       spgr_info(45:74)= (/                                           &
13444            spgr_info_type(  7,"P 1 1 A     ","P -2a           ", 2, 4, (/ 0, 0, 0, 24, 24, 12/),"c1   ") , &
13445            spgr_info_type(  7,"P 1 1 N     ","P -2ab          ", 2, 4, (/ 0, 0, 0, 24, 24, 12/),"c2   ") , &
13446            spgr_info_type(  7,"P 1 1 B     ","P -2b           ", 2, 4, (/ 0, 0, 0, 24, 24, 12/),"c3   ") , &
13447            spgr_info_type(  7,"P B 1 1     ","P -2xb          ", 2, 4, (/ 0, 0, 0, 12, 24, 24/),"a1   ") , &
13448            spgr_info_type(  7,"P N 1 1     ","P -2xbc         ", 2, 4, (/ 0, 0, 0, 12, 24, 24/),"a2   ") , &
13449            spgr_info_type(  7,"P C 1 1     ","P -2xc          ", 2, 4, (/ 0, 0, 0, 12, 24, 24/),"a3   ") , &
13450            spgr_info_type(  8,"C 1 M 1     ","C -2y           ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13451            spgr_info_type(  8,"C M         ","C -2y           ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13452            spgr_info_type(  8,"A 1 M 1     ","A -2y           ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b2   ") , &
13453            spgr_info_type(  8,"A M         ","A -2y           ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b2   ") , &
13454            spgr_info_type(  8,"I 1 M 1     ","I -2y           ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b3   ") , &
13455            spgr_info_type(  8,"I M         ","I -2y           ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b3   ") , &
13456            spgr_info_type(  8,"A 1 1 M     ","A -2            ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"c1   ") , &
13457            spgr_info_type(  8,"B 1 1 M     ","B -2            ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"c2   ") , &
13458            spgr_info_type(  8,"I 1 1 M     ","I -2            ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"c3   ") , &
13459            spgr_info_type(  8,"B M 1 1     ","B -2x           ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"a1   ") , &
13460            spgr_info_type(  8,"C M 1 1     ","C -2x           ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"a2   ") , &
13461            spgr_info_type(  8,"I M 1 1     ","I -2x           ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"a3   ") , &
13462            spgr_info_type(  9,"C 1 C 1     ","C -2yc          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13463            spgr_info_type(  9,"C C         ","C -2yc          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13464            spgr_info_type(  9,"A 1 N 1     ","A -2yac         ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b2   ") , &
13465            spgr_info_type(  9,"A N         ","A -2yac         ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b2   ") , &
13466            spgr_info_type(  9,"I 1 A 1     ","I -2ya          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b3   ") , &
13467            spgr_info_type(  9,"I A         ","I -2ya          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"b3   ") , &
13468            spgr_info_type(  9,"A 1 A 1     ","A -2ya          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"-b1  ") , &
13469            spgr_info_type(  9,"A A         ","A -2ya          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"-b1  ") , &
13470            spgr_info_type(  9,"C 1 N 1     ","C -2ybc         ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"-b2  ") , &
13471            spgr_info_type(  9,"C N         ","C -2ybc         ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"-b2  ") , &
13472            spgr_info_type(  9,"I 1 C 1     ","I -2yc          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"-b3  ") , &
13473            spgr_info_type(  9,"I C         ","I -2yc          ", 2, 4, (/ 0, 0, 0, 24,  6, 24/),"-b3  ") /)
13474
13475       spgr_info(75:104)= (/                                           &
13476            spgr_info_type(  9,"A 1 1 A     ","A -2a           ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"c1   ") , &
13477            spgr_info_type(  9,"B 1 1 N     ","B -2bc          ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"c2   ") , &
13478            spgr_info_type(  9,"I 1 1 B     ","I -2b           ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"c3   ") , &
13479            spgr_info_type(  9,"B 1 1 B     ","B -2b           ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"-c1  ") , &
13480            spgr_info_type(  9,"A 1 1 N     ","A -2ac          ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"-c2  ") , &
13481            spgr_info_type(  9,"I 1 1 A     ","I -2a           ", 2, 4, (/ 0, 0, 0, 24, 24,  6/),"-c3  ") , &
13482            spgr_info_type(  9,"B B 1 1     ","B -2xb          ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"a1   ") , &
13483            spgr_info_type(  9,"C N 1 1     ","C -2xbc         ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"a2   ") , &
13484            spgr_info_type(  9,"I C 1 1     ","I -2xc          ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"a3   ") , &
13485            spgr_info_type(  9,"C C 1 1     ","C -2xc          ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"-a1  ") , &
13486            spgr_info_type(  9,"B N 1 1     ","B -2xbc         ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"-a2  ") , &
13487            spgr_info_type(  9,"I B 1 1     ","I -2xb          ", 2, 4, (/ 0, 0, 0,  6, 24, 24/),"-a3  ") , &
13488            spgr_info_type( 10,"P 1 2/M 1   ","-P 2y           ", 2, 5, (/ 0, 0, 0, 12, 12, 24/),"b    ") , &
13489            spgr_info_type( 10,"P 2/M       ","-P 2y           ", 2, 5, (/ 0, 0, 0, 12, 12, 24/),"b    ") , &
13490            spgr_info_type( 10,"P 1 1 2/M   ","-P 2            ", 2, 5, (/ 0, 0, 0, 24, 12, 12/),"c    ") , &
13491            spgr_info_type( 10,"P 2/M 1 1   ","-P 2x           ", 2, 5, (/ 0, 0, 0, 12, 24, 12/),"a    ") , &
13492            spgr_info_type( 11,"P 1 21/M 1  ","-P 2yb          ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b    ") , &
13493            spgr_info_type( 11,"P 21/M      ","-P 2yb          ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b    ") , &
13494            spgr_info_type( 11,"P 1 1 21/M  ","-P 2c           ", 2, 5, (/ 0, 0, 0, 24, 24,  6/),"c    ") , &
13495            spgr_info_type( 11,"P 21/M 1 1  ","-P 2xa          ", 2, 5, (/ 0, 0, 0,  6, 24, 24/),"a    ") , &
13496            spgr_info_type( 11,"B 1 21/M 1  ","-B 2yb          ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b    ") , &
13497            spgr_info_type( 11,"B 21/M      ","-B 2yb          ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b    ") , &
13498            spgr_info_type( 12,"C 1 2/M 1   ","-C 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b1   ") , &
13499            spgr_info_type( 12,"C 2/M       ","-C 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b1   ") , &
13500            spgr_info_type( 12,"A 1 2/M 1   ","-A 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b2   ") , &
13501            spgr_info_type( 12,"A 2/M       ","-A 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b2   ") , &
13502            spgr_info_type( 12,"I 1 2/M 1   ","-I 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b3   ") , &
13503            spgr_info_type( 12,"I 2/M       ","-I 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b3   ") , &
13504            spgr_info_type( 12,"A 1 1 2/M   ","-A 2            ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"c1   ") , &
13505            spgr_info_type( 12,"B 1 1 2/M   ","-B 2            ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"c2   ") /)
13506
13507       spgr_info(105:134)= (/                                           &
13508            spgr_info_type( 12,"I 1 1 2/M   ","-I 2            ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"c3   ") , &
13509            spgr_info_type( 12,"B 2/M 1 1   ","-B 2x           ", 2, 5, (/ 0, 0, 0,  6, 24, 12/),"a1   ") , &
13510            spgr_info_type( 12,"C 2/M 1 1   ","-C 2x           ", 2, 5, (/ 0, 0, 0,  6, 24, 12/),"a2   ") , &
13511            spgr_info_type( 12,"I 2/M 1 1   ","-I 2x           ", 2, 5, (/ 0, 0, 0,  6, 24, 12/),"a3   ") , &
13512            spgr_info_type( 12,"F 1 2/M 1   ","-F 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b1   ") , &
13513            spgr_info_type( 12,"F 2/M       ","-F 2y           ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"b1   ") , &
13514            spgr_info_type( 13,"P 1 2/C 1   ","-P 2yc          ", 2, 5, (/ 0, 0, 0, 12, 24, 12/),"b1   ") , &
13515            spgr_info_type( 13,"P 2/C       ","-P 2yc          ", 2, 5, (/ 0, 0, 0, 12, 24, 12/),"b1   ") , &
13516            spgr_info_type( 13,"P 1 2/C 1   ","-P 2yc          ", 2, 5, (/ 0, 0, 0, 12, 24, 12/),"b1   ") , &
13517            spgr_info_type( 13,"P 1 2/N 1   ","-P 2yac         ", 2, 5, (/ 0, 0, 0, 24, 24,  6/),"b2   ") , &
13518            spgr_info_type( 13,"P 2/N       ","-P 2yac         ", 2, 5, (/ 0, 0, 0, 24, 24,  6/),"b2   ") , &
13519            spgr_info_type( 13,"P 1 2/A 1   ","-P 2ya          ", 2, 5, (/ 0, 0, 0, 12, 24, 12/),"b3   ") , &
13520            spgr_info_type( 13,"P 2/A       ","-P 2ya          ", 2, 5, (/ 0, 0, 0, 12, 24, 12/),"b3   ") , &
13521            spgr_info_type( 13,"P 1 1 2/A   ","-P 2a           ", 2, 5, (/ 0, 0, 0, 12, 12, 24/),"c1   ") , &
13522            spgr_info_type( 13,"C 1 1 2/A   ","-C 2a           ", 2, 5, (/ 0, 0, 0, 12, 12, 24/),"c1   ") , &
13523            spgr_info_type( 13,"P 1 1 2/N   ","-P 2ab          ", 2, 5, (/ 0, 0, 0,  6, 24, 24/),"c2   ") , &
13524            spgr_info_type( 13,"P 1 1 2/B   ","-P 2b           ", 2, 5, (/ 0, 0, 0, 12, 12, 24/),"c3   ") , &
13525            spgr_info_type( 13,"P 2/B 1 1   ","-P 2xb          ", 2, 5, (/ 0, 0, 0, 24, 12, 12/),"a1   ") , &
13526            spgr_info_type( 13,"P 2/N 1 1   ","-P 2xbc         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"a2   ") , &
13527            spgr_info_type( 13,"P 2/C 1 1   ","-P 2xc          ", 2, 5, (/ 0, 0, 0, 24, 12, 12/),"a3   ") , &
13528            spgr_info_type( 14,"P 1 21/C 1  ","-P 2ybc         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13529            spgr_info_type( 14,"P 21/C      ","-P 2ybc         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13530            spgr_info_type( 14,"B 1 21/C 1  ","-B 2ybc         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13531            spgr_info_type( 14,"B 21/C      ","-B 2ybc         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b1   ") , &
13532            spgr_info_type( 14,"P 1 21/N 1  ","-P 2yn          ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b2   ") , &
13533            spgr_info_type( 14,"P 21/N      ","-P 2yn          ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b2   ") , &
13534            spgr_info_type( 14,"P 1 21/A 1  ","-P 2yab         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b3   ") , &
13535            spgr_info_type( 14,"P 21/A      ","-P 2yab         ", 2, 5, (/ 0, 0, 0, 24,  6, 24/),"b3   ") , &
13536            spgr_info_type( 14,"P 1 1 21/A  ","-P 2ac          ", 2, 5, (/ 0, 0, 0, 24, 24,  6/),"c1   ") , &
13537            spgr_info_type( 14,"P 1 1 21/N  ","-P 2n           ", 2, 5, (/ 0, 0, 0, 24, 24,  6/),"c2   ") /)
13538
13539       spgr_info(135:162)= (/                                           &
13540            spgr_info_type( 14,"P 1 1 21/B  ","-P 2bc          ", 2, 5, (/ 0, 0, 0, 24, 24,  6/),"c3   ") , &
13541            spgr_info_type( 14,"P 21/B 1 1  ","-P 2xab         ", 2, 5, (/ 0, 0, 0,  6, 24, 24/),"a1   ") , &
13542            spgr_info_type( 14,"P 21/N 1 1  ","-P 2xn          ", 2, 5, (/ 0, 0, 0,  6, 24, 24/),"a2   ") , &
13543            spgr_info_type( 14,"P 21/C 1 1  ","-P 2xac         ", 2, 5, (/ 0, 0, 0,  6, 24, 24/),"a3   ") , &
13544            spgr_info_type( 15,"C 1 2/C 1   ","-C 2yc          ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"b1   ") , &
13545            spgr_info_type( 15,"C 2/C       ","-C 2yc          ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"b1   ") , &
13546            spgr_info_type( 15,"A 1 2/N 1   ","-A 2yac         ", 2, 5, (/ 0, 0, 0, 12, 24,  6/),"b2   ") , &
13547            spgr_info_type( 15,"A 2/N       ","-A 2yac         ", 2, 5, (/ 0, 0, 0, 12, 24,  6/),"b2   ") , &
13548            spgr_info_type( 15,"I 1 2/A 1   ","-I 2ya          ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"b3   ") , &
13549            spgr_info_type( 15,"I 2/A       ","-I 2ya          ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"b3   ") , &
13550            spgr_info_type( 15,"A 1 2/A 1   ","-A 2ya          ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"-b1  ") , &
13551            spgr_info_type( 15,"A 2/A       ","-A 2ya          ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"-b1  ") , &
13552            spgr_info_type( 15,"C 1 2/N 1   ","-C 2ybc         ", 2, 5, (/ 0, 0, 0,  6, 24, 12/),"-b2  ") , &
13553            spgr_info_type( 15,"C 2/N       ","-C 2ybc         ", 2, 5, (/ 0, 0, 0,  6, 24, 12/),"-b2  ") , &
13554            spgr_info_type( 15,"I 1 2/C 1   ","-I 2yc          ", 2, 5, (/ 0, 0, 0,  6, 12, 24/),"-b3  ") , &
13555            spgr_info_type( 15,"I 2/C       ","-I 2yc          ", 2, 5, (/ 0, 0, 0,  6, 12, 24/),"-b3  ") , &
13556            spgr_info_type( 15,"A 1 1 2/A   ","-A 2a           ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"c1   ") , &
13557            spgr_info_type( 15,"B 1 1 2/N   ","-B 2bc          ", 2, 5, (/ 0, 0, 0,  6, 12, 24/),"c2   ") , &
13558            spgr_info_type( 15,"I 1 1 2/B   ","-I 2b           ", 2, 5, (/ 0, 0, 0,  6, 24, 12/),"c3   ") , &
13559            spgr_info_type( 15,"B 1 1 2/B   ","-B 2b           ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"-c1  ") , &
13560            spgr_info_type( 15,"A 1 1 2/N   ","-A 2ac          ", 2, 5, (/ 0, 0, 0, 12,  6, 24/),"-c2  ") , &
13561            spgr_info_type( 15,"I 1 1 2/A   ","-I 2a           ", 2, 5, (/ 0, 0, 0, 24,  6, 12/),"-c3  ") , &
13562            spgr_info_type( 15,"B 2/B 1 1   ","-B 2xb          ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"a1   ") , &
13563            spgr_info_type( 15,"C 2/N 1 1   ","-C 2xbc         ", 2, 5, (/ 0, 0, 0, 24,  6, 12/),"a2   ") , &
13564            spgr_info_type( 15,"I 2/C 1 1   ","-I 2xc          ", 2, 5, (/ 0, 0, 0, 24,  6, 12/),"a3   ") , &
13565            spgr_info_type( 15,"C 2/C 1 1   ","-C 2xc          ", 2, 5, (/ 0, 0, 0, 12, 12, 12/),"-a1  ") , &
13566            spgr_info_type( 15,"B 2/N 1 1   ","-B 2xbc         ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"-a2  ") , &
13567            spgr_info_type( 15,"I 2/B 1 1   ","-I 2xb          ", 2, 5, (/ 0, 0, 0, 24, 12,  6/),"-a3  ") /)
13568
13569       !---- Orthorhombic ----!
13570       spgr_info(163:192)= (/                                           &
13571            spgr_info_type( 16,"P 2 2 2     ","P 2 2           ", 3, 6, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13572            spgr_info_type( 17,"P 2 2 21    ","P 2c 2          ", 3, 6, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13573            spgr_info_type( 17,"P 21 2 2    ","P 2a 2a         ", 3, 6, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13574            spgr_info_type( 17,"P 2 21 2    ","P 2 2b          ", 3, 6, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13575            spgr_info_type( 18,"P 21 21 2   ","P 2 2ab         ", 3, 6, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13576            spgr_info_type( 18,"P 2 21 21   ","P 2bc 2         ", 3, 6, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13577            spgr_info_type( 18,"P 21 2 21   ","P 2ac 2ac       ", 3, 6, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13578            spgr_info_type( 19,"P 21 21 21  ","P 2ac 2ab       ", 3, 6, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13579            spgr_info_type( 20,"C 2 2 21    ","C 2c 2          ", 3, 6, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13580            spgr_info_type( 20,"A 21 2 2    ","A 2a 2a         ", 3, 6, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13581            spgr_info_type( 20,"B 2 21 2    ","B 2 2b          ", 3, 6, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13582            spgr_info_type( 21,"C 2 2 2     ","C 2 2           ", 3, 6, (/ 0, 0, 0,  6, 12, 24/),"     ") , &
13583            spgr_info_type( 21,"A 2 2 2     ","A 2 2           ", 3, 6, (/ 0, 0, 0, 24,  6, 12/),"cab  ") , &
13584            spgr_info_type( 21,"B 2 2 2     ","B 2 2           ", 3, 6, (/ 0, 0, 0, 12, 24,  6/),"bca  ") , &
13585            spgr_info_type( 22,"F 2 2 2     ","F 2 2           ", 3, 6, (/ 0, 0, 0,  6,  6, 24/),"     ") , &
13586            spgr_info_type( 23,"I 2 2 2     ","I 2 2           ", 3, 6, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13587            spgr_info_type( 24,"I 21 21 21  ","I 2b 2c         ", 3, 6, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13588            spgr_info_type( 25,"P M M 2     ","P 2 -2          ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13589            spgr_info_type( 25,"P 2 M M     ","P -2 2          ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13590            spgr_info_type( 25,"P M 2 M     ","P -2 -2         ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13591            spgr_info_type( 26,"P M C 21    ","P 2c -2         ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13592            spgr_info_type( 26,"P C M 21    ","P 2c -2c        ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"ba-c ") , &
13593            spgr_info_type( 26,"P 21 M A    ","P -2a 2a        ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13594            spgr_info_type( 26,"P 21 A M    ","P -2 2a         ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"-cba ") , &
13595            spgr_info_type( 26,"P B 21 M    ","P -2 -2b        ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13596            spgr_info_type( 26,"P M 21 B    ","P -2b -2        ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"a-cb ") , &
13597            spgr_info_type( 27,"P C C 2     ","P 2 -2c         ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13598            spgr_info_type( 27,"P 2 A A     ","P -2a 2         ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13599            spgr_info_type( 27,"P B 2 B     ","P -2b -2b       ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13600            spgr_info_type( 28,"P M A 2     ","P 2 -2a         ", 3, 7, (/ 0, 0, 0,  6, 24, 24/),"     ") /)
13601
13602       spgr_info(193:222)= (/                                           &
13603            spgr_info_type( 28,"P B M 2     ","P 2 -2b         ", 3, 7, (/ 0, 0, 0, 24,  6, 24/),"ba-c ") , &
13604            spgr_info_type( 28,"P 2 M B     ","P -2b 2         ", 3, 9, (/ 0, 0, 0, 24,  6, 24/),"cab  ") , &
13605            spgr_info_type( 28,"P 2 C M     ","P -2c 2         ", 3, 9, (/ 0, 0, 0, 24, 24,  6/),"-cba ") , &
13606            spgr_info_type( 28,"P C 2 M     ","P -2c -2c       ", 3, 8, (/ 0, 0, 0, 24, 24,  6/),"bca  ") , &
13607            spgr_info_type( 28,"P M 2 A     ","P -2a -2a       ", 3, 8, (/ 0, 0, 0,  6, 24, 24/),"a-cb ") , &
13608            spgr_info_type( 29,"P C A 21    ","P 2c -2ac       ", 3, 7, (/ 0, 0, 0,  6, 24, 24/),"     ") , &
13609            spgr_info_type( 29,"P B C 21    ","P 2c -2b        ", 3, 7, (/ 0, 0, 0, 24,  6, 24/),"ba-c ") , &
13610            spgr_info_type( 29,"P 21 A B    ","P -2b 2a        ", 3, 9, (/ 0, 0, 0, 24,  6, 24/),"cab  ") , &
13611            spgr_info_type( 29,"P 21 C A    ","P -2ac 2a       ", 3, 9, (/ 0, 0, 0, 24, 24,  6/),"-cba ") , &
13612            spgr_info_type( 29,"P C 21 B    ","P -2bc -2c      ", 3, 8, (/ 0, 0, 0, 24, 24,  6/),"bca  ") , &
13613            spgr_info_type( 29,"P B 21 A    ","P -2a -2ab      ", 3, 8, (/ 0, 0, 0,  6, 24, 24/),"a-cb ") , &
13614            spgr_info_type( 30,"P N C 2     ","P 2 -2bc        ", 3, 7, (/ 0, 0, 0, 12, 24, 12/),"     ") , &
13615            spgr_info_type( 30,"P C N 2     ","P 2 -2ac        ", 3, 7, (/ 0, 0, 0, 24, 12, 12/),"ba-c ") , &
13616            spgr_info_type( 30,"P 2 N A     ","P -2ac 2        ", 3, 9, (/ 0, 0, 0, 12, 12, 24/),"cab  ") , &
13617            spgr_info_type( 30,"P 2 A N     ","P -2ab 2        ", 3, 9, (/ 0, 0, 0, 12, 24, 12/),"-cba ") , &
13618            spgr_info_type( 30,"P B 2 N     ","P -2ab -2ab     ", 3, 8, (/ 0, 0, 0, 24, 12, 12/),"bca  ") , &
13619            spgr_info_type( 30,"P N 2 B     ","P -2bc -2bc     ", 3, 8, (/ 0, 0, 0, 12, 12, 24/),"a-cb ") , &
13620            spgr_info_type( 31,"P M N 21    ","P 2ac -2        ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13621            spgr_info_type( 31,"P N M 21    ","P 2bc -2bc      ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"ba-c ") , &
13622            spgr_info_type( 31,"P 21 M N    ","P -2ab 2ab      ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13623            spgr_info_type( 31,"P 21 N M    ","P -2 2ac        ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"-cba ") , &
13624            spgr_info_type( 31,"P N 21 M    ","P -2 -2bc       ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13625            spgr_info_type( 31,"P M 21 N    ","P -2ab -2       ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"a-cb ") , &
13626            spgr_info_type( 32,"P B A 2     ","P 2 -2ab        ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13627            spgr_info_type( 32,"P 2 C B     ","P -2bc 2        ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13628            spgr_info_type( 32,"P C 2 A     ","P -2ac -2ac     ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13629            spgr_info_type( 33,"P N A 21    ","P 2c -2n        ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13630            spgr_info_type( 33,"P B N 21    ","P 2c -2ab       ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"ba-c ") , &
13631            spgr_info_type( 33,"P 21 N B    ","P -2bc 2a       ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13632            spgr_info_type( 33,"P 21 C N    ","P -2n 2a        ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"-cba ") /)
13633
13634       spgr_info(223:252)= (/                                           &
13635            spgr_info_type( 33,"P C 21 N    ","P -2n -2ac      ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13636            spgr_info_type( 33,"P N 21 A    ","P -2ac -2n      ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"a-cb ") , &
13637            spgr_info_type( 34,"P N N 2     ","P 2 -2n         ", 3, 7, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13638            spgr_info_type( 34,"P 2 N N     ","P -2n 2         ", 3, 9, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13639            spgr_info_type( 34,"P N 2 N     ","P -2n -2n       ", 3, 8, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13640            spgr_info_type( 35,"C M M 2     ","C 2 -2          ", 3, 7, (/ 0, 0, 0,  6, 12, 24/),"     ") , &
13641            spgr_info_type( 35,"A 2 M M     ","A -2 2          ", 3, 9, (/ 0, 0, 0, 24,  6, 12/),"cab  ") , &
13642            spgr_info_type( 35,"B M 2 M     ","B -2 -2         ", 3, 8, (/ 0, 0, 0, 12, 24,  6/),"bca  ") , &
13643            spgr_info_type( 36,"C M C 21    ","C 2c -2         ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13644            spgr_info_type( 36,"C C M 21    ","C 2c -2c        ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"ba-c ") , &
13645            spgr_info_type( 36,"A 21 M A    ","A -2a 2a        ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13646            spgr_info_type( 36,"A 21 A M    ","A -2 2a         ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"-cba ") , &
13647            spgr_info_type( 36,"B B 21 M    ","B -2 -2b        ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13648            spgr_info_type( 36,"B M 21 B    ","B -2b -2        ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"a-cb ") , &
13649            spgr_info_type( 37,"C C C 2     ","C 2 -2c         ", 3, 7, (/ 0, 0, 0,  6, 12, 24/),"     ") , &
13650            spgr_info_type( 37,"A 2 A A     ","A -2a 2         ", 3, 9, (/ 0, 0, 0, 24,  6, 12/),"cab  ") , &
13651            spgr_info_type( 37,"B B 2 B     ","B -2b -2b       ", 3, 8, (/ 0, 0, 0, 12, 24,  6/),"bca  ") , &
13652            spgr_info_type( 38,"A M M 2     ","A 2 -2          ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13653            spgr_info_type( 38,"B M M 2     ","B 2 -2          ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"ba-c ") , &
13654            spgr_info_type( 38,"B 2 M M     ","B -2 2          ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13655            spgr_info_type( 38,"C 2 M M     ","C -2 2          ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"-cba ") , &
13656            spgr_info_type( 38,"C M 2 M     ","C -2 -2         ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13657            spgr_info_type( 38,"A M 2 M     ","A -2 -2         ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"a-cb ") , &
13658            spgr_info_type( 39,"A B M 2     ","A 2 -2c         ", 3, 7, (/ 0, 0, 0, 12,  6, 24/),"     ") , &
13659            spgr_info_type( 39,"B M A 2     ","B 2 -2c         ", 3, 7, (/ 0, 0, 0,  6, 12, 24/),"ba-c ") , &
13660            spgr_info_type( 39,"B 2 C M     ","B -2c 2         ", 3, 9, (/ 0, 0, 0, 24, 12,  6/),"cab  ") , &
13661            spgr_info_type( 39,"C 2 M B     ","C -2b 2         ", 3, 9, (/ 0, 0, 0, 24,  6, 12/),"-cba ") , &
13662            spgr_info_type( 39,"C M 2 A     ","C -2b -2b       ", 3, 8, (/ 0, 0, 0,  6, 24, 12/),"bca  ") , &
13663            spgr_info_type( 39,"A C 2 M     ","A -2c -2c       ", 3, 8, (/ 0, 0, 0, 12, 24,  6/),"a-cb ") , &
13664            spgr_info_type( 40,"A M A 2     ","A 2 -2a         ", 3, 7, (/ 0, 0, 0,  6, 12, 24/),"     ") /)
13665
13666       spgr_info(253:282)= (/                                           &
13667            spgr_info_type( 40,"B B M 2     ","B 2 -2b         ", 3, 7, (/ 0, 0, 0, 12,  6, 24/),"ba-c ") , &
13668            spgr_info_type( 40,"B 2 M B     ","B -2b 2         ", 3, 9, (/ 0, 0, 0, 24,  6, 12/),"cab  ") , &
13669            spgr_info_type( 40,"C 2 C M     ","C -2c 2         ", 3, 9, (/ 0, 0, 0, 24, 12,  6/),"-cba ") , &
13670            spgr_info_type( 40,"C C 2 M     ","C -2c -2c       ", 3, 8, (/ 0, 0, 0, 12, 24,  6/),"bca  ") , &
13671            spgr_info_type( 40,"A M 2 A     ","A -2a -2a       ", 3, 8, (/ 0, 0, 0,  6, 24, 12/),"a-cb ") , &
13672            spgr_info_type( 41,"A B A 2     ","A 2 -2ac        ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13673            spgr_info_type( 41,"B B A 2     ","B 2 -2bc        ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"ba-c ") , &
13674            spgr_info_type( 41,"B 2 C B     ","B -2bc 2        ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13675            spgr_info_type( 41,"C 2 C B     ","C -2bc 2        ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"-cba ") , &
13676            spgr_info_type( 41,"C C 2 A     ","C -2bc -2bc     ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13677            spgr_info_type( 41,"A C 2 A     ","A -2ac -2ac     ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"a-cb ") , &
13678            spgr_info_type( 42,"F M M 2     ","F 2 -2          ", 3, 7, (/ 0, 0, 0,  6,  6, 24/),"     ") , &
13679            spgr_info_type( 42,"F 2 M M     ","F -2 2          ", 3, 9, (/ 0, 0, 0, 24,  6,  6/),"cab  ") , &
13680            spgr_info_type( 42,"F M 2 M     ","F -2 -2         ", 3, 8, (/ 0, 0, 0,  6, 24,  6/),"bca  ") , &
13681            spgr_info_type( 43,"F D D 2     ","F 2 -2d         ", 3, 7, (/ 0, 0, 0,  6,  6, 24/),"     ") , &
13682            spgr_info_type( 43,"F 2 D D     ","F -2d 2         ", 3, 9, (/ 0, 0, 0, 24,  6,  6/),"cab  ") , &
13683            spgr_info_type( 43,"F D 2 D     ","F -2d -2d       ", 3, 8, (/ 0, 0, 0,  6, 24,  6/),"bca  ") , &
13684            spgr_info_type( 44,"I M M 2     ","I 2 -2          ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13685            spgr_info_type( 44,"I 2 M M     ","I -2 2          ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13686            spgr_info_type( 44,"I M 2 M     ","I -2 -2         ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13687            spgr_info_type( 45,"I B A 2     ","I 2 -2c         ", 3, 7, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13688            spgr_info_type( 45,"I 2 C B     ","I -2a 2         ", 3, 9, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13689            spgr_info_type( 45,"I C 2 A     ","I -2b -2b       ", 3, 8, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13690            spgr_info_type( 46,"I M A 2     ","I 2 -2a         ", 3, 7, (/ 0, 0, 0,  6, 24, 12/),"     ") , &
13691            spgr_info_type( 46,"I B M 2     ","I 2 -2b         ", 3, 7, (/ 0, 0, 0, 24,  6, 12/),"ba-c ") , &
13692            spgr_info_type( 46,"I 2 M B     ","I -2b 2         ", 3, 9, (/ 0, 0, 0, 12,  6, 24/),"cab  ") , &
13693            spgr_info_type( 46,"I 2 C M     ","I -2c 2         ", 3, 9, (/ 0, 0, 0, 12, 24,  6/),"-cba ") , &
13694            spgr_info_type( 46,"I C 2 M     ","I -2c -2c       ", 3, 8, (/ 0, 0, 0, 24, 12,  6/),"bca  ") , &
13695            spgr_info_type( 46,"I M 2 A     ","I -2a -2a       ", 3, 8, (/ 0, 0, 0,  6, 12, 12/),"a-cb ") , &
13696            spgr_info_type( 47,"P M M M     ","-P 2 2          ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") /)
13697
13698       spgr_info(283:312)= (/                                           &
13699            spgr_info_type( 48,"P N N N:1   ","P 2 2 -1n       ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"1    ") , &
13700            spgr_info_type( 48,"P N N N     ","-P 2ab 2bc      ", 3,10, (/ 0,-6, 0,  6,  6, 24/),"2    ") , &
13701            spgr_info_type( 49,"P C C M     ","-P 2 2c         ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13702            spgr_info_type( 49,"P M A A     ","-P 2a 2         ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13703            spgr_info_type( 49,"P B M B     ","-P 2b 2b        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13704            spgr_info_type( 50,"P B A N:1   ","P 2 2 -1ab      ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"1    ") , &
13705            spgr_info_type( 50,"P B A N     ","-P 2ab 2b       ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"2    ") , &
13706            spgr_info_type( 50,"P N C B:1   ","P 2 2 -1bc      ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"1cab ") , &
13707            spgr_info_type( 50,"P N C B     ","-P 2b 2bc       ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"2cab ") , &
13708            spgr_info_type( 50,"P C N A:1   ","P 2 2 -1ac      ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"1bca ") , &
13709            spgr_info_type( 50,"P C N A     ","-P 2a 2c        ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"2bca ") , &
13710            spgr_info_type( 51,"P M M A     ","-P 2a 2a        ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"     ") , &
13711            spgr_info_type( 51,"P M M B     ","-P 2b 2         ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"ba-c ") , &
13712            spgr_info_type( 51,"P B M M     ","-P 2 2b         ", 3,10, (/ 0, 0, 0, 24,  6, 12/),"cab  ") , &
13713            spgr_info_type( 51,"P C M M     ","-P 2c 2c        ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"-cba ") , &
13714            spgr_info_type( 51,"P M C M     ","-P 2c 2         ", 3,10, (/ 0, 0, 0, 12, 24,  6/),"bca  ") , &
13715            spgr_info_type( 51,"P M A M     ","-P 2 2a         ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"a-cb ") , &
13716            spgr_info_type( 52,"P N N A     ","-P 2a 2bc       ", 3,10, (/ 0, 0, 0, 24,  6, 12/),"     ") , &
13717            spgr_info_type( 52,"P N N B     ","-P 2b 2n        ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"ba-c ") , &
13718            spgr_info_type( 52,"P B N N     ","-P 2n 2b        ", 3,10, (/ 0, 0, 0, 12, 24,  6/),"cab  ") , &
13719            spgr_info_type( 52,"P C N N     ","-P 2ab 2c       ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"-cba ") , &
13720            spgr_info_type( 52,"P N C N     ","-P 2ab 2n       ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"bca  ") , &
13721            spgr_info_type( 52,"P N A N     ","-P 2n 2bc       ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"a-cb ") , &
13722            spgr_info_type( 53,"P M N A     ","-P 2ac 2        ", 3,10, (/ 0, 0, 0, 12, 24,  6/),"     ") , &
13723            spgr_info_type( 53,"P N M B     ","-P 2bc 2bc      ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"ba-c ") , &
13724            spgr_info_type( 53,"P B M N     ","-P 2ab 2ab      ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"cab  ") , &
13725            spgr_info_type( 53,"P C N M     ","-P 2 2ac        ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"-cba ") , &
13726            spgr_info_type( 53,"P N C M     ","-P 2 2bc        ", 3,10, (/ 0, 0, 0, 24,  6, 12/),"bca  ") , &
13727            spgr_info_type( 53,"P M A N     ","-P 2ab 2        ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"a-cb ") , &
13728            spgr_info_type( 54,"P C C A     ","-P 2a 2ac       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") /)
13729
13730       spgr_info(313:342)= (/                                           &
13731            spgr_info_type( 54,"P C C B     ","-P 2b 2c        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"ba-c ") , &
13732            spgr_info_type( 54,"P B A A     ","-P 2a 2b        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13733            spgr_info_type( 54,"P C A A     ","-P 2ac 2c       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"-cba ") , &
13734            spgr_info_type( 54,"P B C B     ","-P 2bc 2b       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13735            spgr_info_type( 54,"P B A B     ","-P 2b 2ab       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"a-cb ") , &
13736            spgr_info_type( 55,"P B A M     ","-P 2 2ab        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13737            spgr_info_type( 55,"P M C B     ","-P 2bc 2        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13738            spgr_info_type( 55,"P C M A     ","-P 2ac 2ac      ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13739            spgr_info_type( 56,"P C C N     ","-P 2ab 2ac      ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"     ") , &
13740            spgr_info_type( 56,"P N A A     ","-P 2ac 2bc      ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"cab  ") , &
13741            spgr_info_type( 56,"P B N B     ","-P 2bc 2ab      ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"bca  ") , &
13742            spgr_info_type( 57,"P B C M     ","-P 2c 2b        ", 3,10, (/ 0, 0, 0, 12, 24,  6/),"     ") , &
13743            spgr_info_type( 57,"P C A M     ","-P 2c 2ac       ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"ba-c ") , &
13744            spgr_info_type( 57,"P M C A     ","-P 2ac 2a       ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"cab  ") , &
13745            spgr_info_type( 57,"P M A B     ","-P 2b 2a        ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"-cba ") , &
13746            spgr_info_type( 57,"P B M A     ","-P 2a 2ab       ", 3,10, (/ 0, 0, 0, 24,  6, 12/),"bca  ") , &
13747            spgr_info_type( 57,"P C M B     ","-P 2bc 2c       ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"a-cb ") , &
13748            spgr_info_type( 58,"P N N M     ","-P 2 2n         ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13749            spgr_info_type( 58,"P M N N     ","-P 2n 2         ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13750            spgr_info_type( 58,"P N M N     ","-P 2n 2n        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13751            spgr_info_type( 59,"P M M N:1   ","P 2 2ab -1ab    ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"1    ") , &
13752            spgr_info_type( 59,"P M M N     ","-P 2ab 2a       ", 3,10, (/ 0,-6, 0,  6,  6, 24/),"2    ") , &
13753            spgr_info_type( 59,"P N M M:1   ","P 2bc 2 -1bc    ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"1cab ") , &
13754            spgr_info_type( 59,"P N M M     ","-P 2c 2bc       ", 3,10, (/ 0, 0,-6, 24,  6,  6/),"2cab ") , &
13755            spgr_info_type( 59,"P M N M:1   ","P 2ac 2ac -1ac  ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"1bca ") , &
13756            spgr_info_type( 59,"P M N M     ","-P 2c 2a        ", 3,10, (/-6, 0, 0,  6, 24,  6/),"2bca ") , &
13757            spgr_info_type( 60,"P B C N     ","-P 2n 2ab       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13758            spgr_info_type( 60,"P C A N     ","-P 2n 2c        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"ba-c ") , &
13759            spgr_info_type( 60,"P N C A     ","-P 2a 2n        ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"cab  ") , &
13760            spgr_info_type( 60,"P N A B     ","-P 2bc 2n       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"-cba ") /)
13761
13762       spgr_info(343:372)= (/                                           &
13763            spgr_info_type( 60,"P B N A     ","-P 2ac 2b       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"bca  ") , &
13764            spgr_info_type( 60,"P C N B     ","-P 2b 2ac       ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"a-cb ") , &
13765            spgr_info_type( 61,"P B C A     ","-P 2ac 2ab      ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13766            spgr_info_type( 61,"P C A B     ","-P 2bc 2ac      ", 3,10, (/ 0, 0, 0, 12, 12, 12/),"ba-c ") , &
13767            spgr_info_type( 62,"P N M A     ","-P 2ac 2n       ", 3,10, (/ 0, 0, 0, 12,  6, 24/),"     ") , &
13768            spgr_info_type( 62,"P M N B     ","-P 2bc 2a       ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"ba-c ") , &
13769            spgr_info_type( 62,"P M N B:1   ","P 2ac 2ab -1ab  ", 3,10, (/ 0, 0, 0,  6, 12, 24/),"     ") , &
13770            spgr_info_type( 62,"P B N M     ","-P 2c 2ab       ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"cab  ") , &
13771            spgr_info_type( 62,"P B N M:1   ","P 2c 2n -1c     ", 3,10, (/ 0, 0, 0, 24, 12,  6/),"     ") , &
13772            spgr_info_type( 62,"P C M N     ","-P 2n 2ac       ", 3,10, (/ 0, 0, 0, 24,  6, 12/),"-cba ") , &
13773            spgr_info_type( 62,"P M C N     ","-P 2n 2a        ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"bca  ") , &
13774            spgr_info_type( 62,"P M C N:1   ","P 2bc 2a -1a    ", 3,10, (/ 0, 0, 0,  6, 24, 12/),"     ") , &
13775            spgr_info_type( 62,"P N A M     ","-P 2c 2n        ", 3,10, (/ 0, 0, 0, 12, 24,  6/),"a-cb ") , &
13776            spgr_info_type( 63,"C M C M     ","-C 2c 2         ", 3,10, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13777            spgr_info_type( 63,"C C M M     ","-C 2c 2c        ", 3,10, (/ 0, 0, 0, 12, 12, 24/),"ba-c ") , &
13778            spgr_info_type( 63,"A M M A     ","-A 2a 2a        ", 3,10, (/ 0, 0, 0, 24, 12, 12/),"cab  ") , &
13779            spgr_info_type( 63,"A M A M     ","-A 2 2a         ", 3,10, (/ 0, 0, 0, 24, 12, 12/),"-cba ") , &
13780            spgr_info_type( 63,"B B M M     ","-B 2 2b         ", 3,10, (/ 0, 0, 0, 12, 24, 12/),"bca  ") , &
13781            spgr_info_type( 63,"B M M B     ","-B 2b 2         ", 3,10, (/ 0, 0, 0, 12, 24, 12/),"a-cb ") , &
13782            spgr_info_type( 63,"B M M B:1   ","B 2ab 2c -1ac   ", 3,10, (/ 0, 0, 0, 12, 24, 12/),"     ") , &
13783            spgr_info_type( 64,"C M C A     ","-C 2bc 2        ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"     ") , &
13784            spgr_info_type( 64,"C C M B     ","-C 2bc 2bc      ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"ba-c ") , &
13785            spgr_info_type( 64,"C C M B:1   ","C 2bc 2n -1ab   ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"     ") , &
13786            spgr_info_type( 64,"A B M A     ","-A 2ac 2ac      ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"cab  ") , &
13787            spgr_info_type( 64,"A C A M     ","-A 2 2ac        ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"-cba ") , &
13788            spgr_info_type( 64,"B B C M     ","-B 2 2bc        ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"bca  ") , &
13789            spgr_info_type( 64,"B M A B     ","-B 2bc 2        ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"a-cb ") , &
13790            spgr_info_type( 65,"C M M M     ","-C 2 2          ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"     ") , &
13791            spgr_info_type( 65,"A M M M     ","-A 2 2          ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"cab  ") , &
13792            spgr_info_type( 65,"B M M M     ","-B 2 2          ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"bca  ") /)
13793
13794       spgr_info(373:402)= (/                                           &
13795            spgr_info_type( 66,"C C C M     ","-C 2 2c         ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"     ") , &
13796            spgr_info_type( 66,"A M A A     ","-A 2a 2         ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"cab  ") , &
13797            spgr_info_type( 66,"B A M B     ","-B 2b 2b        ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"bca  ") , &
13798            spgr_info_type( 67,"C M M A     ","-C 2b 2         ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"     ") , &
13799            spgr_info_type( 67,"C M M B     ","-C 2b 2b        ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"ba-c ") , &
13800            spgr_info_type( 67,"A B M M     ","-A 2c 2c        ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"cab  ") , &
13801            spgr_info_type( 67,"A C M M     ","-A 2 2c         ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"-cba ") , &
13802            spgr_info_type( 67,"B M C M     ","-B 2 2c         ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"bca  ") , &
13803            spgr_info_type( 67,"B M A M     ","-B 2c 2         ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"a-cb ") , &
13804            spgr_info_type( 68,"C C C A:1   ","C 2 2 -1bc      ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"1    ") , &
13805            spgr_info_type( 68,"C C C A     ","-C 2b 2bc       ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"2    ") , &
13806            spgr_info_type( 68,"C C C B:1   ","C 2 2 -1bc      ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"1ba-c") , &
13807            spgr_info_type( 68,"C C C B     ","-C 2b 2c        ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"2ba-c") , &
13808            spgr_info_type( 68,"A B A A:1   ","A 2 2 -1ac      ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"1cab ") , &
13809            spgr_info_type( 68,"A B A A     ","-A 2a 2c        ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"2cab ") , &
13810            spgr_info_type( 68,"A C A A:1   ","A 2 2 -1ac      ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"1-cba") , &
13811            spgr_info_type( 68,"A C A A     ","-A 2ac 2c       ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"2-cba") , &
13812            spgr_info_type( 68,"B B C B:1   ","B 2 2 -1bc      ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"1bca ") , &
13813            spgr_info_type( 68,"B B C B     ","-B 2bc 2b       ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"2bca ") , &
13814            spgr_info_type( 68,"B B A B:1   ","B 2 2 -1bc      ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"1a-cb") , &
13815            spgr_info_type( 68,"B B A B     ","-B 2b 2bc       ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"2a-cb") , &
13816            spgr_info_type( 69,"F M M M     ","-F 2 2          ", 3,10, (/ 0, 0, 0,  6,  6, 12/),"     ") , &
13817            spgr_info_type( 70,"F D D D:1   ","F 2 2 -1d       ", 3,10, (/ 0, 0, 0,  3,  6, 24/),"1    ") , &
13818            spgr_info_type( 70,"F D D D     ","-F 2uv 2vw      ", 3,10, (/ 0,-3, 0,  3,  3, 24/),"2    ") , &
13819            spgr_info_type( 71,"I M M M     ","-I 2 2          ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"     ") , &
13820            spgr_info_type( 72,"I B A M     ","-I 2 2c         ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"     ") , &
13821            spgr_info_type( 72,"I M C B     ","-I 2a 2         ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"cab  ") , &
13822            spgr_info_type( 72,"I C M A:1   ","I 2 2 -1b       ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13823            spgr_info_type( 72,"I C M A     ","-I 2b 2b        ", 3,10, (/ 0, 0, 0, 12, 12,  6/),"bca  ") , &
13824            spgr_info_type( 73,"I B C A     ","-I 2b 2c        ", 3,10, (/ 0, 0, 0,  6, 12, 12/),"     ") /)
13825
13826       spgr_info(403:409)= (/                                           &
13827            spgr_info_type( 73,"I C A B     ","-I 2a 2b        ", 3,10, (/ 0, 0, 0, 12,  6, 12/),"ba-c ") , &
13828            spgr_info_type( 74,"I M M A     ","-I 2b 2         ", 3,10, (/ 0, 0, 0,  6,  6, 24/),"     ") , &
13829            spgr_info_type( 74,"I M M B     ","-I 2a 2a        ", 3,10, (/ 0, 0, 0,  6,  6, 24/),"ba-c ") , &
13830            spgr_info_type( 74,"I B M M     ","-I 2c 2c        ", 3,10, (/ 0, 0, 0, 24,  6,  6/),"cab  ") , &
13831            spgr_info_type( 74,"I C M M     ","-I 2 2b         ", 3,10, (/ 0, 0, 0, 24,  6,  6/),"-cba ") , &
13832            spgr_info_type( 74,"I M C M     ","-I 2 2a         ", 3,10, (/ 0, 0, 0,  6, 24,  6/),"bca  ") , &
13833            spgr_info_type( 74,"I M A M     ","-I 2c 2         ", 3,10, (/ 0, 0, 0,  6, 24,  6/),"a-cb ") /)
13834
13835       !---- Tetragonal ----!
13836       spgr_info(410:439)= (/                                           &
13837            spgr_info_type( 75,"P 4         ","P 4             ", 4,11, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13838            spgr_info_type( 76,"P 41        ","P 4w            ", 4,11, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13839            spgr_info_type( 77,"P 42        ","P 4c            ", 4,11, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13840            spgr_info_type( 78,"P 43        ","P 4cw           ", 4,11, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13841            spgr_info_type( 79,"I 4         ","I 4             ", 4,11, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13842            spgr_info_type( 80,"I 41        ","I 4bw           ", 4,11, (/ 0, 0, 0, 12, 24,  6/),"     ") , &
13843            spgr_info_type( 81,"P -4        ","P -4            ", 4,12, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13844            spgr_info_type( 82,"I -4        ","I -4            ", 4,12, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13845            spgr_info_type( 83,"P 4/M       ","-P 4            ", 4,13, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13846            spgr_info_type( 84,"P 42/M      ","-P 4c           ", 4,13, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13847            spgr_info_type( 85,"P 4/N:1     ","P 4ab -1ab      ", 4,13, (/ 0, 0, 0, 12, 12, 12/),"1    ") , &
13848            spgr_info_type( 85,"P 4/N       ","-P 4a           ", 4,13, (/-6,-6, 0,  6,  6, 12/),"2    ") , &
13849            spgr_info_type( 86,"P 42/N:1    ","P 4n -1n        ", 4,13, (/ 0, 0, 0, 12, 24,  6/),"1    ") , &
13850            spgr_info_type( 86,"P 42/N      ","-P 4bc          ", 4,13, (/-6,-6, 0,  6,  6, 12/),"2    ") , &
13851            spgr_info_type( 87,"I 4/M       ","-I 4            ", 4,13, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13852            spgr_info_type( 88,"I 41/A:1    ","I 4bw -1bw      ", 4,13, (/ 0, 0, 0,  6,  6, 24/),"1    ") , &
13853            spgr_info_type( 88,"I 41/A      ","-I 4ad          ", 4,13, (/ 0, 0, 0,  6,  6, 24/),"2    ") , &
13854            spgr_info_type( 89,"P 4 2 2     ","P 4 2           ", 5,14, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13855            spgr_info_type( 90,"P 4 21 2    ","P 4ab 2ab       ", 5,14, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13856            spgr_info_type( 90,"C 4 2 21    ","C 4b 2          ", 5,14, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13857            spgr_info_type( 91,"P 41 2 2    ","P 4w 2c         ", 5,14, (/ 0, 0, 0, 24, 24,  3/),"     ") , &
13858            spgr_info_type( 92,"P 41 21 2   ","P 4abw 2nw      ", 5,14, (/ 0, 0, 0, 24, 24,  3/),"     ") , &
13859            spgr_info_type( 93,"P 42 2 2    ","P 4c 2          ", 5,14, (/ 0, 0, 0, 12, 24,  6/),"     ") , &
13860            spgr_info_type( 94,"P 42 21 2   ","P 4n 2n         ", 5,14, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13861            spgr_info_type( 95,"P 43 2 2    ","P 4cw 2c        ", 5,14, (/ 0, 0, 0, 24, 24,  3/),"     ") , &
13862            spgr_info_type( 96,"P 43 21 2   ","P 4nw 2abw      ", 5,14, (/ 0, 0, 0, 24, 24,  3/),"     ") , &
13863            spgr_info_type( 97,"I 4 2 2     ","I 4 2           ", 5,14, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13864            spgr_info_type( 98,"I 41 2 2    ","I 4bw 2bw       ", 5,14, (/ 0, 0, 0, 12, 24,  3/),"     ") , &
13865            spgr_info_type( 99,"P 4 M M     ","P 4 -2          ", 5,15, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13866            spgr_info_type(100,"P 4 B M     ","P 4 -2ab        ", 5,15, (/ 0, 0, 0, 12, 12, 24/),"     ") /)
13867
13868       spgr_info(440:469)= (/                                           &
13869            spgr_info_type(101,"P 42 C M    ","P 4c -2c        ", 5,15, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13870            spgr_info_type(102,"P 42 N M    ","P 4n -2n        ", 5,15, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13871            spgr_info_type(103,"P 4 C C     ","P 4 -2c         ", 5,15, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13872            spgr_info_type(104,"P 4 N C     ","P 4 -2n         ", 5,15, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13873            spgr_info_type(105,"P 42 M C    ","P 4c -2         ", 5,15, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13874            spgr_info_type(106,"P 42 B C    ","P 4c -2ab       ", 5,15, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13875            spgr_info_type(107,"I 4 M M     ","I 4 -2          ", 5,15, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13876            spgr_info_type(108,"I 4 C M     ","I 4 -2c         ", 5,15, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13877            spgr_info_type(109,"I 41 M D    ","I 4bw -2        ", 5,15, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13878            spgr_info_type(110,"I 41 C D    ","I 4bw -2c       ", 5,15, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13879            spgr_info_type(111,"P -4 2 M    ","P -4 2          ", 5,16, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13880            spgr_info_type(112,"P -4 2 C    ","P -4 2c         ", 5,16, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13881            spgr_info_type(113,"P -4 21 M   ","P -4 2ab        ", 5,16, (/ 0, 0, 0, 12, 12, 24/),"     ") , &
13882            spgr_info_type(114,"P -4 21 C   ","P -4 2n         ", 5,16, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13883            spgr_info_type(115,"P -4 M 2    ","P -4 -2         ", 5,17, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13884            spgr_info_type(116,"P -4 C 2    ","P -4 -2c        ", 5,17, (/ 0, 0, 0, 12, 24,  6/),"     ") , &
13885            spgr_info_type(117,"P -4 B 2    ","P -4 -2ab       ", 5,17, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13886            spgr_info_type(117,"C -4 B 2    ","C -4 2b         ", 5,17, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13887            spgr_info_type(118,"P -4 N 2    ","P -4 -2n        ", 5,17, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13888            spgr_info_type(119,"I -4 M 2    ","I -4 -2         ", 5,17, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13889            spgr_info_type(120,"I -4 C 2    ","I -4 -2c        ", 5,17, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13890            spgr_info_type(121,"I -4 2 M    ","I -4 2          ", 5,16, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13891            spgr_info_type(122,"I -4 2 D    ","I -4 2bw        ", 5,16, (/ 0, 0, 0, 12, 24,  3/),"     ") , &
13892            spgr_info_type(122,"F -4 D 2    ","F -4 -2cd       ", 5,16, (/ 0, 0, 0, 12, 24,  3/),"     ") , &
13893            spgr_info_type(123,"P 4/M M M   ","-P 4 2          ", 5,18, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13894            spgr_info_type(124,"P 4/M C C   ","-P 4 2c         ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13895            spgr_info_type(125,"P 4/N B M:1 ","P 4 2 -1ab      ", 5,18, (/ 0, 0, 0, 12, 12, 12/),"1    ") , &
13896            spgr_info_type(125,"P 4/N B M   ","-P 4a 2b        ", 5,18, (/-6,-6, 0,  6,  6, 12/),"2    ") , &
13897            spgr_info_type(126,"P 4/N N C:1 ","P 4 2 -1n       ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"1    ") , &
13898            spgr_info_type(126,"P 4/N N C   ","-P 4a 2bc       ", 5,18, (/-6,-6, 0,  6,  6,  6/),"2    ") /)
13899
13900       spgr_info(470:494)= (/                                           &
13901            spgr_info_type(127,"P 4/M B M   ","-P 4 2ab        ", 5,18, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13902            spgr_info_type(128,"P 4/M N C   ","-P 4 2n         ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13903            spgr_info_type(129,"P 4/N M M:1 ","P 4ab 2ab -1ab  ", 5,18, (/ 0, 0, 0, 12, 12, 12/),"1    ") , &
13904            spgr_info_type(129,"P 4/N M M   ","-P 4a 2a        ", 5,18, (/-6,-6, 0,  6,  6, 12/),"2    ") , &
13905            spgr_info_type(130,"P 4/N C C:1 ","P 4ab 2n -1ab   ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"1    ") , &
13906            spgr_info_type(130,"P 4/N C C   ","-P 4a 2ac       ", 5,18, (/-6,-6, 0,  6,  6,  6/),"2    ") , &
13907            spgr_info_type(131,"P 42/M M C  ","-P 4c 2         ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13908            spgr_info_type(132,"P 42/M C M  ","-P 4c 2c        ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13909            spgr_info_type(133,"P 42/N B C:1","P 4n 2c -1n     ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"1    ") , &
13910            spgr_info_type(133,"P 42/N B C  ","-P 4ac 2b       ", 5,18, (/-6,-6, 0,  6,  6,  6/),"2    ") , &
13911            spgr_info_type(134,"P 42/N N M:1","P 4n 2 -1n      ", 5,18, (/ 0, 0, 0, 12, 24,  6/),"1    ") , &
13912            spgr_info_type(134,"P 42/N N M  ","-P 4ac 2bc      ", 5,18, (/-6,-6, 0,  6,  6, 12/),"2    ") , &
13913            spgr_info_type(135,"P 42/M B C  ","-P 4c 2ab       ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13914            spgr_info_type(136,"P 42/M N M  ","-P 4n 2n        ", 5,18, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
13915            spgr_info_type(137,"P 42/N M C:1","P 4n 2n -1n     ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"1    ") , &
13916            spgr_info_type(137,"P 42/N M C  ","-P 4ac 2a       ", 5,18, (/-6,-6, 0,  6,  6,  6/),"2    ") , &
13917            spgr_info_type(138,"P 42/N C M:1","P 4n 2ab -1n    ", 5,18, (/ 0, 0, 0,  6, 12, 24/),"1    ") , &
13918            spgr_info_type(138,"P 42/N C M  ","-P 4ac 2ac      ", 5,18, (/-6,-6, 0,  6,  6, 12/),"2    ") , &
13919            spgr_info_type(139,"I 4/M M M   ","-I 4 2          ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13920            spgr_info_type(139,"F 4/M M M   ","-F 4 2          ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13921            spgr_info_type(140,"I 4/M C M   ","-I 4 2c         ", 5,18, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
13922            spgr_info_type(141,"I 41/A M D:1","I 4bw 2bw -1bw  ", 5,18, (/ 0, 0, 0, 12, 12,  3/),"1    ") , &
13923            spgr_info_type(141,"I 41/A M D  ","-I 4bd 2        ", 5,18, (/ 0,-6, 0, 12,  6,  3/),"2    ") , &
13924            spgr_info_type(142,"I 41/A C D:1","I 4bw 2aw -1bw  ", 5,18, (/ 0, 0, 0, 12, 12,  3/),"1    ") , &
13925            spgr_info_type(142,"I 41/A C D  ","-I 4bd 2c       ", 5,18, (/ 0,-6, 0, 12,  6,  3/),"2    ") /)
13926
13927       !---- Trigonal/Rhombohedral ----!
13928       spgr_info(495:526)= (/                                           &
13929            spgr_info_type(143,"P 3         ","P 3             ", 8,19, (/ 0, 0, 0, 16, 16, 24/),"     ") , &
13930            spgr_info_type(144,"P 31        ","P 31            ", 8,19, (/ 0, 0, 0, 24, 24,  8/),"     ") , &
13931            spgr_info_type(145,"P 32        ","P 32            ", 8,19, (/ 0, 0, 0, 24, 24,  8/),"     ") , &
13932            spgr_info_type(146,"R 3         ","R 3             ", 8,19, (/ 0, 0, 0, 16, 16,  8/),"H    ") , &
13933            spgr_info_type(146,"R 3:R       ","P 3*            ", 6,19, (/ 0, 0, 0, 24, 24, 24/),"R    ") , &
13934            spgr_info_type(147,"P -3        ","-P 3            ", 8,20, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13935            spgr_info_type(148,"R -3        ","-R 3            ", 8,20, (/ 0, 0, 0, 16, 16,  4/),"H    ") , &
13936            spgr_info_type(148,"R -3:R      ","-P 3*           ", 6,20, (/ 0, 0, 0, 24, 24, 12/),"R    ") , &
13937            spgr_info_type(149,"P 3 1 2     ","P 3 2           ",10,24, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13938            spgr_info_type(150,"P 3 2 1     ","P 3 2""         ", 9,21, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13939            spgr_info_type(151,"P 31 1 2    ","P 31 2c (0 0 1) ",10,24, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13940            spgr_info_type(152,"P 31 2 1    ","P 31 2""        ", 9,21, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13941            spgr_info_type(153,"P 32 1 2    ","P 32 2c (0 0 -1)",10,24, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13942            spgr_info_type(154,"P 32 2 1    ","P 32 2""        ", 9,21, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13943            spgr_info_type(155,"R 3 2       ","R 3 2""         ", 9,21, (/ 0, 0, 0, 16, 16,  4/),"H    ") , &
13944            spgr_info_type(155,"R 3 2:R     ","P 3* 2          ", 7,21, (/ 0, 0, 0, 24, 24, 12/),"R    ") , &
13945            spgr_info_type(156,"P 3 M 1     ","P 3 -2""        ", 9,22, (/ 0, 0, 0, 16, 16, 24/),"     ") , &
13946            spgr_info_type(157,"P 3 1 M     ","P 3 -2          ",10,25, (/ 0, 0, 0, 16, 12, 24/),"     ") , &
13947            spgr_info_type(158,"P 3 C 1     ","P 3 -2""c       ", 9,22, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13948            spgr_info_type(159,"P 3 1 C     ","P 3 -2c         ",10,25, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13949            spgr_info_type(160,"R 3 M       ","R 3 -2""        ", 9,22, (/ 0, 0, 0, 16, 16,  8/),"H    ") , &
13950            spgr_info_type(160,"R 3 M:R     ","P 3* -2         ", 7,22, (/ 0, 0, 0, 24, 24, 24/),"R    ") , &
13951            spgr_info_type(161,"R 3 C       ","R 3 -2""c       ", 9,22, (/ 0, 0, 0, 16, 16,  4/),"H    ") , &
13952            spgr_info_type(161,"R 3 C:R     ","P 3* -2n        ", 7,22, (/ 0, 0, 0, 24, 24, 24/),"R    ") , &
13953            spgr_info_type(162,"P -3 1 M    ","-P 3 2          ",10,26, (/ 0, 0, 0, 16, 12, 12/),"     ") , &
13954            spgr_info_type(163,"P -3 1 C    ","-P 3 2c         ",10,26, (/ 0, 0, 0, 16, 16,  6/),"     ") , &
13955            spgr_info_type(164,"P -3 M 1    ","-P 3 2""        ", 9,23, (/ 0, 0, 0, 16,  8, 24/),"     ") , &
13956            spgr_info_type(165,"P -3 C 1    ","-P 3 2""c       ", 9,23, (/ 0, 0, 0, 16, 16,  6/),"     ") , &
13957            spgr_info_type(166,"R -3 M      ","-R 3 2""        ", 9,23, (/ 0, 0, 0, 16, 16,  4/),"H    ") , &
13958            spgr_info_type(166,"R -3 M:R    ","-P 3* 2         ", 7,23, (/ 0, 0, 0, 24, 24, 12/),"R    ") , &
13959            spgr_info_type(167,"R -3 C      ","-R 3 2""c       ", 9,23, (/ 0, 0, 0, 16, 16,  2/),"H    ") , &
13960            spgr_info_type(167,"R -3 C:R    ","-P 3* 2n        ", 7,23, (/ 6, 6, 6, 30, 30, 18/),"R    ") /)
13961
13962       !---- Hexagonal ----!
13963       spgr_info(527:553)= (/                                           &
13964            spgr_info_type(168,"P 6         ","P 6             ",11,27, (/ 0, 0, 0, 16, 12, 24/),"     ") , &
13965            spgr_info_type(169,"P 61        ","P 61            ",11,27, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13966            spgr_info_type(170,"P 65        ","P 65            ",11,27, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13967            spgr_info_type(171,"P 62        ","P 62            ",11,27, (/ 0, 0, 0, 24, 24,  8/),"     ") , &
13968            spgr_info_type(172,"P 64        ","P 64            ",11,27, (/ 0, 0, 0, 24, 24,  8/),"     ") , &
13969            spgr_info_type(173,"P 63        ","P 6c            ",11,27, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13970            spgr_info_type(174,"P -6        ","P -6            ",11,28, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13971            spgr_info_type(175,"P 6/M       ","-P 6            ",11,29, (/ 0, 0, 0, 16, 12, 12/),"     ") , &
13972            spgr_info_type(176,"P 63/M      ","-P 6c           ",11,29, (/ 0, 0, 0, 16, 16,  6/),"     ") , &
13973            spgr_info_type(177,"P 6 2 2     ","P 6 2           ",12,30, (/ 0, 0, 0, 16, 12, 12/),"     ") , &
13974            spgr_info_type(178,"P 61 2 2    ","P 61 2 (0 0 -1) ",12,30, (/ 0, 0, 0, 24, 24,  2/),"     ") , &
13975            spgr_info_type(179,"P 65 2 2    ","P 65 2 (0 0 1)  ",12,30, (/ 0, 0, 0, 24, 24,  2/),"     ") , &
13976            spgr_info_type(180,"P 62 2 2    ","P 62 2c (0 0 1) ",12,30, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13977            spgr_info_type(181,"P 64 2 2    ","P 64 2c (0 0 -1)",12,30, (/ 0, 0, 0, 24, 24,  4/),"     ") , &
13978            spgr_info_type(182,"P 63 2 2    ","P 6c 2c         ",12,30, (/ 0, 0, 0, 16, 16,  3/),"     ") , &
13979            spgr_info_type(183,"P 6 M M     ","P 6 -2          ",12,31, (/ 0, 0, 0, 16,  8, 24/),"     ") , &
13980            spgr_info_type(184,"P 6 C C     ","P 6 -2c         ",12,31, (/ 0, 0, 0, 16, 12, 12/),"     ") , &
13981            spgr_info_type(185,"P 63 C M    ","P 6c -2         ",12,31, (/ 0, 0, 0, 16, 12, 12/),"     ") , &
13982            spgr_info_type(186,"P 63 M C    ","P 6c -2c        ",12,31, (/ 0, 0, 0, 16,  8, 24/),"     ") , &
13983            spgr_info_type(187,"P -6 M 2    ","P -6 2          ",12,33, (/ 0, 0, 0, 16, 16, 12/),"     ") , &
13984            spgr_info_type(188,"P -6 C 2    ","P -6c 2         ",12,33, (/ 0, 0, 0, 16, 16,  6/),"     ") , &
13985            spgr_info_type(189,"P -6 2 M    ","P -6 -2         ",12,32, (/ 0, 0, 0, 16, 12, 12/),"     ") , &
13986            spgr_info_type(190,"P -6 2 C    ","P -6c -2c       ",12,32, (/ 0, 0, 0, 16, 16,  6/),"     ") , &
13987            spgr_info_type(191,"P 6/M M M   ","-P 6 2          ",12,34, (/ 0, 0, 0, 16,  8, 12/),"     ") , &
13988            spgr_info_type(192,"P 6/M C C   ","-P 6 2c         ",12,34, (/ 0, 0, 0, 16, 12,  6/),"     ") , &
13989            spgr_info_type(193,"P 63/M C M  ","-P 6c 2         ",12,34, (/ 0, 0, 0, 16, 12,  6/),"     ") , &
13990            spgr_info_type(194,"P 63/M M C  ","-P 6c 2c        ",12,34, (/ 0, 0, 0, 16, 16,  6/),"     ") /)
13991
13992       !---- Cubic ----!
13993       spgr_info(554:583)= (/                                           &
13994            spgr_info_type(195,"P 2 3       ","P 2 2 3         ",13,35, (/ 0, 0,  0, 24, 24, 12/),"     ") , &
13995            spgr_info_type(196,"F 2 3       ","F 2 2 3         ",13,35, (/ 0, 0, -6, 12, 12,  6/),"     ") , &
13996            spgr_info_type(197,"I 2 3       ","I 2 2 3         ",13,35, (/ 0, 0,  0, 24, 12, 12/),"     ") , &
13997            spgr_info_type(198,"P 21 3      ","P 2ac 2ab 3     ",13,35, (/ 0, 0,-12, 12, 12, 12/),"     ") , &
13998            spgr_info_type(199,"I 21 3      ","I 2b 2c 3       ",13,35, (/ 0, 0,  0, 12, 12, 12/),"     ") , &
13999            spgr_info_type(200,"P M -3      ","-P 2 2 3        ",13,36, (/ 0, 0,  0, 12, 12, 12/),"     ") , &
14000            spgr_info_type(200,"P M 3       ","-P 2 2 3        ",13,36, (/ 0, 0,  0, 12, 12, 12/),"     ") , &
14001            spgr_info_type(201,"P N -3:1    ","P 2 2 3 -1n     ",13,36, (/ 0, 0, 0, 24, 12,  12/),"1    ") , &
14002            spgr_info_type(201,"P N -3      ","-P 2ab 2bc 3    ",13,36, (/-6,-6,-6, 18,  6,   6/),"2    ") , &
14003            spgr_info_type(201,"P N 3       ","-P 2ab 2bc 3    ",13,36, (/-6,-6,-6, 18,  6,   6/),"2    ") , &
14004            spgr_info_type(202,"F M -3      ","-F 2 2 3        ",13,36, (/ 0, 0, 0, 12, 12,   6/),"     ") , &
14005            spgr_info_type(202,"F M 3       ","-F 2 2 3        ",13,36, (/ 0, 0, 0, 12, 12,   6/),"     ") , &
14006            spgr_info_type(203,"F D -3:1    ","F 2 2 3 -1d     ",13,36, (/ 0, 0,-6, 12,  6,   6/),"1    ") , &
14007            spgr_info_type(203,"F D -3      ","-F 2uv 2vw 3    ",13,36, (/-3,-3,-9,  9,  3,   3/),"2    ") , &
14008            spgr_info_type(203,"F D 3       ","-F 2uv 2vw 3    ",13,36, (/-3,-3,-9,  9,  3,   3/),"2    ") , &
14009            spgr_info_type(204,"I M -3      ","-I 2 2 3        ",13,36, (/ 0, 0, 0, 12, 12,  12/),"     ") , &
14010            spgr_info_type(204,"I M 3       ","-I 2 2 3        ",13,36, (/ 0, 0, 0, 12, 12,  12/),"     ") , &
14011            spgr_info_type(205,"P A -3      ","-P 2ac 2ab 3    ",13,36, (/ 0, 0, 0, 12, 12,  12/),"     ") , &
14012            spgr_info_type(205,"P A 3       ","-P 2ac 2ab 3    ",13,36, (/ 0, 0, 0, 12, 12,  12/),"     ") , &
14013            spgr_info_type(206,"I A -3      ","-I 2b 2c 3      ",13,36, (/ 0, 0, 0, 12, 12,   6/),"     ") , &
14014            spgr_info_type(206,"I A 3       ","-I 2b 2c 3      ",13,36, (/ 0, 0, 0, 12, 12,   6/),"     ") , &
14015            spgr_info_type(207,"P 4 3 2     ","P 4 2 3         ",14,37, (/ 0, 0, 0, 24, 12,  12/),"     ") , &
14016            spgr_info_type(208,"P 42 3 2    ","P 4n 2 3        ",14,37, (/ 0, 0,-6, 12, 12,   6/),"     ") , &
14017            spgr_info_type(209,"F 4 3 2     ","F 4 2 3         ",14,37, (/ 0, 0,-6, 12,  6,   6/),"     ") , &
14018            spgr_info_type(210,"F 41 3 2    ","F 4d 2 3        ",14,37, (/ 0,-3,-3, 12,  3,   3/),"     ") , &
14019            spgr_info_type(211,"I 4 3 2     ","I 4 2 3         ",14,37, (/ 0, 0, 0, 12, 12,   6/),"     ") , &
14020            spgr_info_type(212,"P 43 3 2    ","P 4acd 2ab 3    ",14,37, (/ 0, 0,-12, 12, 18,  6/),"     ") , &
14021            spgr_info_type(213,"P 41 3 2    ","P 4bd 2ab 3     ",14,37, (/-6, 0, 0, 12, 18,  12/),"     ") , &
14022            spgr_info_type(214,"I 41 3 2    ","I 4bd 2c 3      ",14,37, (/-9,-3,-3,  3,  3,   9/),"     ") , &
14023            spgr_info_type(215,"P -4 3 M    ","P -4 2 3        ",14,38, (/ 0, 0, 0, 24, 12,  12/),"     ") /)
14024
14025       spgr_info(584:612)= (/                                           &
14026            spgr_info_type(216,"F -4 3 M    ","F -4 2 3        ",14,38, (/ 0, 0,-6, 12,  6,  6/),"     ") , &
14027            spgr_info_type(217,"I -4 3 M    ","I -4 2 3        ",14,38, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
14028            spgr_info_type(218,"P -4 3 N    ","P -4n 2 3       ",14,38, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
14029            spgr_info_type(219,"F -4 3 C    ","F -4c 2 3       ",14,38, (/ 0, 0,-6, 12,  6,  6/),"     ") , &
14030            spgr_info_type(220,"I -4 3 D    ","I -4bd 2c 3     ",14,38, (/ 6, 6, 0, 12, 12, 12/),"     ") , &
14031            spgr_info_type(221,"P M -3 M    ","-P 4 2 3        ",14,39, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
14032            spgr_info_type(221,"P M 3 M     ","-P 4 2 3        ",14,39, (/ 0, 0, 0, 12, 12, 12/),"     ") , &
14033            spgr_info_type(222,"P N -3 N:1  ","P 4 2 3 -1n     ",14,39, (/ 0, 0, 0, 12, 12, 12/),"1    ") , &
14034            spgr_info_type(222,"P N -3 N    ","-P 4a 2bc 3     ",14,39, (/ 6, 6, 6, 18, 18, 18/),"2    ") , &
14035            spgr_info_type(222,"P N 3 N     ","-P 4a 2bc 3     ",14,39, (/ 6, 6, 6, 18, 18, 18/),"2    ") , &
14036            spgr_info_type(223,"P M -3 N    ","-P 4n 2 3       ",14,39, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
14037            spgr_info_type(223,"P M 3 N     ","-P 4n 2 3       ",14,39, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
14038            spgr_info_type(224,"P N -3 M:1  ","P 4n 2 3 -1n    ",14,39, (/ 0, 0,-6, 12, 12,  6/),"1    ") , &
14039            spgr_info_type(224,"P N -3 M    ","-P 4bc 2bc 3    ",14,39, (/ 6, 6, 0, 18, 18, 12/),"2    ") , &
14040            spgr_info_type(224,"P N 3 M     ","-P 4bc 2bc 3    ",14,39, (/ 6, 6, 0, 18, 18, 12/),"2    ") , &
14041            spgr_info_type(225,"F M -3 M    ","-F 4 2 3        ",14,39, (/ 0, 0, 0, 12,  6,  6/),"     ") , &
14042            spgr_info_type(225,"F M 3 M     ","-F 4 2 3        ",14,39, (/ 0, 0, 0, 12,  6,  6/),"     ") , &
14043            spgr_info_type(226,"F M -3 C    ","-F 4c 2 3       ",14,39, (/ 0, 0, 0, 12,  6,  6/),"     ") , &
14044            spgr_info_type(226,"F M 3 C     ","-F 4c 2 3       ",14,39, (/ 0, 0, 0, 12,  6,  6/),"     ") , &
14045            spgr_info_type(227,"F D -3 M:1  ","F 4d 2 3 -1d    ",14,39, (/ 0, 0,-3, 12,  3,  3/),"1    ") , &
14046            spgr_info_type(227,"F D -3 M    ","-F 4vw 2vw 3    ",14,39, (/-3,-3,-6,  9,  0,  0/),"2    ") , &
14047            spgr_info_type(227,"F D 3 M     ","-F 4vw 2vw 3    ",14,39, (/-3,-3,-6,  9,  0,  0/),"2    ") , &
14048            spgr_info_type(228,"F D -3 C:1  ","F 4d 2 3 -1cd   ",14,39, (/ 0, 0,-3, 12,  3,  3/),"1    ") , &
14049            spgr_info_type(228,"F D -3 C    ","-F 4cvw 2vw 3   ",14,39, (/-3,-3,-6,  9,  0,  0/),"2    ") , &
14050            spgr_info_type(228,"F D 3 C     ","-F 4cvw 2vw 3   ",14,39, (/-3,-3,-6,  9,  0,  0/),"2    ") , &
14051            spgr_info_type(229,"I M -3 M    ","-I 4 2 3        ",14,39, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
14052            spgr_info_type(229,"I M 3 M     ","-I 4 2 3        ",14,39, (/ 0, 0, 0, 12, 12,  6/),"     ") , &
14053            spgr_info_type(230,"I A -3 D    ","-I 4bd 2c 3     ",14,39, (/-3,-3, 0,  3,  3,  6/),"     ") , &
14054            spgr_info_type(230,"I A 3 D     ","-I 4bd 2c 3     ",14,39, (/-3,-3, 0,  3,  3,  6/),"     ") /)
14055
14056       return
14057    End Subroutine Set_Spgr_Info
14058
14059    !!----
14060    !!---- Subroutine Set_System_Equiv()
14061    !!----
14062    !!----    Conversion Table    IT - ML - Kov - BC - Zak
14063    !!----
14064    !!--..   The information given in this file corresponds to that of TABLE 6 of
14065    !!--..   "Isotropy Subgroups of the 230 Crystallographic Space Groups", by
14066    !!--..   Harold T Stokes and Dorian M Hatch, World Scientific, Singapore (1988).
14067    !!--..
14068    !!--..   The transformation operators that take space group elements in the
14069    !!--..   International setting (International Tables of Crystallography, Hahn 1983)
14070    !!--..   to space-groups elements in the Miller and Love ( ML, 1967), Kovalev
14071    !!--..   (Kov,1986) Bradley anb Cracknell (BC, 1972) and Zak (Zak, 1969) settings.
14072    !!--..
14073    !!--..   In the international setting the basis vectors are always those of the
14074    !!--..   conventional unit cell. In the Trigonal system the primitive basis
14075    !!--..   vectors are in an obverse relationship given by (2/3 1/3 1/3),
14076    !!--..   (-1/3 1/3 1/3) and (-1/3, -2/3 1/3).
14077    !!--..   In ML the same basis vectors are chosen except that for trigonal/rhombohedral
14078    !!--..   system the reverse setting is adopted, so the primitive basis vectors
14079    !!--..   are: t1=(1/3 -1/3 1/3), t2=(1/3, 2/3 1/3) and t3=(2/3 1/3 1/3)
14080    !!--..   In Kovalev the a,b,c axes of the coordinate system are along the
14081    !!--..   conventional basis vectors of the lattice, however in the trigonal
14082    !!--..   system an hexagonal system is chosen so that the primitive basis vectors
14083    !!--..   are a1=(-1 -1 1/3), a2=(1 0 1/3) and a3=(0 1 1/3).
14084    !!--..   In the setting of BC the axes a,b,c of the coordinate system are chosen
14085    !!--..   to be the primitive basis vectors t1,t2,t3 as defined in their book.
14086    !!--..   The setting of Zak the basis vectors are as in the international setting,
14087    !!--..   but for trigonal/rhombohedral system the primitive basis vectors w.r.t. the selected
14088    !!--..   hexagonal coordinate system are given by: (1/3 2/3 1) (1/3 -1/3 1)
14089    !!--..   (-2/3 -1/3 1)
14090    !!--..
14091    !!--..   Symmetry and transformation operators of Space Groups can be given as
14092    !!--..   4 x 4 Seitz matrices or as a character string called Jones Faithful
14093    !!--..   representation. This last representation is that used in this file.
14094    !!--..
14095    !!--..   To transform a symmetry operator "gI" in the international setting into
14096    !!--..   a symmetry element "g" in one of the other settings, we simply perform
14097    !!--..   the following operation:  g = gT gI gT(-1), where gT is the transformation
14098    !!--..   given tabulated below.
14099    !!----
14100    !!---- Update: February - 2005
14101    !!
14102    Subroutine Set_System_Equiv()
14103
14104       if (.not. allocated(system_equiv) ) allocate(system_equiv(230))
14105
14106       system_equiv(1:10) = (/         &
14107          table_equiv_type("C1_1  ","x,y,z            "," x,y,z            ",        &
14108                      " x,y,z                          "," x,y,z            "), &
14109          table_equiv_type("C1_i  ","x,y,z            "," x,y,z            ",        &
14110                      " x,y,z                          "," x,y,z            "), &
14111          table_equiv_type("C1_2  ","z,x,y            ","-z,x,-y           ",        &
14112                      "-x,z,y                          "," z,x,y            "), &
14113          table_equiv_type("C2_2  ","z,x,y            ","-z,x,-y           ",        &
14114                      "-x,z,y                          "," z,x,y            "), &
14115          table_equiv_type("C3_2  ","z,x,y            ","-z,x,-y           ",        &
14116                      " z,-x+y,-x-y                    ","-x,z,y            "), &
14117          table_equiv_type("C1_s  ","z,x,y            ","-z,x,-y           ",        &
14118                      "-x,z,y                          "," z,x,y            "), &
14119          table_equiv_type("C2_s  ","z,x,y            ","-z,x,-y           ",        &
14120                      " z,-x,-y                        "," z,x,y            "), &
14121          table_equiv_type("C3_s  ","z,x,y            ","-z,x,-y           ",        &
14122                      " z,-x+y,-x-y                    ","-x,z,y            "), &
14123          table_equiv_type("C4_s  ","z,x,y            ","-z,x,-y           ",        &
14124                      " z,-x+y,-x-y                    ","-x,z,y            "), &
14125          table_equiv_type("C1_2h ","z,x,y            ","-z,x,-y           ",        &
14126                      "-x,z,y                          "," z,x,y            ") /)
14127
14128       system_equiv(11:20)= (/         &
14129          table_equiv_type("C2_2h ","z,x,y            ","-z,x,-y+1/4       ",        &
14130                      "-x,z,y+1/4                      "," z,x,y            "), &
14131          table_equiv_type("C3_2h ","z,x,y            ","-z,x,-y           ",        &
14132                      " z,-x+y,-x-y                    ","-x,z,y            "), &
14133          table_equiv_type("C4_2h ","z,x,y            ","-z+1/4,x,-y       ",        &
14134                      " z-1/4,-x,-y                    ","-x,z,y            "), &
14135          table_equiv_type("C5_2h ","z,x,y            ","-z+1/4,x,-y+1/4   ",        &
14136                      " z-1/4,-x,-y+1/4                ","-x,z,y            "), &
14137          table_equiv_type("C6_2h ","z,x,y            ","-z+1/4,x,-y       ",        &
14138                      " z-1/4,-x+y,-x-y                ","-x,z,y            "), &
14139          table_equiv_type("D1_2  ","x,y,z            "," x,y,z            ",        &
14140                      "-y,x,z                          "," x,y,z            "), &
14141          table_equiv_type("D2_2  ","x,y,z            "," x,y,z            ",        &
14142                      "-y,x,z+1/4                      "," x,y,z            "), &
14143          table_equiv_type("D3_2  ","x,y,z            "," x,y,z            ",        &
14144                      "-y,x,z                          "," x,y,z            "), &
14145          table_equiv_type("D4_2  ","x,y,z            "," x,y,z            ",        &
14146                      "-x,-y,z                         "," x,y,z            "), &
14147          table_equiv_type("D5_2  ","x,y,z            "," x,y,z+1/4        ",        &
14148                      " x-y,x+y,z                      "," x,y,z            ")/)
14149
14150       system_equiv(21:30)= (/         &
14151          table_equiv_type("D6_2  ","x,y,z            "," x,y,z            ",        &
14152                      " x-y,x+y,z                      "," x,y,z            "), &
14153          table_equiv_type("D7_2  ","x,y,z            "," x,y,z            ",        &
14154                      " x+y+z,-x-y+z,x-y-z             "," x,y,z            "), &
14155          table_equiv_type("D8_2  ","x,y,z            "," x,y,z            ",        &
14156                      " x+z,-y+z,x-y                   "," x,y,z            "), &
14157          table_equiv_type("D9_2  ","x,y,z            "," x,y,z            ",        &
14158                      "-y+z,-x+z,-x-y                  "," x,y,z            "), &
14159          table_equiv_type("C1_2v ","x,y,z            "," x,y,z            ",        &
14160                      "-y,x,z                          "," x,y,z            "), &
14161          table_equiv_type("C2_2v ","x,y,z            "," y,x,z            ",        &
14162                      "-y,x,z                          "," x,y,z            "), &
14163          table_equiv_type("C3_2v ","x,y,z            "," x,y,z            ",        &
14164                      "-y,x,z                          "," x,y,z            "), &
14165          table_equiv_type("C4_2v ","x,y,z            "," x+1/4,y,z        ",        &
14166                      "-x-1/4,-y,z                     "," x,y,z            "), &
14167          table_equiv_type("C5_2v ","x,y,z            "," x+1/4,y,z        ",        &
14168                      "-x-1/4,-y,z                     "," x,y,z            "), &
14169          table_equiv_type("C6_2v ","x,y,z            "," y+1/4,x,z        ",        &
14170                      "-y-1/4,x,z                      "," x,y,z            ") /)
14171
14172       system_equiv(31:40)= (/         &
14173          table_equiv_type("C7_2v ","x,y,z            "," x,y,z            ",        &
14174                      "-x,-y,z                         "," x,y,z            "), &
14175          table_equiv_type("C8_2v ","x,y,z            "," x+1/4,y+1/4,z    ",        &
14176                      "-y-1/4,x+1/4,z                  "," x,y,z            "), &
14177          table_equiv_type("C9_2v ","x,y,z            "," x+1/4,y+1/4,z    ",        &
14178                      "-x-1/4,-y+1/4,z                 "," x,y,z            "), &
14179          table_equiv_type("C10_2v","x,y,z            "," x+1/4,y+1/4,z    ",        &
14180                      "-y-1/4,x+1/4,z                  "," x,y,z            "), &
14181          table_equiv_type("C11_2v","x,y,z            "," x,y,z            ",        &
14182                      " x-y,x+y,z                      "," x,y,z            "), &
14183          table_equiv_type("C12_2v","x,y,z            "," x,y,z            ",        &
14184                      "-x-y,x-y,z                      "," x,y,z            "), &
14185          table_equiv_type("C13_2v","x,y,z            "," x,y,z            ",        &
14186                      " x-y,x+y,z                      "," x,y,z            "), &
14187          table_equiv_type("C14_2v","-z,y,x           "," -z,y,x           ",        &
14188                      "-y+z,-y-z,x                     ","-y,-z,x           "), &
14189          table_equiv_type("C15_2v","-z,y,x           "," -z,y,x           ",        &
14190                      "-y+z,-y-z,x                     ","-y,-z,x           "), &
14191          table_equiv_type("C16_2v","-z,y,x           "," -z,y,x           ",        &
14192                      "-y+z,-y-z,x                     ","-y,-z,x           ") /)
14193
14194       system_equiv(41:50)= (/         &
14195          table_equiv_type("C17_2v","-z,y,x           "," -z,y,x           ",        &
14196                      "-y+z,-y-z,x                     ","-y,-z,x           "), &
14197          table_equiv_type("C18_2v","x,y,z            "," x,y,z            ",        &
14198                      " x+y+z,-x-y+z,x-y-z             "," x,y,z            "), &
14199          table_equiv_type("C19_2v","x,y,z            "," x-1/8,y-1/8,z    ",        &
14200                      " x+y+z+1/2,-x-y+z-1/2,x-y-z-1/4 "," x,y,z            "), &
14201          table_equiv_type("C20_2v","x,y,z            "," x,y,z            ",        &
14202                      " x+z,-y+z,x-y                   "," x,y,z            "), &
14203          table_equiv_type("C21_2v","x,y,z            "," x,y,z            ",        &
14204                      " x+z,-y+z,x-y                   "," x,y,z            "), &
14205          table_equiv_type("C22_2v","x,y,z            "," x,y,z            ",        &
14206                      "-y+z,-x+z,-x-y                  "," x,y,z            "), &
14207          table_equiv_type("D1_2h ","x,y,z            "," x,y,z            ",        &
14208                      "-y,x,z                          "," x,y,z            "), &
14209          table_equiv_type("D2_2h ","x-1/4,y-1/4,z-1/4"," x-1/4,y-1/4,z-1/4",        &
14210                      "-y+1/4,x-1/4,z-1/4              "," x-1/4,y-1/4,z-1/4"), &
14211          table_equiv_type("D3_2h ","x,y,z            "," x,y,z+1/4        ",        &
14212                      "-y,x,z+1/4                      "," x,y,z            "), &
14213          table_equiv_type("D4_2h ","x-1/4,y-1/4,z    "," x-1/4,y-1/4,z    ",        &
14214                      "-y+1/4,x-1/4,z                  "," x-1/4,y-1/4,z    ") /)
14215
14216       system_equiv(51:60)= (/         &
14217          table_equiv_type("D5_2h ","x,y,z            "," y,z,x            ",        &
14218                      "-y,z,-x                         "," x,y,z            "), &
14219          table_equiv_type("D6_2h ","x,y,z            "," z+1/4,x+1/4,y    ",        &
14220                      " z-1/4,x+1/4,y                  "," x,y,z            "), &
14221          table_equiv_type("D7_2h ","x,y,z            "," x-1/4,y,z        ",        &
14222                      "-x-1/4,-y,z                     "," x,y,z            "), &
14223          table_equiv_type("D8_2h ","x,y,z            "," y,z+1/4,x        ",        &
14224                      "-y,z+1/4,-x                     "," x,y,z            "), &
14225          table_equiv_type("D9_2h ","x,y,z            "," x,y,z            ",        &
14226                      "-y,x,z                          "," x,y,z            "), &
14227          table_equiv_type("D10_2h","x,y,z            "," x+1/4,y+1/4,z+1/4",        &
14228                      "-y-1/4,x+1/4,z+1/4              "," x,y,z            "), &
14229          table_equiv_type("D11_2h","x,y,z            "," -z,-y-1/4,-x     ",        &
14230                      "-z,y+1/4,x                      "," x,y,z            "), &
14231          table_equiv_type("D12_2h","x,y,z            "," x,y,z-1/4        ",        &
14232                      "-y,x,z+1/4                      "," x,y,z            "), &
14233          table_equiv_type("D13_2h","x-1/4,y-1/4,z    "," x-1/4,y-1/4,z    ",        &
14234                      "-y+1/4,x-1/4,z                  "," x-1/4,y-1/4,z+1/4"), &
14235          table_equiv_type("D14_2h","x,y,z            "," z+1/4,x,y+1/4    ",        &
14236                      " z-1/4,x,y+1/4                  "," x,y,z            ") /)
14237
14238       system_equiv(61:70)= (/         &
14239          table_equiv_type("D15_2h","x,y,z            "," x,y,z            ",        &
14240                      "-x,-y,z                         "," x,y,z            "), &
14241          table_equiv_type("D16_2h","x,y,z            "," y+1/4,x+1/4,z    ",        &
14242                      "-y-1/4,x+1/4,z                  "," x,y,z            "), &
14243          table_equiv_type("D17_2h","x,y,z            "," y,x,z            ",        &
14244                      " x-y,x+y,z                      "," x,y,z            "), &
14245          table_equiv_type("D18_2h","x,y,z            "," y,x+1/4,z        ",        &
14246                      " x-y+1/4,x+y+1/4,z              "," x,y,z            "), &
14247          table_equiv_type("D19_2h","x,y,z            "," x,y,z            ",        &
14248                      " x-y,x+y,z                      "," x,y,z            "), &
14249          table_equiv_type("D20_2h","x,y,z            "," x,y,z+1/4        ",        &
14250                      " x-y,x+y,z+1/4                  "," x,y,z            "), &
14251          table_equiv_type("D21_2h","x,y,z            "," x+1/4,y,z        ",        &
14252                      " x-y+1/4,x+y+1/4,z              "," x,y,z            "), &
14253          table_equiv_type("D22_2h","x,y-1/4,z-1/4    "," x,y-1/4,z-1/4    ",        &
14254                      " x-y+1/4,x+y-1/4,z-1/4          "," x,y-1/4,z-1/4    "), &
14255          table_equiv_type("D23_2h","x,y,z            "," x,y,z            ",        &
14256                      " x+y+z,-x-y+z,x-y-z             "," x,y,z            "), &
14257          table_equiv_type("D24_2h","x-7/8,y-7/8,z-7/8"," x-7/8,y-7/8,z-7/8",        &
14258                      " x+y+z-15/8,-x-y+z+5/8,x-y-z+5/8"," x-7/8,y-7/8,z-7/8") /)
14259
14260       system_equiv(71:80)= (/         &
14261          table_equiv_type("D25_2h","x,y,z            "," x,y,z            ",        &
14262                      " x+z,-y+z,x-y                   "," x,y,z            "), &
14263          table_equiv_type("D26_2h","x,y,z            "," x,y,z-1/4        ",        &
14264                      " x+z+1/4,-y+z+1/4,x-y           "," x,y,z            "), &
14265          table_equiv_type("D27_2h","x,y,z            "," x,y,z            ",        &
14266                      " x+z+1/2,-y+z,x-y               "," x,y,z            "), &
14267          table_equiv_type("D28_2h","x,y,z            "," x,y,z+1/4        ",        &
14268                      " x+z+1/4,-y+z-1/4,x-y           "," x,y,z            "), &
14269          table_equiv_type("C1_4  ","x,y,z            "," x,y,z            ",        &
14270                      " x,y,z                          "," x,y,z            "), &
14271          table_equiv_type("C2_4  ","x,y,z            "," x,y,z            ",        &
14272                      " x,y,z                          "," x,y,z            "), &
14273          table_equiv_type("C3_4  ","x,y,z            "," x,y,z            ",        &
14274                      " x,y,z                          "," x,y,z            "), &
14275          table_equiv_type("C4_4  ","x,y,z            "," x,y,z            ",        &
14276                      " x,y,z                          "," x,y,z            "), &
14277          table_equiv_type("C5_4  ","x,y,z            "," x,y,z            ",        &
14278                      " y+z,x+z,x+y                    "," x,y,z            "), &
14279          table_equiv_type("C6_4  ","x,y,z            "," x,y,z            ",        &
14280                      " y+z,x+z,x+y                    "," x,y,z            ") /)
14281
14282       system_equiv(81:90)= (/         &
14283          table_equiv_type("S1_4  ","x,y,z            "," x,y,z            ",        &
14284                      " x,y,z                          "," x,y,z            "), &
14285          table_equiv_type("S2_4  ","x,y,z            "," x,y,z            ",        &
14286                      " y+z,x+z,x+y                    "," x,y,z            "), &
14287          table_equiv_type("C1_4h ","x,y,z            "," x,y,z            ",        &
14288                      " x,y,z                          "," x,y,z            "), &
14289          table_equiv_type("C2_4h ","x,y,z            "," x,y,z+1/4        ",        &
14290                      " x,y,z+1/4                      "," x,y,z            "), &
14291          table_equiv_type("C3_4h ","x-3/4,y-1/4,z    "," x-3/4,y-1/4,z    ",        &
14292                      " x-3/4,y-1/4,z                  "," x-3/4,y-1/4,z    "), &
14293          table_equiv_type("C4_4h ","x-3/4,y-3/4,z-3/4"," x-3/4,y-3/4,z-3/4",        &
14294                      " x-3/4,y-3/4,z-3/4              "," x-3/4,y-3/4,z-3/4"), &
14295          table_equiv_type("C5_4h ","x,y,z            "," x,y,z            ",        &
14296                      " y+z,x+z,x+y                    "," x,y,z            "), &
14297          table_equiv_type("C6_4h ","x,y-3/4,z-7/8    "," x,y-3/4,z-7/8    ",        &
14298                      " y+z-13/8,x+z-7/8,x+y-3/4       "," x,y-3/4,z-7/8    "), &
14299          table_equiv_type("D1_4  ","x,y,z            "," x,y,z            ",        &
14300                      " x,y,z                          "," x,y,z            "), &
14301          table_equiv_type("D2_4  ","x,y,z            "," x,y-1/2,z        ",        &
14302                      " x+1/2,y,z                      "," x,y,z            ") /)
14303
14304       system_equiv(91:100) = (/         &
14305          table_equiv_type("D3_4  ","x,y,z            "," x,y,z+1/4        ",        &
14306                      " x,y,z+1/4                      "," x,y,z            "), &
14307          table_equiv_type("D4_4  ","x,y,z            "," x,y-1/2,z+1/8    ",        &
14308                      " x+1/2,y,z+1/8                  "," x,y,z            "), &
14309          table_equiv_type("D5_4  ","x,y,z            "," x,y,z            ",        &
14310                      " x,y,z                          "," x,y,z            "), &
14311          table_equiv_type("D6_4  ","x,y,z            "," x,y+1/2,z+1/4    ",        &
14312                      " x+1/2,y,z+1/4                  "," x,y,z            "), &
14313          table_equiv_type("D7_4  ","x,y,z            "," x,y,z+1/4        ",        &
14314                      " x,y,z+1/4                      "," x,y,z            "), &
14315          table_equiv_type("D8_4  ","x,y,z            "," x,y-1/2,z-1/8    ",        &
14316                      " x+1/2,y,z+3/8                  "," x,y,z            "), &
14317          table_equiv_type("D9_4  ","x,y,z            "," x,y,z            ",        &
14318                      " y+z,x+z,x+y                    "," x,y,z            "), &
14319          table_equiv_type("D10_4 ","x,y,z            "," x,y,z            ",        &
14320                      " y+z+1/8,x+z+1/8,x+y            "," x,y,z            "), &
14321          table_equiv_type("C1_4v ","x,y,z            "," x,y,z            ",        &
14322                      " x,y,z                          "," x,y,z            "), &
14323          table_equiv_type("C2_4v ","x,y,z            "," x,y,z            ",        &
14324                      " x,y,z                          "," x,y,z            ") /)
14325
14326       system_equiv(101:110)= (/         &
14327          table_equiv_type("C3_4v ","x,y,z            "," x,y,z            ",        &
14328                      " x,y,z                          "," x,y,z            "), &
14329          table_equiv_type("C4_4v ","x,y,z            "," x,y-1/2,z        ",        &
14330                      " x+1/2,y,z                      "," x,y,z            "), &
14331          table_equiv_type("C5_4v ","x,y,z            "," x,y,z            ",        &
14332                      " x,y,z                          "," x,y,z            "), &
14333          table_equiv_type("C6_4v ","x,y,z            "," x,y,z            ",        &
14334                      " x,y,z                          "," x,y,z            "), &
14335          table_equiv_type("C7_4v ","x,y,z            "," x,y,z            ",        &
14336                      " x,y,z                          "," x,y,z            "), &
14337          table_equiv_type("C8_4v ","x,y,z            "," x,y,z            ",        &
14338                      " x,y,z                          "," x,y,z            "), &
14339          table_equiv_type("C9_4v ","x,y,z            "," x,y,z            ",        &
14340                      " y+z,x+z,x+y                    "," x,y,z            "), &
14341          table_equiv_type("C10_4v","x,y,z            "," x,y,z            ",        &
14342                      " y+z,x+z,x+y                    "," x,y,z            "), &
14343          table_equiv_type("C11_4v","x,y,z            "," x,y,z            ",        &
14344                      " y+z,x+z,x+y                    "," x,y,z            "), &
14345          table_equiv_type("C12_4v","x,y,z            "," x,y,z            ",        &
14346                      " y+z,x+z,x+y                    "," x,y,z            ") /)
14347
14348       system_equiv(111:120)= (/         &
14349          table_equiv_type("D1_2d ","x,y,z            "," x,y,z            ",        &
14350                      " x,y,z                          "," x,y,z            "), &
14351          table_equiv_type("D2_2d ","x,y,z            "," x,y,z            ",        &
14352                      " x,y,z                          "," x,y,z            "), &
14353          table_equiv_type("D3_2d ","x,y,z            "," x,y,z            ",        &
14354                      " x,y,z                          "," x,y,z            "), &
14355          table_equiv_type("D4_2d ","x,y,z            "," x,y,z            ",        &
14356                      " x,y,z                          "," x,y,z            "), &
14357          table_equiv_type("D5_2d ","x,y,z            "," x,y,z            ",        &
14358                      " x,y,z                          "," x,y,z            "), &
14359          table_equiv_type("D6_2d ","x,y,z            "," x,y,z            ",        &
14360                      " x,y,z                          "," x,y,z            "), &
14361          table_equiv_type("D7_2d ","x,y,z            "," x,y,z            ",        &
14362                      " x,y,z                          "," x,y,z            "), &
14363          table_equiv_type("D8_2d ","x,y,z            "," x,y,z            ",        &
14364                      " x,y,z                          "," x,y,z            "), &
14365          table_equiv_type("D9_2d ","x,y,z            "," x,y,z            ",        &
14366                      " y+z,x+z,x+y                    "," x,y,z            "), &
14367          table_equiv_type("D10_2d","x,y,z            "," x,y,z            ",        &
14368                      " y+z,x+z,x+y                    "," x,y,z            ")  /)
14369
14370       system_equiv(121:130)= (/         &
14371          table_equiv_type("D11_2d","x,y,z            "," x,y,z            ",        &
14372                      " y+z,x+z,x+y                    "," x,y,z            "), &
14373          table_equiv_type("D12_2d","x,y,z            "," x+1/2,y,z+1/4    ",        &
14374                      " x+z,-y+z,x-y                   "," x,y,z            "), &
14375          table_equiv_type("D1_4h ","x,y,z            "," x,y,z            ",        &
14376                      " x,y,z                          "," x,y,z            "), &
14377          table_equiv_type("D2_4h ","x,y,z            "," x,y,z-1/4        ",        &
14378                      " x,y,z+1/4                      "," x,y,z            "), &
14379          table_equiv_type("D3_4h ","x-3/4,y-3/4,z    "," x-3/4,y-3/4,z    ",        &
14380                      " x-1/4,y-3/4,z                  "," x-3/4,y-3/4,z    "), &
14381          table_equiv_type("D4_4h ","x-3/4,y-3/4,z-3/4"," x-3/4,y-3/4,z-3/4",        &
14382                      " x-1/4,y-3/4,z-3/4              "," x-3/4,y-3/4,z-3/4"), &
14383          table_equiv_type("D5_4h ","x,y,z            "," x,y,z            ",        &
14384                      " x+1/2,y,z                      "," x,y,z            "), &
14385          table_equiv_type("D6_4h ","x,y,z            "," x,y,z+1/4        ",        &
14386                      " x+1/2,y,z+1/4                  "," x,y,z            "), &
14387          table_equiv_type("D7_4h ","x-3/4,y-1/4,z    "," x-3/4,y+1/4,z    ",        &
14388                      " x-1/4,y-1/4,z                  "," x-3/4,y-1/4,z    "), &
14389          table_equiv_type("D8_4h ","x-3/4,y-1/4,z    "," x-3/4,y+1/4,z+1/4",        &
14390                      " x-1/4,y-1/4,z+1/4              "," x,y,z            ") /)
14391
14392       system_equiv(131:140)= (/         &
14393          table_equiv_type("D9_4d ","x,y,z            "," x,y,z            ",        &
14394                      " x,y,z                          "," x,y,z            "), &
14395          table_equiv_type("D10_4d","x,y,z            "," x,y,z-1/4        ",        &
14396                      " x,y,z+1/4                      "," x,y,z            "), &
14397          table_equiv_type("D11_4d","x-3/4,y-1/4,z-3/4"," x-3/4,y+1/4,z-1/2",        &
14398                      " x-3/4,y-1/4,z-1/2              "," x,y,z            "), &
14399          table_equiv_type("D12_4d","x-3/4,y-1/4,z-3/4"," x-3/4,y+1/4,z-3/4",        &
14400                      " x-3/4,y-1/4,z-3/4              "," x-3/4,y-1/4,z-3/4"), &
14401          table_equiv_type("D13_4d","x,y,z            "," x,y,z            ",        &
14402                      " x+1/2,y,z                      "," x,y,z            "), &
14403          table_equiv_type("D14_4d","x,y,z            "," x,y+1/2,z+1/4    ",        &
14404                      " x,y,z+1/4                      "," x+1/2,y,z        "), &
14405          table_equiv_type("D15_4d","x-3/4,y-1/4,z-3/4"," x-3/4,y+1/4,z-1/2",        &
14406                      " x-1/4,y-1/4,z-1/2              "," x,y,z            "), &
14407          table_equiv_type("D16_4d","x-3/4,y-1/4,z-3/4"," x-3/4,y+1/4,z-3/4",        &
14408                      " x-1/4,y-1/4,z-3/4              "," x,y,z            "), &
14409          table_equiv_type("D17_4d","x,y,z            "," x,y,z            ",        &
14410                      " y+z,x+z,x+y                    "," x,y,z            "), &
14411          table_equiv_type("D18_4d","x,y,z            "," x,y,z+1/4        ",        &
14412                      " y+z+1/4,x+z+3/4,x+y+1/2        "," x,y,z            ") /)
14413
14414       system_equiv(141:150)= (/         &
14415          table_equiv_type("D19_4d","x,y-1/4,z-7/8    "," x,y-1/4,z-7/8    ",        &
14416                      " y+z-3/4,x+z-3/4,x+y            "," x,y-1/4,z-7/8    "), &
14417          table_equiv_type("D20_4d","x,y-1/4,z-7/8    "," x,y-1/4,z-9/8    ",        &
14418                      " y+z,x+z-1/2,x+y+1/2            "," x,y,z            "), &
14419          table_equiv_type("C1_3  ","x,y,z            "," x,y,z            ",        &
14420                      " x,y,z                          "," x,y,z            "), &
14421          table_equiv_type("C2_3  ","x,y,z            "," x,y,z            ",        &
14422                      " x,y,z                          "," x,y,z            "), &
14423          table_equiv_type("C3_3  ","x,y,z            "," x,y,z            ",        &
14424                      " x,y,z                          "," x,y,z            "), &
14425          table_equiv_type("C4_3  ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14426                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        "), &
14427          table_equiv_type("C1_3i ","x,y,z            "," x,y,z            ",        &
14428                      " x,y,z                          "," x,y,z            "), &
14429          table_equiv_type("C2_3i ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14430                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        "), &
14431          table_equiv_type("D1_3  ","x,y,z            "," x,y,z            ",        &
14432                      " x,y,z                          "," x,y,z            "), &
14433          table_equiv_type("D2_3  ","x,y,z            "," x,y,z            ",        &
14434                      " x,y,z                          "," x,y,z            ") /)
14435
14436       system_equiv(151:160)= (/         &
14437          table_equiv_type("D3_3  ","x,y,z-1/6        "," x,y,z+1/6        ",        &
14438                      " x,y,z+1/6                      "," x,y,z+1/6        "), &
14439          table_equiv_type("D4_3  ","x,y,z            "," x,y,z+1/3        ",        &
14440                      " x,y,z                          "," x,y,z            "), &
14441          table_equiv_type("D5_3  ","x,y,z-5/6        "," x,y,z+1/3        ",        &
14442                      " x,y,z-1/6                      "," x,y,z-1/6        "), &
14443          table_equiv_type("D6_3  ","x,y,z-1/6        "," x,y,z+1/6        ",        &
14444                      " x,y,z+1/2                      "," x,y,z+1/2        "), &
14445          table_equiv_type("D7_3  ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14446                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        "), &
14447          table_equiv_type("C1_3v ","x,y,z            "," x,y,z            ",        &
14448                      " x,y,z                          "," x,y,z            "), &
14449          table_equiv_type("C2_3v ","x,y,z            "," x,y,z            ",        &
14450                      " x,y,z                          "," x,y,z            "), &
14451          table_equiv_type("C3_3v ","x,y,z            "," x,y,z            ",        &
14452                      " x,y,z                          "," x,y,z            "), &
14453          table_equiv_type("C4_3v ","x,y,z            "," x,y,z            ",        &
14454                      " x,y,z                          "," x,y,z            "), &
14455          table_equiv_type("C5_3v ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14456                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        ")/)
14457
14458       system_equiv(161:170)= (/         &
14459          table_equiv_type("C6_3v ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14460                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        "), &
14461          table_equiv_type("D1_3d ","x,y,z            "," x,y,z            ",        &
14462                      " x,y,z                          "," x,y,z            "), &
14463          table_equiv_type("D2_3d ","x,y,z            "," x,y,z+1/4        ",        &
14464                      " x,y,z                          "," x,y,z            "), &
14465          table_equiv_type("D3_3d ","x,y,z            "," x,y,z            ",        &
14466                      " x,y,z                          "," x,y,z            "), &
14467          table_equiv_type("D4_3d ","x,y,z            "," x,y,z+1/4        ",        &
14468                      " x,y,z                          "," x,y,z            "), &
14469          table_equiv_type("D5_3d ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14470                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        "), &
14471          table_equiv_type("D6_3d ","y,-x+y,z         ","-2x+y,-x-y,z      ",        &
14472                      " x+z,-x+y+z,-y+z                "," y,-x+y,3z        "), &
14473          table_equiv_type("C1_6  ","x,y,z            "," x,y,z            ",        &
14474                      " x,y,z                          "," x,y,z            "), &
14475          table_equiv_type("C2_6  ","x,y,z            "," x,y,z            ",        &
14476                      " x,y,z                          "," x,y,z            "), &
14477          table_equiv_type("C3_6  ","x,y,z            "," x,y,z            ",        &
14478                      " x,y,z                          "," x,y,z            ") /)
14479
14480       system_equiv(171:180)= (/         &
14481          table_equiv_type("C4_6  ","x,y,z            "," x,y,z            ",        &
14482                      " x,y,z                          "," x,y,z            "), &
14483          table_equiv_type("C5_6  ","x,y,z            "," x,y,z            ",        &
14484                      " x,y,z                          "," x,y,z            "), &
14485          table_equiv_type("C6_6  ","x,y,z            "," x,y,z            ",        &
14486                      " x,y,z                          "," x,y,z            "), &
14487          table_equiv_type("C7_6  ","x,y,z            "," x,y,z            ",        &
14488                      " x,y,z                          "," x,y,z            "), &
14489          table_equiv_type("C1_6h ","x,y,z            "," x,y,z            ",        &
14490                      " x,y,z                          "," x,y,z            "), &
14491          table_equiv_type("C2_6h ","x,y,z            "," x,y,z            ",        &
14492                      " x,y,z+1/4                      "," x,y,z            "), &
14493          table_equiv_type("D1_6  ","x,y,z            "," x,y,z            ",        &
14494                      " x,y,z                          "," x,y,z            "), &
14495          table_equiv_type("D2_6  ","x,y,z            "," x,y,z+1/6        ",        &
14496                      " x,y,z+1/4                      "," x,y,z            "), &
14497          table_equiv_type("D3_6  ","x,y,z            "," x,y,z+1/3        ",        &
14498                      " x,y,z+1/4                      "," x,y,z            "), &
14499          table_equiv_type("D4_6  ","x,y,z            "," x,y,z+1/3        ",        &
14500                      " x,y,z                          "," x,y,z            ") /)
14501
14502       system_equiv(181:190)= (/         &
14503          table_equiv_type("D5_6  ","x,y,z            "," x,y,z-1/3        ",        &
14504                      " x,y,z                          "," x,y,z            "), &
14505          table_equiv_type("D6_6  ","x,y,z            "," x,y,z            ",        &
14506                      " x,y,z+1/4                      "," x,y,z            "), &
14507          table_equiv_type("C1_6v ","x,y,z            "," x,y,z            ",        &
14508                      " x,y,z                          "," x,y,z            "), &
14509          table_equiv_type("C2_6v ","x,y,z            "," x,y,z            ",        &
14510                      " x,y,z                          "," x,y,z            "), &
14511          table_equiv_type("C3_6v ","x,y,z            "," x,y,z            ",        &
14512                      " x,y,z                          "," x,y,z            "), &
14513          table_equiv_type("C4_6v ","x,y,z            "," x,y,z            ",        &
14514                      " x,y,z                          "," x,y,z            "), &
14515          table_equiv_type("D1_3h ","x,y,z            "," x,y,z            ",        &
14516                      " x,y,z                          "," x,y,z            "), &
14517          table_equiv_type("D2_3h ","x,y,z            "," x,y,z            ",        &
14518                      " x,y,z+1/4                      "," x,y,z            "), &
14519          table_equiv_type("D3_3h ","x,y,z            "," x,y,z            ",        &
14520                      " x,y,z                          "," x,y,z            "), &
14521          table_equiv_type("D4_3h ","x,y,z            "," x,y,z            ",        &
14522                      " x,y,z+1/4                      "," x,y,z            ") /)
14523
14524       system_equiv(191:200)= (/         &
14525          table_equiv_type("D1_6h ","x,y,z            "," x,y,z            ",        &
14526                      " x,y,z                          "," x,y,z            "), &
14527          table_equiv_type("D2_6h ","x,y,z            "," x,y,z-1/4        ",        &
14528                      " x,y,z                          "," x,y,z            "), &
14529          table_equiv_type("D3_6h ","x,y,z            "," x,y,z-1/4        ",        &
14530                      " x,y,z                          "," x,y,z            "), &
14531          table_equiv_type("D4_6h ","x,y,z            "," x,y,z            ",        &
14532                      " x,y,z                          "," x,y,z            "), &
14533          table_equiv_type("T1    ","x,y,z            "," x,y,z            ",        &
14534                      " x,y,z                          "," x,y,z            "), &
14535          table_equiv_type("T2    ","x,y,z            "," x,y,z            ",        &
14536                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            "), &
14537          table_equiv_type("T3    ","x,y,z            "," x,y,z            ",        &
14538                      " y+z,x+z,x+y                    "," x,y,z            "), &
14539          table_equiv_type("T4    ","x,y,z            "," x,y,z            ",        &
14540                      " x,y,z                          "," x,y,z            "), &
14541          table_equiv_type("T5    ","x,y,z            "," x,y,z            ",        &
14542                      " y+z,x+z,x+y                    "," x,y,z            "), &
14543          table_equiv_type("T1_h  ","x,y,z            "," x,y,z            ",        &
14544                      " x,y,z                          "," x,y,z            ") /)
14545
14546       system_equiv(201:210)= (/         &
14547          table_equiv_type("T2_h  ","x-3/4,y-3/4,z-3/4"," x-3/4,y-3/4,z-3/4",        &
14548                      " x-3/4,y-3/4,z-3/4              "," x-3/4,y-3/4,z-3/4"), &
14549          table_equiv_type("T3_h  ","x,y,z            "," x,y,z            ",        &
14550                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            "), &
14551          table_equiv_type("T4_h  ","x-7/8,y-7/8,z-7/8"," x-7/8,y-7/8,z-7/8",        &
14552                      "-x+y+z-7/8,x-y+z-7/8,x+y-z-7/8  "," x-7/8,y-7/8,z-7/8"), &
14553          table_equiv_type("T5_h  ","x,y,z            "," x,y,z            ",        &
14554                      " y+z,x+z,x+y                    "," x,y,z            "), &
14555          table_equiv_type("T6_h  ","x,y,z            "," x,y,z            ",        &
14556                      " x,y,z                          "," x,y,z            "), &
14557          table_equiv_type("T7_h  ","x,y,z            "," x,y,z            ",        &
14558                      " y+z,x+z,x+y                    "," x,y,z            "), &
14559          table_equiv_type("O1    ","x,y,z            "," x,y,z            ",        &
14560                      " x,y,z                          "," x,y,z            "), &
14561          table_equiv_type("O2    ","x,y,z            "," x,y,z            ",        &
14562                      " x,y,z                          "," x,y,z            "), &
14563          table_equiv_type("O3    ","x,y,z            "," x,y,z            ",        &
14564                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            "), &
14565          table_equiv_type("O4    ","x,y,z            "," x,y,z            ",        &
14566                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            ") /)
14567
14568       system_equiv(211:220)= (/         &
14569          table_equiv_type("O5    ","x,y,z            "," x,y,z            ",        &
14570                      " y+z,x+z,x+y                    "," x,y,z            "), &
14571          table_equiv_type("O6    ","x,y,z            "," x,y,z            ",        &
14572                      " x,y,z                          "," x,y,z            "), &
14573          table_equiv_type("O7    ","x,y,z            "," x,y,z            ",        &
14574                      " x,y,z                          "," x,y,z            "), &
14575          table_equiv_type("O8    ","x,y,z            "," x,y,z            ",        &
14576                      " y+z,x+z,x+y                    "," x,y,z            "), &
14577          table_equiv_type("T1_d  ","x,y,z            "," x,y,z            ",        &
14578                      " x,y,z                          "," x,y,z            "), &
14579          table_equiv_type("T2_d  ","x,y,z            "," x,y,z            ",        &
14580                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            "), &
14581          table_equiv_type("T3_d  ","x,y,z            "," x,y,z            ",        &
14582                      " y+z,x+z,x+y                    "," x,y,z            "), &
14583          table_equiv_type("T4_d  ","x,y,z            "," x,y,z            ",        &
14584                      " x,y,z                          "," x,y,z            "), &
14585          table_equiv_type("T5_d  ","x,y,z            "," x,y,z            ",        &
14586                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            "), &
14587          table_equiv_type("T6_d  ","x,y,z            "," x,y,z            ",        &
14588                      " y+z,x+z,x+y                    "," x,y,z            ") /)
14589
14590       system_equiv(221:230)= (/         &
14591          table_equiv_type("O1_h  ","x,y,z            "," x,y,z            ",        &
14592                      " x,y,z                          "," x,y,z            "), &
14593          table_equiv_type("O2_h  ","x-3/4,y-3/4,z-3/4"," x-3/4,y-3/4,z-3/4",        &
14594                      " x-3/4,y-3/4,z-3/4              "," x-3/4,y-3/4,z-3/4"), &
14595          table_equiv_type("O3_h  ","x,y,z            "," x,y,z            ",        &
14596                      " x,y,z                          "," x,y,z            "), &
14597          table_equiv_type("O4_h  ","x-3/4,y-3/4,z-3/4"," x-3/4,y-3/4,z-3/4",        &
14598                      " x-3/4,y-3/4,z-3/4              "," x-3/4,y-3/4,z-3/4"), &
14599          table_equiv_type("O5_h  ","x,y,z            "," x,y,z            ",        &
14600                      "-x+y+z,x-y+z,x+y-z              "," x,y,z            "), &
14601          table_equiv_type("O6_h  ","x,y,z            "," x-1/4,y-1/4,z-1/4",        &
14602                      "-x+y+z+1/4,x-y+z+1/4,x+y-z+1/4  "," x,y,z            "), &
14603          table_equiv_type("O7_h  ","x,y,z            "," x+1/8,y+1/8,z+1/8",        &
14604                      "-x+y+z+1/8,x-y+z+1/8,x+y-z+1/8  "," x+1/8,y+1/8,z+1/8"), &
14605          table_equiv_type("O8_h  ","x,y,z            "," x+3/8,y+3/8,z+3/8",        &
14606                      "-x+y+z+3/8,x-y+z+3/8,x+y-z+3/8  "," x+3/8,y+3/8,z+3/8"), &
14607          table_equiv_type("O9_h  ","x,y,z            "," x,y,z            ",        &
14608                      " y+z,x+z,x+y                    "," x,y,z            "), &
14609          table_equiv_type("O10_h ","x,y,z            "," x,y,z            ",        &
14610                      " y+z,x+z,x+y                    "," x,y,z            ") /)
14611
14612       return
14613    End Subroutine Set_System_Equiv
14614
14615    !!----
14616    !!---- Subroutine Set_Wyckoff_Info()
14617    !!----
14618    !!----    Set Information on Wyckoff_info array
14619    !!----
14620    !!---- Update: February - 2005
14621    !!
14622    Subroutine Set_Wyckoff_Info()
14623
14624       if (.not. allocated(wyckoff_info) ) allocate(wyckoff_info(273) )
14625
14626       wyckoff_info(  1)= wyck_info_type("P 1         ", 0,     &
14627                    (/"               ", "               ", "               ",    &
14628                      "               ", "               ", "               ",    &
14629                      "               ", "               ", "               ",    &
14630                      "               ", "               ", "               ",    &
14631                      "               ", "               ", "               ",    &
14632                      "               ", "               ", "               ",    &
14633                      "               ", "               ", "               ",    &
14634                      "               ", "               ", "               ",    &
14635                      "               ", "               "/) )
14636       wyckoff_info(  2)= wyck_info_type("P -1        ", 8,     &
14637                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
14638                      "1/2,0,0        ", "1/2,1/2,0      ", "1/2,0,1/2      ",    &
14639                      "0,1/2,1/2      ", "1/2,1/2,1/2    ", "               ",    &
14640                      "               ", "               ", "               ",    &
14641                      "               ", "               ", "               ",    &
14642                      "               ", "               ", "               ",    &
14643                      "               ", "               ", "               ",    &
14644                      "               ", "               ", "               ",    &
14645                      "               ", "               "/) )
14646       wyckoff_info(  3)= wyck_info_type("P 2         ", 4,     &
14647                    (/"0,y,0          ", "0,y,1/2        ", "1/2,y,0        ",    &
14648                      "1/2,y,1/2      ", "               ", "               ",    &
14649                      "               ", "               ", "               ",    &
14650                      "               ", "               ", "               ",    &
14651                      "               ", "               ", "               ",    &
14652                      "               ", "               ", "               ",    &
14653                      "               ", "               ", "               ",    &
14654                      "               ", "               ", "               ",    &
14655                      "               ", "               "/) )
14656       wyckoff_info(  4)= wyck_info_type("P 21        ", 0,     &
14657                    (/"               ", "               ", "               ",    &
14658                      "               ", "               ", "               ",    &
14659                      "               ", "               ", "               ",    &
14660                      "               ", "               ", "               ",    &
14661                      "               ", "               ", "               ",    &
14662                      "               ", "               ", "               ",    &
14663                      "               ", "               ", "               ",    &
14664                      "               ", "               ", "               ",    &
14665                      "               ", "               "/) )
14666       wyckoff_info(  5)= wyck_info_type("C 2         ", 2,     &
14667                    (/"0,y,0          ", "0,y,1/2        ", "               ",    &
14668                      "               ", "               ", "               ",    &
14669                      "               ", "               ", "               ",    &
14670                      "               ", "               ", "               ",    &
14671                      "               ", "               ", "               ",    &
14672                      "               ", "               ", "               ",    &
14673                      "               ", "               ", "               ",    &
14674                      "               ", "               ", "               ",    &
14675                      "               ", "               "/) )
14676       wyckoff_info(  6)= wyck_info_type("A 2         ", 2,     &
14677                    (/"0,y,0          ", "1/2,y,1/2      ", "               ",    &
14678                      "               ", "               ", "               ",    &
14679                      "               ", "               ", "               ",    &
14680                      "               ", "               ", "               ",    &
14681                      "               ", "               ", "               ",    &
14682                      "               ", "               ", "               ",    &
14683                      "               ", "               ", "               ",    &
14684                      "               ", "               ", "               ",    &
14685                      "               ", "               "/) )
14686       wyckoff_info(  7)= wyck_info_type("I 2         ", 2,     &
14687                    (/"0,y,0          ", "1/2,y,0        ", "               ",    &
14688                      "               ", "               ", "               ",    &
14689                      "               ", "               ", "               ",    &
14690                      "               ", "               ", "               ",    &
14691                      "               ", "               ", "               ",    &
14692                      "               ", "               ", "               ",    &
14693                      "               ", "               ", "               ",    &
14694                      "               ", "               ", "               ",    &
14695                      "               ", "               "/) )
14696       wyckoff_info(  8)= wyck_info_type("P M         ", 2,     &
14697                    (/"x,0,z          ", "x,1/2,z        ", "               ",    &
14698                      "               ", "               ", "               ",    &
14699                      "               ", "               ", "               ",    &
14700                      "               ", "               ", "               ",    &
14701                      "               ", "               ", "               ",    &
14702                      "               ", "               ", "               ",    &
14703                      "               ", "               ", "               ",    &
14704                      "               ", "               ", "               ",    &
14705                      "               ", "               "/) )
14706       wyckoff_info(  9)= wyck_info_type("P C         ", 0,     &
14707                    (/"               ", "               ", "               ",    &
14708                      "               ", "               ", "               ",    &
14709                      "               ", "               ", "               ",    &
14710                      "               ", "               ", "               ",    &
14711                      "               ", "               ", "               ",    &
14712                      "               ", "               ", "               ",    &
14713                      "               ", "               ", "               ",    &
14714                      "               ", "               ", "               ",    &
14715                      "               ", "               "/) )
14716       wyckoff_info( 10)= wyck_info_type("C M         ", 1,     &
14717                    (/"x,0,z          ", "               ", "               ",    &
14718                      "               ", "               ", "               ",    &
14719                      "               ", "               ", "               ",    &
14720                      "               ", "               ", "               ",    &
14721                      "               ", "               ", "               ",    &
14722                      "               ", "               ", "               ",    &
14723                      "               ", "               ", "               ",    &
14724                      "               ", "               ", "               ",    &
14725                      "               ", "               "/) )
14726       wyckoff_info( 11)= wyck_info_type("A M         ", 1,     &
14727                    (/"x,0,z          ", "               ", "               ",    &
14728                      "               ", "               ", "               ",    &
14729                      "               ", "               ", "               ",    &
14730                      "               ", "               ", "               ",    &
14731                      "               ", "               ", "               ",    &
14732                      "               ", "               ", "               ",    &
14733                      "               ", "               ", "               ",    &
14734                      "               ", "               ", "               ",    &
14735                      "               ", "               "/) )
14736       wyckoff_info( 12)= wyck_info_type("I M         ", 1,     &
14737                    (/"x,0,z          ", "               ", "               ",    &
14738                      "               ", "               ", "               ",    &
14739                      "               ", "               ", "               ",    &
14740                      "               ", "               ", "               ",    &
14741                      "               ", "               ", "               ",    &
14742                      "               ", "               ", "               ",    &
14743                      "               ", "               ", "               ",    &
14744                      "               ", "               ", "               ",    &
14745                      "               ", "               "/) )
14746       wyckoff_info( 13)= wyck_info_type("C C         ", 0,     &
14747                    (/"               ", "               ", "               ",    &
14748                      "               ", "               ", "               ",    &
14749                      "               ", "               ", "               ",    &
14750                      "               ", "               ", "               ",    &
14751                      "               ", "               ", "               ",    &
14752                      "               ", "               ", "               ",    &
14753                      "               ", "               ", "               ",    &
14754                      "               ", "               ", "               ",    &
14755                      "               ", "               "/) )
14756       wyckoff_info( 14)= wyck_info_type("P 2/M       ",14,     &
14757                    (/"0,0,0          ", "0,1/2,0        ", "0,0,1/2        ",    &
14758                      "1/2,0,0        ", "1/2,1/2,0      ", "0,1/2,1/2      ",    &
14759                      "1/2,0,1/2      ", "1/2,1/2,1/2    ", "0,y,0          ",    &
14760                      "1/2,y,0        ", "0,y,1/2        ", "1/2,y,1/2      ",    &
14761                      "x,0,z          ", "x,1/2,z        ", "               ",    &
14762                      "               ", "               ", "               ",    &
14763                      "               ", "               ", "               ",    &
14764                      "               ", "               ", "               ",    &
14765                      "               ", "               "/) )
14766       wyckoff_info( 15)= wyck_info_type("P 21/M      ", 5,     &
14767                    (/"0,0,0          ", "1/2,0,0        ", "0,0,1/2        ",    &
14768                      "1/2,0,1/2      ", "x,1/4,z        ", "               ",    &
14769                      "               ", "               ", "               ",    &
14770                      "               ", "               ", "               ",    &
14771                      "               ", "               ", "               ",    &
14772                      "               ", "               ", "               ",    &
14773                      "               ", "               ", "               ",    &
14774                      "               ", "               ", "               ",    &
14775                      "               ", "               "/) )
14776       wyckoff_info( 16)= wyck_info_type("C 2/M       ", 9,     &
14777                    (/"0,0,0          ", "0,1/2,0        ", "0,0,1/2        ",    &
14778                      "0,1/2,1/2      ", "1/4,1/4,0      ", "1/4,1/4,1/2    ",    &
14779                      "0,y,0          ", "0,y,1/2        ", "x,0,z          ",    &
14780                      "               ", "               ", "               ",    &
14781                      "               ", "               ", "               ",    &
14782                      "               ", "               ", "               ",    &
14783                      "               ", "               ", "               ",    &
14784                      "               ", "               ", "               ",    &
14785                      "               ", "               "/) )
14786       wyckoff_info( 17)= wyck_info_type("A 2/M       ", 9,     &
14787                    (/"0,0,0          ", "0,1/2,0        ", "1/2,0,1/2      ",    &
14788                      "1/2,1/2,1/2    ", "0,1/4,1/4      ", "1/2,1/4,3/4    ",    &
14789                      "0,y,0          ", "1/2,y,1/2      ", "x,0,z          ",    &
14790                      "               ", "               ", "               ",    &
14791                      "               ", "               ", "               ",    &
14792                      "               ", "               ", "               ",    &
14793                      "               ", "               ", "               ",    &
14794                      "               ", "               ", "               ",    &
14795                      "               ", "               "/) )
14796       wyckoff_info( 18)= wyck_info_type("I 2/M       ", 9,     &
14797                    (/"0,0,0          ", "0,1/2,0        ", "1/2,0,0        ",    &
14798                      "1/2,1/2,0      ", "3/4,1/4,3/4    ", "1/4,1/4,3/4    ",    &
14799                      "0,y,0          ", "1/2,y,0        ", "x,0,z          ",    &
14800                      "               ", "               ", "               ",    &
14801                      "               ", "               ", "               ",    &
14802                      "               ", "               ", "               ",    &
14803                      "               ", "               ", "               ",    &
14804                      "               ", "               ", "               ",    &
14805                      "               ", "               "/) )
14806       wyckoff_info( 19)= wyck_info_type("P 2/C       ", 6,     &
14807                    (/"0,0,0          ", "1/2,1/2,0      ", "0,1/2,0        ",    &
14808                      "1/2,0,0        ", "0,y,1/4        ", "1/2,y,1/4      ",    &
14809                      "               ", "               ", "               ",    &
14810                      "               ", "               ", "               ",    &
14811                      "               ", "               ", "               ",    &
14812                      "               ", "               ", "               ",    &
14813                      "               ", "               ", "               ",    &
14814                      "               ", "               ", "               ",    &
14815                      "               ", "               "/) )
14816       wyckoff_info( 20)= wyck_info_type("P 2/N       ", 6,     &
14817                    (/"0,0,0          ", "0,1/2,1/2      ", "0,1/2,0        ",    &
14818                      "0,0,1/2        ", "3/4,y,3/4      ", "3/4,y,1/4      ",    &
14819                      "               ", "               ", "               ",    &
14820                      "               ", "               ", "               ",    &
14821                      "               ", "               ", "               ",    &
14822                      "               ", "               ", "               ",    &
14823                      "               ", "               ", "               ",    &
14824                      "               ", "               ", "               ",    &
14825                      "               ", "               "/) )
14826       wyckoff_info( 21)= wyck_info_type("P 2/A       ", 6,     &
14827                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,1/2,0        ",    &
14828                      "1/2,0,1/2      ", "1/4,y,0        ", "3/4,y,1/2      ",    &
14829                      "               ", "               ", "               ",    &
14830                      "               ", "               ", "               ",    &
14831                      "               ", "               ", "               ",    &
14832                      "               ", "               ", "               ",    &
14833                      "               ", "               ", "               ",    &
14834                      "               ", "               ", "               ",    &
14835                      "               ", "               "/) )
14836       wyckoff_info( 22)= wyck_info_type("P 21/C      ", 4,     &
14837                    (/"0,0,0          ", "1/2,0,0        ", "0,0,1/2        ",    &
14838                      "1/2,0,1/2      ", "               ", "               ",    &
14839                      "               ", "               ", "               ",    &
14840                      "               ", "               ", "               ",    &
14841                      "               ", "               ", "               ",    &
14842                      "               ", "               ", "               ",    &
14843                      "               ", "               ", "               ",    &
14844                      "               ", "               ", "               ",    &
14845                      "               ", "               "/) )
14846       wyckoff_info( 23)= wyck_info_type("P 21/N      ", 4,     &
14847                    (/"0,0,0          ", "0,0,1/2        ", "1/2,0,1/2      ",    &
14848                      "1/2,0,0        ", "               ", "               ",    &
14849                      "               ", "               ", "               ",    &
14850                      "               ", "               ", "               ",    &
14851                      "               ", "               ", "               ",    &
14852                      "               ", "               ", "               ",    &
14853                      "               ", "               ", "               ",    &
14854                      "               ", "               ", "               ",    &
14855                      "               ", "               "/) )
14856       wyckoff_info( 24)= wyck_info_type("P 21/A      ", 4,     &
14857                    (/"0,0,0          ", "1/2,0,1/2      ", "1/2,0,0        ",    &
14858                      "0,0,1/2        ", "               ", "               ",    &
14859                      "               ", "               ", "               ",    &
14860                      "               ", "               ", "               ",    &
14861                      "               ", "               ", "               ",    &
14862                      "               ", "               ", "               ",    &
14863                      "               ", "               ", "               ",    &
14864                      "               ", "               ", "               ",    &
14865                      "               ", "               "/) )
14866       wyckoff_info( 25)= wyck_info_type("C 2/C       ", 5,     &
14867                    (/"0,0,0          ", "0,1/2,0        ", "1/4,1/4,0      ",    &
14868                      "1/4,1/4,1/2    ", "0,y,1/4        ", "               ",    &
14869                      "               ", "               ", "               ",    &
14870                      "               ", "               ", "               ",    &
14871                      "               ", "               ", "               ",    &
14872                      "               ", "               ", "               ",    &
14873                      "               ", "               ", "               ",    &
14874                      "               ", "               ", "               ",    &
14875                      "               ", "               "/) )
14876       wyckoff_info( 26)= wyck_info_type("A 2/N       ", 5,     &
14877                    (/"0,0,0          ", "0,1/2,0        ", "0,1/4,1/4      ",    &
14878                      "1/2,1/4,3/4    ", "3/4,y,3/4      ", "               ",    &
14879                      "               ", "               ", "               ",    &
14880                      "               ", "               ", "               ",    &
14881                      "               ", "               ", "               ",    &
14882                      "               ", "               ", "               ",    &
14883                      "               ", "               ", "               ",    &
14884                      "               ", "               ", "               ",    &
14885                      "               ", "               "/) )
14886       wyckoff_info( 27)= wyck_info_type("I 2/A       ", 5,     &
14887                    (/"0,0,0          ", "0,1/2,0        ", "3/4,1/4,3/4    ",    &
14888                      "1/4,1/4,3/4    ", "1/4,y,0        ", "               ",    &
14889                      "               ", "               ", "               ",    &
14890                      "               ", "               ", "               ",    &
14891                      "               ", "               ", "               ",    &
14892                      "               ", "               ", "               ",    &
14893                      "               ", "               ", "               ",    &
14894                      "               ", "               ", "               ",    &
14895                      "               ", "               "/) )
14896       wyckoff_info( 28)= wyck_info_type("P 2 2 2     ",20,     &
14897                    (/"0,0,0          ", "1/2,0,0        ", "0,1/2,0        ",    &
14898                      "0,0,1/2        ", "1/2,1/2,0      ", "1/2,0,1/2      ",    &
14899                      "0,1/2,1/2      ", "1/2,1/2,1/2    ", "x,0,0          ",    &
14900                      "x,0,1/2        ", "x,1/2,0        ", "x,1/2,1/2      ",    &
14901                      "0,y,0          ", "0,y,1/2        ", "1/2,y,0        ",    &
14902                      "1/2,y,1/2      ", "0,0,z          ", "1/2,0,z        ",    &
14903                      "0,1/2,z        ", "1/2,1/2,z      ", "               ",    &
14904                      "               ", "               ", "               ",    &
14905                      "               ", "               "/) )
14906       wyckoff_info( 29)= wyck_info_type("P 2 2 21    ", 4,     &
14907                    (/"x,0,0          ", "x,1/2,0        ", "0,y,1/4        ",    &
14908                      "1/2,y,1/4      ", "               ", "               ",    &
14909                      "               ", "               ", "               ",    &
14910                      "               ", "               ", "               ",    &
14911                      "               ", "               ", "               ",    &
14912                      "               ", "               ", "               ",    &
14913                      "               ", "               ", "               ",    &
14914                      "               ", "               ", "               ",    &
14915                      "               ", "               "/) )
14916       wyckoff_info( 30)= wyck_info_type("P 21 21 2   ", 2,     &
14917                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
14918                      "               ", "               ", "               ",    &
14919                      "               ", "               ", "               ",    &
14920                      "               ", "               ", "               ",    &
14921                      "               ", "               ", "               ",    &
14922                      "               ", "               ", "               ",    &
14923                      "               ", "               ", "               ",    &
14924                      "               ", "               ", "               ",    &
14925                      "               ", "               "/) )
14926       wyckoff_info( 31)= wyck_info_type("P 21 21 21  ", 0,     &
14927                    (/"               ", "               ", "               ",    &
14928                      "               ", "               ", "               ",    &
14929                      "               ", "               ", "               ",    &
14930                      "               ", "               ", "               ",    &
14931                      "               ", "               ", "               ",    &
14932                      "               ", "               ", "               ",    &
14933                      "               ", "               ", "               ",    &
14934                      "               ", "               ", "               ",    &
14935                      "               ", "               "/) )
14936       wyckoff_info( 32)= wyck_info_type("C 2 2 21    ", 2,     &
14937                    (/"x,0,0          ", "0,y,1/4        ", "               ",    &
14938                      "               ", "               ", "               ",    &
14939                      "               ", "               ", "               ",    &
14940                      "               ", "               ", "               ",    &
14941                      "               ", "               ", "               ",    &
14942                      "               ", "               ", "               ",    &
14943                      "               ", "               ", "               ",    &
14944                      "               ", "               ", "               ",    &
14945                      "               ", "               "/) )
14946       wyckoff_info( 33)= wyck_info_type("C 2 2 2     ",11,     &
14947                    (/"0,0,0          ", "0,1/2,0        ", "1/2,0,1/2      ",    &
14948                      "0,0,1/2        ", "x,0,0          ", "x,0,1/2        ",    &
14949                      "0,y,0          ", "0,y,1/2        ", "0,0,z          ",    &
14950                      "0,1/2,z        ", "1/4,1/4,z      ", "               ",    &
14951                      "               ", "               ", "               ",    &
14952                      "               ", "               ", "               ",    &
14953                      "               ", "               ", "               ",    &
14954                      "               ", "               ", "               ",    &
14955                      "               ", "               "/) )
14956       wyckoff_info( 34)= wyck_info_type("F 2 2 2     ",10,     &
14957                    (/"0,0,0          ", "0,0,1/2        ", "1/4,1/4,1/4    ",    &
14958                      "1/4,1/4,3/4    ", "x,0,0          ", "0,y,0          ",    &
14959                      "0,0,z          ", "1/4,1/4,z      ", "1/4,y,1/4      ",    &
14960                      "x,1/4,1/4      ", "               ", "               ",    &
14961                      "               ", "               ", "               ",    &
14962                      "               ", "               ", "               ",    &
14963                      "               ", "               ", "               ",    &
14964                      "               ", "               ", "               ",    &
14965                      "               ", "               "/) )
14966       wyckoff_info( 35)= wyck_info_type("I 2 2 2     ",10,     &
14967                    (/"0,0,0          ", "1/2,0,0        ", "0,0,1/2        ",    &
14968                      "0,1/2,0        ", "x,0,0          ", "x,0,1/2        ",    &
14969                      "0,y,0          ", "1/2,y,0        ", "0,0,z          ",    &
14970                      "0,1/2,z        ", "               ", "               ",    &
14971                      "               ", "               ", "               ",    &
14972                      "               ", "               ", "               ",    &
14973                      "               ", "               ", "               ",    &
14974                      "               ", "               ", "               ",    &
14975                      "               ", "               "/) )
14976       wyckoff_info( 36)= wyck_info_type("I 21 21 21  ", 3,     &
14977                    (/"x,0,1/4        ", "1/4,y,0        ", "0,1/4,z        ",    &
14978                      "               ", "               ", "               ",    &
14979                      "               ", "               ", "               ",    &
14980                      "               ", "               ", "               ",    &
14981                      "               ", "               ", "               ",    &
14982                      "               ", "               ", "               ",    &
14983                      "               ", "               ", "               ",    &
14984                      "               ", "               ", "               ",    &
14985                      "               ", "               "/) )
14986       wyckoff_info( 37)= wyck_info_type("P M M 2     ", 8,     &
14987                    (/"0,0,z          ", "0,1/2,z        ", "1/2,0,z        ",    &
14988                      "1/2,1/2,z      ", "x,0,z          ", "x,1/2,z        ",    &
14989                      "0,y,z          ", "1/2,y,z        ", "               ",    &
14990                      "               ", "               ", "               ",    &
14991                      "               ", "               ", "               ",    &
14992                      "               ", "               ", "               ",    &
14993                      "               ", "               ", "               ",    &
14994                      "               ", "               ", "               ",    &
14995                      "               ", "               "/) )
14996       wyckoff_info( 38)= wyck_info_type("P M C 21    ", 2,     &
14997                    (/"0,y,z          ", "1/2,y,z        ", "               ",    &
14998                      "               ", "               ", "               ",    &
14999                      "               ", "               ", "               ",    &
15000                      "               ", "               ", "               ",    &
15001                      "               ", "               ", "               ",    &
15002                      "               ", "               ", "               ",    &
15003                      "               ", "               ", "               ",    &
15004                      "               ", "               ", "               ",    &
15005                      "               ", "               "/) )
15006       wyckoff_info( 39)= wyck_info_type("P C C 2     ", 4,     &
15007                    (/"0,0,z          ", "0,1/2,z        ", "1/2,0,z        ",    &
15008                      "1/2,1/2,z      ", "               ", "               ",    &
15009                      "               ", "               ", "               ",    &
15010                      "               ", "               ", "               ",    &
15011                      "               ", "               ", "               ",    &
15012                      "               ", "               ", "               ",    &
15013                      "               ", "               ", "               ",    &
15014                      "               ", "               ", "               ",    &
15015                      "               ", "               "/) )
15016       wyckoff_info( 40)= wyck_info_type("P M A 2     ", 3,     &
15017                    (/"0,0,z          ", "0,1/2,z        ", "1/4,y,z        ",    &
15018                      "               ", "               ", "               ",    &
15019                      "               ", "               ", "               ",    &
15020                      "               ", "               ", "               ",    &
15021                      "               ", "               ", "               ",    &
15022                      "               ", "               ", "               ",    &
15023                      "               ", "               ", "               ",    &
15024                      "               ", "               ", "               ",    &
15025                      "               ", "               "/) )
15026       wyckoff_info( 41)= wyck_info_type("P C A 21    ", 0,     &
15027                    (/"               ", "               ", "               ",    &
15028                      "               ", "               ", "               ",    &
15029                      "               ", "               ", "               ",    &
15030                      "               ", "               ", "               ",    &
15031                      "               ", "               ", "               ",    &
15032                      "               ", "               ", "               ",    &
15033                      "               ", "               ", "               ",    &
15034                      "               ", "               ", "               ",    &
15035                      "               ", "               "/) )
15036       wyckoff_info( 42)= wyck_info_type("P N C 2     ", 2,     &
15037                    (/"0,0,z          ", "1/2,0,z        ", "               ",    &
15038                      "               ", "               ", "               ",    &
15039                      "               ", "               ", "               ",    &
15040                      "               ", "               ", "               ",    &
15041                      "               ", "               ", "               ",    &
15042                      "               ", "               ", "               ",    &
15043                      "               ", "               ", "               ",    &
15044                      "               ", "               ", "               ",    &
15045                      "               ", "               "/) )
15046       wyckoff_info( 43)= wyck_info_type("P M N 21    ", 1,     &
15047                    (/"0,y,z          ", "               ", "               ",    &
15048                      "               ", "               ", "               ",    &
15049                      "               ", "               ", "               ",    &
15050                      "               ", "               ", "               ",    &
15051                      "               ", "               ", "               ",    &
15052                      "               ", "               ", "               ",    &
15053                      "               ", "               ", "               ",    &
15054                      "               ", "               ", "               ",    &
15055                      "               ", "               "/) )
15056       wyckoff_info( 44)= wyck_info_type("P B A 2     ", 2,     &
15057                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
15058                      "               ", "               ", "               ",    &
15059                      "               ", "               ", "               ",    &
15060                      "               ", "               ", "               ",    &
15061                      "               ", "               ", "               ",    &
15062                      "               ", "               ", "               ",    &
15063                      "               ", "               ", "               ",    &
15064                      "               ", "               ", "               ",    &
15065                      "               ", "               "/) )
15066       wyckoff_info( 45)= wyck_info_type("P N A 21    ", 0,     &
15067                    (/"               ", "               ", "               ",    &
15068                      "               ", "               ", "               ",    &
15069                      "               ", "               ", "               ",    &
15070                      "               ", "               ", "               ",    &
15071                      "               ", "               ", "               ",    &
15072                      "               ", "               ", "               ",    &
15073                      "               ", "               ", "               ",    &
15074                      "               ", "               ", "               ",    &
15075                      "               ", "               "/) )
15076       wyckoff_info( 46)= wyck_info_type("P N N 2     ", 2,     &
15077                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
15078                      "               ", "               ", "               ",    &
15079                      "               ", "               ", "               ",    &
15080                      "               ", "               ", "               ",    &
15081                      "               ", "               ", "               ",    &
15082                      "               ", "               ", "               ",    &
15083                      "               ", "               ", "               ",    &
15084                      "               ", "               ", "               ",    &
15085                      "               ", "               "/) )
15086       wyckoff_info( 47)= wyck_info_type("C M M 2     ", 5,     &
15087                    (/"0,0,z          ", "0,1/2,z        ", "1/4,1/4,z      ",    &
15088                      "x,0,z          ", "0,y,z          ", "               ",    &
15089                      "               ", "               ", "               ",    &
15090                      "               ", "               ", "               ",    &
15091                      "               ", "               ", "               ",    &
15092                      "               ", "               ", "               ",    &
15093                      "               ", "               ", "               ",    &
15094                      "               ", "               ", "               ",    &
15095                      "               ", "               "/) )
15096       wyckoff_info( 48)= wyck_info_type("C M C 21    ", 1,     &
15097                    (/"0,y,z          ", "               ", "               ",    &
15098                      "               ", "               ", "               ",    &
15099                      "               ", "               ", "               ",    &
15100                      "               ", "               ", "               ",    &
15101                      "               ", "               ", "               ",    &
15102                      "               ", "               ", "               ",    &
15103                      "               ", "               ", "               ",    &
15104                      "               ", "               ", "               ",    &
15105                      "               ", "               "/) )
15106       wyckoff_info( 49)= wyck_info_type("C C C 2     ", 3,     &
15107                    (/"0,0,z          ", "0,1/2,z        ", "1/4,1/4,z      ",    &
15108                      "               ", "               ", "               ",    &
15109                      "               ", "               ", "               ",    &
15110                      "               ", "               ", "               ",    &
15111                      "               ", "               ", "               ",    &
15112                      "               ", "               ", "               ",    &
15113                      "               ", "               ", "               ",    &
15114                      "               ", "               ", "               ",    &
15115                      "               ", "               "/) )
15116       wyckoff_info( 50)= wyck_info_type("A M M 2     ", 5,     &
15117                    (/"0,0,z          ", "1/2,0,z        ", "x,0,z          ",    &
15118                      "0,y,z          ", "1/2,y,z        ", "               ",    &
15119                      "               ", "               ", "               ",    &
15120                      "               ", "               ", "               ",    &
15121                      "               ", "               ", "               ",    &
15122                      "               ", "               ", "               ",    &
15123                      "               ", "               ", "               ",    &
15124                      "               ", "               ", "               ",    &
15125                      "               ", "               "/) )
15126       wyckoff_info( 51)= wyck_info_type("A B M 2     ", 3,     &
15127                    (/"0,0,z          ", "1/2,0,z        ", "x,1/4,z        ",    &
15128                      "               ", "               ", "               ",    &
15129                      "               ", "               ", "               ",    &
15130                      "               ", "               ", "               ",    &
15131                      "               ", "               ", "               ",    &
15132                      "               ", "               ", "               ",    &
15133                      "               ", "               ", "               ",    &
15134                      "               ", "               ", "               ",    &
15135                      "               ", "               "/) )
15136       wyckoff_info( 52)= wyck_info_type("A M A 2     ", 2,     &
15137                    (/"0,0,z          ", "1/4,y,z        ", "               ",    &
15138                      "               ", "               ", "               ",    &
15139                      "               ", "               ", "               ",    &
15140                      "               ", "               ", "               ",    &
15141                      "               ", "               ", "               ",    &
15142                      "               ", "               ", "               ",    &
15143                      "               ", "               ", "               ",    &
15144                      "               ", "               ", "               ",    &
15145                      "               ", "               "/) )
15146       wyckoff_info( 53)= wyck_info_type("A B A 2     ", 1,     &
15147                    (/"0,0,z          ", "               ", "               ",    &
15148                      "               ", "               ", "               ",    &
15149                      "               ", "               ", "               ",    &
15150                      "               ", "               ", "               ",    &
15151                      "               ", "               ", "               ",    &
15152                      "               ", "               ", "               ",    &
15153                      "               ", "               ", "               ",    &
15154                      "               ", "               ", "               ",    &
15155                      "               ", "               "/) )
15156       wyckoff_info( 54)= wyck_info_type("F M M 2     ", 4,     &
15157                    (/"0,0,z          ", "1/4,1/4,z      ", "0,y,z          ",    &
15158                      "x,0,z          ", "               ", "               ",    &
15159                      "               ", "               ", "               ",    &
15160                      "               ", "               ", "               ",    &
15161                      "               ", "               ", "               ",    &
15162                      "               ", "               ", "               ",    &
15163                      "               ", "               ", "               ",    &
15164                      "               ", "               ", "               ",    &
15165                      "               ", "               "/) )
15166       wyckoff_info( 55)= wyck_info_type("F D D 2     ", 1,     &
15167                    (/"0,0,z          ", "               ", "               ",    &
15168                      "               ", "               ", "               ",    &
15169                      "               ", "               ", "               ",    &
15170                      "               ", "               ", "               ",    &
15171                      "               ", "               ", "               ",    &
15172                      "               ", "               ", "               ",    &
15173                      "               ", "               ", "               ",    &
15174                      "               ", "               ", "               ",    &
15175                      "               ", "               "/) )
15176       wyckoff_info( 56)= wyck_info_type("I M M 2     ", 4,     &
15177                    (/"0,0,z          ", "0,1/2,z        ", "x,0,z          ",    &
15178                      "0,y,z          ", "               ", "               ",    &
15179                      "               ", "               ", "               ",    &
15180                      "               ", "               ", "               ",    &
15181                      "               ", "               ", "               ",    &
15182                      "               ", "               ", "               ",    &
15183                      "               ", "               ", "               ",    &
15184                      "               ", "               ", "               ",    &
15185                      "               ", "               "/) )
15186       wyckoff_info( 57)= wyck_info_type("I B A 2     ", 2,     &
15187                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
15188                      "               ", "               ", "               ",    &
15189                      "               ", "               ", "               ",    &
15190                      "               ", "               ", "               ",    &
15191                      "               ", "               ", "               ",    &
15192                      "               ", "               ", "               ",    &
15193                      "               ", "               ", "               ",    &
15194                      "               ", "               ", "               ",    &
15195                      "               ", "               "/) )
15196       wyckoff_info( 58)= wyck_info_type("I M A 2     ", 2,     &
15197                    (/"0,0,z          ", "1/4,y,z        ", "               ",    &
15198                      "               ", "               ", "               ",    &
15199                      "               ", "               ", "               ",    &
15200                      "               ", "               ", "               ",    &
15201                      "               ", "               ", "               ",    &
15202                      "               ", "               ", "               ",    &
15203                      "               ", "               ", "               ",    &
15204                      "               ", "               ", "               ",    &
15205                      "               ", "               "/) )
15206       wyckoff_info( 59)= wyck_info_type("P M M M     ",26,     &
15207                    (/"0,0,0          ", "1/2,0,0        ", "0,0,1/2        ",    &
15208                      "1/2,0,1/2      ", "0,1/2,0        ", "1/2,1/2,0      ",    &
15209                      "0,1/2,1/2      ", "1/2,1/2,1/2    ", "x,0,0          ",    &
15210                      "x,0,1/2        ", "x,1/2,0        ", "x,1/2,1/2      ",    &
15211                      "0,y,0          ", "0,y,1/2        ", "1/2,y,0        ",    &
15212                      "1/2,y,1/2      ", "0,0,z          ", "0,1/2,z        ",    &
15213                      "1/2,0,z        ", "1/2,1/2,z      ", "0,y,z          ",    &
15214                      "1/2,y,z        ", "x,0,z          ", "x,1/2,z        ",    &
15215                      "x,y,0          ", "x,y,1/2        "/) )
15216       wyckoff_info( 60)= wyck_info_type("P N N N:1   ",12,     &
15217                    (/"0,0,0          ", "1/2,0,0        ", "0,0,1/2        ",    &
15218                      "0,1/2,0        ", "1/4,1/4,1/4    ", "3/4,3/4,3/4    ",    &
15219                      "x,0,0          ", "x,0,1/2        ", "0,y,0          ",    &
15220                      "1/2,y,0        ", "0,0,z          ", "0,1/2,z        ",    &
15221                      "               ", "               ", "               ",    &
15222                      "               ", "               ", "               ",    &
15223                      "               ", "               ", "               ",    &
15224                      "               ", "               ", "               ",    &
15225                      "               ", "               "/) )
15226       wyckoff_info( 61)= wyck_info_type("P N N N     ",12,     &
15227                    (/"1/4,1/4,1/4    ", "3/4,1/4,1/4    ", "1/4,1/4,3/4    ",    &
15228                      "1/4,3/4,1/4    ", "1/2,1/2,1/2    ", "0,0,0          ",    &
15229                      "x,1/4,1/4      ", "x,1/4,3/4      ", "1/4,y,1/4      ",    &
15230                      "3/4,y,1/4      ", "1/4,1/4,z      ", "1/4,3/4,z      ",    &
15231                      "               ", "               ", "               ",    &
15232                      "               ", "               ", "               ",    &
15233                      "               ", "               ", "               ",    &
15234                      "               ", "               ", "               ",    &
15235                      "               ", "               "/) )
15236       wyckoff_info( 62)= wyck_info_type("P C C M     ",17,     &
15237                    (/"0,0,0          ", "1/2,1/2,0      ", "0,1/2,0        ",    &
15238                      "1/2,0,0        ", "0,0,1/4        ", "1/2,0,1/4      ",    &
15239                      "0,1/2,1/4      ", "1/2,1/2,1/4    ", "x,0,1/4        ",    &
15240                      "x,1/2,1/4      ", "0,y,1/4        ", "1/2,y,1/4      ",    &
15241                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15242                      "1/2,0,z        ", "x,y,0          ", "               ",    &
15243                      "               ", "               ", "               ",    &
15244                      "               ", "               ", "               ",    &
15245                      "               ", "               "/) )
15246       wyckoff_info( 63)= wyck_info_type("P B A N:1   ",12,     &
15247                    (/"0,0,0          ", "1/2,0,0        ", "1/2,0,1/2      ",    &
15248                      "0,0,1/2        ", "1/4,1/4,0      ", "1/4,1/4,1/2    ",    &
15249                      "x,0,0          ", "x,0,1/2        ", "0,y,0          ",    &
15250                      "0,y,1/2        ", "0,0,z          ", "0,1/2,z        ",    &
15251                      "               ", "               ", "               ",    &
15252                      "               ", "               ", "               ",    &
15253                      "               ", "               ", "               ",    &
15254                      "               ", "               ", "               ",    &
15255                      "               ", "               "/) )
15256       wyckoff_info( 64)= wyck_info_type("P B A N     ",12,     &
15257                    (/"1/4,1/4,0      ", "3/4,1/4,0      ", "3/4,1/4,1/2    ",    &
15258                      "1/4,1/4,1/2    ", "0,0,0          ", "0,0,1/2        ",    &
15259                      "x,1/4,0        ", "x,1/4,1/2      ", "1/4,y,0        ",    &
15260                      "1/4,y,1/2      ", "1/4,1/4,z      ", "1/4,3/4,z      ",    &
15261                      "               ", "               ", "               ",    &
15262                      "               ", "               ", "               ",    &
15263                      "               ", "               ", "               ",    &
15264                      "               ", "               ", "               ",    &
15265                      "               ", "               "/) )
15266       wyckoff_info( 65)= wyck_info_type("P M M A     ",11,     &
15267                    (/"0,0,0          ", "0,1/2,0        ", "0,0,1/2        ",    &
15268                      "0,1/2,1/2      ", "1/4,0,z        ", "1/4,1/2,z      ",    &
15269                      "0,y,0          ", "0,y,1/2        ", "x,0,z          ",    &
15270                      "x,1/2,z        ", "1/4,y,z        ", "               ",    &
15271                      "               ", "               ", "               ",    &
15272                      "               ", "               ", "               ",    &
15273                      "               ", "               ", "               ",    &
15274                      "               ", "               ", "               ",    &
15275                      "               ", "               "/) )
15276       wyckoff_info( 66)= wyck_info_type("P N N A     ", 4,     &
15277                    (/"0,0,0          ", "0,0,1/2        ", "1/4,0,z        ",    &
15278                      "x,1/4,1/4      ", "               ", "               ",    &
15279                      "               ", "               ", "               ",    &
15280                      "               ", "               ", "               ",    &
15281                      "               ", "               ", "               ",    &
15282                      "               ", "               ", "               ",    &
15283                      "               ", "               ", "               ",    &
15284                      "               ", "               ", "               ",    &
15285                      "               ", "               "/) )
15286       wyckoff_info( 67)= wyck_info_type("P M N A     ", 8,     &
15287                    (/"0,0,0          ", "1/2,0,0        ", "1/2,1/2,0      ",    &
15288                      "0,1/2,0        ", "x,0,0          ", "x,1/2,0        ",    &
15289                      "1/4,y,1/4      ", "0,y,z          ", "               ",    &
15290                      "               ", "               ", "               ",    &
15291                      "               ", "               ", "               ",    &
15292                      "               ", "               ", "               ",    &
15293                      "               ", "               ", "               ",    &
15294                      "               ", "               ", "               ",    &
15295                      "               ", "               "/) )
15296       wyckoff_info( 68)= wyck_info_type("P C C A     ", 5,     &
15297                    (/"0,0,0          ", "0,1/2,0        ", "0,y,1/4        ",    &
15298                      "1/4,0,z        ", "1/4,1/2,z      ", "               ",    &
15299                      "               ", "               ", "               ",    &
15300                      "               ", "               ", "               ",    &
15301                      "               ", "               ", "               ",    &
15302                      "               ", "               ", "               ",    &
15303                      "               ", "               ", "               ",    &
15304                      "               ", "               ", "               ",    &
15305                      "               ", "               "/) )
15306       wyckoff_info( 69)= wyck_info_type("P B A M     ", 8,     &
15307                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
15308                      "0,1/2,1/2      ", "0,0,z          ", "0,1/2,z        ",    &
15309                      "x,y,0          ", "x,y,1/2        ", "               ",    &
15310                      "               ", "               ", "               ",    &
15311                      "               ", "               ", "               ",    &
15312                      "               ", "               ", "               ",    &
15313                      "               ", "               ", "               ",    &
15314                      "               ", "               ", "               ",    &
15315                      "               ", "               "/) )
15316       wyckoff_info( 70)= wyck_info_type("P C C N     ", 4,     &
15317                    (/"0,0,0          ", "0,0,1/2        ", "1/4,1/4,z      ",    &
15318                      "1/4,3/4,z      ", "               ", "               ",    &
15319                      "               ", "               ", "               ",    &
15320                      "               ", "               ", "               ",    &
15321                      "               ", "               ", "               ",    &
15322                      "               ", "               ", "               ",    &
15323                      "               ", "               ", "               ",    &
15324                      "               ", "               ", "               ",    &
15325                      "               ", "               "/) )
15326       wyckoff_info( 71)= wyck_info_type("P B C M     ", 4,     &
15327                    (/"0,0,0          ", "1/2,0,0        ", "x,1/4,0        ",    &
15328                      "x,y,1/4        ", "               ", "               ",    &
15329                      "               ", "               ", "               ",    &
15330                      "               ", "               ", "               ",    &
15331                      "               ", "               ", "               ",    &
15332                      "               ", "               ", "               ",    &
15333                      "               ", "               ", "               ",    &
15334                      "               ", "               ", "               ",    &
15335                      "               ", "               "/) )
15336       wyckoff_info( 72)= wyck_info_type("P N N M     ", 7,     &
15337                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
15338                      "0,1/2,1/2      ", "0,0,z          ", "0,1/2,z        ",    &
15339                      "x,y,0          ", "               ", "               ",    &
15340                      "               ", "               ", "               ",    &
15341                      "               ", "               ", "               ",    &
15342                      "               ", "               ", "               ",    &
15343                      "               ", "               ", "               ",    &
15344                      "               ", "               ", "               ",    &
15345                      "               ", "               "/) )
15346       wyckoff_info( 73)= wyck_info_type("P M M N:1   ", 6,     &
15347                    (/"0,0,z          ", "0,1/2,z        ", "1/4,1/4,0      ",    &
15348                      "1/4,1/4,1/2    ", "0,y,z          ", "x,0,z          ",    &
15349                      "               ", "               ", "               ",    &
15350                      "               ", "               ", "               ",    &
15351                      "               ", "               ", "               ",    &
15352                      "               ", "               ", "               ",    &
15353                      "               ", "               ", "               ",    &
15354                      "               ", "               ", "               ",    &
15355                      "               ", "               "/) )
15356       wyckoff_info( 74)= wyck_info_type("P M M N     ", 6,     &
15357                    (/"1/4,1/4,z      ", "1/4,3/4,z      ", "0,0,0          ",    &
15358                      "0,0,1/2        ", "1/4,y,z        ", "x,1/4,z        ",    &
15359                      "               ", "               ", "               ",    &
15360                      "               ", "               ", "               ",    &
15361                      "               ", "               ", "               ",    &
15362                      "               ", "               ", "               ",    &
15363                      "               ", "               ", "               ",    &
15364                      "               ", "               ", "               ",    &
15365                      "               ", "               "/) )
15366       wyckoff_info( 75)= wyck_info_type("P B C N     ", 3,     &
15367                    (/"0,0,0          ", "0,1/2,0        ", "0,y,1/4        ",    &
15368                      "               ", "               ", "               ",    &
15369                      "               ", "               ", "               ",    &
15370                      "               ", "               ", "               ",    &
15371                      "               ", "               ", "               ",    &
15372                      "               ", "               ", "               ",    &
15373                      "               ", "               ", "               ",    &
15374                      "               ", "               ", "               ",    &
15375                      "               ", "               "/) )
15376       wyckoff_info( 76)= wyck_info_type("P B C A     ", 2,     &
15377                    (/"0,0,0          ", "0,0,1/2        ", "               ",    &
15378                      "               ", "               ", "               ",    &
15379                      "               ", "               ", "               ",    &
15380                      "               ", "               ", "               ",    &
15381                      "               ", "               ", "               ",    &
15382                      "               ", "               ", "               ",    &
15383                      "               ", "               ", "               ",    &
15384                      "               ", "               ", "               ",    &
15385                      "               ", "               "/) )
15386       wyckoff_info( 77)= wyck_info_type("P N M A     ", 3,     &
15387                    (/"0,0,0          ", "0,0,1/2        ", "x,1/4,z        ",    &
15388                      "               ", "               ", "               ",    &
15389                      "               ", "               ", "               ",    &
15390                      "               ", "               ", "               ",    &
15391                      "               ", "               ", "               ",    &
15392                      "               ", "               ", "               ",    &
15393                      "               ", "               ", "               ",    &
15394                      "               ", "               ", "               ",    &
15395                      "               ", "               "/) )
15396       wyckoff_info( 78)= wyck_info_type("C M C M     ", 7,     &
15397                    (/"0,0,0          ", "0,1/2,0        ", "0,y,1/4        ",    &
15398                      "1/4,1/4,0      ", "x,0,0          ", "0,y,z          ",    &
15399                      "x,y,1/4        ", "               ", "               ",    &
15400                      "               ", "               ", "               ",    &
15401                      "               ", "               ", "               ",    &
15402                      "               ", "               ", "               ",    &
15403                      "               ", "               ", "               ",    &
15404                      "               ", "               ", "               ",    &
15405                      "               ", "               "/) )
15406       wyckoff_info( 79)= wyck_info_type("C M C A     ", 6,     &
15407                    (/"0,0,0          ", "1/2,0,0        ", "1/4,1/4,0      ",    &
15408                      "x,0,0          ", "1/4,y,1/4      ", "0,y,z          ",    &
15409                      "               ", "               ", "               ",    &
15410                      "               ", "               ", "               ",    &
15411                      "               ", "               ", "               ",    &
15412                      "               ", "               ", "               ",    &
15413                      "               ", "               ", "               ",    &
15414                      "               ", "               ", "               ",    &
15415                      "               ", "               "/) )
15416       wyckoff_info( 80)= wyck_info_type("C M M M     ",17,     &
15417                    (/"0,0,0          ", "1/2,0,0        ", "1/2,0,1/2      ",    &
15418                      "0,0,1/2        ", "1/4,1/4,0      ", "1/4,1/4,1/2    ",    &
15419                      "x,0,0          ", "x,0,1/2        ", "0,y,0          ",    &
15420                      "0,y,1/2        ", "0,0,z          ", "0,1/2,z        ",    &
15421                      "1/4,1/4,z      ", "0,y,z          ", "x,0,z          ",    &
15422                      "x,y,0          ", "x,y,1/2        ", "               ",    &
15423                      "               ", "               ", "               ",    &
15424                      "               ", "               ", "               ",    &
15425                      "               ", "               "/) )
15426       wyckoff_info( 81)= wyck_info_type("C C C M     ",12,     &
15427                    (/"0,0,1/4        ", "0,1/2,1/4      ", "0,0,0          ",    &
15428                      "0,1/2,0        ", "1/4,1/4,0      ", "1/4,3/4,0      ",    &
15429                      "x,0,1/4        ", "0,y,1/4        ", "0,0,z          ",    &
15430                      "0,1/2,z        ", "1/4,1/4,z      ", "x,y,0          ",    &
15431                      "               ", "               ", "               ",    &
15432                      "               ", "               ", "               ",    &
15433                      "               ", "               ", "               ",    &
15434                      "               ", "               ", "               ",    &
15435                      "               ", "               "/) )
15436       wyckoff_info( 82)= wyck_info_type("C M M A     ",14,     &
15437                    (/"1/4,0,0        ", "1/4,0,1/2      ", "0,0,0          ",    &
15438                      "0,0,1/2        ", "1/4,1/4,0      ", "1/4,1/4,1/2    ",    &
15439                      "0,1/4,z        ", "x,0,0          ", "x,0,1/2        ",    &
15440                      "1/4,y,0        ", "1/4,y,1/2      ", "1/4,0,z        ",    &
15441                      "0,y,z          ", "x,1/4,z        ", "               ",    &
15442                      "               ", "               ", "               ",    &
15443                      "               ", "               ", "               ",    &
15444                      "               ", "               ", "               ",    &
15445                      "               ", "               "/) )
15446       wyckoff_info( 83)= wyck_info_type("C C C A:1   ", 8,     &
15447                    (/"0,0,0          ", "0,0,1/2        ", "1/4,0,1/4      ",    &
15448                      "0,1/4,1/4      ", "x,0,0          ", "0,y,0          ",    &
15449                      "0,0,z          ", "1/4,1/4,z      ", "               ",    &
15450                      "               ", "               ", "               ",    &
15451                      "               ", "               ", "               ",    &
15452                      "               ", "               ", "               ",    &
15453                      "               ", "               ", "               ",    &
15454                      "               ", "               ", "               ",    &
15455                      "               ", "               "/) )
15456       wyckoff_info( 84)= wyck_info_type("C C C A     ", 8,     &
15457                    (/"0,1/4,1/4      ", "0,1/4,3/2      ", "1/4,3/4,0      ",    &
15458                      "0,0,0          ", "x,1/4,1/4      ", "0,y,1/4        ",    &
15459                      "0,1/4,z        ", "1/4,0,z        ", "               ",    &
15460                      "               ", "               ", "               ",    &
15461                      "               ", "               ", "               ",    &
15462                      "               ", "               ", "               ",    &
15463                      "               ", "               ", "               ",    &
15464                      "               ", "               ", "               ",    &
15465                      "               ", "               "/) )
15466       wyckoff_info( 85)= wyck_info_type("F M M M     ",15,     &
15467                    (/"0,0,0          ", "0,0,1/2        ", "0,1/4,1/4      ",    &
15468                      "1/4,0,1/4      ", "1/4,1/4,0      ", "1/4,1/4,1/4    ",    &
15469                      "x,0,0          ", "0,y,0          ", "0,0,z          ",    &
15470                      "1/4,1/4,z      ", "1/4,y,1/4      ", "x,1/4,1/4      ",    &
15471                      "0,y,z          ", "x,0,z          ", "x,y,0          ",    &
15472                      "               ", "               ", "               ",    &
15473                      "               ", "               ", "               ",    &
15474                      "               ", "               ", "               ",    &
15475                      "               ", "               "/) )
15476       wyckoff_info( 86)= wyck_info_type("F D D D:1   ", 7,     &
15477                    (/"0,0,0          ", "0,0,1/2        ", "1/8,1/8,1/8    ",    &
15478                      "5/8,5/8,5/8    ", "x,0,0          ", "0,y,0          ",    &
15479                      "0,0,z          ", "               ", "               ",    &
15480                      "               ", "               ", "               ",    &
15481                      "               ", "               ", "               ",    &
15482                      "               ", "               ", "               ",    &
15483                      "               ", "               ", "               ",    &
15484                      "               ", "               ", "               ",    &
15485                      "               ", "               "/) )
15486       wyckoff_info( 87)= wyck_info_type("F D D D     ", 7,     &
15487                    (/"1/8,1/8,1/8    ", "1/8,1/8,5/8    ", "0,0,0          ",    &
15488                      "1/2,1/2,1/2    ", "x,1/8,1/8      ", "1/8,y,1/8      ",    &
15489                      "1/8,1/8,z      ", "               ", "               ",    &
15490                      "               ", "               ", "               ",    &
15491                      "               ", "               ", "               ",    &
15492                      "               ", "               ", "               ",    &
15493                      "               ", "               ", "               ",    &
15494                      "               ", "               ", "               ",    &
15495                      "               ", "               "/) )
15496       wyckoff_info( 88)= wyck_info_type("I M M M     ",14,     &
15497                    (/"0,0,0          ", "0,1/2,1/2      ", "1/2,1/2,0      ",    &
15498                      "1/2,0,1/2      ", "x,0,0          ", "x,1/2,0        ",    &
15499                      "0,y,0          ", "0,y,1/2        ", "0,0,z          ",    &
15500                      "1/2,0,z        ", "1/4,1/4,1/4    ", "0,y,z          ",    &
15501                      "x,0,z          ", "x,y,0          ", "               ",    &
15502                      "               ", "               ", "               ",    &
15503                      "               ", "               ", "               ",    &
15504                      "               ", "               ", "               ",    &
15505                      "               ", "               "/) )
15506       wyckoff_info( 89)= wyck_info_type("I B A M     ",10,     &
15507                    (/"0,0,1/4        ", "1/2,0,1/4      ", "0,0,0          ",    &
15508                      "1/2,0,0        ", "1/4,1/4,1/4    ", "x,0,1/4        ",    &
15509                      "0,y,1/4        ", "0,0,z          ", "0,1/2,z        ",    &
15510                      "x,y,0          ", "               ", "               ",    &
15511                      "               ", "               ", "               ",    &
15512                      "               ", "               ", "               ",    &
15513                      "               ", "               ", "               ",    &
15514                      "               ", "               ", "               ",    &
15515                      "               ", "               "/) )
15516       wyckoff_info( 90)= wyck_info_type("I B C A     ", 5,     &
15517                    (/"0,0,0          ", "1/4,1/4,1/4    ", "x,0,1/4        ",    &
15518                      "1/4,y,0        ", "0,1/4,z        ", "               ",    &
15519                      "               ", "               ", "               ",    &
15520                      "               ", "               ", "               ",    &
15521                      "               ", "               ", "               ",    &
15522                      "               ", "               ", "               ",    &
15523                      "               ", "               ", "               ",    &
15524                      "               ", "               ", "               ",    &
15525                      "               ", "               "/) )
15526       wyckoff_info( 91)= wyck_info_type("I M M A     ", 9,     &
15527                    (/"0,0,0          ", "0,0,1/2        ", "1/4,1/4,1/4    ",    &
15528                      "1/4,1/4,3/4    ", "0,1/4,z        ", "x,0,0          ",    &
15529                      "1/4,y,1/4      ", "0,y,z          ", "x,1/4,z        ",    &
15530                      "               ", "               ", "               ",    &
15531                      "               ", "               ", "               ",    &
15532                      "               ", "               ", "               ",    &
15533                      "               ", "               ", "               ",    &
15534                      "               ", "               ", "               ",    &
15535                      "               ", "               "/) )
15536       wyckoff_info( 92)= wyck_info_type("P 4         ", 3,     &
15537                    (/"0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15538                      "               ", "               ", "               ",    &
15539                      "               ", "               ", "               ",    &
15540                      "               ", "               ", "               ",    &
15541                      "               ", "               ", "               ",    &
15542                      "               ", "               ", "               ",    &
15543                      "               ", "               ", "               ",    &
15544                      "               ", "               ", "               ",    &
15545                      "               ", "               "/) )
15546       wyckoff_info( 93)= wyck_info_type("P 41        ", 0,     &
15547                    (/"               ", "               ", "               ",    &
15548                      "               ", "               ", "               ",    &
15549                      "               ", "               ", "               ",    &
15550                      "               ", "               ", "               ",    &
15551                      "               ", "               ", "               ",    &
15552                      "               ", "               ", "               ",    &
15553                      "               ", "               ", "               ",    &
15554                      "               ", "               ", "               ",    &
15555                      "               ", "               "/) )
15556       wyckoff_info( 94)= wyck_info_type("P 42        ", 3,     &
15557                    (/"0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15558                      "               ", "               ", "               ",    &
15559                      "               ", "               ", "               ",    &
15560                      "               ", "               ", "               ",    &
15561                      "               ", "               ", "               ",    &
15562                      "               ", "               ", "               ",    &
15563                      "               ", "               ", "               ",    &
15564                      "               ", "               ", "               ",    &
15565                      "               ", "               "/) )
15566       wyckoff_info( 95)= wyck_info_type("P 43        ", 0,     &
15567                    (/"               ", "               ", "               ",    &
15568                      "               ", "               ", "               ",    &
15569                      "               ", "               ", "               ",    &
15570                      "               ", "               ", "               ",    &
15571                      "               ", "               ", "               ",    &
15572                      "               ", "               ", "               ",    &
15573                      "               ", "               ", "               ",    &
15574                      "               ", "               ", "               ",    &
15575                      "               ", "               "/) )
15576       wyckoff_info( 96)= wyck_info_type("I 4         ", 2,     &
15577                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
15578                      "               ", "               ", "               ",    &
15579                      "               ", "               ", "               ",    &
15580                      "               ", "               ", "               ",    &
15581                      "               ", "               ", "               ",    &
15582                      "               ", "               ", "               ",    &
15583                      "               ", "               ", "               ",    &
15584                      "               ", "               ", "               ",    &
15585                      "               ", "               "/) )
15586       wyckoff_info( 97)= wyck_info_type("I 41        ", 1,     &
15587                    (/"0,0,z          ", "               ", "               ",    &
15588                      "               ", "               ", "               ",    &
15589                      "               ", "               ", "               ",    &
15590                      "               ", "               ", "               ",    &
15591                      "               ", "               ", "               ",    &
15592                      "               ", "               ", "               ",    &
15593                      "               ", "               ", "               ",    &
15594                      "               ", "               ", "               ",    &
15595                      "               ", "               "/) )
15596       wyckoff_info( 98)= wyck_info_type("P -4        ", 7,     &
15597                    (/"0,0,0          ", "0,0,1/2        ", "1/2,1/2,0      ",    &
15598                      "1/2,1/2,1/2    ", "0,0,z          ", "1/2,1/2,z      ",    &
15599                      "0,1/2,z        ", "               ", "               ",    &
15600                      "               ", "               ", "               ",    &
15601                      "               ", "               ", "               ",    &
15602                      "               ", "               ", "               ",    &
15603                      "               ", "               ", "               ",    &
15604                      "               ", "               ", "               ",    &
15605                      "               ", "               "/) )
15606       wyckoff_info( 99)= wyck_info_type("I -4        ", 6,     &
15607                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,1/4      ",    &
15608                      "0,1/2,3/4      ", "0,0,z          ", "0,1/2,z        ",    &
15609                      "               ", "               ", "               ",    &
15610                      "               ", "               ", "               ",    &
15611                      "               ", "               ", "               ",    &
15612                      "               ", "               ", "               ",    &
15613                      "               ", "               ", "               ",    &
15614                      "               ", "               ", "               ",    &
15615                      "               ", "               "/) )
15616       wyckoff_info(100)= wyck_info_type("P 4/M       ",11,     &
15617                    (/"0,0,0          ", "0,0,1/2        ", "1/2,1/2,0      ",    &
15618                      "1/2,1/2,1/2    ", "0,1/2,0        ", "0,1/2,1/2      ",    &
15619                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15620                      "x,y,0          ", "x,y,1/2        ", "               ",    &
15621                      "               ", "               ", "               ",    &
15622                      "               ", "               ", "               ",    &
15623                      "               ", "               ", "               ",    &
15624                      "               ", "               ", "               ",    &
15625                      "               ", "               "/) )
15626       wyckoff_info(101)= wyck_info_type("P 42/M      ",10,     &
15627                    (/"0,0,0          ", "1/2,1/2,0      ", "0,1/2,0        ",    &
15628                      "0,1/2,1/2      ", "0,0,1/4        ", "1/2,1/2,1/4    ",    &
15629                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15630                      "x,y,0          ", "               ", "               ",    &
15631                      "               ", "               ", "               ",    &
15632                      "               ", "               ", "               ",    &
15633                      "               ", "               ", "               ",    &
15634                      "               ", "               ", "               ",    &
15635                      "               ", "               "/) )
15636       wyckoff_info(102)= wyck_info_type("P 4/N:1     ", 6,     &
15637                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,z        ",    &
15638                      "1/4,1/4,0      ", "1/4,1/4,1/2    ", "0,0,z          ",    &
15639                      "               ", "               ", "               ",    &
15640                      "               ", "               ", "               ",    &
15641                      "               ", "               ", "               ",    &
15642                      "               ", "               ", "               ",    &
15643                      "               ", "               ", "               ",    &
15644                      "               ", "               ", "               ",    &
15645                      "               ", "               "/) )
15646       wyckoff_info(103)= wyck_info_type("P 4/N       ", 6,     &
15647                    (/"1/4,3/4,0      ", "1/4,3/4,1/2    ", "1/4,1/4,z      ",    &
15648                      "0,0,0          ", "0,0,1/2        ", "1/4,3/4,z      ",    &
15649                      "               ", "               ", "               ",    &
15650                      "               ", "               ", "               ",    &
15651                      "               ", "               ", "               ",    &
15652                      "               ", "               ", "               ",    &
15653                      "               ", "               ", "               ",    &
15654                      "               ", "               ", "               ",    &
15655                      "               ", "               "/) )
15656       wyckoff_info(104)= wyck_info_type("P 42/N:1    ", 6,     &
15657                    (/"0,0,0          ", "0,0,1/2        ", "1/4,1/4,1/4    ",    &
15658                      "1/4,1/4,3/4    ", "0,1/2,z        ", "0,0,z          ",    &
15659                      "               ", "               ", "               ",    &
15660                      "               ", "               ", "               ",    &
15661                      "               ", "               ", "               ",    &
15662                      "               ", "               ", "               ",    &
15663                      "               ", "               ", "               ",    &
15664                      "               ", "               ", "               ",    &
15665                      "               ", "               "/) )
15666       wyckoff_info(105)= wyck_info_type("P 42/N      ", 6,     &
15667                    (/"1/4,1/4,1/4    ", "1/4,1/4,3/4    ", "0,0,0          ",    &
15668                      "0,0,1/2        ", "3/4,1/4,z      ", "1/4,1/4,z      ",    &
15669                      "               ", "               ", "               ",    &
15670                      "               ", "               ", "               ",    &
15671                      "               ", "               ", "               ",    &
15672                      "               ", "               ", "               ",    &
15673                      "               ", "               ", "               ",    &
15674                      "               ", "               ", "               ",    &
15675                      "               ", "               "/) )
15676       wyckoff_info(106)= wyck_info_type("I 4/M       ", 8,     &
15677                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
15678                      "0,1/2,1/4      ", "0,0,z          ", "1/4,1/4,1/4    ",    &
15679                      "0,1/2,z        ", "x,y,0          ", "               ",    &
15680                      "               ", "               ", "               ",    &
15681                      "               ", "               ", "               ",    &
15682                      "               ", "               ", "               ",    &
15683                      "               ", "               ", "               ",    &
15684                      "               ", "               ", "               ",    &
15685                      "               ", "               "/) )
15686       wyckoff_info(107)= wyck_info_type("I 41/A:1    ", 5,     &
15687                    (/"0,0,0          ", "0,0,1/2        ", "0,1/4,1/8      ",    &
15688                      "0,1/4,5/8      ", "0,0,z          ", "               ",    &
15689                      "               ", "               ", "               ",    &
15690                      "               ", "               ", "               ",    &
15691                      "               ", "               ", "               ",    &
15692                      "               ", "               ", "               ",    &
15693                      "               ", "               ", "               ",    &
15694                      "               ", "               ", "               ",    &
15695                      "               ", "               "/) )
15696       wyckoff_info(108)= wyck_info_type("I 41/A      ", 5,     &
15697                    (/"0,1/4,1/8      ", "0,1/4,5/8      ", "0,0,0          ",    &
15698                      "0,0,1/2        ", "0,1/4,z        ", "               ",    &
15699                      "               ", "               ", "               ",    &
15700                      "               ", "               ", "               ",    &
15701                      "               ", "               ", "               ",    &
15702                      "               ", "               ", "               ",    &
15703                      "               ", "               ", "               ",    &
15704                      "               ", "               ", "               ",    &
15705                      "               ", "               "/) )
15706       wyckoff_info(109)= wyck_info_type("P 4 2 2     ",15,     &
15707                    (/"0,0,0          ", "0,0,1/2        ", "1/2,1/2,0      ",    &
15708                      "1/2,1/2,1/2    ", "1/2,0,0        ", "1/2,0,1/2      ",    &
15709                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15710                      "x,x,0          ", "x,x,1/2        ", "x,0,0          ",    &
15711                      "x,1/2,1/2      ", "x,0,1/2        ", "x,1/2,0        ",    &
15712                      "               ", "               ", "               ",    &
15713                      "               ", "               ", "               ",    &
15714                      "               ", "               ", "               ",    &
15715                      "               ", "               "/) )
15716       wyckoff_info(110)= wyck_info_type("P 4 21 2    ", 6,     &
15717                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,z        ",    &
15718                      "0,0,z          ", "x,x,0          ", "x,x,1/2        ",    &
15719                      "               ", "               ", "               ",    &
15720                      "               ", "               ", "               ",    &
15721                      "               ", "               ", "               ",    &
15722                      "               ", "               ", "               ",    &
15723                      "               ", "               ", "               ",    &
15724                      "               ", "               ", "               ",    &
15725                      "               ", "               "/) )
15726       wyckoff_info(111)= wyck_info_type("P 41 2 2    ", 3,     &
15727                    (/"0,y,0          ", "1/2,y,0        ", "x,x,3/8        ",    &
15728                      "               ", "               ", "               ",    &
15729                      "               ", "               ", "               ",    &
15730                      "               ", "               ", "               ",    &
15731                      "               ", "               ", "               ",    &
15732                      "               ", "               ", "               ",    &
15733                      "               ", "               ", "               ",    &
15734                      "               ", "               ", "               ",    &
15735                      "               ", "               "/) )
15736       wyckoff_info(112)= wyck_info_type("P 41 21 2   ", 1,     &
15737                    (/"x,x,0          ", "               ", "               ",    &
15738                      "               ", "               ", "               ",    &
15739                      "               ", "               ", "               ",    &
15740                      "               ", "               ", "               ",    &
15741                      "               ", "               ", "               ",    &
15742                      "               ", "               ", "               ",    &
15743                      "               ", "               ", "               ",    &
15744                      "               ", "               ", "               ",    &
15745                      "               ", "               "/) )
15746       wyckoff_info(113)= wyck_info_type("P 42 2 2    ",15,     &
15747                    (/"0,0,0          ", "1/2,1/2,0      ", "0,1/2,0        ",    &
15748                      "0,1/2,1/2      ", "0,0,1/4        ", "1/2,1/2,1/4    ",    &
15749                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15750                      "x,0,0          ", "x,1/2,1/2      ", "x,0,1/2        ",    &
15751                      "x,1/2,0        ", "x,x,1/4        ", "x,x,3/4        ",    &
15752                      "               ", "               ", "               ",    &
15753                      "               ", "               ", "               ",    &
15754                      "               ", "               ", "               ",    &
15755                      "               ", "               "/) )
15756       wyckoff_info(114)= wyck_info_type("P 42 21 2   ", 6,     &
15757                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
15758                      "0,1/2,z        ", "x,x,0          ", "x,x,1/2        ",    &
15759                      "               ", "               ", "               ",    &
15760                      "               ", "               ", "               ",    &
15761                      "               ", "               ", "               ",    &
15762                      "               ", "               ", "               ",    &
15763                      "               ", "               ", "               ",    &
15764                      "               ", "               ", "               ",    &
15765                      "               ", "               "/) )
15766       wyckoff_info(115)= wyck_info_type("P 43 2 2    ", 3,     &
15767                    (/"0,y,0          ", "1/2,y,0        ", "x,x,5/8        ",    &
15768                      "               ", "               ", "               ",    &
15769                      "               ", "               ", "               ",    &
15770                      "               ", "               ", "               ",    &
15771                      "               ", "               ", "               ",    &
15772                      "               ", "               ", "               ",    &
15773                      "               ", "               ", "               ",    &
15774                      "               ", "               ", "               ",    &
15775                      "               ", "               "/) )
15776       wyckoff_info(116)= wyck_info_type("P 43 21 2   ", 1,     &
15777                    (/"x,x,0          ", "               ", "               ",    &
15778                      "               ", "               ", "               ",    &
15779                      "               ", "               ", "               ",    &
15780                      "               ", "               ", "               ",    &
15781                      "               ", "               ", "               ",    &
15782                      "               ", "               ", "               ",    &
15783                      "               ", "               ", "               ",    &
15784                      "               ", "               ", "               ",    &
15785                      "               ", "               "/) )
15786       wyckoff_info(117)= wyck_info_type("I 4 2 2     ",10,     &
15787                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
15788                      "0,1/2,1/4      ", "0,0,z          ", "0,1/2,z        ",    &
15789                      "x,x,0          ", "x,0,0          ", "x,0,1/2        ",    &
15790                      "x,x+1/2,1/4    ", "               ", "               ",    &
15791                      "               ", "               ", "               ",    &
15792                      "               ", "               ", "               ",    &
15793                      "               ", "               ", "               ",    &
15794                      "               ", "               ", "               ",    &
15795                      "               ", "               "/) )
15796       wyckoff_info(118)= wyck_info_type("I 41 2 2    ", 6,     &
15797                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
15798                      "x,x,0          ", "-x,x,0         ", "x,1/4,1/8      ",    &
15799                      "               ", "               ", "               ",    &
15800                      "               ", "               ", "               ",    &
15801                      "               ", "               ", "               ",    &
15802                      "               ", "               ", "               ",    &
15803                      "               ", "               ", "               ",    &
15804                      "               ", "               ", "               ",    &
15805                      "               ", "               "/) )
15806
15807       wyckoff_info(119)= wyck_info_type("P 4 M M     ", 6,     &
15808                    (/"0,0,z          ", "1/2,1/2,z      ", "1/2,0,z        ",    &
15809                      "x,x,z          ", "x,0,z          ", "x,1/2,z        ",    &
15810                      "               ", "               ", "               ",    &
15811                      "               ", "               ", "               ",    &
15812                      "               ", "               ", "               ",    &
15813                      "               ", "               ", "               ",    &
15814                      "               ", "               ", "               ",    &
15815                      "               ", "               ", "               ",    &
15816                      "               ", "               "/) )
15817       wyckoff_info(120)= wyck_info_type("P 4 B M     ", 3,     &
15818                    (/"0,0,z          ", "0,1/2,z        ", "x,x+1/2,z      ",    &
15819                      "               ", "               ", "               ",    &
15820                      "               ", "               ", "               ",    &
15821                      "               ", "               ", "               ",    &
15822                      "               ", "               ", "               ",    &
15823                      "               ", "               ", "               ",    &
15824                      "               ", "               ", "               ",    &
15825                      "               ", "               ", "               ",    &
15826                      "               ", "               "/) )
15827       wyckoff_info(121)= wyck_info_type("P 42 C M    ", 4,     &
15828                    (/"0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15829                      "x,x,z          ", "               ", "               ",    &
15830                      "               ", "               ", "               ",    &
15831                      "               ", "               ", "               ",    &
15832                      "               ", "               ", "               ",    &
15833                      "               ", "               ", "               ",    &
15834                      "               ", "               ", "               ",    &
15835                      "               ", "               ", "               ",    &
15836                      "               ", "               "/) )
15837       wyckoff_info(122)= wyck_info_type("P 42 N M    ", 3,     &
15838                    (/"0,0,z          ", "0,1/2,z        ", "x,x,z          ",    &
15839                      "               ", "               ", "               ",    &
15840                      "               ", "               ", "               ",    &
15841                      "               ", "               ", "               ",    &
15842                      "               ", "               ", "               ",    &
15843                      "               ", "               ", "               ",    &
15844                      "               ", "               ", "               ",    &
15845                      "               ", "               ", "               ",    &
15846                      "               ", "               "/) )
15847       wyckoff_info(123)= wyck_info_type("P 4 C C     ", 3,     &
15848                    (/"0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15849                      "               ", "               ", "               ",    &
15850                      "               ", "               ", "               ",    &
15851                      "               ", "               ", "               ",    &
15852                      "               ", "               ", "               ",    &
15853                      "               ", "               ", "               ",    &
15854                      "               ", "               ", "               ",    &
15855                      "               ", "               ", "               ",    &
15856                      "               ", "               "/) )
15857       wyckoff_info(124)= wyck_info_type("P 4 N C     ", 2,     &
15858                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
15859                      "               ", "               ", "               ",    &
15860                      "               ", "               ", "               ",    &
15861                      "               ", "               ", "               ",    &
15862                      "               ", "               ", "               ",    &
15863                      "               ", "               ", "               ",    &
15864                      "               ", "               ", "               ",    &
15865                      "               ", "               ", "               ",    &
15866                      "               ", "               "/) )
15867       wyckoff_info(125)= wyck_info_type("P 42 M C    ", 5,     &
15868                    (/"0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15869                      "x,0,z          ", "x,1/2,z        ", "               ",    &
15870                      "               ", "               ", "               ",    &
15871                      "               ", "               ", "               ",    &
15872                      "               ", "               ", "               ",    &
15873                      "               ", "               ", "               ",    &
15874                      "               ", "               ", "               ",    &
15875                      "               ", "               ", "               ",    &
15876                      "               ", "               "/) )
15877       wyckoff_info(126)= wyck_info_type("P 42 B C    ", 2,     &
15878                    (/"0,0,z          ", "0,1/2,z        ", "               ",    &
15879                      "               ", "               ", "               ",    &
15880                      "               ", "               ", "               ",    &
15881                      "               ", "               ", "               ",    &
15882                      "               ", "               ", "               ",    &
15883                      "               ", "               ", "               ",    &
15884                      "               ", "               ", "               ",    &
15885                      "               ", "               ", "               ",    &
15886                      "               ", "               "/) )
15887       wyckoff_info(127)= wyck_info_type("I 4 M M     ", 4,     &
15888                    (/"0,0,z          ", "0,1/2,z        ", "x,x,z          ",    &
15889                      "x,0,z          ", "               ", "               ",    &
15890                      "               ", "               ", "               ",    &
15891                      "               ", "               ", "               ",    &
15892                      "               ", "               ", "               ",    &
15893                      "               ", "               ", "               ",    &
15894                      "               ", "               ", "               ",    &
15895                      "               ", "               ", "               ",    &
15896                      "               ", "               "/) )
15897       wyckoff_info(128)= wyck_info_type("I 4 C M     ", 3,     &
15898                    (/"0,0,z          ", "1/2,0,z        ", "x,x+1/2,z      ",    &
15899                      "               ", "               ", "               ",    &
15900                      "               ", "               ", "               ",    &
15901                      "               ", "               ", "               ",    &
15902                      "               ", "               ", "               ",    &
15903                      "               ", "               ", "               ",    &
15904                      "               ", "               ", "               ",    &
15905                      "               ", "               ", "               ",    &
15906                      "               ", "               "/) )
15907       wyckoff_info(129)= wyck_info_type("I 41 M D    ", 2,     &
15908                    (/"0,0,z          ", "0,y,z          ", "               ",    &
15909                      "               ", "               ", "               ",    &
15910                      "               ", "               ", "               ",    &
15911                      "               ", "               ", "               ",    &
15912                      "               ", "               ", "               ",    &
15913                      "               ", "               ", "               ",    &
15914                      "               ", "               ", "               ",    &
15915                      "               ", "               ", "               ",    &
15916                      "               ", "               "/) )
15917       wyckoff_info(130)= wyck_info_type("I 41 C D    ", 1,     &
15918                    (/"0,0,z          ", "               ", "               ",    &
15919                      "               ", "               ", "               ",    &
15920                      "               ", "               ", "               ",    &
15921                      "               ", "               ", "               ",    &
15922                      "               ", "               ", "               ",    &
15923                      "               ", "               ", "               ",    &
15924                      "               ", "               ", "               ",    &
15925                      "               ", "               ", "               ",    &
15926                      "               ", "               "/) )
15927       wyckoff_info(131)= wyck_info_type("P -4 2 M    ",14,     &
15928                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,0,1/2        ",    &
15929                      "1/2,1/2,0      ", "1/2,0,0        ", "1/2,0,1/2      ",    &
15930                      "0,0,z          ", "1/2,1/2,z      ", "x,0,0          ",    &
15931                      "x,1/2,1/2      ", "x,0,1/2        ", "x,1/2,0        ",    &
15932                      "0,1/2,z        ", "x,x,z          ", "               ",    &
15933                      "               ", "               ", "               ",    &
15934                      "               ", "               ", "               ",    &
15935                      "               ", "               ", "               ",    &
15936                      "               ", "               "/) )
15937       wyckoff_info(132)= wyck_info_type("P -4 2 C    ",13,     &
15938                    (/"0,0,1/4        ", "1/2,0,1/4      ", "1/2,1/2,1/4    ",    &
15939                      "0,1/2,1/4      ", "0,0,0          ", "1/2,1/2,0      ",    &
15940                      "x,0,1/4        ", "1/2,y,1/4      ", "x,1/2,1/4      ",    &
15941                      "0,y,1/4        ", "0,0,z          ", "1/2,1/2,z      ",    &
15942                      "0,1/2,z        ", "               ", "               ",    &
15943                      "               ", "               ", "               ",    &
15944                      "               ", "               ", "               ",    &
15945                      "               ", "               ", "               ",    &
15946                      "               ", "               "/) )
15947       wyckoff_info(133)= wyck_info_type("P -4 21 M   ", 5,     &
15948                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,z        ",    &
15949                      "0,0,z          ", "x,x+1/2,z      ", "               ",    &
15950                      "               ", "               ", "               ",    &
15951                      "               ", "               ", "               ",    &
15952                      "               ", "               ", "               ",    &
15953                      "               ", "               ", "               ",    &
15954                      "               ", "               ", "               ",    &
15955                      "               ", "               ", "               ",    &
15956                      "               ", "               "/) )
15957       wyckoff_info(134)= wyck_info_type("P -4 21 C   ", 4,     &
15958                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
15959                      "0,1/2,z        ", "               ", "               ",    &
15960                      "               ", "               ", "               ",    &
15961                      "               ", "               ", "               ",    &
15962                      "               ", "               ", "               ",    &
15963                      "               ", "               ", "               ",    &
15964                      "               ", "               ", "               ",    &
15965                      "               ", "               ", "               ",    &
15966                      "               ", "               "/) )
15967       wyckoff_info(135)= wyck_info_type("P -4 M 2    ",11,     &
15968                    (/"0,0,0          ", "1/2,1/2,0      ", "1/2,1/2,1/2    ",    &
15969                      "0,0,1/2        ", "0,0,z          ", "1/2,1/2,z      ",    &
15970                      "0,1/2,z        ", "x,x,0          ", "x,x,1/2        ",    &
15971                      "x,0,z          ", "x,1/2,z        ", "               ",    &
15972                      "               ", "               ", "               ",    &
15973                      "               ", "               ", "               ",    &
15974                      "               ", "               ", "               ",    &
15975                      "               ", "               ", "               ",    &
15976                      "               ", "               "/) )
15977       wyckoff_info(136)= wyck_info_type("P -4 C 2    ", 9,     &
15978                    (/"0,0,1/4        ", "1/2,1/2,1/4    ", "0,0,0          ",    &
15979                      "1/2,1/2,0      ", "x,x,1/4        ", "x,x,3/4        ",    &
15980                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
15981                      "               ", "               ", "               ",    &
15982                      "               ", "               ", "               ",    &
15983                      "               ", "               ", "               ",    &
15984                      "               ", "               ", "               ",    &
15985                      "               ", "               ", "               ",    &
15986                      "               ", "               "/) )
15987       wyckoff_info(137)= wyck_info_type("P -4 B 2    ", 8,     &
15988                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
15989                      "0,1/2,1/2      ", "0,0,z          ", "0,1/2,z        ",    &
15990                      "x,x+1/2,0      ", "x,x+1/2,1/2    ", "               ",    &
15991                      "               ", "               ", "               ",    &
15992                      "               ", "               ", "               ",    &
15993                      "               ", "               ", "               ",    &
15994                      "               ", "               ", "               ",    &
15995                      "               ", "               ", "               ",    &
15996                      "               ", "               "/) )
15997       wyckoff_info(138)= wyck_info_type("P -4 N 2    ", 8,     &
15998                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,1/4      ",    &
15999                      "0,1/2,3/4      ", "0,0,z          ", "x,-x+1/2,1/4   ",    &
16000                      "x,x+1/2,1/4    ", "0,1/2,z        ", "               ",    &
16001                      "               ", "               ", "               ",    &
16002                      "               ", "               ", "               ",    &
16003                      "               ", "               ", "               ",    &
16004                      "               ", "               ", "               ",    &
16005                      "               ", "               ", "               ",    &
16006                      "               ", "               "/) )
16007       wyckoff_info(139)= wyck_info_type("I -4 M 2    ", 9,     &
16008                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,1/4      ",    &
16009                      "0,1/2,3/4      ", "0,0,z          ", "0,1/2,z        ",    &
16010                      "x,x,0          ", "x,x+1/2,1/4    ", "x,0,z          ",    &
16011                      "               ", "               ", "               ",    &
16012                      "               ", "               ", "               ",    &
16013                      "               ", "               ", "               ",    &
16014                      "               ", "               ", "               ",    &
16015                      "               ", "               ", "               ",    &
16016                      "               ", "               "/) )
16017       wyckoff_info(140)= wyck_info_type("I -4 C 2    ", 8,     &
16018                    (/"0,0,1/4        ", "0,0,0          ", "0,1/2,1/4      ",    &
16019                      "0,1/2,0        ", "x,x,1/4        ", "0,0,z          ",    &
16020                      "0,1/2,z        ", "x,x+1/2,0      ", "               ",    &
16021                      "               ", "               ", "               ",    &
16022                      "               ", "               ", "               ",    &
16023                      "               ", "               ", "               ",    &
16024                      "               ", "               ", "               ",    &
16025                      "               ", "               ", "               ",    &
16026                      "               ", "               "/) )
16027       wyckoff_info(141)= wyck_info_type("I -4 2 M    ", 9,     &
16028                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
16029                      "0,1/2,1/4      ", "0,0,z          ", "x,0,0          ",    &
16030                      "x,0,1/2        ", "0,1/2,z        ", "x,x,z          ",    &
16031                      "               ", "               ", "               ",    &
16032                      "               ", "               ", "               ",    &
16033                      "               ", "               ", "               ",    &
16034                      "               ", "               ", "               ",    &
16035                      "               ", "               ", "               ",    &
16036                      "               ", "               "/) )
16037       wyckoff_info(142)= wyck_info_type("I -4 2 D    ", 4,     &
16038                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16039                      "x,1/4,1/8      ", "               ", "               ",    &
16040                      "               ", "               ", "               ",    &
16041                      "               ", "               ", "               ",    &
16042                      "               ", "               ", "               ",    &
16043                      "               ", "               ", "               ",    &
16044                      "               ", "               ", "               ",    &
16045                      "               ", "               ", "               ",    &
16046                      "               ", "               "/) )
16047       wyckoff_info(143)= wyck_info_type("P 4/M M M   ",20,     &
16048                    (/"0,0,0          ", "0,0,1/2        ", "1/2,1/2,0      ",    &
16049                      "1/2,1/2,1/2    ", "0,1/2,1/2      ", "0,1/2,0        ",    &
16050                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
16051                      "x,x,0          ", "x,x,1/2        ", "x,0,0          ",    &
16052                      "x,0,1/2        ", "x,1/2,0        ", "x,1/2,1/2      ",    &
16053                      "x,y,0          ", "x,y,1/2        ", "x,x,z          ",    &
16054                      "x,0,z          ", "x,1/2,z        ", "               ",    &
16055                      "               ", "               ", "               ",    &
16056                      "               ", "               "/) )
16057       wyckoff_info(144)= wyck_info_type("P 4/M C C   ",13,     &
16058                    (/"0,0,1/4        ", "0,0,0          ", "1/2,1/2,1/4    ",    &
16059                      "1/2,1/2,0      ", "0,1/2,0        ", "0,1/2,1/4      ",    &
16060                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
16061                      "x,x,1/4        ", "x,0,1/4        ", "x,1/2,1/4      ",    &
16062                      "x,y,0          ", "               ", "               ",    &
16063                      "               ", "               ", "               ",    &
16064                      "               ", "               ", "               ",    &
16065                      "               ", "               ", "               ",    &
16066                      "               ", "               "/) )
16067       wyckoff_info(145)= wyck_info_type("P 4/N B M:1 ",13,     &
16068                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
16069                      "0,1/2,1/2      ", "1/4,1/4,0      ", "1/4,1/4,1/2    ",    &
16070                      "0,0,z          ", "0,1/2,z        ", "x,x,0          ",    &
16071                      "x,x,1/2        ", "x,0,0          ", "x,0,1/2        ",    &
16072                      "x,x+1/2,z      ", "               ", "               ",    &
16073                      "               ", "               ", "               ",    &
16074                      "               ", "               ", "               ",    &
16075                      "               ", "               ", "               ",    &
16076                      "               ", "               "/) )
16077       wyckoff_info(146)= wyck_info_type("P 4/N B M   ",13,     &
16078                    (/"1/4,1/4,0      ", "1/4,1/4,1/2    ", "3/4,1/4,0      ",    &
16079                      "3/4,1/4,1/2    ", "0,0,0          ", "0,0,1/2        ",    &
16080                      "1/4,1/4,z      ", "3/4,1/4,z      ", "x,x,0          ",    &
16081                      "x,x,1/2        ", "x,1/4,0        ", "x,1/4,1/2      ",    &
16082                      "x,-x,z         ", "               ", "               ",    &
16083                      "               ", "               ", "               ",    &
16084                      "               ", "               ", "               ",    &
16085                      "               ", "               ", "               ",    &
16086                      "               ", "               "/) )
16087       wyckoff_info(147)= wyck_info_type("P 4/N N C:1 ",10,     &
16088                    (/"0,0,0          ", "0,0,1/2        ", "1/2,0,0        ",    &
16089                      "1/2,0,1/4      ", "0,0,z          ", "1/4,1/4,1/4    ",    &
16090                      "1/2,0,z        ", "x,x,0          ", "x,0,0          ",    &
16091                      "x,0,1/2        ", "               ", "               ",    &
16092                      "               ", "               ", "               ",    &
16093                      "               ", "               ", "               ",    &
16094                      "               ", "               ", "               ",    &
16095                      "               ", "               ", "               ",    &
16096                      "               ", "               "/) )
16097       wyckoff_info(148)= wyck_info_type("P 4/N N C   ",10,     &
16098                    (/"1/4,1/4,1/4    ", "1/4,1/4,3/4    ", "1/4,3/4,3/4    ",    &
16099                      "1/4,1/4,0      ", "1/4,1/4,z      ", "0,0,0          ",    &
16100                      "1/4,3/4,z      ", "x,x,1/4        ", "x,1/4,1/4      ",    &
16101                      "x,3/4,1/4      ", "               ", "               ",    &
16102                      "               ", "               ", "               ",    &
16103                      "               ", "               ", "               ",    &
16104                      "               ", "               ", "               ",    &
16105                      "               ", "               ", "               ",    &
16106                      "               ", "               "/) )
16107       wyckoff_info(149)= wyck_info_type("P 4/M B M   ",11,     &
16108                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,1/2      ",    &
16109                      "0,1/2,0        ", "0,0,z          ", "0,1/2,z        ",    &
16110                      "x,x+1/2,0      ", "x,x+1/2,1/2    ", "x,y,0          ",    &
16111                      "x,y,1/2        ", "x,x+1/2,z      ", "               ",    &
16112                      "               ", "               ", "               ",    &
16113                      "               ", "               ", "               ",    &
16114                      "               ", "               ", "               ",    &
16115                      "               ", "               ", "               ",    &
16116                      "               ", "               "/) )
16117       wyckoff_info(150)= wyck_info_type("P 4/M N C   ", 8,     &
16118                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
16119                      "0,1/2,1/4      ", "0,0,z          ", "0,1/2,z        ",    &
16120                      "x,x+1/2,1/4    ", "x,y,0          ", "               ",    &
16121                      "               ", "               ", "               ",    &
16122                      "               ", "               ", "               ",    &
16123                      "               ", "               ", "               ",    &
16124                      "               ", "               ", "               ",    &
16125                      "               ", "               ", "               ",    &
16126                      "               ", "               "/) )
16127       wyckoff_info(151)= wyck_info_type("P 4/N M M:1 ",10,     &
16128                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,z        ",    &
16129                      "1/4,1/4,0      ", "1/4,1/4,1/2    ", "0,0,z          ",    &
16130                      "x,x,0          ", "x,x,1/2        ", "0,y,z          ",    &
16131                      "x,x+1/2,z      ", "               ", "               ",    &
16132                      "               ", "               ", "               ",    &
16133                      "               ", "               ", "               ",    &
16134                      "               ", "               ", "               ",    &
16135                      "               ", "               ", "               ",    &
16136                      "               ", "               "/) )
16137       wyckoff_info(152)= wyck_info_type("P 4/N M M   ",10,     &
16138                    (/"3/4,1/4,0      ", "3/4,1/4,1/2    ", "1/4,1/4,z      ",    &
16139                      "0,0,0          ", "0,0,1/2        ", "3/4,1/4,z      ",    &
16140                      "x,-x,0         ", "x,-x,1/2       ", "1/4,y,z        ",    &
16141                      "x,x,z          ", "               ", "               ",    &
16142                      "               ", "               ", "               ",    &
16143                      "               ", "               ", "               ",    &
16144                      "               ", "               ", "               ",    &
16145                      "               ", "               ", "               ",    &
16146                      "               ", "               "/) )
16147       wyckoff_info(153)= wyck_info_type("P 4/N C C:1 ", 6,     &
16148                    (/"0,0,1/4        ", "0,0,0          ", "0,1/2,z        ",    &
16149                      "1/4,1/4,0      ", "0,0,z          ", "x,x,1/4        ",    &
16150                      "               ", "               ", "               ",    &
16151                      "               ", "               ", "               ",    &
16152                      "               ", "               ", "               ",    &
16153                      "               ", "               ", "               ",    &
16154                      "               ", "               ", "               ",    &
16155                      "               ", "               ", "               ",    &
16156                      "               ", "               "/) )
16157       wyckoff_info(154)= wyck_info_type("P 4/N C C   ", 6,     &
16158                    (/"3/4,1/4,1/4    ", "3/4,1/4,0      ", "1/4,1/4,z      ",    &
16159                      "0,0,0          ", "3/4,1/4,z      ", "x,-x,1/4       ",    &
16160                      "               ", "               ", "               ",    &
16161                      "               ", "               ", "               ",    &
16162                      "               ", "               ", "               ",    &
16163                      "               ", "               ", "               ",    &
16164                      "               ", "               ", "               ",    &
16165                      "               ", "               ", "               ",    &
16166                      "               ", "               "/) )
16167       wyckoff_info(155)= wyck_info_type("P 42/M M C  ",17,     &
16168                    (/"0,0,0          ", "1/2,1/2,0      ", "0,1/2,0        ",    &
16169                      "0,1/2,1/2      ", "0,0,1/4        ", "1/2,1/2,1/4    ",    &
16170                      "0,0,z          ", "1/2,1/2,z      ", "0,1/2,z        ",    &
16171                      "x,0,0          ", "x,1/2,1/2      ", "x,0,1/2        ",    &
16172                      "x,1/2,0        ", "x,x,1/4        ", "0,y,z          ",    &
16173                      "1/2,y,z        ", "x,y,0          ", "               ",    &
16174                      "               ", "               ", "               ",    &
16175                      "               ", "               ", "               ",    &
16176                      "               ", "               "/) )
16177       wyckoff_info(156)= wyck_info_type("P 42/M C M  ",15,     &
16178                    (/"0,0,0          ", "0,0,1/4        ", "1/2,1/2,0      ",    &
16179                      "1/2,1/2,1/4    ", "0,1/2,1/4      ", "0,1/2,0        ",    &
16180                      "0,0,z          ", "1/2,1/2,z      ", "x,x,0          ",    &
16181                      "x,x,1/2        ", "0,1/2,z        ", "x,0,1/4        ",    &
16182                      "x,1/2,1/4      ", "x,y,0          ", "x,x,z          ",    &
16183                      "               ", "               ", "               ",    &
16184                      "               ", "               ", "               ",    &
16185                      "               ", "               ", "               ",    &
16186                      "               ", "               "/) )
16187       wyckoff_info(157)= wyck_info_type("P 42/N B C:1",10,     &
16188                    (/"0,1/2,1/4      ", "0,0,1/4        ", "0,1/2,0        ",    &
16189                      "0,0,0          ", "1/4,1/4,1/4    ", "0,1/2,z        ",    &
16190                      "0,0,z          ", "x,0,1/4        ", "x,0,3/4        ",    &
16191                      "x,x+1/2,0      ", "               ", "               ",    &
16192                      "               ", "               ", "               ",    &
16193                      "               ", "               ", "               ",    &
16194                      "               ", "               ", "               ",    &
16195                      "               ", "               ", "               ",    &
16196                      "               ", "               "/) )
16197       wyckoff_info(158)= wyck_info_type("P 42/N B C  ",10,     &
16198                    (/"1/4,1/4,0      ", "3/4,1/4,0      ", "1/4,1/4,1/4    ",    &
16199                      "3/4,1/4,3/4    ", "0,0,0          ", "1/4,1/4,z      ",    &
16200                      "3/4,1/4,z      ", "x,1/4,0        ", "x,1/4,1/2      ",    &
16201                      "x,x,1/4        ", "               ", "               ",    &
16202                      "               ", "               ", "               ",    &
16203                      "               ", "               ", "               ",    &
16204                      "               ", "               ", "               ",    &
16205                      "               ", "               ", "               ",    &
16206                      "               ", "               "/) )
16207       wyckoff_info(159)= wyck_info_type("P 42/N N M:1",13,     &
16208                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
16209                      "0,1/2,1/4      ", "1/4,1/4,1/4    ", "3/4,3/4,3/4    ",    &
16210                      "0,0,z          ", "0,1/2,z        ", "x,0,0          ",    &
16211                      "x,0,1/2        ", "x,x+1/2,1/4    ", "x,x+1/2,3/4    ",    &
16212                      "x,x,z          ", "               ", "               ",    &
16213                      "               ", "               ", "               ",    &
16214                      "               ", "               ", "               ",    &
16215                      "               ", "               ", "               ",    &
16216                      "               ", "               "/) )
16217       wyckoff_info(160)= wyck_info_type("P 42/N N M  ",13,     &
16218                    (/"1/4,3/4,1/4    ", "3/4,1/4,1/4    ", "1/4,1/4,1/4    ",    &
16219                      "1/4,1/4,0      ", "0,0,1/2        ", "0,0,0          ",    &
16220                      "3/4,1/4,z      ", "1/4,1/4,z      ", "x,1/4,3/4      ",    &
16221                      "x,1/4,1/4      ", "x,x,0          ", "x,x,1/2        ",    &
16222                      "x,-x,z         ", "               ", "               ",    &
16223                      "               ", "               ", "               ",    &
16224                      "               ", "               ", "               ",    &
16225                      "               ", "               ", "               ",    &
16226                      "               ", "               "/) )
16227       wyckoff_info(161)= wyck_info_type("P 42/M B C  ", 8,     &
16228                    (/"0,0,0          ", "0,0,1/4        ", "0,1/2,0        ",    &
16229                      "0,1/2,1/4      ", "0,0,z          ", "0,1/2,z        ",    &
16230                      "x,x+1/2,1/4    ", "x,y,0          ", "               ",    &
16231                      "               ", "               ", "               ",    &
16232                      "               ", "               ", "               ",    &
16233                      "               ", "               ", "               ",    &
16234                      "               ", "               ", "               ",    &
16235                      "               ", "               ", "               ",    &
16236                      "               ", "               "/) )
16237       wyckoff_info(162)= wyck_info_type("P 42/M N M  ",10,     &
16238                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
16239                      "0,1/2,1/4      ", "0,0,z          ", "x,x,0          ",    &
16240                      "x,-x,0         ", "0,1/2,z        ", "x,y,0          ",    &
16241                      "x,x,z          ", "               ", "               ",    &
16242                      "               ", "               ", "               ",    &
16243                      "               ", "               ", "               ",    &
16244                      "               ", "               ", "               ",    &
16245                      "               ", "               ", "               ",    &
16246                      "               ", "               "/) )
16247       wyckoff_info(163)= wyck_info_type("P 42/N M C:1", 7,     &
16248                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16249                      "0,1/2,z        ", "1/4,1/4,1/4    ", "x,x,0          ",    &
16250                      "0,y,z          ", "               ", "               ",    &
16251                      "               ", "               ", "               ",    &
16252                      "               ", "               ", "               ",    &
16253                      "               ", "               ", "               ",    &
16254                      "               ", "               ", "               ",    &
16255                      "               ", "               ", "               ",    &
16256                      "               ", "               "/) )
16257       wyckoff_info(164)= wyck_info_type("P 42/N M C  ", 7,     &
16258                    (/"3/4,1/4,3/4    ", "3/4,1/4,1/4    ", "3/4,1/4,z      ",    &
16259                      "1/4,1/4,z      ", "0,0,0          ", "x,-x,1/4       ",    &
16260                      "1/4,y,z        ", "               ", "               ",    &
16261                      "               ", "               ", "               ",    &
16262                      "               ", "               ", "               ",    &
16263                      "               ", "               ", "               ",    &
16264                      "               ", "               ", "               ",    &
16265                      "               ", "               ", "               ",    &
16266                      "               ", "               "/) )
16267       wyckoff_info(165)= wyck_info_type("P 42/N C M:1", 9,     &
16268                    (/"0,0,1/4        ", "0,0,0          ", "1/4,1/4,1/4    ",    &
16269                      "1/4,1/4,3/4    ", "0,1/2,z        ", "0,0,z          ",    &
16270                      "x,x,1/4        ", "x,x,3/4        ", "x,x+1/2,z      ",    &
16271                      "               ", "               ", "               ",    &
16272                      "               ", "               ", "               ",    &
16273                      "               ", "               ", "               ",    &
16274                      "               ", "               ", "               ",    &
16275                      "               ", "               ", "               ",    &
16276                      "               ", "               "/) )
16277       wyckoff_info(166)= wyck_info_type("P 42/N C M  ", 9,     &
16278                    (/"3/4,1/4,0      ", "3/4,1/4,3/4    ", "0,0,1/2        ",    &
16279                      "0,0,0          ", "1/4,1/4,z      ", "3/4,1/4,z      ",    &
16280                      "x,-x,1/2       ", "x,-x,0         ", "x,x,z          ",    &
16281                      "               ", "               ", "               ",    &
16282                      "               ", "               ", "               ",    &
16283                      "               ", "               ", "               ",    &
16284                      "               ", "               ", "               ",    &
16285                      "               ", "               ", "               ",    &
16286                      "               ", "               "/) )
16287       wyckoff_info(167)= wyck_info_type("I 4/M M M   ",14,     &
16288                    (/"0,0,0          ", "0,0,1/2        ", "0,1/2,0        ",    &
16289                      "0,1/2,1/4      ", "0,0,z          ", "1/4,1/4,1/4    ",    &
16290                      "0,1/2,z        ", "x,x,0          ", "x,0,0          ",    &
16291                      "x,1/2,0        ", "x,x+1/2,1/4    ", "x,y,0          ",    &
16292                      "x,x,z          ", "0,y,z          ", "               ",    &
16293                      "               ", "               ", "               ",    &
16294                      "               ", "               ", "               ",    &
16295                      "               ", "               ", "               ",    &
16296                      "               ", "               "/) )
16297       wyckoff_info(168)= wyck_info_type("I 4/M C M   ",12,     &
16298                    (/"0,0,1/4        ", "0,1/2,1/4      ", "0,0,0          ",    &
16299                      "0,1/2,0        ", "1/4,1/4,1/4    ", "0,0,z          ",    &
16300                      "0,1/2,z        ", "x,x+1/2,0      ", "x,x,1/4        ",    &
16301                      "x,0,1/4        ", "x,y,0          ", "x,x+1/2,z      ",    &
16302                      "               ", "               ", "               ",    &
16303                      "               ", "               ", "               ",    &
16304                      "               ", "               ", "               ",    &
16305                      "               ", "               ", "               ",    &
16306                      "               ", "               "/) )
16307       wyckoff_info(169)= wyck_info_type("I 41/A M D:1", 8,     &
16308                    (/"0,0,0          ", "0,0,1/2        ", "0,1/4,1/8      ",    &
16309                      "0,1/4,5/8      ", "0,0,z          ", "x,1/4,1/8      ",    &
16310                      "x,x,0          ", "0,y,z          ", "               ",    &
16311                      "               ", "               ", "               ",    &
16312                      "               ", "               ", "               ",    &
16313                      "               ", "               ", "               ",    &
16314                      "               ", "               ", "               ",    &
16315                      "               ", "               ", "               ",    &
16316                      "               ", "               "/) )
16317       wyckoff_info(170)= wyck_info_type("I 41/A M D  ", 8,     &
16318                    (/"0,3/4,1/8      ", "0,1/4,3/8      ", "0,0,0          ",    &
16319                      "0,0,1/2        ", "0,1/4,z        ", "x,0,0          ",    &
16320                      "x,x+1/4,7/8    ", "0,y,z          ", "               ",    &
16321                      "               ", "               ", "               ",    &
16322                      "               ", "               ", "               ",    &
16323                      "               ", "               ", "               ",    &
16324                      "               ", "               ", "               ",    &
16325                      "               ", "               ", "               ",    &
16326                      "               ", "               "/) )
16327       wyckoff_info(171)= wyck_info_type("I 41/A C D:1", 6,     &
16328                    (/"0,0,0          ", "0,0,1/4        ", "0,1/4,1/8      ",    &
16329                      "0,0,z          ", "1/4,y,1/8      ", "x,x,1/4        ",    &
16330                      "               ", "               ", "               ",    &
16331                      "               ", "               ", "               ",    &
16332                      "               ", "               ", "               ",    &
16333                      "               ", "               ", "               ",    &
16334                      "               ", "               ", "               ",    &
16335                      "               ", "               ", "               ",    &
16336                      "               ", "               "/) )
16337       wyckoff_info(172)= wyck_info_type("I 41/A C D  ", 6,     &
16338                    (/"0,1/4,3/8      ", "0,1/4,1/8      ", "0,0,0          ",    &
16339                      "0,1/4,z        ", "x,0,1/4        ", "x,x+1/4,1/8    ",    &
16340                      "               ", "               ", "               ",    &
16341                      "               ", "               ", "               ",    &
16342                      "               ", "               ", "               ",    &
16343                      "               ", "               ", "               ",    &
16344                      "               ", "               ", "               ",    &
16345                      "               ", "               ", "               ",    &
16346                      "               ", "               "/) )
16347       wyckoff_info(173)= wyck_info_type("P 3         ", 3,     &
16348                    (/"0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16349                      "               ", "               ", "               ",    &
16350                      "               ", "               ", "               ",    &
16351                      "               ", "               ", "               ",    &
16352                      "               ", "               ", "               ",    &
16353                      "               ", "               ", "               ",    &
16354                      "               ", "               ", "               ",    &
16355                      "               ", "               ", "               ",    &
16356                      "               ", "               "/) )
16357       wyckoff_info(174)= wyck_info_type("P 31        ", 0,     &
16358                    (/"               ", "               ", "               ",    &
16359                      "               ", "               ", "               ",    &
16360                      "               ", "               ", "               ",    &
16361                      "               ", "               ", "               ",    &
16362                      "               ", "               ", "               ",    &
16363                      "               ", "               ", "               ",    &
16364                      "               ", "               ", "               ",    &
16365                      "               ", "               ", "               ",    &
16366                      "               ", "               "/) )
16367       wyckoff_info(175)= wyck_info_type("P 32        ", 0,     &
16368                    (/"               ", "               ", "               ",    &
16369                      "               ", "               ", "               ",    &
16370                      "               ", "               ", "               ",    &
16371                      "               ", "               ", "               ",    &
16372                      "               ", "               ", "               ",    &
16373                      "               ", "               ", "               ",    &
16374                      "               ", "               ", "               ",    &
16375                      "               ", "               ", "               ",    &
16376                      "               ", "               "/) )
16377       wyckoff_info(176)= wyck_info_type("R 3         ", 1,     &
16378                    (/"0,0,z          ", "               ", "               ",    &
16379                      "               ", "               ", "               ",    &
16380                      "               ", "               ", "               ",    &
16381                      "               ", "               ", "               ",    &
16382                      "               ", "               ", "               ",    &
16383                      "               ", "               ", "               ",    &
16384                      "               ", "               ", "               ",    &
16385                      "               ", "               ", "               ",    &
16386                      "               ", "               "/) )
16387       wyckoff_info(177)= wyck_info_type("R 3:H       ", 1,     &
16388                    (/"x,x,x          ", "               ", "               ",    &
16389                      "               ", "               ", "               ",    &
16390                      "               ", "               ", "               ",    &
16391                      "               ", "               ", "               ",    &
16392                      "               ", "               ", "               ",    &
16393                      "               ", "               ", "               ",    &
16394                      "               ", "               ", "               ",    &
16395                      "               ", "               ", "               ",    &
16396                      "               ", "               "/) )
16397       wyckoff_info(178)= wyck_info_type("P -3        ", 6,     &
16398                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16399                      "1/3,2/3,z      ", "1/2,0,0        ", "1/2,0,1/2      ",    &
16400                      "               ", "               ", "               ",    &
16401                      "               ", "               ", "               ",    &
16402                      "               ", "               ", "               ",    &
16403                      "               ", "               ", "               ",    &
16404                      "               ", "               ", "               ",    &
16405                      "               ", "               ", "               ",    &
16406                      "               ", "               "/) )
16407       wyckoff_info(179)= wyck_info_type("R -3        ", 5,     &
16408                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16409                      "1/2,0,1/2      ", "1/2,0,0        ", "               ",    &
16410                      "               ", "               ", "               ",    &
16411                      "               ", "               ", "               ",    &
16412                      "               ", "               ", "               ",    &
16413                      "               ", "               ", "               ",    &
16414                      "               ", "               ", "               ",    &
16415                      "               ", "               ", "               ",    &
16416                      "               ", "               "/) )
16417       wyckoff_info(180)= wyck_info_type("R -3:H      ", 5,     &
16418                    (/"0,0,0          ", "1/2,1/2,1/2    ", "x,x,x          ",    &
16419                      "1/2,0,0        ", "0,1/2,1/2      ", "               ",    &
16420                      "               ", "               ", "               ",    &
16421                      "               ", "               ", "               ",    &
16422                      "               ", "               ", "               ",    &
16423                      "               ", "               ", "               ",    &
16424                      "               ", "               ", "               ",    &
16425                      "               ", "               ", "               ",    &
16426                      "               ", "               "/) )
16427       wyckoff_info(181)= wyck_info_type("P 3 1 2     ",11,     &
16428                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16429                      "1/3,2/3,1/2    ", "2/3,1/3,0      ", "2/3,1/3,1/2    ",    &
16430                      "0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16431                      "x,-x,0         ", "x,-x,1/2       ", "               ",    &
16432                      "               ", "               ", "               ",    &
16433                      "               ", "               ", "               ",    &
16434                      "               ", "               ", "               ",    &
16435                      "               ", "               ", "               ",    &
16436                      "               ", "               "/) )
16437       wyckoff_info(182)= wyck_info_type("P 3 2 1     ", 6,     &
16438                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16439                      "1/3,2/3,z      ", "x,0,0          ", "x,0,1/2        ",    &
16440                      "               ", "               ", "               ",    &
16441                      "               ", "               ", "               ",    &
16442                      "               ", "               ", "               ",    &
16443                      "               ", "               ", "               ",    &
16444                      "               ", "               ", "               ",    &
16445                      "               ", "               ", "               ",    &
16446                      "               ", "               "/) )
16447       wyckoff_info(183)= wyck_info_type("P 31 1 2    ", 2,     &
16448                    (/"x,-x,1/3       ", "x,-x,5/6       ", "               ",    &
16449                      "               ", "               ", "               ",    &
16450                      "               ", "               ", "               ",    &
16451                      "               ", "               ", "               ",    &
16452                      "               ", "               ", "               ",    &
16453                      "               ", "               ", "               ",    &
16454                      "               ", "               ", "               ",    &
16455                      "               ", "               ", "               ",    &
16456                      "               ", "               "/) )
16457       wyckoff_info(184)= wyck_info_type("P 31 2 1    ", 2,     &
16458                    (/"x,0,1/3        ", "x,0,5/6        ", "               ",    &
16459                      "               ", "               ", "               ",    &
16460                      "               ", "               ", "               ",    &
16461                      "               ", "               ", "               ",    &
16462                      "               ", "               ", "               ",    &
16463                      "               ", "               ", "               ",    &
16464                      "               ", "               ", "               ",    &
16465                      "               ", "               ", "               ",    &
16466                      "               ", "               "/) )
16467       wyckoff_info(185)= wyck_info_type("P 32 1 2    ", 2,     &
16468                    (/"x,-x,2/3       ", "x,-x,1/6       ", "               ",    &
16469                      "               ", "               ", "               ",    &
16470                      "               ", "               ", "               ",    &
16471                      "               ", "               ", "               ",    &
16472                      "               ", "               ", "               ",    &
16473                      "               ", "               ", "               ",    &
16474                      "               ", "               ", "               ",    &
16475                      "               ", "               ", "               ",    &
16476                      "               ", "               "/) )
16477       wyckoff_info(186)= wyck_info_type("P 32 2 1    ", 2,     &
16478                    (/"x,0,2/3        ", "x,0,1/6        ", "               ",    &
16479                      "               ", "               ", "               ",    &
16480                      "               ", "               ", "               ",    &
16481                      "               ", "               ", "               ",    &
16482                      "               ", "               ", "               ",    &
16483                      "               ", "               ", "               ",    &
16484                      "               ", "               ", "               ",    &
16485                      "               ", "               ", "               ",    &
16486                      "               ", "               "/) )
16487       wyckoff_info(187)= wyck_info_type("R 3 2       ", 5,     &
16488                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16489                      "x,0,0          ", "x,0,1/2        ", "               ",    &
16490                      "               ", "               ", "               ",    &
16491                      "               ", "               ", "               ",    &
16492                      "               ", "               ", "               ",    &
16493                      "               ", "               ", "               ",    &
16494                      "               ", "               ", "               ",    &
16495                      "               ", "               ", "               ",    &
16496                      "               ", "               "/) )
16497       wyckoff_info(188)= wyck_info_type("R 3 2:R     ", 5,     &
16498                    (/"0,0,0          ", "1/2,1/2,1/2    ", "x,x,x          ",    &
16499                      "0,y,-y         ", "1/2,y,-y       ", "               ",    &
16500                      "               ", "               ", "               ",    &
16501                      "               ", "               ", "               ",    &
16502                      "               ", "               ", "               ",    &
16503                      "               ", "               ", "               ",    &
16504                      "               ", "               ", "               ",    &
16505                      "               ", "               ", "               ",    &
16506                      "               ", "               "/) )
16507       wyckoff_info(189)= wyck_info_type("P 3 M 1     ", 4,     &
16508                    (/"0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16509                      "x,-x,z         ", "               ", "               ",    &
16510                      "               ", "               ", "               ",    &
16511                      "               ", "               ", "               ",    &
16512                      "               ", "               ", "               ",    &
16513                      "               ", "               ", "               ",    &
16514                      "               ", "               ", "               ",    &
16515                      "               ", "               ", "               ",    &
16516                      "               ", "               "/) )
16517       wyckoff_info(190)= wyck_info_type("P 3 1 M     ", 3,     &
16518                    (/"0,0,z          ", "1/3,2/3,z      ", "x,0,z          ",    &
16519                      "               ", "               ", "               ",    &
16520                      "               ", "               ", "               ",    &
16521                      "               ", "               ", "               ",    &
16522                      "               ", "               ", "               ",    &
16523                      "               ", "               ", "               ",    &
16524                      "               ", "               ", "               ",    &
16525                      "               ", "               ", "               ",    &
16526                      "               ", "               "/) )
16527       wyckoff_info(191)= wyck_info_type("P 3 C 1     ", 3,     &
16528                    (/"0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16529                      "               ", "               ", "               ",    &
16530                      "               ", "               ", "               ",    &
16531                      "               ", "               ", "               ",    &
16532                      "               ", "               ", "               ",    &
16533                      "               ", "               ", "               ",    &
16534                      "               ", "               ", "               ",    &
16535                      "               ", "               ", "               ",    &
16536                      "               ", "               "/) )
16537       wyckoff_info(192)= wyck_info_type("P 3 1 C     ", 2,     &
16538                    (/"0,0,z          ", "1/3,2/3,z      ", "               ",    &
16539                      "               ", "               ", "               ",    &
16540                      "               ", "               ", "               ",    &
16541                      "               ", "               ", "               ",    &
16542                      "               ", "               ", "               ",    &
16543                      "               ", "               ", "               ",    &
16544                      "               ", "               ", "               ",    &
16545                      "               ", "               ", "               ",    &
16546                      "               ", "               "/) )
16547       wyckoff_info(193)= wyck_info_type("R 3 M       ", 2,     &
16548                    (/"0,0,z          ", "x,-x,z         ", "               ",    &
16549                      "               ", "               ", "               ",    &
16550                      "               ", "               ", "               ",    &
16551                      "               ", "               ", "               ",    &
16552                      "               ", "               ", "               ",    &
16553                      "               ", "               ", "               ",    &
16554                      "               ", "               ", "               ",    &
16555                      "               ", "               ", "               ",    &
16556                      "               ", "               "/) )
16557       wyckoff_info(194)= wyck_info_type("R 3 M:R     ", 2,     &
16558                    (/"x,x,x          ", "x,x,z          ", "               ",    &
16559                      "               ", "               ", "               ",    &
16560                      "               ", "               ", "               ",    &
16561                      "               ", "               ", "               ",    &
16562                      "               ", "               ", "               ",    &
16563                      "               ", "               ", "               ",    &
16564                      "               ", "               ", "               ",    &
16565                      "               ", "               ", "               ",    &
16566                      "               ", "               "/) )
16567       wyckoff_info(195)= wyck_info_type("R 3 C       ", 1,     &
16568                    (/"0,0,z          ", "               ", "               ",    &
16569                      "               ", "               ", "               ",    &
16570                      "               ", "               ", "               ",    &
16571                      "               ", "               ", "               ",    &
16572                      "               ", "               ", "               ",    &
16573                      "               ", "               ", "               ",    &
16574                      "               ", "               ", "               ",    &
16575                      "               ", "               ", "               ",    &
16576                      "               ", "               "/) )
16577       wyckoff_info(196)= wyck_info_type("R 3 C:R     ", 1,     &
16578                    (/"x,x,x          ", "               ", "               ",    &
16579                      "               ", "               ", "               ",    &
16580                      "               ", "               ", "               ",    &
16581                      "               ", "               ", "               ",    &
16582                      "               ", "               ", "               ",    &
16583                      "               ", "               ", "               ",    &
16584                      "               ", "               ", "               ",    &
16585                      "               ", "               ", "               ",    &
16586                      "               ", "               "/) )
16587       wyckoff_info(197)= wyck_info_type("P -3 1 M    ",11,     &
16588                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16589                      "1/3,2/3,1/2    ", "0,0,z          ", "1/2,0,0        ",    &
16590                      "1/2,0,1/2      ", "1/3,2/3,z      ", "x,-x,0         ",    &
16591                      "x,-x,1/2       ", "x,0,z          ", "               ",    &
16592                      "               ", "               ", "               ",    &
16593                      "               ", "               ", "               ",    &
16594                      "               ", "               ", "               ",    &
16595                      "               ", "               ", "               ",    &
16596                      "               ", "               "/) )
16597       wyckoff_info(198)= wyck_info_type("P -3 1 C    ", 8,     &
16598                    (/"0,0,1/4        ", "0,0,0          ", "1/3,2/3,1/4    ",    &
16599                      "2/3,1/3,1/4    ", "0,0,z          ", "1/3,2/3,z      ",    &
16600                      "1/2,0,0        ", "x,-x,1/4       ", "               ",    &
16601                      "               ", "               ", "               ",    &
16602                      "               ", "               ", "               ",    &
16603                      "               ", "               ", "               ",    &
16604                      "               ", "               ", "               ",    &
16605                      "               ", "               ", "               ",    &
16606                      "               ", "               "/) )
16607       wyckoff_info(199)= wyck_info_type("P -3 M 1    ", 9,     &
16608                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16609                      "1/3,2/3,z      ", "1/2,0,0        ", "1/2,0,1/2      ",    &
16610                      "x,0,0          ", "x,0,1/2        ", "x,-x,z         ",    &
16611                      "               ", "               ", "               ",    &
16612                      "               ", "               ", "               ",    &
16613                      "               ", "               ", "               ",    &
16614                      "               ", "               ", "               ",    &
16615                      "               ", "               ", "               ",    &
16616                      "               ", "               "/) )
16617       wyckoff_info(200)= wyck_info_type("P -3 C 1    ", 6,     &
16618                    (/"0,0,1/4        ", "0,0,0          ", "0,0,z          ",    &
16619                      "1/3,2/3,z      ", "1/2,0,0        ", "x,0,1/4        ",    &
16620                      "               ", "               ", "               ",    &
16621                      "               ", "               ", "               ",    &
16622                      "               ", "               ", "               ",    &
16623                      "               ", "               ", "               ",    &
16624                      "               ", "               ", "               ",    &
16625                      "               ", "               ", "               ",    &
16626                      "               ", "               "/) )
16627       wyckoff_info(201)= wyck_info_type("R -3 M      ", 8,     &
16628                    (/"0,0,0          ", "0,0,1/2        ", "0,0,z          ",    &
16629                      "1/2,0,1/2      ", "1/2,0,0        ", "x,0,0          ",    &
16630                      "x,0,1/2        ", "x,-x,z         ", "               ",    &
16631                      "               ", "               ", "               ",    &
16632                      "               ", "               ", "               ",    &
16633                      "               ", "               ", "               ",    &
16634                      "               ", "               ", "               ",    &
16635                      "               ", "               ", "               ",    &
16636                      "               ", "               "/) )
16637       wyckoff_info(202)= wyck_info_type("R -3 M:R    ", 8,     &
16638                    (/"0,0,0          ", "1/2,1/2,1/2    ", "x,x,x          ",    &
16639                      "1/2,0,0        ", "0,1/2,1/2      ", "x,-x,0         ",    &
16640                      "x,-x,1/2       ", "x,x,z          ", "               ",    &
16641                      "               ", "               ", "               ",    &
16642                      "               ", "               ", "               ",    &
16643                      "               ", "               ", "               ",    &
16644                      "               ", "               ", "               ",    &
16645                      "               ", "               ", "               ",    &
16646                      "               ", "               "/) )
16647       wyckoff_info(203)= wyck_info_type("R -3 C      ", 5,     &
16648                    (/"0,0,1/4        ", "0,0,0          ", "0,0,z          ",    &
16649                      "1/2,0,0        ", "x,0,1/4        ", "               ",    &
16650                      "               ", "               ", "               ",    &
16651                      "               ", "               ", "               ",    &
16652                      "               ", "               ", "               ",    &
16653                      "               ", "               ", "               ",    &
16654                      "               ", "               ", "               ",    &
16655                      "               ", "               ", "               ",    &
16656                      "               ", "               "/) )
16657       wyckoff_info(204)= wyck_info_type("R -3 C:R    ", 5,     &
16658                    (/"1/4,1/4,1/4    ", "0,0,0          ", "x,x,x          ",    &
16659                      "1/2,0,0        ", "x,-x+1/2,1/4   ", "               ",    &
16660                      "               ", "               ", "               ",    &
16661                      "               ", "               ", "               ",    &
16662                      "               ", "               ", "               ",    &
16663                      "               ", "               ", "               ",    &
16664                      "               ", "               ", "               ",    &
16665                      "               ", "               ", "               ",    &
16666                      "               ", "               "/) )
16667       wyckoff_info(205)= wyck_info_type("P 6         ", 3,     &
16668                    (/"0,0,z          ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16669                      "               ", "               ", "               ",    &
16670                      "               ", "               ", "               ",    &
16671                      "               ", "               ", "               ",    &
16672                      "               ", "               ", "               ",    &
16673                      "               ", "               ", "               ",    &
16674                      "               ", "               ", "               ",    &
16675                      "               ", "               ", "               ",    &
16676                      "               ", "               "/) )
16677       wyckoff_info(206)= wyck_info_type("P 61        ", 0,     &
16678                    (/"               ", "               ", "               ",    &
16679                      "               ", "               ", "               ",    &
16680                      "               ", "               ", "               ",    &
16681                      "               ", "               ", "               ",    &
16682                      "               ", "               ", "               ",    &
16683                      "               ", "               ", "               ",    &
16684                      "               ", "               ", "               ",    &
16685                      "               ", "               ", "               ",    &
16686                      "               ", "               "/) )
16687       wyckoff_info(207)= wyck_info_type("P 65        ", 0,     &
16688                    (/"               ", "               ", "               ",    &
16689                      "               ", "               ", "               ",    &
16690                      "               ", "               ", "               ",    &
16691                      "               ", "               ", "               ",    &
16692                      "               ", "               ", "               ",    &
16693                      "               ", "               ", "               ",    &
16694                      "               ", "               ", "               ",    &
16695                      "               ", "               ", "               ",    &
16696                      "               ", "               "/) )
16697       wyckoff_info(208)= wyck_info_type("P 62        ", 2,     &
16698                    (/"0,0,z          ", "1/2,1/2,z      ", "               ",    &
16699                      "               ", "               ", "               ",    &
16700                      "               ", "               ", "               ",    &
16701                      "               ", "               ", "               ",    &
16702                      "               ", "               ", "               ",    &
16703                      "               ", "               ", "               ",    &
16704                      "               ", "               ", "               ",    &
16705                      "               ", "               ", "               ",    &
16706                      "               ", "               "/) )
16707       wyckoff_info(209)= wyck_info_type("P 64        ", 2,     &
16708                    (/"0,0,z          ", "1/2,1/2,z      ", "               ",    &
16709                      "               ", "               ", "               ",    &
16710                      "               ", "               ", "               ",    &
16711                      "               ", "               ", "               ",    &
16712                      "               ", "               ", "               ",    &
16713                      "               ", "               ", "               ",    &
16714                      "               ", "               ", "               ",    &
16715                      "               ", "               ", "               ",    &
16716                      "               ", "               "/) )
16717       wyckoff_info(210)= wyck_info_type("P 63        ", 2,     &
16718                    (/"0,0,z          ", "1/3,2/3,z      ", "               ",    &
16719                      "               ", "               ", "               ",    &
16720                      "               ", "               ", "               ",    &
16721                      "               ", "               ", "               ",    &
16722                      "               ", "               ", "               ",    &
16723                      "               ", "               ", "               ",    &
16724                      "               ", "               ", "               ",    &
16725                      "               ", "               ", "               ",    &
16726                      "               ", "               "/) )
16727       wyckoff_info(211)= wyck_info_type("P -6        ",11,     &
16728                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16729                      "1/3,2/3,1/2    ", "2/3,1/3,0      ", "2/3,1/3,1/2    ",    &
16730                      "0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16731                      "x,y,0          ", "x,y,1/2        ", "               ",    &
16732                      "               ", "               ", "               ",    &
16733                      "               ", "               ", "               ",    &
16734                      "               ", "               ", "               ",    &
16735                      "               ", "               ", "               ",    &
16736                      "               ", "               "/) )
16737       wyckoff_info(212)= wyck_info_type("P 6/M       ",11,     &
16738                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16739                      "1/3,2/3,1/2    ", "0,0,z          ", "1/2,0,0        ",    &
16740                      "1/2,0,1/2      ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16741                      "x,y,0          ", "x,y,1/2        ", "               ",    &
16742                      "               ", "               ", "               ",    &
16743                      "               ", "               ", "               ",    &
16744                      "               ", "               ", "               ",    &
16745                      "               ", "               ", "               ",    &
16746                      "               ", "               "/) )
16747       wyckoff_info(213)= wyck_info_type("P 63/M      ", 8,     &
16748                    (/"0,0,1/4        ", "0,0,0          ", "1/3,2/3,1/4    ",    &
16749                      "2/3,1/3,1/4    ", "0,0,z          ", "1/3,2/3,z      ",    &
16750                      "1/2,0,0        ", "x,y,1/4        ", "               ",    &
16751                      "               ", "               ", "               ",    &
16752                      "               ", "               ", "               ",    &
16753                      "               ", "               ", "               ",    &
16754                      "               ", "               ", "               ",    &
16755                      "               ", "               ", "               ",    &
16756                      "               ", "               "/) )
16757       wyckoff_info(214)= wyck_info_type("P 6 2 2     ",13,     &
16758                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16759                      "1/3,2/3,1/2    ", "0,0,z          ", "1/2,0,0        ",    &
16760                      "1/2,0,1/2      ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16761                      "x,0,0          ", "x,0,1/2        ", "x,-x,0         ",    &
16762                      "x,-x,1/2       ", "               ", "               ",    &
16763                      "               ", "               ", "               ",    &
16764                      "               ", "               ", "               ",    &
16765                      "               ", "               ", "               ",    &
16766                      "               ", "               "/) )
16767       wyckoff_info(215)= wyck_info_type("P 61 2 2    ", 2,     &
16768                    (/"x,0,0          ", "x,2x,1/4       ", "               ",    &
16769                      "               ", "               ", "               ",    &
16770                      "               ", "               ", "               ",    &
16771                      "               ", "               ", "               ",    &
16772                      "               ", "               ", "               ",    &
16773                      "               ", "               ", "               ",    &
16774                      "               ", "               ", "               ",    &
16775                      "               ", "               ", "               ",    &
16776                      "               ", "               "/) )
16777       wyckoff_info(216)= wyck_info_type("P 65 2 2    ", 2,     &
16778                    (/"x,0,0          ", "x,2x,3/4       ", "               ",    &
16779                      "               ", "               ", "               ",    &
16780                      "               ", "               ", "               ",    &
16781                      "               ", "               ", "               ",    &
16782                      "               ", "               ", "               ",    &
16783                      "               ", "               ", "               ",    &
16784                      "               ", "               ", "               ",    &
16785                      "               ", "               ", "               ",    &
16786                      "               ", "               "/) )
16787       wyckoff_info(217)= wyck_info_type("P 62 2 2    ",10,     &
16788                    (/"0,0,0          ", "0,0,1/2        ", "1/2,0,0        ",    &
16789                      "1/2,0,1/2      ", "0,0,z          ", "1/2,0,z        ",    &
16790                      "x,0,0          ", "x,0,1/2        ", "x,2x,0         ",    &
16791                      "x,2x,1/2       ", "               ", "               ",    &
16792                      "               ", "               ", "               ",    &
16793                      "               ", "               ", "               ",    &
16794                      "               ", "               ", "               ",    &
16795                      "               ", "               ", "               ",    &
16796                      "               ", "               "/) )
16797       wyckoff_info(218)= wyck_info_type("P 64 2 2    ",10,     &
16798                    (/"0,0,0          ", "0,0,1/2        ", "1/2,0,0        ",    &
16799                      "1/2,0,/1,2     ", "0,0,z          ", "1/2,0,z        ",    &
16800                      "x,0,0          ", "x,0,1/2        ", "x,2x,0         ",    &
16801                      "x,2x,1/2       ", "               ", "               ",    &
16802                      "               ", "               ", "               ",    &
16803                      "               ", "               ", "               ",    &
16804                      "               ", "               ", "               ",    &
16805                      "               ", "               ", "               ",    &
16806                      "               ", "               "/) )
16807       wyckoff_info(219)= wyck_info_type("P 63 2 2    ", 8,     &
16808                    (/"0,0,0          ", "0,0,1/4        ", "1/3,2/3,1/4    ",    &
16809                      "1/3,2/3,3/4    ", "0,0,z          ", "1/3,2/3,z      ",    &
16810                      "x,0,0          ", "x,2x,1/4       ", "               ",    &
16811                      "               ", "               ", "               ",    &
16812                      "               ", "               ", "               ",    &
16813                      "               ", "               ", "               ",    &
16814                      "               ", "               ", "               ",    &
16815                      "               ", "               ", "               ",    &
16816                      "               ", "               "/) )
16817       wyckoff_info(220)= wyck_info_type("P 6 M M     ", 5,     &
16818                    (/"0,0,z          ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16819                      "x,0,z          ", "x,-x,z         ", "               ",    &
16820                      "               ", "               ", "               ",    &
16821                      "               ", "               ", "               ",    &
16822                      "               ", "               ", "               ",    &
16823                      "               ", "               ", "               ",    &
16824                      "               ", "               ", "               ",    &
16825                      "               ", "               ", "               ",    &
16826                      "               ", "               "/) )
16827       wyckoff_info(221)= wyck_info_type("P 6 C C     ", 3,     &
16828                    (/"0,0,z          ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16829                      "               ", "               ", "               ",    &
16830                      "               ", "               ", "               ",    &
16831                      "               ", "               ", "               ",    &
16832                      "               ", "               ", "               ",    &
16833                      "               ", "               ", "               ",    &
16834                      "               ", "               ", "               ",    &
16835                      "               ", "               ", "               ",    &
16836                      "               ", "               "/) )
16837       wyckoff_info(222)= wyck_info_type("P 63 C M    ", 3,     &
16838                    (/"0,0,z          ", "1/3,2/3,z      ", "x,0,z          ",    &
16839                      "               ", "               ", "               ",    &
16840                      "               ", "               ", "               ",    &
16841                      "               ", "               ", "               ",    &
16842                      "               ", "               ", "               ",    &
16843                      "               ", "               ", "               ",    &
16844                      "               ", "               ", "               ",    &
16845                      "               ", "               ", "               ",    &
16846                      "               ", "               "/) )
16847       wyckoff_info(223)= wyck_info_type("P 63 M C    ", 3,     &
16848                    (/"0,0,z          ", "1/3,2/3,z      ", "x,-x,z         ",    &
16849                      "               ", "               ", "               ",    &
16850                      "               ", "               ", "               ",    &
16851                      "               ", "               ", "               ",    &
16852                      "               ", "               ", "               ",    &
16853                      "               ", "               ", "               ",    &
16854                      "               ", "               ", "               ",    &
16855                      "               ", "               ", "               ",    &
16856                      "               ", "               "/) )
16857       wyckoff_info(224)= wyck_info_type("P -6 M 2    ",14,     &
16858                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16859                      "1/3,2/3,1/2    ", "2/3,1/3,0      ", "2/3,1/3,1/2    ",    &
16860                      "0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16861                      "x,-x,0         ", "x,-x,1/2       ", "x,y,0          ",    &
16862                      "x,y,1/2        ", "x,-x,z         ", "               ",    &
16863                      "               ", "               ", "               ",    &
16864                      "               ", "               ", "               ",    &
16865                      "               ", "               ", "               ",    &
16866                      "               ", "               "/) )
16867       wyckoff_info(225)= wyck_info_type("P -6 C 2    ",11,     &
16868                    (/"0,0,0          ", "0,0,1/4        ", "1/3,2/3,0      ",    &
16869                      "1/3,2/3,1/4    ", "2/3,1/3,0      ", "2/3,1/3,1/4    ",    &
16870                      "0,0,z          ", "1/3,2/3,z      ", "2/3,1/3,z      ",    &
16871                      "x,-x,0         ", "x,y,1/4        ", "               ",    &
16872                      "               ", "               ", "               ",    &
16873                      "               ", "               ", "               ",    &
16874                      "               ", "               ", "               ",    &
16875                      "               ", "               ", "               ",    &
16876                      "               ", "               "/) )
16877       wyckoff_info(226)= wyck_info_type("P -6 2 M    ",11,     &
16878                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16879                      "1/3,2/3,1/2    ", "0,0,z          ", "x,0,0          ",    &
16880                      "x,0,1/2        ", "1/3,2/3,z      ", "x,0,z          ",    &
16881                      "x,y,0          ", "x,y,1/2        ", "               ",    &
16882                      "               ", "               ", "               ",    &
16883                      "               ", "               ", "               ",    &
16884                      "               ", "               ", "               ",    &
16885                      "               ", "               ", "               ",    &
16886                      "               ", "               "/) )
16887       wyckoff_info(227)= wyck_info_type("P -6 2 C    ", 8,     &
16888                    (/"0,0,0          ", "0,0,1/4        ", "1/3,2/3,1/4    ",    &
16889                      "2/3,1/3,1/4    ", "0,0,z          ", "1/3,2/3,z      ",    &
16890                      "x,0,0          ", "x,y,1/4        ", "               ",    &
16891                      "               ", "               ", "               ",    &
16892                      "               ", "               ", "               ",    &
16893                      "               ", "               ", "               ",    &
16894                      "               ", "               ", "               ",    &
16895                      "               ", "               ", "               ",    &
16896                      "               ", "               "/) )
16897       wyckoff_info(228)= wyck_info_type("P 6/M M M   ",17,     &
16898                    (/"0,0,0          ", "0,0,1/2        ", "1/3,2/3,0      ",    &
16899                      "1/3,2/3,1/2    ", "0,0,z          ", "1/2,0,0        ",    &
16900                      "1/2,0,1/2      ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16901                      "x,0,0          ", "x,0,1/2        ", "x,2x,0         ",    &
16902                      "x,2x,1/2       ", "x,0,z          ", "x,2x,z         ",    &
16903                      "x,y,0          ", "x,y,1/2        ", "               ",    &
16904                      "               ", "               ", "               ",    &
16905                      "               ", "               ", "               ",    &
16906                      "               ", "               "/) )
16907       wyckoff_info(229)= wyck_info_type("P 6/M C C   ",12,     &
16908                    (/"0,0,1/4        ", "0,0,0          ", "1/3,2/3,1/4    ",    &
16909                      "1/3,2/3,0      ", "0,0,z          ", "1/2,0,1/4      ",    &
16910                      "1/2,0,0        ", "1/3,2/3,z      ", "1/2,0,z        ",    &
16911                      "x,0,1/4        ", "x,2x,1/4       ", "x,y,0          ",    &
16912                      "               ", "               ", "               ",    &
16913                      "               ", "               ", "               ",    &
16914                      "               ", "               ", "               ",    &
16915                      "               ", "               ", "               ",    &
16916                      "               ", "               "/) )
16917       wyckoff_info(230)= wyck_info_type("P 63/M C M  ",11,     &
16918                    (/"0,0,1/4        ", "0,0,0          ", "1/3,2/3,1/4    ",    &
16919                      "1/3,2/3,0      ", "0,0,z          ", "1/2,0,0        ",    &
16920                      "x,0,1/4        ", "1/3,2/3,z      ", "x,2x,0         ",    &
16921                      "x,y,1/4        ", "x,0,z          ", "               ",    &
16922                      "               ", "               ", "               ",    &
16923                      "               ", "               ", "               ",    &
16924                      "               ", "               ", "               ",    &
16925                      "               ", "               ", "               ",    &
16926                      "               ", "               "/) )
16927       wyckoff_info(231)= wyck_info_type("P 63/M M C  ",11,     &
16928                    (/"0,0,0          ", "0,0,1/4        ", "1/3,2/3,1/4    ",    &
16929                      "1/3,2/3,3/4    ", "0,0,z          ", "1/3,2/3,z      ",    &
16930                      "1/2,0,0        ", "x,2x,1/4       ", "x,0,0          ",    &
16931                      "x,y,1/4        ", "x,2x,z         ", "               ",    &
16932                      "               ", "               ", "               ",    &
16933                      "               ", "               ", "               ",    &
16934                      "               ", "               ", "               ",    &
16935                      "               ", "               ", "               ",    &
16936                      "               ", "               "/) )
16937       wyckoff_info(232)= wyck_info_type("P 2 3       ", 9,     &
16938                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,1/2,1/2      ",    &
16939                      "1/2,0,0        ", "x,x,x          ", "x,0,0          ",    &
16940                      "x,0,1/2        ", "x,1/2,0        ", "x,1/2,1/2      ",    &
16941                      "               ", "               ", "               ",    &
16942                      "               ", "               ", "               ",    &
16943                      "               ", "               ", "               ",    &
16944                      "               ", "               ", "               ",    &
16945                      "               ", "               ", "               ",    &
16946                      "               ", "               "/) )
16947       wyckoff_info(233)= wyck_info_type("F 2 3       ", 7,     &
16948                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/4,1/4,1/4    ",    &
16949                      "3/4,3/4,3/4    ", "x,x,x          ", "x,0,0          ",    &
16950                      "x,1/4,1/4      ", "               ", "               ",    &
16951                      "               ", "               ", "               ",    &
16952                      "               ", "               ", "               ",    &
16953                      "               ", "               ", "               ",    &
16954                      "               ", "               ", "               ",    &
16955                      "               ", "               ", "               ",    &
16956                      "               ", "               "/) )
16957       wyckoff_info(234)= wyck_info_type("I 2 3       ", 5,     &
16958                    (/"0,0,0          ", "0,1/2,1/2      ", "x,x,x          ",    &
16959                      "x,0,0          ", "x,1/2,0        ", "               ",    &
16960                      "               ", "               ", "               ",    &
16961                      "               ", "               ", "               ",    &
16962                      "               ", "               ", "               ",    &
16963                      "               ", "               ", "               ",    &
16964                      "               ", "               ", "               ",    &
16965                      "               ", "               ", "               ",    &
16966                      "               ", "               "/) )
16967       wyckoff_info(235)= wyck_info_type("P 21 3      ", 1,     &
16968                    (/"x,x,x          ", "               ", "               ",    &
16969                      "               ", "               ", "               ",    &
16970                      "               ", "               ", "               ",    &
16971                      "               ", "               ", "               ",    &
16972                      "               ", "               ", "               ",    &
16973                      "               ", "               ", "               ",    &
16974                      "               ", "               ", "               ",    &
16975                      "               ", "               ", "               ",    &
16976                      "               ", "               "/) )
16977       wyckoff_info(236)= wyck_info_type("I 21 3      ", 2,     &
16978                    (/"x,x,x          ", "x,0,1/4        ", "               ",    &
16979                      "               ", "               ", "               ",    &
16980                      "               ", "               ", "               ",    &
16981                      "               ", "               ", "               ",    &
16982                      "               ", "               ", "               ",    &
16983                      "               ", "               ", "               ",    &
16984                      "               ", "               ", "               ",    &
16985                      "               ", "               ", "               ",    &
16986                      "               ", "               "/) )
16987       wyckoff_info(237)= wyck_info_type("P M -3      ",11,     &
16988                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,1/2,1/2      ",    &
16989                      "1/2,0,0        ", "x,0,0          ", "x,0,1/2        ",    &
16990                      "x,1/2,0        ", "x,1/2,1/2      ", "x,x,x          ",    &
16991                      "0,y,z          ", "1/2,y,z        ", "               ",    &
16992                      "               ", "               ", "               ",    &
16993                      "               ", "               ", "               ",    &
16994                      "               ", "               ", "               ",    &
16995                      "               ", "               ", "               ",    &
16996                      "               ", "               "/) )
16997       wyckoff_info(238)= wyck_info_type("P N -3:1    ", 7,     &
16998                    (/"0,0,0          ", "1/4,1/4,1/4    ", "3/4,3/4,3/4    ",    &
16999                      "0,1/2,1/2      ", "x,x,x          ", "x,0,0          ",    &
17000                      "x,1/2,0        ", "               ", "               ",    &
17001                      "               ", "               ", "               ",    &
17002                      "               ", "               ", "               ",    &
17003                      "               ", "               ", "               ",    &
17004                      "               ", "               ", "               ",    &
17005                      "               ", "               ", "               ",    &
17006                      "               ", "               "/) )
17007       wyckoff_info(239)= wyck_info_type("P N -3      ", 7,     &
17008                    (/"1/4,1/4,1/4    ", "0,0,0          ", "1/2,1/2,1/2    ",    &
17009                      "1/4,3/4,3/4    ", "x,x,x          ", "x,1/4,1/4      ",    &
17010                      "x,3/4,1/4      ", "               ", "               ",    &
17011                      "               ", "               ", "               ",    &
17012                      "               ", "               ", "               ",    &
17013                      "               ", "               ", "               ",    &
17014                      "               ", "               ", "               ",    &
17015                      "               ", "               ", "               ",    &
17016                      "               ", "               "/) )
17017       wyckoff_info(240)= wyck_info_type("F M -3      ", 8,     &
17018                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/4,1/4,1/4    ",    &
17019                      "0,1/4,1/4      ", "x,0,0          ", "x,x,x          ",    &
17020                      "x,1/4,1/4      ", "0,y,z          ", "               ",    &
17021                      "               ", "               ", "               ",    &
17022                      "               ", "               ", "               ",    &
17023                      "               ", "               ", "               ",    &
17024                      "               ", "               ", "               ",    &
17025                      "               ", "               ", "               ",    &
17026                      "               ", "               "/) )
17027       wyckoff_info(241)= wyck_info_type("F D -3:1    ", 6,     &
17028                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/8,1/8,1/8    ",    &
17029                      "5/8,5/8,5/8    ", "x,x,x          ", "x,0,0          ",    &
17030                      "               ", "               ", "               ",    &
17031                      "               ", "               ", "               ",    &
17032                      "               ", "               ", "               ",    &
17033                      "               ", "               ", "               ",    &
17034                      "               ", "               ", "               ",    &
17035                      "               ", "               ", "               ",    &
17036                      "               ", "               "/) )
17037       wyckoff_info(242)= wyck_info_type("F D -3      ", 6,     &
17038                    (/"1/8,1/8,1/8    ", "5/8,5/8,5/8    ", "0,0,0          ",    &
17039                      "1/2,1/2,1/2    ", "x,x,x          ", "x,1/8,1/8      ",    &
17040                      "               ", "               ", "               ",    &
17041                      "               ", "               ", "               ",    &
17042                      "               ", "               ", "               ",    &
17043                      "               ", "               ", "               ",    &
17044                      "               ", "               ", "               ",    &
17045                      "               ", "               ", "               ",    &
17046                      "               ", "               "/) )
17047       wyckoff_info(243)= wyck_info_type("I M -3      ", 7,     &
17048                    (/"0,0,0          ", "0,1/2,1/2      ", "1/4,1/4,1/4    ",    &
17049                      "x,0,0          ", "x,0,1/2        ", "x,x,x          ",    &
17050                      "0,y,z          ", "               ", "               ",    &
17051                      "               ", "               ", "               ",    &
17052                      "               ", "               ", "               ",    &
17053                      "               ", "               ", "               ",    &
17054                      "               ", "               ", "               ",    &
17055                      "               ", "               ", "               ",    &
17056                      "               ", "               "/) )
17057       wyckoff_info(244)= wyck_info_type("P A -3      ", 3,     &
17058                    (/"0,0,0          ", "1/2,1/2,1/2    ", "x,x,x          ",    &
17059                      "               ", "               ", "               ",    &
17060                      "               ", "               ", "               ",    &
17061                      "               ", "               ", "               ",    &
17062                      "               ", "               ", "               ",    &
17063                      "               ", "               ", "               ",    &
17064                      "               ", "               ", "               ",    &
17065                      "               ", "               ", "               ",    &
17066                      "               ", "               "/) )
17067       wyckoff_info(245)= wyck_info_type("I A -3      ", 4,     &
17068                    (/"0,0,0          ", "1/4,1/4,1/4    ", "x,x,x          ",    &
17069                      "x,0,1/4        ", "               ", "               ",    &
17070                      "               ", "               ", "               ",    &
17071                      "               ", "               ", "               ",    &
17072                      "               ", "               ", "               ",    &
17073                      "               ", "               ", "               ",    &
17074                      "               ", "               ", "               ",    &
17075                      "               ", "               ", "               ",    &
17076                      "               ", "               "/) )
17077       wyckoff_info(246)= wyck_info_type("P 4 3 2     ",10,     &
17078                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,1/2,1/2      ",    &
17079                      "1/2,0,0        ", "x,0,0          ", "x,1/2,1/2      ",    &
17080                      "x,x,x          ", "x,1/2,0        ", "0,y,y          ",    &
17081                      "1/2,y,y        ", "               ", "               ",    &
17082                      "               ", "               ", "               ",    &
17083                      "               ", "               ", "               ",    &
17084                      "               ", "               ", "               ",    &
17085                      "               ", "               ", "               ",    &
17086                      "               ", "               "/) )
17087       wyckoff_info(247)= wyck_info_type("P 42 3 2    ",12,     &
17088                    (/"0,0,0          ", "1/4,1/4,1/4    ", "3/4,3/4,3/4    ",    &
17089                      "0,1/2,1/2      ", "1/4,0,1/2      ", "1/4,1/2,0      ",    &
17090                      "x,x,x          ", "x,0,0          ", "x,0,1/2        ",    &
17091                      "x,1/2,0        ", "1/4,y,-y+1/2   ", "1/4,y,y+1/2    ",    &
17092                      "               ", "               ", "               ",    &
17093                      "               ", "               ", "               ",    &
17094                      "               ", "               ", "               ",    &
17095                      "               ", "               ", "               ",    &
17096                      "               ", "               "/) )
17097       wyckoff_info(248)= wyck_info_type("F 4 3 2    ", 9,     &
17098                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/4,1/4,1/4    ",    &
17099                      "0,1/4,1/4      ", "x,0,0          ", "x,x,x          ",    &
17100                      "0,y,y          ", "1/2,y,y        ", "x,1/4,1/4      ",    &
17101                      "               ", "               ", "               ",    &
17102                      "               ", "               ", "               ",    &
17103                      "               ", "               ", "               ",    &
17104                      "               ", "               ", "               ",    &
17105                      "               ", "               ", "               ",    &
17106                      "               ", "               "/) )
17107       wyckoff_info(249)= wyck_info_type("F 41 3 2    ", 7,     &
17108                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/8,1/8,1/8    ",    &
17109                      "5/8,5/8,5/8    ", "x,x,x          ", "x,0,0          ",    &
17110                      "1/8,y,-y+1/4   ", "               ", "               ",    &
17111                      "               ", "               ", "               ",    &
17112                      "               ", "               ", "               ",    &
17113                      "               ", "               ", "               ",    &
17114                      "               ", "               ", "               ",    &
17115                      "               ", "               ", "               ",    &
17116                      "               ", "               "/) )
17117       wyckoff_info(250)= wyck_info_type("I 4 3 2     ", 9,     &
17118                    (/"0,0,0          ", "0,1/2,1/2      ", "1/4,1/4,1/4    ",    &
17119                      "1/4,1/2,0      ", "x,0,0          ", "x,x,x          ",    &
17120                      "x,1/2,0        ", "0,y,y          ", "1/4,y,-y+1/2   ",    &
17121                      "               ", "               ", "               ",    &
17122                      "               ", "               ", "               ",    &
17123                      "               ", "               ", "               ",    &
17124                      "               ", "               ", "               ",    &
17125                      "               ", "               ", "               ",    &
17126                      "               ", "               "/) )
17127       wyckoff_info(251)= wyck_info_type("P 43 3 2    ", 4,     &
17128                    (/"1/8,1/8,1/8    ", "5/8,5/8,5/8    ", "x,x,x          ",    &
17129                      "1/8,y,-y+1/4   ", "               ", "               ",    &
17130                      "               ", "               ", "               ",    &
17131                      "               ", "               ", "               ",    &
17132                      "               ", "               ", "               ",    &
17133                      "               ", "               ", "               ",    &
17134                      "               ", "               ", "               ",    &
17135                      "               ", "               ", "               ",    &
17136                      "               ", "               "/) )
17137       wyckoff_info(252)= wyck_info_type("P 41 3 2    ", 4,     &
17138                    (/"3/8,3/8,3/8    ", "7/8,7/8,7/8    ", "x,x,x          ",    &
17139                      "1/8,y,y+1/4    ", "               ", "               ",    &
17140                      "               ", "               ", "               ",    &
17141                      "               ", "               ", "               ",    &
17142                      "               ", "               ", "               ",    &
17143                      "               ", "               ", "               ",    &
17144                      "               ", "               ", "               ",    &
17145                      "               ", "               ", "               ",    &
17146                      "               ", "               "/) )
17147       wyckoff_info(253)= wyck_info_type("I 41 3 2    ", 8,     &
17148                    (/"1/8,1/8,1/8    ", "7/8,7/8,7/8    ", "1/8,0,1/4      ",    &
17149                      "5/8,0,1/4      ", "x,x,x          ", "x,0,1/4        ",    &
17150                      "1/8,y,y+1/4    ", "1/8,y,-y+1/4   ", "               ",    &
17151                      "               ", "               ", "               ",    &
17152                      "               ", "               ", "               ",    &
17153                      "               ", "               ", "               ",    &
17154                      "               ", "               ", "               ",    &
17155                      "               ", "               ", "               ",    &
17156                      "               ", "               "/) )
17157       wyckoff_info(254)= wyck_info_type("P -4 3 M    ", 9,     &
17158                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,1/2,1/2      ",    &
17159                      "1/2,0,0        ", "x,x,x          ", "x,0,0          ",    &
17160                      "x,1/2,1/2      ", "x,1/2,0        ", "x,x,z          ",    &
17161                      "               ", "               ", "               ",    &
17162                      "               ", "               ", "               ",    &
17163                      "               ", "               ", "               ",    &
17164                      "               ", "               ", "               ",    &
17165                      "               ", "               ", "               ",    &
17166                      "               ", "               "/) )
17167       wyckoff_info(255)= wyck_info_type("F -4 3 M    ", 8,     &
17168                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/4,1/4,1/4    ",    &
17169                      "3/4,3/4,3/4    ", "x,x,x          ", "x,0,0          ",    &
17170                      "x,1/4,1/4      ", "x,x,z          ", "               ",    &
17171                      "               ", "               ", "               ",    &
17172                      "               ", "               ", "               ",    &
17173                      "               ", "               ", "               ",    &
17174                      "               ", "               ", "               ",    &
17175                      "               ", "               ", "               ",    &
17176                      "               ", "               "/) )
17177       wyckoff_info(256)= wyck_info_type("I -4 3 M    ", 7,     &
17178                    (/"0,0,0          ", "0,1/2,1/2      ", "x,x,x          ",    &
17179                      "1/4,1/2,0      ", "x,0,0          ", "x,1/2,0        ",    &
17180                      "x,x,z          ", "               ", "               ",    &
17181                      "               ", "               ", "               ",    &
17182                      "               ", "               ", "               ",    &
17183                      "               ", "               ", "               ",    &
17184                      "               ", "               ", "               ",    &
17185                      "               ", "               ", "               ",    &
17186                      "               ", "               "/) )
17187       wyckoff_info(257)= wyck_info_type("P -4 3 N    ", 8,     &
17188                    (/"0,0,0          ", "0,1/2,1/2      ", "1/4,1/2,0      ",    &
17189                      "1/4,0,1/2      ", "x,x,x          ", "x,0,0          ",    &
17190                      "x,1/2,0        ", "x,0,1/2        ", "               ",    &
17191                      "               ", "               ", "               ",    &
17192                      "               ", "               ", "               ",    &
17193                      "               ", "               ", "               ",    &
17194                      "               ", "               ", "               ",    &
17195                      "               ", "               ", "               ",    &
17196                      "               ", "               "/) )
17197       wyckoff_info(258)= wyck_info_type("F -4 3 C    ", 7,     &
17198                    (/"0,0,0          ", "1/4,1/4,1/4    ", "0,1/4,1/4      ",    &
17199                      "1/4,0,0        ", "x,x,x          ", "x,0,0          ",    &
17200                      "x,1/4,1/4      ", "               ", "               ",    &
17201                      "               ", "               ", "               ",    &
17202                      "               ", "               ", "               ",    &
17203                      "               ", "               ", "               ",    &
17204                      "               ", "               ", "               ",    &
17205                      "               ", "               ", "               ",    &
17206                      "               ", "               "/) )
17207       wyckoff_info(259)= wyck_info_type("I -4 3 D    ", 4,     &
17208                    (/"3/8,0,1/4      ", "7/8,0,1/4      ", "x,x,x          ",    &
17209                      "x,0,1/4        ", "               ", "               ",    &
17210                      "               ", "               ", "               ",    &
17211                      "               ", "               ", "               ",    &
17212                      "               ", "               ", "               ",    &
17213                      "               ", "               ", "               ",    &
17214                      "               ", "               ", "               ",    &
17215                      "               ", "               ", "               ",    &
17216                      "               ", "               "/) )
17217       wyckoff_info(260)= wyck_info_type("P M -3 M    ",13,     &
17218                    (/"0,0,0          ", "1/2,1/2,1/2    ", "0,1/2,1/2      ",    &
17219                      "1/2,0,0        ", "x,0,0          ", "x,1/2,1/2      ",    &
17220                      "x,x,x          ", "x,1/2,0        ", "0,y,y          ",    &
17221                      "1/2,y,y        ", "0,y,z          ", "1/2,y,z        ",    &
17222                      "x,x,z          ", "               ", "               ",    &
17223                      "               ", "               ", "               ",    &
17224                      "               ", "               ", "               ",    &
17225                      "               ", "               ", "               ",    &
17226                      "               ", "               "/) )
17227       wyckoff_info(261)= wyck_info_type("P N -3 N:1  ", 8,     &
17228                    (/"0,0,0          ", "0,1/2,1/2      ", "1/4,1/4,1/4    ",    &
17229                      "1/4,0,1/2      ", "x,0,0          ", "x,x,x          ",    &
17230                      "x,0,1/2        ", "0,y,y          ", "               ",    &
17231                      "               ", "               ", "               ",    &
17232                      "               ", "               ", "               ",    &
17233                      "               ", "               ", "               ",    &
17234                      "               ", "               ", "               ",    &
17235                      "               ", "               ", "               ",    &
17236                      "               ", "               "/) )
17237       wyckoff_info(262)= wyck_info_type("P N -3 N    ", 8,     &
17238                    (/"1/4,1/4,1/4    ", "3/4,1/4,1/4    ", "0,0,0          ",    &
17239                      "0,3/4,1/4      ", "x,1/4,1/4      ", "x,x,x          ",    &
17240                      "x,3/4,1/4      ", "1/4,y,y        ", "               ",    &
17241                      "               ", "               ", "               ",    &
17242                      "               ", "               ", "               ",    &
17243                      "               ", "               ", "               ",    &
17244                      "               ", "               ", "               ",    &
17245                      "               ", "               ", "               ",    &
17246                      "               ", "               "/) )
17247       wyckoff_info(263)= wyck_info_type("P M -3 N    ",11,     &
17248                    (/"0,0,0          ", "0,1/2,1/2      ", "1/4,0,1/2      ",    &
17249                      "1/4,1/2,0      ", "1/4,1/4,1/4    ", "x,0,0          ",    &
17250                      "x,0,1/2        ", "x,1/2,0        ", "x,x,x          ",    &
17251                      "1/4,y,y+1/2    ", "0,y,z          ", "               ",    &
17252                      "               ", "               ", "               ",    &
17253                      "               ", "               ", "               ",    &
17254                      "               ", "               ", "               ",    &
17255                      "               ", "               ", "               ",    &
17256                      "               ", "               "/) )
17257       wyckoff_info(264)= wyck_info_type("P N -3 M:1  ",11,     &
17258                    (/"0,0,0          ", "1/4,1/4,1/4    ", "3/4,3/4,3/4    ",    &
17259                      "0,1/2,1/2      ", "x,x,x          ", "1/4,0,1/2      ",    &
17260                      "x,0,0          ", "x,0,1/2        ", "1/4,y,-y+1/2   ",    &
17261                      "1/4,y,y+1/2    ", "x,x,z          ", "               ",    &
17262                      "               ", "               ", "               ",    &
17263                      "               ", "               ", "               ",    &
17264                      "               ", "               ", "               ",    &
17265                      "               ", "               ", "               ",    &
17266                      "               ", "               "/) )
17267       wyckoff_info(265)= wyck_info_type("P N -3 M    ",11,     &
17268                    (/"1/4,1/4,1/4    ", "0,0,0          ", "1/2,1/2,1/2    ",    &
17269                      "1/4,3/4,3/4    ", "x,x,x          ", "1/2,1/4,3/4    ",    &
17270                      "x,1/4,1/4      ", "x,1/4,3/4      ", "1/2,y,y+1/2    ",    &
17271                      "1/2,y,-y       ", "x,x,z          ", "               ",    &
17272                      "               ", "               ", "               ",    &
17273                      "               ", "               ", "               ",    &
17274                      "               ", "               ", "               ",    &
17275                      "               ", "               ", "               ",    &
17276                      "               ", "               "/) )
17277       wyckoff_info(266)= wyck_info_type("F M -3 M    ",11,     &
17278                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/4,1/4,1/4    ",    &
17279                      "0,1/4,1/4      ", "x,0,0          ", "x,x,x          ",    &
17280                      "x,1/4,1/4      ", "0,y,y          ", "1/2,y,y        ",    &
17281                      "0,y,z          ", "x,x,z          ", "               ",    &
17282                      "               ", "               ", "               ",    &
17283                      "               ", "               ", "               ",    &
17284                      "               ", "               ", "               ",    &
17285                      "               ", "               ", "               ",    &
17286                      "               ", "               "/) )
17287       wyckoff_info(267)= wyck_info_type("F M -3 C    ", 9,     &
17288                    (/"1/4,1/4,1/4    ", "0,0,0          ", "1/4,0,0        ",    &
17289                      "0,1/4,1/4      ", "x,0,0          ", "x,1/4,1/4      ",    &
17290                      "x,x,x          ", "1/4,y,y        ", "0,y,z          ",    &
17291                      "               ", "               ", "               ",    &
17292                      "               ", "               ", "               ",    &
17293                      "               ", "               ", "               ",    &
17294                      "               ", "               ", "               ",    &
17295                      "               ", "               ", "               ",    &
17296                      "               ", "               "/) )
17297       wyckoff_info(268)= wyck_info_type("F D -3 M:1  ", 8,     &
17298                    (/"0,0,0          ", "1/2,1/2,1/2    ", "1/8,1/8,1/8    ",    &
17299                      "5/8,5/8,5/8    ", "x,x,x          ", "x,0,0          ",    &
17300                      "x,x,z          ", "1/8,y,-y+1/4   ", "               ",    &
17301                      "               ", "               ", "               ",    &
17302                      "               ", "               ", "               ",    &
17303                      "               ", "               ", "               ",    &
17304                      "               ", "               ", "               ",    &
17305                      "               ", "               ", "               ",    &
17306                      "               ", "               "/) )
17307       wyckoff_info(269)= wyck_info_type("F D -3 M    ", 8,     &
17308                    (/"1/8,1/8,1/8    ", "3/8,3/8,3/8    ", "0,0,0          ",    &
17309                      "1/2,1/2,1/2    ", "x,x,x          ", "x,1/8,1/8      ",    &
17310                      "x,x,z          ", "0,y,-y         ", "               ",    &
17311                      "               ", "               ", "               ",    &
17312                      "               ", "               ", "               ",    &
17313                      "               ", "               ", "               ",    &
17314                      "               ", "               ", "               ",    &
17315                      "               ", "               ", "               ",    &
17316                      "               ", "               "/) )
17317       wyckoff_info(270)= wyck_info_type("F D -3 C:1  ", 7,     &
17318                    (/"0,0,0          ", "1/8,1/8,1/8    ", "3/8,3/8,3/8    ",    &
17319                      "1/4,0,0        ", "x,x,x          ", "x,0,0          ",    &
17320                      "1/8,y,-y+1/4   ", "               ", "               ",    &
17321                      "               ", "               ", "               ",    &
17322                      "               ", "               ", "               ",    &
17323                      "               ", "               ", "               ",    &
17324                      "               ", "               ", "               ",    &
17325                      "               ", "               ", "               ",    &
17326                      "               ", "               "/) )
17327       wyckoff_info(271)= wyck_info_type("F D -3 C    ", 7,     &
17328                    (/"1/8,1/8,1/8    ", "1/4,1/4,1/4    ", "0,0,0          ",    &
17329                      "7/8,1/8,1/8    ", "x,x,x          ", "x,1/8,1/8      ",    &
17330                      "1/4,y,-y       ", "               ", "               ",    &
17331                      "               ", "               ", "               ",    &
17332                      "               ", "               ", "               ",    &
17333                      "               ", "               ", "               ",    &
17334                      "               ", "               ", "               ",    &
17335                      "               ", "               ", "               ",    &
17336                      "               ", "               "/) )
17337      wyckoff_info(272)= wyck_info_type("I M -3 M    ",11,     &
17338                    (/"0,0,0          ", "0,1/2,1/2      ", "1/4,1/4,1/4    ",    &
17339                      "1/4,0,1/2      ", "x,0,0          ", "x,x,x          ",    &
17340                      "x,0,1/2        ", "0,y,y          ", "1/4,y,-y+1/2   ",    &
17341                      "0,y,z          ", "x,x,z          ", "               ",    &
17342                      "               ", "               ", "               ",    &
17343                      "               ", "               ", "               ",    &
17344                      "               ", "               ", "               ",    &
17345                      "               ", "               ", "               ",    &
17346                      "               ", "               "/) )
17347       wyckoff_info(273)= wyck_info_type("I A -3 D    ", 7,     &
17348                    (/"0,0,0          ", "1/8,1/8,1/8    ", "1/8,0,1/4      ",    &
17349                      "3/8,0,1/4      ", "x,x,x          ", "x,0,1/4        ",    &
17350                      "1/8,y,-y+1/4   ", "               ", "               ",    &
17351                      "               ", "               ", "               ",    &
17352                      "               ", "               ", "               ",    &
17353                      "               ", "               ", "               ",    &
17354                      "               ", "               ", "               ",    &
17355                      "               ", "               ", "               ",    &
17356                      "               ", "               "/) )
17357
17358
17359       return
17360    End Subroutine Set_Wyckoff_Info
17361
17362 End Module CFML_Symmetry_Tables
17363!!-------------------------------------------------------
17364!!---- Crystallographic Fortran Modules Library (CrysFML)
17365!!-------------------------------------------------------
17366!!---- The CrysFML project is distributed under LGPL. In agreement with the
17367!!---- Intergovernmental Convention of the ILL, this software cannot be used
17368!!---- in military applications.
17369!!----
17370!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
17371!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
17372!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
17373!!----
17374!!---- Authors: Juan Rodriguez-Carvajal (ILL)
17375!!----          Javier Gonzalez-Platas  (ULL)
17376!!----
17377!!---- Contributors: Laurent Chapon     (ILL)
17378!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
17379!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
17380!!----               Tierry Roisnel     (CDIFX,Rennes France)
17381!!----               Eric Pellegrini    (ILL)
17382!!----
17383!!---- This library is free software; you can redistribute it and/or
17384!!---- modify it under the terms of the GNU Lesser General Public
17385!!---- License as published by the Free Software Foundation; either
17386!!---- version 3.0 of the License, or (at your option) any later version.
17387!!----
17388!!---- This library is distributed in the hope that it will be useful,
17389!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
17390!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17391!!---- Lesser General Public License for more details.
17392!!----
17393!!---- You should have received a copy of the GNU Lesser General Public
17394!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
17395!!----
17396!!----
17397!!---- MODULE: CFML_Scattering_Chemical_Tables
17398!!----
17399!!----   INFO: Tabulated information about atomic chemical and scattering data. A set of fortran
17400!!----         TYPEs and variables are defined. Tables are declared as allocatable arrays of
17401!!----         types and they are charged only if the setting (initialising) procedures are called.
17402!!----         It is convenient in a particular program using this moduled to call the "removing"
17403!!----         procedures (making a deallocation) to liberate memory after the required information
17404!!----         is found and stored in user-defined variables.
17405!!----
17406!!---- HISTORY
17407!!----    Updated: 04/03/2011
17408!!----
17409!!---- DEPENDENCIES
17410!!--++    Use CFML_GlobalDeps,       only: Cp
17411!!--++    Use CFML_String_Utilities, only: L_Case, U_Case
17412!!----
17413!!---- VARIABLES
17414!!----    ANOMALOUS_SC_TYPE
17415!!----    ANOMALOUS_SCFAC
17416!!----    CHEM_INFO_TYPE
17417!!----    CHEM_INFO
17418!!----    MAGNETIC_FORM_TYPE
17419!!----    MAGNETIC_FORM
17420!!----    MAGNETIC_J2
17421!!----    MAGNETIC_J4
17422!!----    MAGNETIC_J6
17423!!----    NUM_CHEM_INFO
17424!!----    NUM_DELTA_FP
17425!!----    NUM_MAG_FORM
17426!!----    NUM_MAG_J2
17427!!----    NUM_MAG_J4
17428!!----    NUM_MAG_J6
17429!!----    NUM_XRAY_FORM
17430!!----    XRAY_FORM_TYPE
17431!!----    XRAY_FORM
17432!!----    XRAY_WAVELENGTH_TYPE
17433!!----    XRAY_WAVELENGTHS
17434!!----
17435!!---- PROCEDURES
17436!!----    Functions:
17437!!----
17438!!----    Subroutines:
17439!!----       GET_ATOMIC_MASS
17440!!----       GET_ATOMIC_VOL
17441!!----       GET_CHEMSYMB
17442!!----       GET_COVALENT_RADIUS
17443!!----       GET_FERMI_LENGTH
17444!!----       GET_ABS_XS
17445!!----       GET_INC_XS
17446!!----       GET_IONIC_RADIUS
17447!!----       REMOVE_CHEM_INFO
17448!!----       REMOVE_DELTA_FP_FPP
17449!!----       REMOVE_MAGNETIC_FORM
17450!!----       REMOVE_XRAY_FORM
17451!!----       SET_CHEM_INFO
17452!!----       SET_DELTA_FP_FPP
17453!!----       SET_MAGNETIC_FORM
17454!!----       SET_XRAY_FORM
17455!!----
17456!!
17457 Module CFML_Scattering_Chemical_Tables
17458    !---- Use Modules ----!
17459    Use CFML_GlobalDeps,       only: Cp
17460    Use CFML_String_Utilities, only: U_Case, L_Case
17461
17462    implicit none
17463
17464    private
17465
17466    !---- List of public subroutines ----!
17467    public :: Get_Atomic_Mass, Get_Atomic_Vol, Get_ChemSymb, Get_Covalent_radius, Get_Ionic_radius
17468    public :: Get_Fermi_Length, Get_Abs_Xs, Get_Inc_Xs
17469    public :: Remove_Chem_Info, Remove_Delta_Fp_Fpp, Remove_Magnetic_Form, Remove_Xray_Form
17470    public :: Set_Chem_Info, Set_Delta_Fp_Fpp, Set_Magnetic_Form, Set_Xray_Form
17471
17472    !---- Definitions ----!
17473
17474    !!----
17475    !!---- TYPE, PUBLIC :: ANOMALOUS_SC_TYPE
17476    !!--..
17477    !!---- Type, public :: Anomalous_Sc_Type
17478    !!----    character (len= 2)           :: Symb  ! Symbol of the Chemical species
17479    !!----    real(kind=cp), dimension(5)  :: Fp    ! Delta Fp
17480    !!----    real(kind=cp), dimension(5)  :: Fpp   ! Delta Fpp
17481    !!---- End Type Anomalous_Sc_Type
17482    !!----
17483    !!---- Update: February - 2005
17484    !!
17485    Type, public :: Anomalous_Sc_Type
17486       character(len= 2)            :: Symb
17487       real(kind=cp), dimension(5)  :: Fp
17488       real(kind=cp), dimension(5)  :: Fpp
17489    End Type Anomalous_Sc_Type
17490
17491    !!----
17492    !!---- ANOMALOUS_SCFAC
17493    !!----    Type(Anomalous_Sc_Type), allocatable, dimension(:), public :: Anomalous_ScFac
17494    !!----
17495    !!----    Table of Delta-Fp and Delta-Fpp for 5 common radiations.
17496    !!----    The order is the following:
17497    !!--<<
17498    !!----                          1         2         3          4          5
17499    !!----        Wavelenghts:     Cr        Fe        Cu         Mo         Ag
17500    !!----             Lambda   2.28962   1.93597   1.54051    0.70926    0.556363
17501    !!-->>
17502    !!----
17503    !!---- Update: February - 2005
17504    !!
17505    Type(Anomalous_Sc_Type), allocatable, dimension(:), public :: Anomalous_ScFac
17506
17507    !!----
17508    !!---- TYPE, PUBLIC :: CHEM_INFO_TYPE
17509    !!--..
17510    !!---- Type, public :: Chem_Info_Type
17511    !!----    character (len= 2)         :: Symb     ! Symbol of the Element
17512    !!----    character (len=12)         :: Name     ! Name of the Element
17513    !!----    integer                    :: Z        ! Atomic Number
17514    !!----    real(kind=cp)              :: AtWe     ! Atomic weight
17515    !!----    real(kind=cp)              :: RCov     ! Covalent Radio
17516    !!----    real(kind=cp)              :: RWaals   ! van der Waals Radio
17517    !!----    real(kind=cp)              :: VAtm     ! Atomic volumen
17518    !!----    integer, dimension(5)      :: Oxid     ! Oxidation State
17519    !!----    real(kind=cp), dimension(5):: Rion     ! Ionic Radio (depending of the oxidation)
17520    !!----    real(kind=cp)              :: SctF     ! Scattering length Fermi
17521    !!----    real(kind=cp)              :: SedInc   ! Incoherent Scattering Neutron cross-section (barns -> [10**(-24) cm**2] )
17522    !!----    real(kind=cp)              :: Sea      ! Neutron Absorption cross-section ( barns, for v= 2200m/s, l(A)=3.95/v (km/s) )
17523    !!---- End Type Chem_Info_Type
17524    !!----
17525    !!---- Update: February - 2005
17526    !!
17527    Type, public :: Chem_Info_Type
17528       character (len= 2)         :: Symb          ! Symbol of the Element
17529       character (len=12)         :: Name          ! Name of the Element
17530       integer                    :: Z             ! Atomic Number
17531       real(kind=cp)              :: AtWe          ! Atomic weight
17532       real(kind=cp)              :: RCov          ! Covalent Radius
17533       real(kind=cp)              :: RWaals        ! van der Waals Radius
17534       real(kind=cp)              :: VAtm          ! Atomic volumen
17535       integer, dimension(5)      :: Oxid          ! Oxidation State
17536       real(kind=cp), dimension(5):: Rion          ! Ionic Radius (depending of the oxidation)
17537       real(kind=cp)              :: SctF          ! Fermi length [10**(-12) cm]
17538       real(kind=cp)              :: SedInc        ! Incoherent Scattering Neutron cross-section (barns -> [10**(-24) cm**2] )
17539       real(kind=cp)              :: Sea           ! Neutron Absorption cross-section ( barns, for v= 2200m/s, l(A)=3.95/v (km/s) )
17540    End Type Chem_Info_Type
17541
17542    !!----
17543    !!---- CHEM_INFO
17544    !!----    Type (Chem_Info_Type), allocatable, dimension(:), public :: Chem_Info
17545    !!----
17546    !!----    Tabulated chemical data according to the items specified in the definition of Chem_Info_Type.
17547    !!----
17548    !!---- Update: February - 2005
17549    !!
17550    Type(Chem_Info_Type), allocatable, dimension(:), public :: Chem_Info
17551
17552    !!----
17553    !!---- TYPE :: MAGNETIC_FORM_TYPE
17554    !!--..
17555    !!---- Type, public :: Magnetic_Form_Type
17556    !!----    character (len= 4)          :: Symb   ! Symbol of the Chemical species
17557    !!----    real(kind=cp), dimension(7) :: SctM   ! Scattering Factors
17558    !!---- End Type Magnetic_Form_Type
17559    !!----
17560    !!---- Update: February - 2005
17561    !!
17562    Type, public :: Magnetic_Form_Type
17563       character (len= 4)         :: Symb         ! Symbol of the Chemical species
17564       real(kind=cp), dimension(7):: SctM
17565    End Type Magnetic_Form_Type
17566
17567    !!----
17568    !!---- MAGNETIC_FORM
17569    !!----    Type (Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_Form
17570    !!----
17571    !!----    Tabulated magnetic form factor data
17572    !!----
17573    !!---- Update: February - 2005
17574    !!
17575    Type(Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_Form
17576
17577    !!----
17578    !!---- MAGNETIC_J2
17579    !!----    Type (Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_j2
17580    !!----
17581    !!----    Tabulated magnetic form factor J2
17582    !!----
17583    !!---- Update: February - 2005
17584    !!
17585    Type(Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_j2
17586
17587    !!----
17588    !!---- MAGNETIC_J4
17589    !!----    Type (Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_J4
17590    !!----
17591    !!----    Tabulated magnetic form factor J4
17592    !!----
17593    !!---- Update: February - 2005
17594    !!
17595    Type(Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_j4
17596
17597    !!----
17598    !!---- MAGNETIC_J6
17599    !!----    Type (Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_J6
17600    !!----
17601    !!----    Tabulated magnetic form factor J6
17602    !!----
17603    !!---- Update: February - 2005
17604    !!
17605    Type(Magnetic_Form_Type), allocatable, dimension(:), public :: Magnetic_j6
17606
17607    !!----
17608    !!---- NUM_CHEM_INFO
17609    !!----    integer, parameter, public :: Num_Chem_Info = 108
17610    !!----
17611    !!----    Number of total Chem_info Data
17612    !!----
17613    !!---- Update: February - 2005
17614    !!
17615    integer, parameter, public :: Num_Chem_Info = 108
17616
17617    !!----
17618    !!---- NUM_DELTA_FP
17619    !!----    integer, parameter, public :: Num_Delta_Fp  = 98
17620    !!----
17621    !!----    Number of total Delta (Fp,Fpp) Data
17622    !!----
17623    !!---- Update: February - 2005
17624    !!
17625    integer, parameter, public :: Num_Delta_Fp  = 98
17626
17627    !!----
17628    !!---- NUM_MAG_FORM
17629    !!----    integer, parameter, public :: Num_Mag_Form  = 117
17630    !!----
17631    !!----    Number of total Magnetic_Form Data
17632    !!----
17633    !!---- Update: February - 2005
17634    !!
17635    integer, parameter, public :: Num_Mag_Form  = 119
17636
17637    !!----
17638    !!---- NUM_MAG_J2
17639    !!----    integer, parameter, public :: Num_Mag_J2 = 97
17640    !!----
17641    !!----    Number of <j2> Magnetic_Form Data
17642    !!----
17643    !!---- Update: February - 2005
17644    !!
17645    integer, parameter, public :: Num_Mag_j2  = 97
17646
17647    !!----
17648    !!---- NUM_MAG_J4
17649    !!----    integer, parameter, public :: Num_Mag_J4 = 97
17650    !!----
17651    !!----    Number of <j4> Magnetic_Form Data
17652    !!----
17653    !!---- Update: February - 2005
17654    !!
17655    integer, parameter, public :: Num_Mag_j4  = 97
17656
17657    !!----
17658    !!---- NUM_MAG_J6
17659    !!----    integer, parameter, public :: Num_Mag_J6 = 39
17660    !!----
17661    !!----    Number of <j5> Magnetic_Form Data
17662    !!----
17663    !!---- Update: February - 2005
17664    !!
17665    integer, parameter, public :: Num_Mag_j6  = 39
17666
17667    !!----
17668    !!---- NUM_XRAY_FORM
17669    !!----    integer, parameter, public :: Num_Xray_Form = 214
17670    !!----
17671    !!----    Number of total Xray_Form Data
17672    !!----
17673    !!---- Update: February - 2005
17674    !!
17675    integer, parameter, public :: Num_Xray_Form = 214
17676
17677    !!----
17678    !!---- TYPE :: XRAY_FORM_TYPE
17679    !!--..
17680    !!---- Type, public :: Xray_Form_Type
17681    !!----    character (len= 4)         :: Symb  ! Symbol of the Chemical species
17682    !!----    integer                    :: Z     ! Atomic Number
17683    !!----    real(kind=cp), dimension(4):: a     ! Coefficients for calculating the X-ray scattering factors
17684    !!----    real(kind=cp), dimension(4):: b     ! f(s) = Sum_{i=1,4} { a(i) exp(-b(i)*s^2) } + c
17685    !!----    real(kind=cp)              :: c     ! s=sinTheta/Lambda
17686    !!---- End Type Xray_Form_Type
17687    !!----
17688    !!---- Update: February - 2005
17689    !!
17690    Type, public :: Xray_Form_Type
17691       character (len= 4)         :: Symb
17692       integer                    :: Z
17693       real(kind=cp), dimension(4):: a
17694       real(kind=cp), dimension(4):: b
17695       real(kind=cp)              :: c
17696    End Type Xray_Form_Type
17697
17698    !!----
17699    !!---- XRAY_FORM
17700    !!----    Type (Xray_Form_Type), allocatable, dimension(:), public :: Xray_Form
17701    !!----
17702    !!----    Tabulated Xray scattering factor coefficients
17703    !!----
17704    !!---- Update: February - 2005
17705    !!
17706    Type(Xray_Form_Type), allocatable, dimension(:), public :: Xray_Form
17707
17708    !!----
17709    !!---- TYPE :: XRAY_WAVELENGTH_TYPE
17710    !!--..
17711    !!---- Type, public :: Xray_Wavelength_Type
17712    !!----    character (len= 2)                :: Symb  ! Symbol of the Chemical species
17713    !!----    real(kind=cp), dimension(2)       :: Kalfa ! K-Serie for X-ray
17714    !!----    real(kind=cp)                     :: Kbeta ! K-Serie for X-ray
17715    !!---- End Type Xray_Wavelength_Type
17716    !!----
17717    !!---- Update: February - 2005
17718    !!
17719    Type, public :: Xray_Wavelength_Type
17720       character (len= 2)         :: Symb
17721       real(kind=cp), dimension(2):: Kalfa
17722       real(kind=cp)              :: Kbeta
17723    End Type Xray_Wavelength_Type
17724
17725    !!----
17726    !!---- XRAY_WAVELENGTHS
17727    !!----    Type (Xray_Wavelength_Type), dimension(7), public :: Xray_Wavelengths
17728    !!----
17729    !!----    Tabulated K-Series for Xray
17730    !!----
17731    !!---- Update: February - 2005
17732    !!
17733    Type(Xray_Wavelength_Type), dimension(7), public :: Xray_Wavelengths =(/                            &
17734                                                Xray_Wavelength_type("CR",(/2.28988,2.29428/),2.08480), &
17735                                                Xray_Wavelength_type("FE",(/1.93631,1.94043/),1.75650), &
17736                                                Xray_Wavelength_type("CU",(/1.54059,1.54431/),1.39220), &
17737                                                Xray_Wavelength_type("MO",(/0.70932,0.71360/),0.63225), &
17738                                                Xray_Wavelength_type("AG",(/0.55942,0.56380/),0.49708), &
17739                                                Xray_Wavelength_type("CO",(/1.78919,1.79321/),1.62083), &
17740                                                Xray_Wavelength_type("NI",(/1.65805,1.66199/),1.50017)  /)
17741
17742 Contains
17743
17744    !---------------------!
17745    !---- Subroutines ----!
17746    !---------------------!
17747
17748    !!----
17749    !!---- Subroutine Get_Atomic_Mass(Atm,Mass)
17750    !!----    character(len=2), intent(in)  :: Atm
17751    !!----    real(kind=cp),    intent(out) :: Mass
17752    !!----
17753    !!----    Provides the atomic mass given the chemical symbol of the element
17754    !!----    In case of problems the returned mass is ZERO.
17755    !!----
17756    !!---- Update: February - 2005
17757    !!
17758    Subroutine Get_Atomic_Mass(atm,mass)
17759       !---- Arguments ----!
17760       character(len=2), intent (in) :: atm
17761       real(kind=cp),    intent(out) :: Mass
17762
17763       !---- Local variables ----!
17764       character(len=2) :: atm_car
17765       integer :: i
17766
17767       mass=0.0
17768       atm_car=u_case(atm)
17769       if (.not. allocated(chem_info) ) call set_chem_info()
17770
17771       do i=1,Num_Chem_Info
17772          if (index(atm_car,chem_info(i)%Symb) /=0) then
17773             mass=chem_info(i)%AtWe
17774             exit
17775          end if
17776       end do
17777
17778       return
17779    End Subroutine Get_Atomic_Mass
17780
17781    !!----
17782    !!---- Subroutine Get_Atomic_Vol(Atm,Vol)
17783    !!----    character(len=2), intent(in)  :: Atm
17784    !!----    real(kind=cp),    intent(out) :: Vol
17785    !!----
17786    !!----    Provides the atomic volume given the chemical symbol of the element
17787    !!----    In case of problems the returned Volume is ZERO.
17788    !!----
17789    !!---- Update: March- 2013
17790    !!
17791    Subroutine Get_Atomic_Vol(atm,vol)
17792       !---- Arguments ----!
17793       character(len=2), intent (in) :: atm
17794       real(kind=cp),    intent(out) :: Vol
17795
17796       !---- Local variables ----!
17797       character(len=2) :: atm_car
17798       integer :: i
17799
17800       vol=0.0
17801       atm_car=u_case(atm)
17802       if (.not. allocated(chem_info) ) call set_chem_info()
17803
17804       do i=1,Num_Chem_Info
17805          if (index(atm_car,chem_info(i)%Symb) /=0) then
17806             vol=chem_info(i)%VAtm
17807             exit
17808          end if
17809       end do
17810
17811       return
17812    End Subroutine Get_Atomic_Vol
17813
17814    !!----
17815    !!---- Subroutine Get_ChemSymb(Label, ChemSymb, Z)
17816    !!----   character(len=*),  intent(in) :: Label    ! Label
17817    !!----   character(len=*),  intent(out):: ChemSymb ! Chemical Symbol
17818    !!----   integer, optional, intent(out):: Z        ! Atomic number
17819    !!----
17820    !!----  Subroutine to get the chemical symbol from label and optionally
17821    !!----  the atomic number
17822    !!----
17823    !!---- Update: February - 2005
17824    !!
17825    Subroutine Get_ChemSymb(Label, ChemSymb, Z)
17826       !---- Argument ----!
17827       character(len=*),  intent(in) :: Label    ! Label
17828       character(len=*),  intent(out):: ChemSymb ! Chemical Symbol
17829       integer, optional, intent(out):: Z        ! Atomic number
17830
17831       !---- Local variables ----!
17832       character(len=*),  parameter :: parcar="1234567890+-."
17833       character(len=2)             :: car
17834       integer                      :: npos
17835
17836       ChemSymb="**"
17837       car=adjustl(label)
17838       npos=index(parcar,car(2:2))
17839       if (npos /=0) car(2:2)=" "
17840       car=u_case(car)
17841       car(2:2)=l_case(car(2:2))
17842       ChemSymb=car
17843
17844       if (present(z)) then
17845          if (.not. allocated(chem_info) ) call set_chem_info()
17846          car=u_case(chemsymb)
17847          do npos=1,num_chem_info
17848             if (car == Chem_Info(npos)%Symb) then
17849                Z=Chem_Info(npos)%Z
17850                exit
17851             end if
17852          end do
17853       end if
17854
17855       return
17856    End Subroutine Get_ChemSymb
17857
17858    !!----
17859    !!---- Subroutine Get_Covalent_Radius(nam,rad)
17860    !!----    character(len=*), intent (in) :: nam
17861    !!----    real(kind=cp),    intent(out) :: rad
17862    !!----
17863    !!----    Provides the covalent radius given the chemical symbol of the element
17864    !!----    In case of problems the returned radius is 1.4 angstroms.
17865    !!----
17866    !!---- Update: February - 2005
17867    !!
17868    Subroutine Get_Covalent_Radius(nam,rad)
17869       !---- Arguments ----!
17870       character(len=*), intent (in) :: nam
17871       real(kind=cp),    intent(out) :: rad
17872
17873       !---- Local variables ----!
17874       character(len=2) :: atm_car
17875       integer          :: i
17876
17877       rad=1.4
17878       atm_car=u_case(nam(1:2))
17879       if (atm_car(2:2) > "Z" .or. atm_car(2:2) < "A") atm_car(2:2)=" "
17880       if (.not. allocated(chem_info) ) call set_chem_info()
17881       do i=1,Num_Chem_Info
17882          if (index(atm_car,chem_info(i)%Symb) /=0) then
17883             rad=chem_info(i)%RCov
17884             exit
17885          end if
17886       end do
17887
17888       return
17889    End Subroutine Get_Covalent_Radius
17890
17891    !!----
17892    !!---- Subroutine Get_Fermi_Length(nam,b)
17893    !!----    character(len=*), intent (in) :: nam
17894    !!----    real(kind=cp),    intent(out) :: b
17895    !!----
17896    !!----    Provides the Fermi length (in 10-12 cm) given the chemical
17897    !!----    symbol of the element. In case of problems the returned Fermi
17898    !!----    length is 0.0 10-12 cm.
17899    !!----
17900    !!---- Update: February - 2005
17901    !!
17902    Subroutine Get_Fermi_Length(nam,b)
17903       !---- Arguments ----!
17904       character(len=*), intent (in) :: nam
17905       real(kind=cp),    intent(out) :: b
17906
17907       !---- Local variables ----!
17908       character(len=2) :: atm_car
17909       integer          :: i
17910
17911       b=0.0
17912       atm_car=u_case(nam(1:2))
17913       if (atm_car(2:2) > "Z" .or. atm_car(2:2) < "A") atm_car(2:2)=" "
17914       if (.not. allocated(chem_info) ) call set_chem_info()
17915       do i=1,Num_Chem_Info
17916          if (index(atm_car,chem_info(i)%Symb) /=0) then
17917             b=chem_info(i)%SctF
17918             exit
17919          end if
17920       end do
17921
17922       return
17923    End Subroutine Get_Fermi_Length
17924
17925    !!----
17926    !!---- Subroutine Get_Inc_Xs(nam,u)
17927    !!----    character(len=*), intent (in) :: nam
17928    !!----    real(kind=cp),    intent(out) :: u
17929    !!----
17930    !!----    Provides incoherent scattering neutron cross-section (barns -> [10**(-24) cm**2] )
17931    !!----    for given chemical symbol of the element. In case of problems the returned value is 0.0.
17932    !!----
17933    !!----
17934    !!---- Update: Mai - 2013
17935    !!
17936
17937    Subroutine Get_Inc_Xs(nam,u)
17938       !---- Arguments ----!
17939       character(len=*), intent (in) :: nam
17940       real(kind=cp),    intent(out) :: u
17941
17942       !---- Local variables ----!
17943       character(len=2) :: atm_car
17944       integer          :: i
17945
17946       u=0.0
17947       atm_car=u_case(nam(1:2))
17948       if (atm_car(2:2) > "Z" .or. atm_car(2:2) < "A") atm_car(2:2)=" "
17949       if (.not. allocated(chem_info) ) call set_chem_info()
17950       do i=1,Num_Chem_Info
17951          if (index(atm_car,chem_info(i)%Symb) /=0) then
17952             u=chem_info(i)%SedInc
17953             exit
17954          end if
17955       end do
17956
17957       return
17958    End Subroutine Get_Inc_Xs
17959
17960    !!----
17961    !!---- Subroutine Get_Abs_Xs(nam,u)
17962    !!----    character(len=*), intent (in) :: nam
17963    !!----    real(kind=cp),    intent(out) :: u
17964    !!----
17965    !!----    Provides the absorption cross-section ( barns, for v= 2200m/s, l(A)=3.95/v (km/s) )
17966    !!----    for given chemical symbol of the element. In case of problems the returned value is 0.0.
17967    !!----
17968    !!----
17969    !!---- Update: April - 2013
17970    !!
17971
17972    Subroutine Get_Abs_Xs(nam,u)
17973       !---- Arguments ----!
17974       character(len=*), intent (in) :: nam
17975       real(kind=cp),    intent(out) :: u
17976
17977       !---- Local variables ----!
17978       character(len=2) :: atm_car
17979       integer          :: i
17980
17981       u=0.0
17982       atm_car=u_case(nam(1:2))
17983       if (atm_car(2:2) > "Z" .or. atm_car(2:2) < "A") atm_car(2:2)=" "
17984       if (.not. allocated(chem_info) ) call set_chem_info()
17985       do i=1,Num_Chem_Info
17986          if (index(atm_car,chem_info(i)%Symb) /=0) then
17987             u=chem_info(i)%Sea
17988             exit
17989          end if
17990       end do
17991
17992       return
17993    End Subroutine Get_Abs_Xs
17994
17995    !!----
17996    !!---- Subroutine Get_Ionic_Radius(nam,valence,rad)
17997    !!----    character(len=*), intent (in) :: nam
17998    !!----    integer,          intent (in) :: valence
17999    !!----    real(kind=cp),    intent(out) :: rad
18000    !!----
18001    !!----    Provides the ionic radius given the chemical symbol of the element
18002    !!----    and the valence as an integer. In case of problems the returned radius is 0.0 angstroms.
18003    !!----
18004    !!---- Update: February - 2005
18005    !!
18006    Subroutine Get_Ionic_Radius(nam,valence,rad)
18007       !---- Arguments ----!
18008       character(len=*), intent (in) :: nam
18009       integer,          intent (in) :: valence
18010       real(kind=cp),    intent(out) :: rad
18011
18012       !---- Local variables ----!
18013       character(len=2) :: atm_car
18014       integer          :: i,j
18015
18016       rad=0.0
18017       atm_car=u_case(nam(1:2))
18018       if (atm_car(2:2) > "Z" .or. atm_car(2:2) < "A") atm_car(2:2)=" "
18019       if (.not. allocated(chem_info) ) call set_chem_info()
18020       do i=1,Num_Chem_Info
18021          if (index(atm_car,chem_info(i)%Symb) /=0) then
18022             do j=1,5
18023                if (valence == chem_info(i)%oxid(j)) then
18024                   rad=chem_info(i)%Rion(j)
18025                   exit
18026                end if
18027             end do
18028          end if
18029       end do
18030
18031       return
18032    End Subroutine Get_Ionic_Radius
18033
18034    !!----
18035    !!---- Subroutine Remove_Chem_Info()
18036    !!----
18037    !!----    Deallocate Chem_Info Table
18038    !!----
18039    !!---- Update: February - 2005
18040    !!
18041    Subroutine Remove_Chem_Info()
18042
18043       if (allocated(chem_info)) deallocate(chem_info)
18044
18045       return
18046    End Subroutine Remove_Chem_Info
18047
18048    !!----
18049    !!---- Subroutine Remove_Delta_Fp_Fpp()
18050    !!----
18051    !!----    Deallocate Anomalous_ScFac Table
18052    !!----
18053    !!---- Update: February - 2005
18054    !!
18055    Subroutine Remove_Delta_Fp_Fpp()
18056
18057       if (allocated(Anomalous_ScFac)) deallocate(Anomalous_ScFac)
18058
18059       return
18060    End Subroutine Remove_Delta_Fp_Fpp
18061
18062    !!----
18063    !!---- Subroutine Remove_Magnetic_Form()
18064    !!----
18065    !!----    Deallocate Magnetic_Form Table
18066    !!----
18067    !!---- Update: February - 2005
18068    !!
18069    Subroutine Remove_Magnetic_Form()
18070
18071       if (allocated(Magnetic_Form)) deallocate(Magnetic_Form)
18072       if (allocated(Magnetic_j2))   deallocate(Magnetic_j2)
18073       if (allocated(Magnetic_j4))   deallocate(Magnetic_j4)
18074       if (allocated(Magnetic_j6))   deallocate(Magnetic_j6)
18075
18076       return
18077    End Subroutine Remove_Magnetic_form
18078
18079    !!----
18080    !!---- Subroutine Remove_Xray_Form()
18081    !!----
18082    !!----    Deallocate Xray_Form Table
18083    !!----
18084    !!---- Update: February - 2005
18085    !!
18086    Subroutine Remove_Xray_Form()
18087
18088       if (allocated(Xray_Form)) deallocate(Xray_Form)
18089
18090       return
18091    End Subroutine Remove_Xray_form
18092
18093    !!----
18094    !!---- Subroutine Set_Chem_Info()
18095    !!----    Allocates and loads the table  chem_info(num_chem_info):
18096    !!--<<
18097    !!----        1: Symbol of the Element
18098    !!----        2: Name of the Element
18099    !!----        3: Atomic Number
18100    !!----        4: Atomic weight
18101    !!----        5: Covalent Radius
18102    !!----        6: Van der Waals Radius
18103    !!----        7: Atomic volumen
18104    !!----        8: Oxidation State (5 states)
18105    !!----        9: Ionic Radius (depending of the oxidation)
18106    !!----       10: Fermi lenght [10**(-12) cm]
18107    !!----       11: Incoherent Scattering Neutron cross-section (barns -> [10**(-24) cm**2] )
18108    !!----       12: Neutron Absorption cross-section ( barns, for v= 2200m/s, l(A)=3.95/v (km/s) )
18109    !!-->>
18110    !!----
18111    !!---- Update: February - 2005
18112    !!
18113    Subroutine Set_Chem_Info()
18114
18115       if (.not. allocated(chem_info)) allocate(chem_info(num_chem_info))
18116
18117       !  Symb , Name, Z , AtWe  , RCov , RWaals, VAtm, Oxid(5), Rion(5), b=SctF, SedInc, Sea
18118       chem_info( 1:10) = (/  &
18119                          chem_info_type("H ","Hydrogen    ",  1,  1.00797, 0.320, 1.33, 14.1, (/-1, 1, 0, 0, 0/)  ,  &
18120                                                           (/ 2.08, 0.00, 0.00, 0.00, 0.00/),-0.3739,80.2600,  0.33260    ) ,  &
18121                          chem_info_type("HE","Helium      ",  2,  4.00260, 0.930, 1.50, 31.8, (/ 0, 0, 0, 0, 0/)  ,  &
18122                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.3260, 0.0000,  0.00747    ) ,  &
18123                          chem_info_type("LI","Lithium     ",  3,  6.94100, 1.230, 1.78, 13.1, (/ 1, 0, 0, 0, 0/)  ,  &
18124                                                           (/ 0.60, 0.00, 0.00, 0.00, 0.00/),-0.1900, 0.9200, 70.50000    ) ,  &
18125                          chem_info_type("BE","Beryllium   ",  4,  9.01218, 0.900, 1.45,  5.0, (/ 2, 0, 0, 0, 0/)  ,  &
18126                                                           (/ 0.31, 0.00, 0.00, 0.00, 0.00/), 0.7790, 0.0018,  0.00760    ) ,  &
18127                          chem_info_type("B ","Boron       ",  5, 10.81000, 0.820, 1.93,  4.6, (/ 3, 0, 0, 0, 0/)  ,  &
18128                                                           (/ 0.20, 0.00, 0.00, 0.00, 0.00/), 0.5300, 1.7000,767.00000    ) ,  &
18129                          chem_info_type("C ","Carbon      ",  6, 12.01100, 0.770, 1.70,  5.3, (/ 2,-4, 4, 0, 0/)  ,  &
18130                                                           (/ 2.60, 0.15, 0.00, 0.00, 0.00/), 0.6646, 0.0010,  0.0035     ) ,  &
18131                          chem_info_type("N ","Nitrogen    ",  7, 14.00670, 0.750, 1.70, 17.3, (/ 2,-3, 3, 4, 5/)  ,  &
18132                                                           (/ 0.00, 1.71, 0.00, 0.00, 0.11/), 0.9360, 0.5000,  1.9000     ) ,  &
18133                          chem_info_type("O ","Oxygen      ",  8, 15.99940, 0.730, 1.50, 14.0, (/-2, 6, 0, 0, 0/)  ,  &
18134                                                           (/ 1.40, 0.09, 0.00, 0.00, 0.00/), 0.5803, 0.0000,  0.00019    ) ,  &
18135                          chem_info_type("F ","Fluorine    ",  9, 18.99840, 0.720, 1.47, 17.1, (/-1, 7, 0, 0, 0/)  ,  &
18136                                                           (/ 1.36, 0.07, 0.00, 0.00, 0.00/), 0.5654, 0.0008,  0.0096     ) ,  &
18137                          chem_info_type("NE","Neon        ", 10, 20.17900, 0.710, 1.50, 16.8, (/ 0, 0, 0, 0, 0/)  ,  &
18138                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.4566, 0.0080,  0.0039     ) /)
18139
18140       chem_info(11:20) = (/  &
18141                          chem_info_type("NA","Sodium      ", 11, 22.98977, 1.540, 2.07, 23.7, (/ 1, 0, 0, 0, 0/)  ,  &
18142                                                           (/ 0.95, 0.00, 0.00, 0.00, 0.00/), 0.3630, 1.6200,  0.5300     ) ,  &
18143                          chem_info_type("MG","Magnesium   ", 12, 24.30500, 1.360, 2.20, 14.0, (/ 2, 0, 0, 0, 0/)  ,  &
18144                                                           (/ 0.65, 0.00, 0.00, 0.00, 0.00/), 0.5375, 0.0800,  0.063      ) ,  &
18145                          chem_info_type("AL","Aluminum    ", 13, 26.98154, 1.180, 2.45, 10.0, (/ 3, 0, 0, 0, 0/)  ,  &
18146                                                           (/ 0.50, 0.00, 0.00, 0.00, 0.00/), 0.3449, 0.0082,  0.231      ) ,  &
18147                          chem_info_type("SI","Silicon     ", 14, 28.08600, 1.310, 2.30, 12.1, (/-1, 4, 0, 0, 0/)  ,  &
18148                                                           (/ 2.71, 0.41, 0.00, 0.00, 0.00/), 0.4149, 0.0040,  0.171       ) , &
18149                          chem_info_type("P ","Phosphorus  ", 15, 30.97376, 1.060, 2.15, 17.0, (/-3, 3, 4, 5, 0/)  ,  &
18150                                                           (/ 2.12, 0.00, 0.00, 0.34, 0.00/), 0.5130, 0.0050,  0.172      ) ,  &
18151                          chem_info_type("S ","Sulfur      ", 16, 32.06000, 1.020, 1.74, 15.5, (/-2, 2, 4, 6, 0/)  ,  &
18152                                                           (/ 1.84, 0.29, 0.00, 0.00, 0.00/), 0.2847, 0.0070,  0.530      ) ,  &
18153                          chem_info_type("CL","Chlorine    ", 17, 35.45300, 0.990, 1.76, 18.7, (/-1, 1, 3, 5, 7/)  ,  &
18154                                                           (/ 1.81, 0.00, 0.00, 0.00, 0.26/), 0.9577, 5.3000, 33.500      ) ,  &
18155                          chem_info_type("AR","Argon       ", 18, 39.94800, 0.980, 2.00, 24.2, (/ 0, 0, 0, 0, 0/)  ,  &
18156                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.1909, 0.2250,  0.675      ) ,  &
18157                          chem_info_type("K ","Potassium   ", 19, 39.09800, 2.030, 2.43, 45.3, (/ 1, 0, 0, 0, 0/)  ,  &
18158                                                           (/ 1.33, 0.00, 0.00, 0.00, 0.00/), 0.3670, 0.2700,  2.100      ) ,  &
18159                          chem_info_type("CA","Calcium     ", 20, 40.08000, 1.740, 2.09, 29.9, (/ 2, 0, 0, 0, 0/)  ,  &
18160                                                           (/ 0.99, 0.00, 0.00, 0.00, 0.00/), 0.4700, 0.0500,  0.430      ) /)
18161
18162       chem_info(21:30) = (/  &
18163                          chem_info_type("SC","Scandium    ", 21, 44.95590, 1.440, 2.54, 15.0, (/ 3, 0, 0, 0, 0/)  ,  &
18164                                                           (/ 0.81, 0.00, 0.00, 0.00, 0.00/), 1.2290, 4.5000, 27.500      ) ,  &
18165                          chem_info_type("TI","Titanium    ", 22, 47.8670, 1.320, 2.57, 10.6, (/ 2, 4, 0, 0, 0/)  ,  &
18166                                                           (/ 0.90, 0.68, 0.00, 0.00, 0.00/),-0.3438, 2.8700,  6.090      ) ,  &
18167                          chem_info_type("V ","Vanadium    ", 23, 50.94140, 1.320, 2.43,  8.3, (/ 2, 3, 4, 5, 0/)  ,  &
18168                                                           (/ 0.00, 0.74, 0.00, 0.59, 0.00/),-0.0382, 5.0800,  5.080      ) ,  &
18169                          chem_info_type("CR","Chromium    ", 24, 51.99600, 1.180, 2.45,  7.2, (/ 2, 3, 6, 0, 0/)  ,  &
18170                                                           (/ 0.00, 0.69, 0.52, 0.00, 0.00/), 0.3635, 1.8370,  3.050      ) ,  &
18171                          chem_info_type("MN","Manganese   ", 25, 54.93800, 1.170, 2.45,  7.4, (/ 2, 3, 4, 6, 7/)  ,  &
18172                                                           (/ 0.80, 0.72, 0.53, 0.46, 0.46/),-0.3730, 0.4000, 13.300      ) ,  &
18173                          chem_info_type("FE","Iron        ", 26, 55.84700, 1.170, 2.44,  7.1, (/ 2, 3, 0, 0, 0/)  ,  &
18174                                                           (/ 0.76, 0.64, 0.00, 0.00, 0.00/), 0.9450, 0.4000,  2.560      ) ,  &
18175                          chem_info_type("CO","Cobalt      ", 27, 58.93320, 1.160, 2.43,  6.7, (/ 2, 3, 0, 0, 0/)  ,  &
18176                                                           (/ 0.74, 0.63, 0.00, 0.00, 0.00/), 0.2490, 4.8000, 37.180      ) ,  &
18177                          chem_info_type("NI","Nickel      ", 28, 58.70000, 1.160, 2.60,  6.6, (/ 2, 3, 0, 0, 0/)  ,  &
18178                                                           (/ 0.74, 0.63, 0.00, 0.00, 0.00/), 1.0300, 5.2000,  4.490      ) ,  &
18179                          chem_info_type("CU","Copper      ", 29, 63.54600, 1.170, 2.62,  7.1, (/ 1, 2, 0, 0, 0/)  ,  &
18180                                                           (/ 0.96, 0.69, 0.00, 0.00, 0.00/), 0.7718, 0.5500,  3.780      ) ,  &
18181                          chem_info_type("ZN","Zinc        ", 30, 65.38000, 1.250, 2.55,  9.2, (/ 2, 0, 0, 0, 0/)  ,  &
18182                                                           (/ 0.74, 0.00, 0.00, 0.00, 0.00/), 0.5680, 0.0770,  1.110      ) /)
18183
18184       chem_info(31:40) = (/  &
18185                          chem_info_type("GA","Gallium     ", 31, 69.72000, 1.260, 2.32, 11.8, (/ 1, 3, 0, 0, 0/)  ,  &
18186                                                           (/ 1.13, 0.62, 0.00, 0.00, 0.00/), 0.7288, 0.1600,  2.750      ) ,  &
18187                          chem_info_type("GE","Germanium   ", 32, 72.59000, 1.220, 2.27, 13.6, (/ 2, 4, 0, 0, 0/)  ,  &
18188                                                           (/ 0.93, 0.53, 0.00, 0.00, 0.00/), 0.8185, 0.1700,  2.200      ) ,  &
18189                          chem_info_type("AS","Arsenic     ", 33, 74.92160, 1.200, 2.11, 13.1, (/-3, 3, 5, 0, 0/)  ,  &
18190                                                           (/ 2.22, 0.00, 0.47, 0.00, 0.00/), 0.6580, 0.0600,  4.500      ) ,  &
18191                          chem_info_type("SE","Selenium    ", 34, 78.96000, 1.160, 2.32, 16.5, (/-2, 2, 4, 6, 0/)  ,  &
18192                                                           (/ 1.98, 0.00, 0.00, 0.42, 0.00/), 0.7970, 0.3200, 11.700      ) ,  &
18193                          chem_info_type("BR","Bromine     ", 35, 79.90400, 1.140, 1.85, 23.5, (/-1, 1, 3, 5, 7/)  ,  &
18194                                                           (/ 1.95, 0.00, 0.00, 0.00, 0.39/), 0.6795, 0.1000,  6.900      ) ,  &
18195                          chem_info_type("KR","Krypton     ", 36, 83.80000, 1.120, 2.50, 32.2, (/ 0, 0, 0, 0, 0/)  ,  &
18196                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.7810, 0.0100, 25.000      ) ,  &
18197                          chem_info_type("RB","Rubidium    ", 37, 85.46780, 2.160, 2.57, 55.9, (/ 1, 0, 0, 0, 0/)  ,  &
18198                                                           (/ 1.48, 0.00, 0.00, 0.00, 0.00/), 0.7090, 0.5000,  0.380      ) ,  &
18199                          chem_info_type("SR","Strontium   ", 38, 87.62000, 1.910, 2.22, 33.7, (/ 2, 0, 0, 0, 0/)  ,  &
18200                                                           (/ 1.13, 0.00, 0.00, 0.00, 0.00/), 0.7020, 0.0600,  1.280      ) ,  &
18201                          chem_info_type("Y ","Yttrium     ", 39, 88.90590, 1.620, 2.88, 19.8, (/ 3, 0, 0, 0, 0/)  ,  &
18202                                                           (/ 0.93, 0.00, 0.00, 0.00, 0.00/), 0.7750, 0.1500,  1.280      ) ,  &
18203                          chem_info_type("ZR","Zirconium   ", 40, 91.22000, 1.450, 2.66, 14.1, (/ 4, 0, 0, 0, 0/)  ,  &
18204                                                           (/ 0.80, 0.00, 0.00, 0.00, 0.00/), 0.7160, 0.0200,  0.185      ) /)
18205
18206       chem_info(41:50) = (/  &
18207                          chem_info_type("NB","Niobium     ", 41, 92.90640, 1.340, 2.58, 10.8, (/ 3, 5, 0, 0, 0/)  ,  &
18208                                                           (/ 0.70, 0.00, 0.00, 0.00, 0.00/), 0.7054, 0.0024,  1.150      ) ,  &
18209                          chem_info_type("MO","Molybdenum  ", 42, 95.94000, 1.300, 2.57,  9.4, (/ 2, 3, 4, 5, 6/)  ,  &
18210                                                           (/ 0.00, 0.00, 0.68, 0.00, 0.62/), 0.6715, 0.0400,  2.480      ) ,  &
18211                          chem_info_type("TC","Technetium  ", 43, 97.00000, 1.270, 2.45,  0.0, (/ 7, 0, 0, 0, 0/)  ,  &
18212                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.6800, 0.5000, 20.000      ) ,  &
18213                          chem_info_type("RU","Ruthenium   ", 44,101.07000, 1.250, 2.50,  8.3, (/ 2, 3, 4, 6, 8/)  ,  &
18214                                                           (/ 0.00, 0.69, 0.67, 0.00, 0.00/), 0.7030, 0.4000,  2.560      ) ,  &
18215                          chem_info_type("RH","Rhodium     ", 45,102.90550, 1.250, 2.55,  8.3, (/ 2, 3, 4, 0, 0/)  ,  &
18216                                                           (/ 0.86, 0.00, 0.00, 0.00, 0.00/), 0.5880, 0.3000,144.800      ) ,  &
18217                          chem_info_type("PD","Palladium   ", 46,106.40000, 1.280, 2.60,  8.9, (/ 2, 4, 0, 0, 0/)  ,  &
18218                                                           (/ 0.86, 0.00, 0.00, 0.00, 0.00/), 0.5910, 0.0930,  6.900      ) ,  &
18219                          chem_info_type("AG","Silver      ", 47,107.86800, 1.340, 2.69, 10.3, (/ 1, 0, 0, 0, 0/)  ,  &
18220                                                           (/ 1.26, 0.00, 0.00, 0.00, 0.00/), 0.5922, 0.5800, 63.300      ) ,  &
18221                          chem_info_type("CD","Cadmium     ", 48,112.40000, 1.480, 2.79, 13.1, (/ 2, 0, 0, 0, 0/)  ,  &
18222                                                           (/ 0.97, 0.00, 0.00, 0.00, 0.00/), 0.4870, 3.4600,2520.00      ) ,  &
18223                          chem_info_type("IN","Indium      ", 49,114.82000, 1.440, 2.73, 15.7, (/ 1, 3, 0, 0, 0/)  ,  &
18224                                                           (/ 1.32, 0.81, 0.00, 0.00, 0.00/), 0.4065, 0.5400,193.800      ) ,  &
18225                          chem_info_type("SN","Tin         ", 50,118.69000, 1.410, 2.56, 16.3, (/ 2, 4, 0, 0, 0/)  ,  &
18226                                                           (/ 1.12, 0.71, 0.00, 0.00, 0.00/), 0.6225, 0.0220,  0.626      ) /)
18227
18228       chem_info(51:60) = (/  &
18229                          chem_info_type("SB","Antimony    ", 51,121.75000, 1.400, 2.56, 18.4, (/-3, 3, 5, 0, 0/)  ,  &
18230                                                           (/ 2.45, 0.00, 0.62, 0.00, 0.00/), 0.5570, 0.0000,  4.910      ) ,  &
18231                          chem_info_type("TE","Tellurium   ", 52,127.60000, 1.360, 2.57, 20.5, (/-2, 2, 4, 6, 0/)  ,  &
18232                                                           (/ 2.21, 0.00, 0.00, 0.56, 0.00/), 0.5800, 0.0900,  4.700      ) ,  &
18233                          chem_info_type("I ","Iodine      ", 53,126.90450, 1.330, 1.98, 25.7, (/-1, 1, 3, 5, 7/)  ,  &
18234                                                           (/ 2.16, 0.00, 0.00, 0.00, 0.50/), 0.5280, 0.3100,  6.150      ) ,  &
18235                          chem_info_type("XE","Xenon       ", 54,131.30000, 1.310, 2.50, 42.9, (/ 0, 0, 0, 0, 0/)  ,  &
18236                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.4920, 0.0000, 23.900      ) ,  &
18237                          chem_info_type("CS","Cesium      ", 55,132.90540, 2.350, 2.77, 70.0, (/ 1, 0, 0, 0, 0/)  ,  &
18238                                                           (/ 1.69, 0.00, 0.00, 0.00, 0.00/), 0.5420, 0.2100, 29.000      ) ,  &
18239                          chem_info_type("BA","Barium      ", 56,137.34000, 1.980, 2.44, 39.0, (/ 2, 0, 0, 0, 0/)  ,  &
18240                                                           (/ 1.35, 0.00, 0.00, 0.00, 0.00/), 0.5070, 0.1500,  1.100      ) ,  &
18241                          chem_info_type("LA","Lanthanum   ", 57,138.90550, 1.690, 2.97, 22.5, (/ 3, 0, 0, 0, 0/)  ,  &
18242                                                           (/ 1.15, 0.00, 0.00, 0.00, 0.00/), 0.8240, 1.1300,  8.970      ) ,  &
18243                          chem_info_type("CE","Cerium      ", 58,140.12000, 1.650, 2.93, 21.0, (/ 3, 4, 0, 0, 0/)  ,  &
18244                                                           (/ 1.11, 1.01, 0.00, 0.00, 0.00/), 0.4840, 0.0000,  0.630      ) ,  &
18245                          chem_info_type("PR","Praseodymium", 59,140.90770, 1.650, 2.92, 20.8, (/ 3, 4, 0, 0, 0/)  ,  &
18246                                                           (/ 1.09, 0.92, 0.00, 0.00, 0.00/), 0.4580, 0.0150, 11.500      ) ,  &
18247                          chem_info_type("ND","Neodymium   ", 60,144.24000, 1.640, 2.91, 20.6, (/ 3, 0, 0, 0, 0/)  ,  &
18248                                                           (/ 1.08, 0.00, 0.00, 0.00, 0.00/), 0.7690, 9.2000, 50.500      ) /)
18249
18250       chem_info(61:70) = (/  &
18251                          chem_info_type("PM","Promethium  ", 61,145.00000, 1.630, 2.90,  0.0, (/ 3, 0, 0, 0, 0/)  ,  &
18252                                                           (/ 1.06, 0.00, 0.00, 0.00, 0.00/), 1.2600, 1.3000,168.400      ) ,  &
18253                          chem_info_type("SM","Samarium    ", 62,150.40000, 1.620, 2.90, 19.9, (/ 2, 3, 0, 0, 0/)  ,  &
18254                                                           (/ 0.00, 1.04, 0.00, 0.00, 0.00/), 0.8000,39.0000,5922.00      ) ,  &
18255                          chem_info_type("EU","Europium    ", 63,151.96000, 1.850, 2.90, 28.9, (/ 2, 3, 0, 0, 0/)  ,  &
18256                                                           (/ 1.12, 0.00, 0.00, 0.00, 0.00/), 0.7220, 2.5000,4530.00      ) ,  &
18257                          chem_info_type("GD","Gadolinium  ", 64,157.25000, 1.610, 2.89, 19.9, (/ 3, 0, 0, 0, 0/)  ,  &
18258                                                           (/ 1.02, 0.00, 0.00, 0.00, 0.00/), 0.6500, 0.0000,49700.0      ) ,  &
18259                          chem_info_type("TB","Terbium     ", 65,158.92540, 1.590, 2.86, 19.2, (/ 3, 4, 0, 0, 0/)  ,  &
18260                                                           (/ 1.00, 0.00, 0.00, 0.00, 0.00/), 0.7380, 0.0040, 23.400      ) ,  &
18261                          chem_info_type("DY","Dysprosium  ", 66,162.50000, 1.590, 2.85, 19.0, (/ 3, 0, 0, 0, 0/)  ,  &
18262                                                           (/ 0.99, 0.00, 0.00, 0.00, 0.00/), 1.6900,54.4000,994.000      ) ,  &
18263                          chem_info_type("HO","Holmium     ", 67,164.93040, 1.580, 2.84, 18.7, (/ 3, 0, 0, 0, 0/)  ,  &
18264                                                           (/ 0.97, 0.00, 0.00, 0.00, 0.00/), 0.8010, 0.3600, 64.700      ) ,  &
18265                          chem_info_type("ER","Erbium      ", 68,167.26000, 1.570, 2.83, 18.4, (/ 3, 0, 0, 0, 0/)  ,  &
18266                                                           (/ 0.96, 0.00, 0.00, 0.00, 0.00/), 0.7790, 1.1000,159.000      ) ,  &
18267                          chem_info_type("TM","Thulium     ", 69,168.93420, 1.560, 2.82, 18.1, (/ 2, 3, 0, 0, 0/)  ,  &
18268                                                           (/ 0.00, 0.95, 0.00, 0.00, 0.00/), 0.7070, 0.1000,100.000      ) ,  &
18269                          chem_info_type("YB","Ytterbium   ", 70,173.04000, 0.000, 3.04, 24.8, (/ 2, 3, 0, 0, 0/)  ,  &
18270                                                           (/ 1.13, 0.94, 0.00, 0.00, 0.00/), 1.2430, 4.0000, 34.800      ) /)
18271
18272       chem_info(71:80) = (/  &
18273                          chem_info_type("LU","Lutetium    ", 71,174.97000, 1.560, 2.82, 17.8, (/ 3, 0, 0, 0, 0/)  ,  &
18274                                                           (/ 0.93, 0.00, 0.00, 0.00, 0.00/), 0.7210, 0.7000, 74.000      ) ,  &
18275                          chem_info_type("HF","Hafnium     ", 72,178.49000, 1.440, 2.67, 13.6, (/ 4, 0, 0, 0, 0/)  ,  &
18276                                                           (/ 0.81, 0.00, 0.00, 0.00, 0.00/), 0.7770, 2.6000, 74.000      ) ,  &
18277                          chem_info_type("TA","Tantalum    ", 73,180.94790, 1.440, 2.53, 10.9, (/ 5, 0, 0, 0, 0/)  ,  &
18278                                                           (/ 0.73, 0.00, 0.00, 0.00, 0.00/), 0.6910, 0.0100, 20.600      ) ,  &
18279                          chem_info_type("W ","Tungsten    ", 74,183.85000, 1.300, 2.47,  9.5, (/ 2, 3, 4, 5, 6/)  ,  &
18280                                                           (/ 0.00, 0.00, 0.68, 0.00, 0.64/), 0.4860, 1.6300, 18.300      ) ,  &
18281                          chem_info_type("RE","Rhenium     ", 75,186.20700, 1.280, 2.45,  8.8, (/ 1, 2, 4, 6, 7/)  ,  &
18282                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.9200, 0.9000, 89.700      ) ,  &
18283                          chem_info_type("OS","Osmium      ", 76,190.20000, 1.260, 2.47,  8.4, (/ 2, 3, 4, 6, 8/)  ,  &
18284                                                           (/ 0.00, 0.00, 0.69, 0.00, 0.00/), 1.0700, 0.3000, 16.000      ) ,  &
18285                          chem_info_type("IR","Iridium     ", 77,192.22000, 1.270, 2.42,  8.5, (/ 2, 3, 4, 6, 0/)  ,  &
18286                                                           (/ 0.00, 0.00, 0.66, 0.00, 0.00/), 1.0600, 0.0000,425.000      ) ,  &
18287                          chem_info_type("PT","Platinum    ", 78,195.09000, 1.300, 2.60,  9.1, (/ 2, 4, 0, 0, 0/)  ,  &
18288                                                           (/ 0.96, 0.00, 0.00, 0.00, 0.00/), 0.9600, 0.1300, 10.300      ) ,  &
18289                          chem_info_type("AU","Gold        ", 79,196.96650, 1.340, 2.60, 10.2, (/ 1, 3, 0, 0, 0/)  ,  &
18290                                                           (/ 1.37, 0.00, 0.00, 0.00, 0.00/), 0.7630, 0.4300, 98.650      ) ,  &
18291                          chem_info_type("HG","Mercury     ", 80,200.59000, 1.490, 2.80, 14.8, (/ 2, 0, 0, 0, 0/)  ,  &
18292                                                           (/ 1.10, 0.00, 0.00, 0.00, 0.00/), 1.2692, 6.6000,372.300      ) /)
18293
18294       chem_info(81:90) = (/  &
18295                          chem_info_type("TL","Thallium    ", 81,204.37000, 1.480, 2.65, 17.2, (/ 1, 3, 0, 0, 0/)  ,  &
18296                                                           (/ 1.40, 0.95, 0.00, 0.00, 0.00/), 0.8776, 0.2100,  3.430      ) ,  &
18297                          chem_info_type("PB","Lead        ", 82,207.20000, 1.470, 2.64, 18.3, (/ 2, 4, 0, 0, 0/)  ,  &
18298                                                           (/ 1.20, 0.84, 0.00, 0.00, 0.00/), 0.9405, 0.0030,  0.171      ) ,  &
18299                          chem_info_type("BI","Bismuth     ", 83,208.98040, 1.460, 2.64, 21.3, (/ 3, 5, 0, 0, 0/)  ,  &
18300                                                           (/ 1.20, 0.74, 0.00, 0.00, 0.00/), 0.8532, 0.0084,  0.034      ) ,  &
18301                          chem_info_type("PO","Polonium    ", 84,209.00000, 1.460, 2.60, 22.7, (/ 2, 4, 0, 0, 0/)  ,  &
18302                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18303                          chem_info_type("AT","Astatine    ", 85,210.00000, 0.000, 2.60,  0.0, (/-1, 1, 3, 5, 7/)  ,  &
18304                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18305                          chem_info_type("RN","Radon       ", 86,222.00000, 0.000, 2.60,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18306                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18307                          chem_info_type("FR","Francium    ", 87,223.00000, 0.000, 3.00,  0.0, (/ 1, 0, 0, 0, 0/)  ,  &
18308                                                           (/ 1.76, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18309                          chem_info_type("RA","Radium      ", 88,226.02540, 0.000, 3.00, 45.0, (/ 2, 0, 0, 0, 0/)  ,  &
18310                                                           (/ 1.40, 0.00, 0.00, 0.00, 0.00/), 1.0000, 0.0000, 12.800      ) ,  &
18311                          chem_info_type("AC","Actinium    ", 89,227.00000, 0.000, 2.98,  0.0, (/ 3, 0, 0, 0, 0/)  ,  &
18312                                                           (/ 1.18, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18313                          chem_info_type("TH","Thorium     ", 90,232.03810, 1.650, 2.89, 19.9, (/ 3, 4, 0, 0, 0/)  ,  &
18314                                                           (/ 1.14, 0.95, 0.00, 0.00, 0.00/), 1.0310, 0.0000,  7.370      ) /)
18315
18316       chem_info(91:100)= (/  &
18317                          chem_info_type("PA","Protactinium", 91,231.03597, 0.000, 2.71, 15.0, (/ 3, 4, 5, 0, 0/)  ,  &
18318                                                           (/ 1.12, 0.98, 0.00, 0.00, 0.00/), 0.9100, 0.1000,200.600      ) ,  &
18319                          chem_info_type("U ","Uranium     ", 92,238.02900, 1.420, 2.68, 12.5, (/ 3, 4, 5, 6, 0/)  ,  &
18320                                                           (/ 1.11, 0.97, 0.00, 0.00, 0.00/), 0.8417, 0.0050,  7.570      ) ,  &
18321                          chem_info_type("NP","Neptunium   ", 93,237.04820, 0.000, 2.65, 21.1, (/ 3, 4, 5, 6, 0/)  ,  &
18322                                                           (/ 1.09, 0.95, 0.00, 0.00, 0.00/), 1.0550, 0.5000,175.900      ) ,  &
18323                          chem_info_type("PU","Plutonium   ", 94,244.00000, 0.000, 2.43,  0.0, (/ 3, 4, 5, 6, 0/)  ,  &
18324                                                           (/ 1.07, 0.93, 0.00, 0.00, 0.00/), 1.4100, 0.0000,558.000      ) ,  &
18325                          chem_info_type("AM","Americium   ", 95,243.00000, 0.000, 2.61, 20.8, (/ 3, 4, 5, 6, 0/)  ,  &
18326                                                           (/ 1.06, 0.92, 0.00, 0.00, 0.00/), 0.8300, 0.3000, 75.300      ) ,  &
18327                          chem_info_type("CM","Curium      ", 96,247.00000, 0.000, 2.60,  0.0, (/ 3, 0, 0, 0, 0/)  ,  &
18328                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.9500, 0.0000, 16.200      ) ,  &
18329                          chem_info_type("BK","Berkelium   ", 97,247.00000, 0.000, 2.60,  0.0, (/ 3, 4, 0, 0, 0/)  ,  &
18330                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18331                          chem_info_type("CF","Californium ", 98,251.00000, 0.000, 2.60,  0.0, (/ 3, 0, 0, 0, 0/)  ,  &
18332                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18333                          chem_info_type("ES","Einsteinium ", 99,254.00000, 0.000, 0.00,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18334                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18335                          chem_info_type("FM","Fermium     ",100,257.00000, 0.000, 0.00,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18336                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) /)
18337
18338       chem_info(101:108)=(/  &
18339                          chem_info_type("MD","Mendelevium ",101,258.00000, 0.000, 0.00,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18340                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18341                          chem_info_type("NO","Nobelium    ",102,255.00000, 0.000, 0.00,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18342                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18343                          chem_info_type("LR","Lawrencium  ",103,260.00000, 0.000, 0.00,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18344                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18345                          chem_info_type("KU","            ",104,261.00000, 0.000, 0.00,  0.0, (/ 4, 0, 0, 0, 0/)  ,  &
18346                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18347                          chem_info_type("HA","            ",105,262.00000, 0.000, 0.00,  0.0, (/ 0, 0, 0, 0, 0/)  ,  &
18348                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.000      ) ,  &
18349                          chem_info_type("BS","Boron-11    ",  5, 10.81000, 0.820, 1.93,  4.6, (/ 3, 0, 0, 0, 0/)  ,  &
18350                                                           (/ 0.20, 0.00, 0.00, 0.00, 0.00/), 0.6650, 1.7000,767.00000    ) ,  &
18351                          chem_info_type("ZE","Zero-scatter",  1,  0.00000, 0.820, 1.93,  4.6, (/ 0, 0, 0, 0, 0/)  ,  &
18352                                                           (/ 0.00, 0.00, 0.00, 0.00, 0.00/), 0.0000, 0.0000,  0.00000    ) ,  &
18353                          chem_info_type("D ","Deuterium   ",  1,  2.00797, 0.320, 1.33, 14.1, (/-1, 1, 0, 0, 0/)  ,  &
18354                                                           (/ 2.08, 0.00, 0.00, 0.00, 0.00/),0.6671, 0.0000,  0.00000    ) /)
18355       !  Symb , Name, Z , AtWe  , RCov , RWaals, VAtm, Oxid(5), Rion(5), b=SctF, SedInc, Sea
18356       return
18357    End Subroutine Set_Chem_Info
18358
18359    !!----
18360    !!---- Subroutine Set_Delta_Fp_Fpp()
18361    !!--<<
18362    !!----    Wavelenghts:     Cr        Fe        Cu         Mo         Ag
18363    !!----         Lambda   2.28962   1.93597   1.54051    0.70926    0.556363
18364    !!-->>
18365    !!----    Set values for Delta-fp & Delta-fpp for the above wavelengths
18366    !!----
18367    !!---- Update: February - 2005
18368    !!
18369    Subroutine Set_Delta_Fp_Fpp()
18370
18371       if (.not. allocated(anomalous_ScFac)) allocate(anomalous_ScFac(Num_Delta_Fp))
18372
18373       Anomalous_ScFac( 1)=Anomalous_Sc_Type("h ", (/   0.000,   0.000,   0.000,   0.000,   0.000/), &
18374                                                   (/   0.000,   0.000,   0.000,   0.000,   0.000/)  )
18375       Anomalous_ScFac( 2)=Anomalous_Sc_Type("he", (/   0.000,   0.000,   0.000,   0.000,   0.000/), &
18376                                                   (/   0.000,   0.000,   0.000,   0.000,   0.000/)  )
18377       Anomalous_ScFac( 3)=Anomalous_Sc_Type("li", (/   0.002,   0.002,   0.001,   0.000,   0.000/), &
18378                                                   (/   0.001,   0.001,   0.000,   0.000,   0.000/)  )
18379       Anomalous_ScFac( 4)=Anomalous_Sc_Type("be", (/   0.008,   0.005,   0.003,   0.000,  -0.001/), &
18380                                                   (/   0.003,   0.002,   0.001,   0.000,   0.000/)  )
18381       Anomalous_ScFac( 5)=Anomalous_Sc_Type("b ", (/   0.018,   0.013,   0.008,   0.000,   0.000/), &
18382                                                   (/   0.009,   0.007,   0.004,   0.001,   0.000/)  )
18383       Anomalous_ScFac( 6)=Anomalous_Sc_Type("c ", (/   0.035,   0.026,   0.017,   0.002,   0.000/), &
18384                                                   (/   0.021,   0.015,   0.009,   0.002,   0.001/)  )
18385       Anomalous_ScFac( 7)=Anomalous_Sc_Type("n ", (/   0.059,   0.044,   0.029,   0.004,   0.001/), &
18386                                                   (/   0.042,   0.029,   0.018,   0.003,   0.002/)  )
18387       Anomalous_ScFac( 8)=Anomalous_Sc_Type("o ", (/   0.090,   0.069,   0.047,   0.008,   0.003/), &
18388                                                   (/   0.073,   0.052,   0.032,   0.006,   0.004/)  )
18389       Anomalous_ScFac( 9)=Anomalous_Sc_Type("f ", (/   0.129,   0.100,   0.069,   0.014,   0.006/), &
18390                                                   (/   0.119,   0.085,   0.053,   0.010,   0.006/)  )
18391       Anomalous_ScFac(10)=Anomalous_Sc_Type("ne", (/   0.174,   0.138,   0.097,   0.021,   0.011/), &
18392                                                   (/   0.184,   0.132,   0.083,   0.016,   0.010/)  )
18393       Anomalous_ScFac(11)=Anomalous_Sc_Type("na", (/   0.223,   0.180,   0.129,   0.030,   0.016/), &
18394                                                   (/   0.270,   0.195,   0.124,   0.025,   0.015/)  )
18395       Anomalous_ScFac(12)=Anomalous_Sc_Type("mg", (/   0.272,   0.224,   0.165,   0.042,   0.023/), &
18396                                                   (/   0.381,   0.277,   0.177,   0.036,   0.022/)  )
18397       Anomalous_ScFac(13)=Anomalous_Sc_Type("al", (/   0.318,   0.269,   0.204,   0.056,   0.032/), &
18398                                                   (/   0.522,   0.381,   0.246,   0.052,   0.031/)  )
18399       Anomalous_ScFac(14)=Anomalous_Sc_Type("si", (/   0.355,   0.311,   0.244,   0.072,   0.042/), &
18400                                                   (/   0.693,   0.509,   0.330,   0.071,   0.043/)  )
18401       Anomalous_ScFac(15)=Anomalous_Sc_Type("p ", (/   0.377,   0.347,   0.283,   0.090,   0.055/), &
18402                                                   (/   0.900,   0.664,   0.434,   0.095,   0.058/)  )
18403       Anomalous_ScFac(16)=Anomalous_Sc_Type("s ", (/   0.374,   0.370,   0.319,   0.110,   0.068/), &
18404                                                   (/   1.142,   0.847,   0.557,   0.124,   0.076/)  )
18405       Anomalous_ScFac(17)=Anomalous_Sc_Type("cl", (/   0.335,   0.375,   0.348,   0.132,   0.084/), &
18406                                                   (/   1.423,   1.061,   0.702,   0.159,   0.099/)  )
18407       Anomalous_ScFac(18)=Anomalous_Sc_Type("ar", (/   0.243,   0.352,   0.366,   0.155,   0.101/), &
18408                                                   (/   1.747,   1.309,   0.872,   0.201,   0.125/)  )
18409       Anomalous_ScFac(19)=Anomalous_Sc_Type("k ", (/   0.070,   0.286,   0.365,   0.179,   0.118/), &
18410                                                   (/   2.110,   1.589,   1.066,   0.250,   0.156/)  )
18411       Anomalous_ScFac(20)=Anomalous_Sc_Type("ca", (/  -0.221,   0.163,   0.341,   0.203,   0.137/), &
18412                                                   (/   2.514,   1.904,   1.286,   0.306,   0.193/)  )
18413       Anomalous_ScFac(21)=Anomalous_Sc_Type("sc", (/  -0.717,  -0.038,   0.285,   0.226,   0.156/), &
18414                                                   (/   2.968,   2.256,   1.533,   0.372,   0.235/)  )
18415       Anomalous_ScFac(22)=Anomalous_Sc_Type("ti", (/  -1.683,  -0.357,   0.189,   0.248,   0.175/), &
18416                                                   (/   3.470,   2.643,   1.807,   0.446,   0.283/)  )
18417       Anomalous_ScFac(23)=Anomalous_Sc_Type("v ", (/  -3.841,  -0.896,   0.035,   0.267,   0.194/), &
18418                                                   (/   0.459,   3.070,   2.110,   0.530,   0.338/)  )
18419       Anomalous_ScFac(24)=Anomalous_Sc_Type("cr", (/  -2.161,  -1.973,  -0.198,   0.284,   0.213/), &
18420                                                   (/   0.548,   3.533,   2.443,   0.624,   0.399/)  )
18421       Anomalous_ScFac(25)=Anomalous_Sc_Type("mn", (/  -1.639,  -3.367,  -0.568,   0.295,   0.229/), &
18422                                                   (/   0.650,   0.481,   2.808,   0.729,   0.468/)  )
18423       Anomalous_ScFac(26)=Anomalous_Sc_Type("fe", (/  -1.339,  -2.095,  -1.179,   0.301,   0.244/), &
18424                                                   (/   0.764,   0.566,   3.204,   0.845,   0.545/)  )
18425       Anomalous_ScFac(27)=Anomalous_Sc_Type("co", (/  -1.124,  -1.623,  -2.464,   0.299,   0.256/), &
18426                                                   (/   0.893,   0.662,   3.608,   0.973,   0.630/)  )
18427       Anomalous_ScFac(28)=Anomalous_Sc_Type("ni", (/  -0.956,  -1.343,  -2.956,   0.285,   0.261/), &
18428                                                   (/   1.036,   0.769,   0.509,   1.113,   0.724/)  )
18429       Anomalous_ScFac(29)=Anomalous_Sc_Type("cu", (/  -0.795,  -1.129,  -2.019,   0.263,   0.265/), &
18430                                                   (/   1.196,   0.888,   0.589,   1.266,   0.826/)  )
18431       Anomalous_ScFac(30)=Anomalous_Sc_Type("zn", (/  -0.684,  -0.978,  -1.612,   0.222,   0.260/), &
18432                                                   (/   1.373,   1.021,   0.678,   1.431,   0.938/)  )
18433       Anomalous_ScFac(31)=Anomalous_Sc_Type("ga", (/  -0.570,  -0.841,  -1.354,   0.163,   0.249/), &
18434                                                   (/   1.569,   1.168,   0.777,   1.609,   1.059/)  )
18435       Anomalous_ScFac(32)=Anomalous_Sc_Type("ge", (/  -0.462,  -0.717,  -1.163,   0.081,   0.228/), &
18436                                                   (/   1.786,   1.331,   0.886,   1.801,   1.190/)  )
18437       Anomalous_ScFac(33)=Anomalous_Sc_Type("as", (/  -0.365,  -0.607,  -1.011,  -0.030,   0.196/), &
18438                                                   (/   2.022,   1.508,   1.006,   2.007,   1.332/)  )
18439       Anomalous_ScFac(34)=Anomalous_Sc_Type("se", (/  -0.273,  -0.503,  -0.879,  -0.178,   0.152/), &
18440                                                   (/   2.283,   1.704,   1.139,   2.223,   1.481/)  )
18441       Anomalous_ScFac(35)=Anomalous_Sc_Type("br", (/  -0.198,  -0.413,  -0.767,  -0.374,   0.090/), &
18442                                                   (/   2.563,   1.916,   1.283,   2.456,   1.643/)  )
18443       Anomalous_ScFac(36)=Anomalous_Sc_Type("kr", (/  -0.130,  -0.328,  -0.665,  -0.652,   0.008/), &
18444                                                   (/   2.872,   2.149,   1.439,   2.713,   1.820/)  )
18445       Anomalous_ScFac(37)=Anomalous_Sc_Type("rb", (/  -0.082,  -0.256,  -0.574,  -1.044,  -0.099/), &
18446                                                   (/   3.201,   2.398,   1.608,   2.973,   2.003/)  )
18447       Anomalous_ScFac(38)=Anomalous_Sc_Type("sr", (/  -0.012,  -0.161,  -0.465,  -1.657,  -0.230/), &
18448                                                   (/   3.608,   2.709,   1.820,   3.264,   2.203/)  )
18449       Anomalous_ScFac(39)=Anomalous_Sc_Type("y ", (/   0.006,  -0.106,  -0.386,  -2.951,  -0.406/), &
18450                                                   (/   4.002,   3.009,   2.025,   3.542,   2.411/)  )
18451       Anomalous_ScFac(40)=Anomalous_Sc_Type("zr", (/   0.007,  -0.061,  -0.314,  -2.965,  -0.639/), &
18452                                                   (/   4.422,   3.329,   2.245,   0.560,   2.630/)  )
18453       Anomalous_ScFac(41)=Anomalous_Sc_Type("nb", (/  -0.013,  -0.028,  -0.248,  -2.197,  -0.957/), &
18454                                                   (/   4.876,   3.676,   2.482,   0.621,   2.860/)  )
18455       Anomalous_ScFac(42)=Anomalous_Sc_Type("mo", (/  -0.063,  -0.012,  -0.191,  -1.825,  -1.416/), &
18456                                                   (/   5.353,   4.043,   2.735,   0.688,   3.103/)  )
18457       Anomalous_ScFac(43)=Anomalous_Sc_Type("tc", (/  -0.153,  -0.017,  -0.145,  -1.590,  -2.205/), &
18458                                                   (/   5.862,   4.434,   3.005,   0.759,   3.353/)  )
18459       Anomalous_ScFac(44)=Anomalous_Sc_Type("ru", (/  -0.270,  -0.039,  -0.105,  -1.420,  -5.524/), &
18460                                                   (/   6.406,   4.854,   3.296,   0.836,   3.651/)  )
18461       Anomalous_ScFac(45)=Anomalous_Sc_Type("rh", (/  -0.424,  -0.083,  -0.077,  -1.287,  -2.649/), &
18462                                                   (/   6.984,   5.300,   3.605,   0.919,   0.596/)  )
18463       Anomalous_ScFac(46)=Anomalous_Sc_Type("pd", (/  -0.639,  -0.157,  -0.059,  -1.177,  -2.128/), &
18464                                                   (/   7.594,   5.773,   3.934,   1.007,   0.654/)  )
18465       Anomalous_ScFac(47)=Anomalous_Sc_Type("ag", (/  -0.924,  -0.259,  -0.060,  -1.085,  -1.834/), &
18466                                                   (/   8.235,   6.271,   4.282,   1.101,   0.717/)  )
18467       Anomalous_ScFac(48)=Anomalous_Sc_Type("cd", (/  -1.303,  -0.416,  -0.079,  -1.005,  -1.637/), &
18468                                                   (/   8.912,   6.800,   4.653,   1.202,   0.783/)  )
18469       Anomalous_ScFac(49)=Anomalous_Sc_Type("in", (/  -1.788,  -0.626,  -0.126,  -0.936,  -1.493/), &
18470                                                   (/   9.627,   7.356,   5.045,   1.310,   0.854/)  )
18471       Anomalous_ScFac(50)=Anomalous_Sc_Type("sn", (/  -2.401,  -0.888,  -0.194,  -0.873,  -1.378/), &
18472                                                   (/  10.380,   7.943,   5.459,   1.424,   0.930/)  )
18473       Anomalous_ScFac(51)=Anomalous_Sc_Type("sb", (/  -3.194,  -1.214,  -0.287,  -0.816,  -1.284/), &
18474                                                   (/  11.166,   8.557,   5.894,   1.546,   1.010/)  )
18475       Anomalous_ScFac(52)=Anomalous_Sc_Type("te", (/  -4.267,  -1.630,  -0.418,  -0.772,  -1.212/), &
18476                                                   (/  11.995,   9.203,   6.352,   1.675,   1.096/)  )
18477       Anomalous_ScFac(53)=Anomalous_Sc_Type("i ", (/  -5.852,  -2.147,  -0.579,  -0.726,  -1.144/), &
18478                                                   (/  12.850,   9.885,   6.835,   1.812,   1.187/)  )
18479       Anomalous_ScFac(54)=Anomalous_Sc_Type("xe", (/  -8.133,  -2.812,  -0.783,  -0.684,  -1.084/), &
18480                                                   (/  11.933,  10.608,   7.348,   1.958,   1.284/)  )
18481       Anomalous_ScFac(55)=Anomalous_Sc_Type("cs", (/ -10.742,  -3.652,  -1.022,  -0.644,  -1.029/), &
18482                                                   (/  12.919,  11.382,   7.904,   2.119,   1.391/)  )
18483       Anomalous_ScFac(56)=Anomalous_Sc_Type("ba", (/ -11.460,  -4.832,  -1.334,  -0.613,  -0.983/), &
18484                                                   (/   9.981,  12.164,   8.460,   2.282,   1.500/)  )
18485       Anomalous_ScFac(57)=Anomalous_Sc_Type("la", (/ -12.135,  -6.683,  -1.716,  -0.588,  -0.942/), &
18486                                                   (/   3.565,  12.937,   9.036,   2.452,   1.615/)  )
18487       Anomalous_ScFac(58)=Anomalous_Sc_Type("ce", (/  -9.574,  -8.388,  -2.170,  -0.564,  -0.904/), &
18488                                                   (/   3.843,  11.953,   9.648,   2.632,   1.735/)  )
18489       Anomalous_ScFac(59)=Anomalous_Sc_Type("pr", (/  -7.817, -12.457,  -2.939,  -0.530,  -0.859/), &
18490                                                   (/   4.130,   6.285,  10.535,   2.845,   1.873/)  )
18491       Anomalous_ScFac(60)=Anomalous_Sc_Type("nd", (/  -7.486, -11.016,  -3.431,  -0.535,  -0.842/), &
18492                                                   (/   4.427,   9.874,  10.933,   3.018,   1.995/)  )
18493       Anomalous_ScFac(61)=Anomalous_Sc_Type("pm", (/  -6.891, -12.122,  -4.357,  -0.530,  -0.818/), &
18494                                                   (/   4.741,   3.627,  11.614,   3.225,   2.135/)  )
18495       Anomalous_ScFac(62)=Anomalous_Sc_Type("sm", (/  -6.429,  -9.616,  -5.696,  -0.533,  -0.798/), &
18496                                                   (/   5.073,   3.883,  12.320,   3.442,   2.281/)  )
18497       Anomalous_ScFac(63)=Anomalous_Sc_Type("eu", (/  -6.050,  -8.352,  -7.718,  -0.542,  -0.782/), &
18498                                                   (/   5.416,   4.149,  11.276,   3.669,   2.435/)  )
18499       Anomalous_ScFac(64)=Anomalous_Sc_Type("gd", (/  -5.779,  -7.565,  -9.242,  -0.564,  -0.774/), &
18500                                                   (/   5.773,   4.427,  11.946,   3.904,   2.595/)  )
18501       Anomalous_ScFac(65)=Anomalous_Sc_Type("tb", (/  -5.525,  -6.980,  -9.498,  -0.591,  -0.767/), &
18502                                                   (/   6.153,   4.721,   9.242,   4.151,   2.764/)  )
18503       Anomalous_ScFac(66)=Anomalous_Sc_Type("dy", (/  -5.250,  -6.492, -10.423,  -0.619,  -0.761/), &
18504                                                   (/   6.549,   5.026,   9.748,   4.410,   2.940/)  )
18505       Anomalous_ScFac(67)=Anomalous_Sc_Type("ho", (/  -5.040,  -6.112, -12.255,  -0.666,  -0.765/), &
18506                                                   (/   6.958,   5.343,   3.704,   4.678,   3.124/)  )
18507       Anomalous_ScFac(68)=Anomalous_Sc_Type("er", (/  -4.878,  -5.810,  -9.733,  -0.723,  -0.773/), &
18508                                                   (/   7.387,   5.675,   3.937,   4.958,   3.316/)  )
18509       Anomalous_ScFac(69)=Anomalous_Sc_Type("tm", (/  -4.753,  -5.565,  -8.488,  -0.795,  -0.790/), &
18510                                                   (/   7.833,   6.022,   4.181,   5.248,   3.515/)  )
18511       Anomalous_ScFac(70)=Anomalous_Sc_Type("yb", (/  -4.652,  -5.361,  -7.701,  -0.884,  -0.815/), &
18512                                                   (/   8.291,   6.378,   4.432,   5.548,   3.723/)  )
18513       Anomalous_ScFac(71)=Anomalous_Sc_Type("lu", (/  -4.580,  -5.190,  -7.133,  -0.988,  -0.847/), &
18514                                                   (/   8.759,   6.745,   4.693,   5.858,   3.937/)  )
18515       Anomalous_ScFac(72)=Anomalous_Sc_Type("hf", (/  -4.592,  -5.088,  -6.715,  -1.118,  -0.890/), &
18516                                                   (/   9.277,   7.148,   4.977,   6.185,   4.164/)  )
18517       Anomalous_ScFac(73)=Anomalous_Sc_Type("ta", (/  -4.540,  -4.948,  -6.351,  -1.258,  -0.937/), &
18518                                                   (/   9.811,   7.565,   5.271,   6.523,   4.399/)  )
18519       Anomalous_ScFac(74)=Anomalous_Sc_Type("w ", (/  -4.499,  -4.823,  -6.048,  -1.421,  -0.993/), &
18520                                                   (/  10.364,   7.996,   5.577,   6.872,   4.643/)  )
18521       Anomalous_ScFac(75)=Anomalous_Sc_Type("re", (/  -4.483,  -4.719,  -5.790,  -1.598,  -1.048/), &
18522                                                   (/  10.929,   8.439,   5.891,   7.232,   4.894/)  )
18523       Anomalous_ScFac(76)=Anomalous_Sc_Type("os", (/  -4.503,  -4.647,  -5.581,  -1.816,  -1.127/), &
18524                                                   (/  11.520,   8.903,   6.221,   7.605,   5.156/)  )
18525       Anomalous_ScFac(77)=Anomalous_Sc_Type("ir", (/  -4.527,  -4.578,  -5.391,  -2.066,  -1.216/), &
18526                                                   (/  12.140,   9.389,   6.566,   7.990,   5.427/)  )
18527       Anomalous_ScFac(78)=Anomalous_Sc_Type("pt", (/  -4.584,  -4.535,  -5.233,  -2.352,  -1.319/), &
18528                                                   (/  12.787,   9.895,   6.925,   8.388,   5.708/)  )
18529       Anomalous_ScFac(79)=Anomalous_Sc_Type("au", (/  -4.668,  -4.510,  -5.096,  -2.688,  -1.438/), &
18530                                                   (/  13.451,  10.418,   7.297,   8.798,   5.998/)  )
18531       Anomalous_ScFac(80)=Anomalous_Sc_Type("hg", (/  -4.803,  -4.523,  -4.990,  -3.084,  -1.576/), &
18532                                                   (/  14.143,  10.963,   7.686,   9.223,   6.299/)  )
18533       Anomalous_ScFac(81)=Anomalous_Sc_Type("tl", (/  -4.945,  -4.532,  -4.883,  -3.556,  -1.730/), &
18534                                                   (/  14.860,  11.528,   8.089,   9.659,   6.610/)  )
18535       Anomalous_ScFac(82)=Anomalous_Sc_Type("pb", (/  -5.161,  -4.596,  -4.818,  -4.133,  -1.910/), &
18536                                                   (/  15.595,  12.108,   8.505,  10.102,   6.930/)  )
18537       Anomalous_ScFac(83)=Anomalous_Sc_Type("bi", (/  -5.420,  -4.688,  -4.776,  -4.861,  -2.116/), &
18538                                                   (/  16.341,  12.700,   8.930,  10.559,   7.258/)  )
18539       Anomalous_ScFac(84)=Anomalous_Sc_Type("po", (/  -5.742,  -4.817,  -4.756,  -5.924,  -2.353/), &
18540                                                   (/  17.139,  13.331,   9.383,  11.042,   7.600/)  )
18541       Anomalous_ScFac(85)=Anomalous_Sc_Type("at", (/  -6.132,  -4.992,  -4.772,  -7.444,  -2.630/), &
18542                                                   (/  17.942,  13.969,   9.843,   9.961,   7.949/)  )
18543       Anomalous_ScFac(86)=Anomalous_Sc_Type("rn", (/  -6.545,  -5.173,  -4.787,  -8.862,  -2.932/), &
18544                                                   (/  18.775,  14.629,  10.317,  10.403,   8.307/)  )
18545       Anomalous_ScFac(87)=Anomalous_Sc_Type("fr", (/  -7.052,  -5.402,  -4.833,  -7.912,  -3.285/), &
18546                                                   (/  19.615,  15.299,  10.803,   7.754,   8.674/)  )
18547       Anomalous_ScFac(88)=Anomalous_Sc_Type("ra", (/  -7.614,  -5.659,  -4.898,  -7.620,  -3.702/), &
18548                                                   (/  20.461,  15.977,  11.296,   8.105,   9.047/)  )
18549       Anomalous_ScFac(89)=Anomalous_Sc_Type("ac", (/  -8.318,  -5.976,  -4.994,  -7.725,  -4.192/), &
18550                                                   (/  21.327,  16.668,  11.799,   8.472,   9.428/)  )
18551       Anomalous_ScFac(90)=Anomalous_Sc_Type("th", (/  -9.150,  -6.313,  -5.091,  -8.127,  -4.784/), &
18552                                                   (/  22.240,  17.397,  12.330,   8.870,   9.819/)  )
18553       Anomalous_ScFac(91)=Anomalous_Sc_Type("pa", (/ -10.382,  -6.695,  -5.216,  -8.960,  -5.555/), &
18554                                                   (/  23.161,  18.140,  12.868,   9.284,  10.227/)  )
18555       Anomalous_ScFac(92)=Anomalous_Sc_Type("u ", (/ -10.930,  -7.126,  -5.359, -10.673,  -6.735/), &
18556                                                   (/  23.121,  18.879,  13.409,   9.654,  10.637/)  )
18557       Anomalous_ScFac(93)=Anomalous_Sc_Type("np", (/ -12.152,  -7.624,  -5.529, -11.158,  -7.842/), &
18558                                                   (/  24.097,  19.642,  13.967,   4.148,   9.570/)  )
18559       Anomalous_ScFac(94)=Anomalous_Sc_Type("pu", (/ -12.280,  -8.187,  -5.712,  -9.725,  -8.473/), &
18560                                                   (/  23.658,  20.425,  14.536,   4.330,   6.999/)  )
18561       Anomalous_ScFac(95)=Anomalous_Sc_Type("am", (/ -12.771,  -8.872,  -5.930,  -8.926,  -7.701/), &
18562                                                   (/  24.607,  21.173,  15.087,   4.511,   7.296/)  )
18563       Anomalous_ScFac(96)=Anomalous_Sc_Type("cm", (/ -13.513,  -9.743,  -6.176,  -8.416,  -7.388/), &
18564                                                   (/  25.540,  21.896,  15.634,   4.697,   7.589/)  )
18565       Anomalous_ScFac(97)=Anomalous_Sc_Type("bk", (/ -14.827, -10.539,  -6.498,  -7.990,  -7.485/), &
18566                                                   (/  26.801,  21.942,  16.317,   4.908,   7.931/)  )
18567       Anomalous_ScFac(98)=Anomalous_Sc_Type("ze", (/   0.000,   0.000,   0.000,   0.000,   0.000/), &
18568                                                   (/   0.000,   0.000,   0.000,   0.000,   0.000/)  )
18569       return
18570    End Subroutine Set_Delta_Fp_Fpp
18571
18572    !!----
18573    !!---- Subroutine Set_Magnetic_Form()
18574    !!----
18575    !!----    Magnetic form factors <j0> P.J. Brown, ILL prep. SP.88BR5016
18576    !!----    (March 1988)
18577    !!----
18578    !!---- Update: February - 2005
18579    !!
18580    Subroutine Set_Magnetic_Form()
18581
18582       if (.not. allocated(magnetic_form)) allocate(magnetic_form(num_mag_form))
18583       if (.not. allocated(magnetic_j2))   allocate(magnetic_j2(num_mag_j2))
18584       if (.not. allocated(magnetic_j4))   allocate(magnetic_j4(num_mag_j4))
18585       if (.not. allocated(magnetic_j6))   allocate(magnetic_j6(num_mag_j6))
18586
18587       Magnetic_Form(  1) = Magnetic_Form_Type("MSC0", &
18588                                              (/  0.251200, 90.029602,  0.329000, 39.402100,  0.423500, 14.322200, -0.004300/) )
18589       Magnetic_Form(  2) = Magnetic_Form_Type("MSC1", &
18590                                              (/  0.488900, 51.160301,  0.520300, 14.076400, -0.028600,  0.179200,  0.018500/) )
18591       Magnetic_Form(  3) = Magnetic_Form_Type("MSC2", &
18592                                              (/  0.504800, 31.403500,  0.518600, 10.989700, -0.024100,  1.183100,  0.000000/) )
18593       Magnetic_Form(  4) = Magnetic_Form_Type("MTI0", &
18594                                              (/  0.465700, 33.589802,  0.549000,  9.879100, -0.029100,  0.323200,  0.012300/) )
18595       Magnetic_Form(  5) = Magnetic_Form_Type("MTI1", &
18596                                              (/  0.509300, 36.703300,  0.503200, 10.371300, -0.026300,  0.310600,  0.011600/) )
18597       Magnetic_Form(  6) = Magnetic_Form_Type("MTI2", &
18598                                              (/  0.509100, 24.976299,  0.516200,  8.756900, -0.028100,  0.916000,  0.001500/) )
18599       Magnetic_Form(  7) = Magnetic_Form_Type("MTI3", &
18600                                              (/  0.357100, 22.841299,  0.668800,  8.930600, -0.035400,  0.483300,  0.009900/) )
18601       Magnetic_Form(  8) = Magnetic_Form_Type("MV0 ", &
18602                                              (/  0.408600, 28.810900,  0.607700,  8.543700, -0.029500,  0.276800,  0.012300/) )
18603       Magnetic_Form(  9) = Magnetic_Form_Type("MV1 ", &
18604                                              (/  0.444400, 32.647900,  0.568300,  9.097100, -0.228500,  0.021800,  0.215000/) )
18605       Magnetic_Form( 10) = Magnetic_Form_Type("MV2 ", &
18606                                              (/  0.408500, 23.852600,  0.609100,  8.245600, -0.167600,  0.041500,  0.149600/) )
18607       Magnetic_Form( 11) = Magnetic_Form_Type("MV3 ", &
18608                                              (/  0.359800, 19.336399,  0.663200,  7.617200, -0.306400,  0.029600,  0.283500/) )
18609       Magnetic_Form( 12) = Magnetic_Form_Type("MV4 ", &
18610                                              (/  0.310600, 16.816000,  0.719800,  7.048700, -0.052100,  0.302000,  0.022100/) )
18611       Magnetic_Form( 13) = Magnetic_Form_Type("MCR0", &
18612                                              (/  0.113500, 45.199001,  0.348100, 19.493099,  0.547700,  7.354200, -0.009200/) )
18613       Magnetic_Form( 14) = Magnetic_Form_Type("MCR1", &
18614                                              (/ -0.097700,  0.047000,  0.454400, 26.005400,  0.557900,  7.489200,  0.083100/) )
18615       Magnetic_Form( 15) = Magnetic_Form_Type("MCR2", &
18616                                              (/  1.202400, -0.005500,  0.415800, 20.547501,  0.603200,  6.956000, -1.221800/) )
18617       Magnetic_Form( 16) = Magnetic_Form_Type("MCR3", &
18618                                              (/ -0.309400,  0.027400,  0.368000, 17.035500,  0.655900,  6.523600,  0.285600/) )
18619       Magnetic_Form( 17) = Magnetic_Form_Type("MCR4", &
18620                                              (/ -0.232000,  0.043300,  0.310100, 14.951800,  0.718200,  6.172600,  0.204200/) )
18621       Magnetic_Form( 18) = Magnetic_Form_Type("MMN0", &
18622                                              (/  0.243800, 24.962900,  0.147200, 15.672800,  0.618900,  6.540300, -0.010500/) )
18623       Magnetic_Form( 19) = Magnetic_Form_Type("MMN1", &
18624                                              (/ -0.013800,  0.421300,  0.423100, 24.667999,  0.590500,  6.654500, -0.001000/) )
18625       Magnetic_Form( 20) = Magnetic_Form_Type("MMN2", &
18626                                              (/  0.422000, 17.684000,  0.594800,  6.005000,  0.004300, -0.609000, -0.021900/) )
18627       Magnetic_Form( 21) = Magnetic_Form_Type("MMN3", &
18628                                              (/  0.419800, 14.282900,  0.605400,  5.468900,  0.924100, -0.008800, -0.949800/) )
18629       Magnetic_Form( 22) = Magnetic_Form_Type("MMN4", &
18630                                              (/  0.376000, 12.566100,  0.660200,  5.132900, -0.037200,  0.563000,  0.001100/) )
18631       Magnetic_Form( 23) = Magnetic_Form_Type("MMN5", &
18632                                              (/  0.74050,  5.07409,    0.29237,  11.66547,  -1.78834,   0.00593,   1.75568 /) )
18633       Magnetic_Form( 24) = Magnetic_Form_Type("MFE0", &
18634                                              (/  0.070600, 35.008499,  0.358900, 15.358300,  0.581900,  5.560600, -0.011400/) )
18635       Magnetic_Form( 25) = Magnetic_Form_Type("MFE1", &
18636                                              (/  0.125100, 34.963299,  0.362900, 15.514400,  0.522300,  5.591400, -0.010500/) )
18637       Magnetic_Form( 26) = Magnetic_Form_Type("MFE2", &
18638                                              (/  0.026300, 34.959702,  0.366800, 15.943500,  0.618800,  5.593500, -0.011900/) )
18639       Magnetic_Form( 27) = Magnetic_Form_Type("MFE3", &
18640                                              (/  0.397200, 13.244200,  0.629500,  4.903400, -0.031400,  0.349600,  0.004400/) )
18641       Magnetic_Form( 28) = Magnetic_Form_Type("MFE4", &
18642                                              (/  0.378200, 11.380000,  0.655600,  4.592000, -0.034600,  0.483300,  0.000500/) )
18643       Magnetic_Form( 29) = Magnetic_Form_Type("MCO0", &
18644                                              (/  0.413900, 16.161600,  0.601300,  4.780500, -0.151800,  0.021000,  0.134500/) )
18645       Magnetic_Form( 30) = Magnetic_Form_Type("MCO1", &
18646                                              (/  0.099000, 33.125198,  0.364500, 15.176800,  0.547000,  5.008100, -0.010900/) )
18647       Magnetic_Form( 31) = Magnetic_Form_Type("MCO2", &
18648                                              (/  0.433200, 14.355300,  0.585700,  4.607700, -0.038200,  0.133800,  0.017900/) )
18649       Magnetic_Form( 32) = Magnetic_Form_Type("MCO3", &
18650                                              (/  0.390200, 12.507800,  0.632400,  4.457400, -0.150000,  0.034300,  0.127200/) )
18651       Magnetic_Form( 33) = Magnetic_Form_Type("MCO4", &
18652                                              (/  0.351500, 10.778500,  0.677800,  4.234300, -0.038900,  0.240900,  0.009800/) )
18653       Magnetic_Form( 34) = Magnetic_Form_Type("MNI0", &
18654                                              (/ -0.017200, 35.739201,  0.317400, 14.268900,  0.713600,  4.566100, -0.014300/) )
18655       Magnetic_Form( 35) = Magnetic_Form_Type("MNI1", &
18656                                              (/  0.070500, 35.856098,  0.398400, 13.804200,  0.542700,  4.396500, -0.011800/) )
18657       Magnetic_Form( 36) = Magnetic_Form_Type("MNI2", &
18658                                              (/  0.016300, 35.882599,  0.391600, 13.223300,  0.605200,  4.338800, -0.013300/) )
18659       Magnetic_Form( 37) = Magnetic_Form_Type("MNI3", &
18660                                              (/ -0.013400, 35.867699,  0.267800, 12.332600,  0.761400,  4.236900, -0.016200/) )
18661       Magnetic_Form( 38) = Magnetic_Form_Type("MNI4", &
18662                                              (/ -0.009000, 35.861401,  0.277600, 11.790400,  0.747400,  4.201100, -0.016300/) )
18663       Magnetic_Form( 39) = Magnetic_Form_Type("MCU0", &
18664                                              (/  0.090900, 34.983799,  0.408800, 11.443200,  0.512800,  3.824800, -0.012400/) )
18665       Magnetic_Form( 40) = Magnetic_Form_Type("MCU1", &
18666                                              (/  0.074900, 34.965599,  0.414700, 11.764200,  0.523800,  3.849700, -0.012700/) )
18667       Magnetic_Form( 41) = Magnetic_Form_Type("MCU2", &
18668                                              (/  0.023200, 34.968601,  0.402300, 11.564000,  0.588200,  3.842800, -0.013700/) )
18669       Magnetic_Form( 42) = Magnetic_Form_Type("MCU3", &
18670                                              (/  0.003100, 34.907398,  0.358200, 10.913800,  0.653100,  3.827900, -0.014700/) )
18671       Magnetic_Form( 43) = Magnetic_Form_Type("MCU4", &
18672                                              (/ -0.013200, 30.681700,  0.280100, 11.162600,  0.749000,  3.817200, -0.016500/) )
18673       Magnetic_Form( 44) = Magnetic_Form_Type("MY0 ", &
18674                                              (/  0.591500, 67.608101,  1.512300, 17.900400, -1.113000, 14.135900,  0.008000/) )
18675       Magnetic_Form( 45) = Magnetic_Form_Type("MZR0", &
18676                                              (/  0.410600, 59.996101,  1.054300, 18.647600, -0.475100, 10.540000,  0.010600/) )
18677       Magnetic_Form( 46) = Magnetic_Form_Type("MZR1", &
18678                                              (/  0.453200, 59.594799,  0.783400, 21.435699, -0.245100,  9.036000,  0.009800/) )
18679       Magnetic_Form( 47) = Magnetic_Form_Type("MNB0", &
18680                                              (/  0.394600, 49.229698,  1.319700, 14.821600, -0.726900,  9.615600,  0.012900/) )
18681       Magnetic_Form( 48) = Magnetic_Form_Type("MNB1", &
18682                                              (/  0.457200, 49.918201,  1.027400, 15.725600, -0.496200,  9.157300,  0.011800/) )
18683       Magnetic_Form( 49) = Magnetic_Form_Type("MMO0", &
18684                                              (/  0.180600, 49.056801,  1.230600, 14.785900, -0.426800,  6.986600,  0.017100/) )
18685       Magnetic_Form( 50) = Magnetic_Form_Type("MMO1", &
18686                                              (/  0.350000, 48.035400,  1.030500, 15.060400, -0.392900,  7.479000,  0.013900/) )
18687       Magnetic_Form( 51) = Magnetic_Form_Type("MTC0", &
18688                                              (/  0.129800, 49.661098,  1.165600, 14.130700, -0.313400,  5.512900,  0.019500/) )
18689       Magnetic_Form( 52) = Magnetic_Form_Type("MTC1", &
18690                                              (/  0.267400, 48.956600,  0.956900, 15.141300, -0.238700,  5.457800,  0.016000/) )
18691       Magnetic_Form( 53) = Magnetic_Form_Type("MRU0", &
18692                                              (/  0.106900, 49.423801,  1.191200, 12.741700, -0.317600,  4.912500,  0.021300/) )
18693       Magnetic_Form( 54) = Magnetic_Form_Type("MRU1", &
18694                                              (/  0.441000, 33.308601,  1.477500,  9.553100, -0.936100,  6.722000,  0.017600/) )
18695       Magnetic_Form( 55) = Magnetic_Form_Type("MRH0", &
18696                                              (/  0.097600, 49.882500,  1.160100, 11.830700, -0.278900,  4.126600,  0.023400/) )
18697       Magnetic_Form( 56) = Magnetic_Form_Type("MRH1", &
18698                                              (/  0.334200, 29.756399,  1.220900,  9.438400, -0.575500,  5.332000,  0.021000/) )
18699       Magnetic_Form( 57) = Magnetic_Form_Type("MPD0", &
18700                                              (/  0.200300, 29.363300,  1.144600,  9.599300, -0.368900,  4.042300,  0.025100/) )
18701       Magnetic_Form( 58) = Magnetic_Form_Type("MPD1", &
18702                                              (/  0.503300, 24.503700,  1.998200,  6.908200, -1.524000,  5.513300,  0.021300/) )
18703       Magnetic_Form( 59) = Magnetic_Form_Type("MCE2", &
18704                                              (/  0.295300, 17.684601,  0.292300,  6.732900,  0.431300,  5.382700, -0.019400/) )
18705       Magnetic_Form( 60) = Magnetic_Form_Type("MND2", &
18706                                              (/  0.164500, 25.045300,  0.252200, 11.978200,  0.601200,  4.946100, -0.018000/) )
18707       Magnetic_Form( 61) = Magnetic_Form_Type("MND3", &
18708                                              (/  0.054000, 25.029301,  0.310100, 12.102000,  0.657500,  4.722300, -0.021600/) )
18709       Magnetic_Form( 62) = Magnetic_Form_Type("MSM2", &
18710                                              (/  0.090900, 25.203199,  0.303700, 11.856200,  0.625000,  4.236600, -0.020000/) )
18711       Magnetic_Form( 63) = Magnetic_Form_Type("MSM3", &
18712                                              (/  0.028800, 25.206800,  0.297300, 11.831100,  0.695400,  4.211700, -0.021300/) )
18713       Magnetic_Form( 64) = Magnetic_Form_Type("MEU2", &
18714                                              (/  0.075500, 25.296000,  0.300100, 11.599300,  0.643800,  4.025200, -0.019600/) )
18715       Magnetic_Form( 65) = Magnetic_Form_Type("MEU3", &
18716                                              (/  0.020400, 25.307800,  0.301000, 11.474400,  0.700500,  3.942000, -0.022000/) )
18717       Magnetic_Form( 66) = Magnetic_Form_Type("MGD2", &
18718                                              (/  0.063600, 25.382299,  0.303300, 11.212500,  0.652800,  3.787700, -0.019900/) )
18719       Magnetic_Form( 67) = Magnetic_Form_Type("MGD3", &
18720                                              (/  0.018600, 25.386700,  0.289500, 11.142100,  0.713500,  3.752000, -0.021700/) )
18721       Magnetic_Form( 68) = Magnetic_Form_Type("MTB2", &
18722                                              (/  0.054700, 25.508600,  0.317100, 10.591100,  0.649000,  3.517100, -0.021200/) )
18723       Magnetic_Form( 69) = Magnetic_Form_Type("MTB3", &
18724                                              (/  0.017700, 25.509501,  0.292100, 10.576900,  0.713300,  3.512200, -0.023100/) )
18725       Magnetic_Form( 70) = Magnetic_Form_Type("MDY2", &
18726                                              (/  0.130800, 18.315500,  0.311800,  7.664500,  0.579500,  3.146900, -0.022600/) )
18727       Magnetic_Form( 71) = Magnetic_Form_Type("MDY3", &
18728                                              (/  0.115700, 15.073200,  0.327000,  6.799100,  0.582100,  3.020200, -0.024900/) )
18729       Magnetic_Form( 72) = Magnetic_Form_Type("MHO2", &
18730                                              (/  0.099500, 18.176100,  0.330500,  7.855600,  0.592100,  2.979900, -0.023000/) )
18731       Magnetic_Form( 73) = Magnetic_Form_Type("MHO3", &
18732                                              (/  0.056600, 18.317600,  0.336500,  7.688000,  0.631700,  2.942700, -0.024800/) )
18733       Magnetic_Form( 74) = Magnetic_Form_Type("MER2", &
18734                                              (/  0.112200, 18.122299,  0.346200,  6.910600,  0.564900,  2.761400, -0.023500/) )
18735       Magnetic_Form( 75) = Magnetic_Form_Type("MER3", &
18736                                              (/  0.058600, 17.980200,  0.354000,  7.096400,  0.612600,  2.748200, -0.025100/) )
18737       Magnetic_Form( 76) = Magnetic_Form_Type("MTM2", &
18738                                              (/  0.098300, 18.323601,  0.338000,  6.917800,  0.587500,  2.662200, -0.024100/) )
18739       Magnetic_Form( 77) = Magnetic_Form_Type("MTM3", &
18740                                              (/  0.058100, 15.092200,  0.278700,  7.801500,  0.685400,  2.793100, -0.022400/) )
18741       Magnetic_Form( 78) = Magnetic_Form_Type("MYB2", &
18742                                              (/  0.085500, 18.512300,  0.294300,  7.373400,  0.641200,  2.677700, -0.021300/) )
18743       Magnetic_Form( 79) = Magnetic_Form_Type("MYB3", &
18744                                              (/  0.041600, 16.094900,  0.284900,  7.834100,  0.696100,  2.672500, -0.022900/) )
18745       Magnetic_Form( 80) = Magnetic_Form_Type("MU3 ", &
18746                                              (/  0.505800, 23.288200,  1.346400,  7.002800, -0.872400,  4.868300,  0.019200/) )
18747       Magnetic_Form( 81) = Magnetic_Form_Type("MU4 ", &
18748                                              (/  0.329100, 23.547501,  1.083600,  8.454000, -0.434000,  4.119600,  0.021400/) )
18749       Magnetic_Form( 82) = Magnetic_Form_Type("MU5 ", &
18750                                              (/  0.365000, 19.803801,  3.219900,  6.281800, -2.607700,  5.301000,  0.023300/) )
18751       Magnetic_Form( 83) = Magnetic_Form_Type("MNP3", &
18752                                              (/  0.515700, 20.865400,  2.278400,  5.893000, -1.816300,  4.845700,  0.021100/) )
18753       Magnetic_Form( 84) = Magnetic_Form_Type("MNP4", &
18754                                              (/  0.420600, 19.804600,  2.800400,  5.978300, -2.243600,  4.984800,  0.022800/) )
18755       Magnetic_Form( 85) = Magnetic_Form_Type("MNP5", &
18756                                              (/  0.369200, 18.190001,  3.151000,  5.850000, -2.544600,  4.916400,  0.024800/) )
18757       Magnetic_Form( 86) = Magnetic_Form_Type("MNP6", &
18758                                              (/  0.292900, 17.561100,  3.486600,  5.784700, -2.806600,  4.870700,  0.026700/) )
18759       Magnetic_Form( 87) = Magnetic_Form_Type("MPU3", &
18760                                              (/  0.384000, 16.679300,  3.104900,  5.421000, -2.514800,  4.551200,  0.026300/) )
18761       Magnetic_Form( 88) = Magnetic_Form_Type("MPU4", &
18762                                              (/  0.493400, 16.835501,  1.639400,  5.638400, -1.158100,  4.139900,  0.024800/) )
18763       Magnetic_Form( 89) = Magnetic_Form_Type("MPU5", &
18764                                              (/  0.388800, 16.559200,  2.036200,  5.656700, -1.451500,  4.255200,  0.026700/) )
18765       Magnetic_Form( 90) = Magnetic_Form_Type("MPU6", &
18766                                              (/  0.317200, 16.050699,  3.465400,  5.350700, -2.810200,  4.513300,  0.028100/) )
18767       Magnetic_Form( 91) = Magnetic_Form_Type("MAM2", &
18768                                              (/  0.474300, 21.776100,  1.580000,  5.690200, -1.077900,  4.145100,  0.021800/) )
18769       Magnetic_Form( 92) = Magnetic_Form_Type("MAM3", &
18770                                              (/  0.423900, 19.573900,  1.457300,  5.872200, -0.905200,  3.968200,  0.023800/) )
18771       Magnetic_Form( 93) = Magnetic_Form_Type("MAM4", &
18772                                              (/  0.373700, 17.862499,  1.352100,  6.042600, -0.751400,  3.719900,  0.025800/) )
18773       Magnetic_Form( 94) = Magnetic_Form_Type("MAM5", &
18774                                              (/  0.295600, 17.372499,  1.452500,  6.073400, -0.775500,  3.661900,  0.027700/) )
18775       Magnetic_Form( 95) = Magnetic_Form_Type("MAM6", &
18776                                              (/  0.230200, 16.953300,  1.486400,  6.115900, -0.745700,  3.542600,  0.029400/) )
18777       Magnetic_Form( 96) = Magnetic_Form_Type("MAM7", &
18778                                              (/  0.360100, 12.729900,  1.964000,  5.120300, -1.356000,  3.714200,  0.031600/) )
18779       Magnetic_Form( 97) = Magnetic_Form_Type("MPR3", &
18780                                              (/  0.050400, 24.998900,  0.257200, 12.037700,  0.714200,  5.003900, -0.021900/) )
18781       Magnetic_Form( 98) = Magnetic_Form_Type("MO1", &
18782                                              (/  0.115285, 85.197300,  0.556229, 25.252200,  0.332476,  6.362070, -0.00460676/) )
18783       Magnetic_Form( 99) = Magnetic_Form_Type("MXX1", &
18784                                              (/  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0/) ) !for future use
18785       Magnetic_Form(100) = Magnetic_Form_Type("MXX2", &
18786                                              (/  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0/) ) !for future use
18787       Magnetic_Form(101) = Magnetic_Form_Type("JCE2", &
18788                                              (/  0.031972,  8.926222,  0.265792,  7.678510,  0.682151,  2.329783,  0.020578/) )
18789       Magnetic_Form(102) = Magnetic_Form_Type("JCE3", &
18790                                              (/  0.051183,  6.115375,  0.277738,  7.952485,  0.654079,  2.287000,  0.016355/) )
18791       Magnetic_Form(103) = Magnetic_Form_Type("JPR3", &
18792                                              (/  0.023288,  0.582954,  0.349391,  5.601756,  0.615363,  1.932779,  0.011454/) )
18793       Magnetic_Form(104) = Magnetic_Form_Type("JND2", &
18794                                              (/  0.089354,  2.282004,  0.206157,  1.708607,  0.669916,  2.297662,  0.048390/) )
18795       Magnetic_Form(105) = Magnetic_Form_Type("JND3", &
18796                                              (/  0.073287,  4.412361,  0.371485,  4.019648,  0.539459,  1.557985,  0.017335/) )
18797       Magnetic_Form(106) = Magnetic_Form_Type("JGD3", &
18798                                              (/  0.060537, 10.775218,  0.271475, 13.097898,  0.665241,  3.162837,  0.001566/) )
18799       Magnetic_Form(107) = Magnetic_Form_Type("JTB2", &
18800                                              (/  0.049801, 18.734161,  0.277437, 10.084129,  0.661194,  2.745624,  0.010774/) )
18801       Magnetic_Form(108) = Magnetic_Form_Type("JTB3", &
18802                                              (/  0.049792, 15.112189,  0.270644,  9.158312,  0.679388,  2.880260, -0.000131/) )
18803       Magnetic_Form(109) = Magnetic_Form_Type("JDY2", &
18804                                              (/  0.175586,  5.938148,  0.228867, 11.464046,  0.583298,  2.167554,  0.011186/) )
18805       Magnetic_Form(110) = Magnetic_Form_Type("JDY3", &
18806                                              (/  0.146536, 12.639305,  0.375822,  5.511785,  0.515731,  2.090789,  0.093576/) )
18807       Magnetic_Form(111) = Magnetic_Form_Type("JHO2", &
18808                                              (/  0.023234,  0.703240,  0.270745,  9.993475,  0.677581,  2.521403,  0.027101/) )
18809       Magnetic_Form(112) = Magnetic_Form_Type("JHO2", &
18810                                              (/  0.023234,  0.703240,  0.270745,  9.993475,  0.677581,  2.521403,  0.027101/) )
18811       Magnetic_Form(113) = Magnetic_Form_Type("JHO3", &
18812                                              (/  0.043204,  0.910121,  0.279392,  8.683387,  0.668537,  2.417518,  0.008207/) )
18813       Magnetic_Form(114) = Magnetic_Form_Type("JER2", &
18814                                              (/  0.037734,  6.081446,  0.256447,  9.598846,  0.679204,  2.139296,  0.025543/) )
18815       Magnetic_Form(115) = Magnetic_Form_Type("JER3", &
18816                                              (/  0.038871,  5.311772,  0.259781,  8.173226,  0.678414,  2.082836,  0.022169/) )
18817       Magnetic_Form(116) = Magnetic_Form_Type("JTM2", &
18818                                              (/  0.037670,  4.455198,  0.254184,  9.151058,  0.677308,  2.021746,  0.029718/) )
18819       Magnetic_Form(117) = Magnetic_Form_Type("JTM3", &
18820                                              (/  0.028279,  2.291633,  0.265583,  7.776700,  0.675720,  2.018924,  0.029883/) )
18821       Magnetic_Form(118) = Magnetic_Form_Type("JYB3", &
18822                                           (/  0.092380,  2.046342,  0.258408,  7.471918,  0.609716,  1.913869,  0.038824/) )
18823       Magnetic_Form(119) = Magnetic_Form_Type("JO1 ", &
18824                                              (/  0.115285, 85.197300,  0.556229, 25.252200,  0.332476,  6.362070,-0.00460676/) )
18825
18826       !---- <j2> Coefficients ----!
18827       Magnetic_j2(  1) = Magnetic_Form_Type("SC0 ",(/10.8172,54.327, 4.7353,14.847, 0.6071, 4.218, 0.0011/))
18828       Magnetic_j2(  2) = Magnetic_Form_Type("SC1 ",(/ 8.5021,34.285, 3.2116,10.994, 0.4244, 3.605, 0.0009/))
18829       Magnetic_j2(  3) = Magnetic_Form_Type("SC2 ",(/ 4.3683,28.654, 3.7231,10.823, 0.6074, 3.668, 0.0014/))
18830       Magnetic_j2(  4) = Magnetic_Form_Type("TI0 ",(/ 4.3583,36.056, 3.8230,11.133, 0.6855, 3.469, 0.0020/))
18831       Magnetic_j2(  5) = Magnetic_Form_Type("TI1 ",(/ 6.1567,27.275, 2.6833, 8.983, 0.4070, 3.052, 0.0011/))
18832       Magnetic_j2(  6) = Magnetic_Form_Type("TI2 ",(/ 4.3107,18.348, 2.0960, 6.797, 0.2984, 2.548, 0.0007/))
18833       Magnetic_j2(  7) = Magnetic_Form_Type("TI3 ",(/ 3.3717,14.444, 1.8258, 5.713, 0.2470, 2.265, 0.0005/))
18834       Magnetic_j2(  8) = Magnetic_Form_Type("V0  ",(/ 3.8099,21.347, 2.3295, 7.409, 0.4333, 2.632, 0.0015/))
18835       Magnetic_j2(  9) = Magnetic_Form_Type("V1  ",(/ 4.7474,23.323, 2.3609, 7.808, 0.4105, 2.706, 0.0014/))
18836       Magnetic_j2( 10) = Magnetic_Form_Type("V2  ",(/ 3.4386,16.530, 1.9638, 6.141, 0.2997, 2.267, 0.0009/))
18837       Magnetic_j2( 11) = Magnetic_Form_Type("V3  ",(/ 2.3005,14.682, 2.0364, 6.130, 0.4099, 2.382, 0.0014/))
18838       Magnetic_j2( 12) = Magnetic_Form_Type("V4  ",(/ 1.8377,12.267, 1.8247, 5.458, 0.3979, 2.248, 0.0012/))
18839       Magnetic_j2( 13) = Magnetic_Form_Type("CR0 ",(/ 3.4085,20.127, 2.1006, 6.802, 0.4266, 2.394, 0.0019/))
18840       Magnetic_j2( 14) = Magnetic_Form_Type("CR1 ",(/ 3.7768,20.346, 2.1028, 6.893, 0.4010, 2.411, 0.0017/))
18841       Magnetic_j2( 15) = Magnetic_Form_Type("CR2 ",(/ 2.6422,16.060, 1.9198, 6.253, 0.4446, 2.372, 0.0020/))
18842       Magnetic_j2( 16) = Magnetic_Form_Type("CR3 ",(/ 1.6262,15.066, 2.0618, 6.284, 0.5281, 2.368, 0.0023/))
18843       Magnetic_j2( 17) = Magnetic_Form_Type("CR4 ",(/ 1.0293,13.950, 1.9933, 6.059, 0.5974, 2.346, 0.0027/))
18844       Magnetic_j2( 18) = Magnetic_Form_Type("MN0 ",(/ 2.6681,16.060, 1.7561, 5.640, 0.3675, 2.049, 0.0017/))
18845       Magnetic_j2( 19) = Magnetic_Form_Type("MN1 ",(/ 3.2953,18.695, 1.8792, 6.240, 0.3927, 2.201, 0.0022/))
18846       Magnetic_j2( 20) = Magnetic_Form_Type("MN2 ",(/ 2.0515,15.556, 1.8841, 6.063, 0.4787, 2.232, 0.0027/))
18847       Magnetic_j2( 21) = Magnetic_Form_Type("MN3 ",(/ 1.2427,14.997, 1.9567, 6.118, 0.5732, 2.258, 0.0031/))
18848       Magnetic_j2( 22) = Magnetic_Form_Type("MN4 ",(/ 0.7879,13.886, 1.8717, 5.743, 0.5981, 2.182, 0.0034/))
18849       Magnetic_j2( 23) = Magnetic_Form_Type("MN5 ",(/-0.11904,6.59893,-0.23941,10.73086, 0.35048,1.49116,0.00776/))
18850       Magnetic_j2( 24) = Magnetic_Form_Type("FE0 ",(/ 1.9405,18.473, 1.9566, 6.323, 0.5166, 2.161, 0.0036/))
18851       Magnetic_j2( 25) = Magnetic_Form_Type("FE1 ",(/ 2.6290,18.660, 1.8704, 6.331, 0.4690, 2.163, 0.0031/))
18852       Magnetic_j2( 26) = Magnetic_Form_Type("FE2 ",(/ 1.6490,16.559, 1.9064, 6.133, 0.5206, 2.137, 0.0035/))
18853       Magnetic_j2( 27) = Magnetic_Form_Type("FE3 ",(/ 1.3602,11.998, 1.5188, 5.003, 0.4705, 1.991, 0.0038/))
18854       Magnetic_j2( 28) = Magnetic_Form_Type("FE4 ",(/ 1.5582, 8.275, 1.1863, 3.279, 0.1366, 1.107,-0.0022/))
18855       Magnetic_j2( 29) = Magnetic_Form_Type("CO0 ",(/ 1.9678,14.170, 1.4911, 4.948, 0.3844, 1.797, 0.0027/))
18856       Magnetic_j2( 30) = Magnetic_Form_Type("CO1 ",(/ 2.4097,16.161, 1.5780, 5.460, 0.4095, 1.914, 0.0031/))
18857       Magnetic_j2( 31) = Magnetic_Form_Type("CO2 ",(/ 1.9049,11.644, 1.3159, 4.357, 0.3146, 1.645, 0.0017/))
18858       Magnetic_j2( 32) = Magnetic_Form_Type("CO3 ",(/ 1.7058, 8.859, 1.1409, 3.309, 0.1474, 1.090,-0.0025/))
18859       Magnetic_j2( 33) = Magnetic_Form_Type("CO4 ",(/ 1.3110, 8.025, 1.1551, 3.179, 0.1608, 1.130,-0.0011/))
18860       Magnetic_j2( 34) = Magnetic_Form_Type("NI0 ",(/ 1.0302,12.252, 1.4669, 4.745, 0.4521, 1.744, 0.0036/))
18861       Magnetic_j2( 35) = Magnetic_Form_Type("NI1 ",(/ 2.1040,14.866, 1.4302, 5.071, 0.4031, 1.778, 0.0034/))
18862       Magnetic_j2( 36) = Magnetic_Form_Type("NI2 ",(/ 1.7080,11.016, 1.2147, 4.103, 0.3150, 1.533, 0.0018/))
18863       Magnetic_j2( 37) = Magnetic_Form_Type("NI3 ",(/ 1.1612, 7.700, 1.0027, 3.263, 0.2719, 1.378, 0.0025/))
18864       Magnetic_j2( 38) = Magnetic_Form_Type("NI4 ",(/ 1.1612, 7.700, 1.0027, 3.263, 0.2719, 1.378, 0.0025/))
18865       Magnetic_j2( 39) = Magnetic_Form_Type("CU0 ",(/ 1.9182,14.490, 1.3329, 4.730, 0.3842, 1.639, 0.0035/))
18866       Magnetic_j2( 40) = Magnetic_Form_Type("CU1 ",(/ 1.8814,13.433, 1.2809, 4.545, 0.3646, 1.602, 0.0033/))
18867       Magnetic_j2( 41) = Magnetic_Form_Type("CU2 ",(/ 1.5189,10.478, 1.1512, 3.813, 0.2918, 1.398, 0.0017/))
18868       Magnetic_j2( 42) = Magnetic_Form_Type("CU3 ",(/ 1.2797, 8.450, 1.0315, 3.280, 0.2401, 1.250, 0.0015/))
18869       Magnetic_j2( 43) = Magnetic_Form_Type("CU4 ",(/ 0.9568, 7.448, 0.9099, 3.396, 0.3729, 1.494, 0.0049/))
18870       Magnetic_j2( 44) = Magnetic_Form_Type("Y0  ",(/14.4084,44.658, 5.1045,14.904,-0.0535, 3.319, 0.0028/))
18871       Magnetic_j2( 45) = Magnetic_Form_Type("ZR0 ",(/10.1378,35.337, 4.7734,12.545,-0.0489, 2.672, 0.0036/))
18872       Magnetic_j2( 46) = Magnetic_Form_Type("ZR1 ",(/11.8722,34.920, 4.0502,12.127,-0.0632, 2.828, 0.0034/))
18873       Magnetic_j2( 47) = Magnetic_Form_Type("NB0 ",(/ 7.4796,33.179, 5.0884,11.571,-0.0281, 1.564, 0.0047/))
18874       Magnetic_j2( 48) = Magnetic_Form_Type("NB1 ",(/ 8.7735,33.285, 4.6556,11.605,-0.0268, 1.539, 0.0044/))
18875       Magnetic_j2( 49) = Magnetic_Form_Type("MO0 ",(/ 5.1180,23.422, 4.1809, 9.208,-0.0505, 1.743, 0.0053/))
18876       Magnetic_j2( 50) = Magnetic_Form_Type("MO1 ",(/ 7.2367,28.128, 4.0705, 9.923,-0.0317, 1.455, 0.0049/))
18877       Magnetic_j2( 51) = Magnetic_Form_Type("TC0 ",(/ 4.2441,21.397, 3.9439, 8.375,-0.0371, 1.187, 0.0066/))
18878       Magnetic_j2( 52) = Magnetic_Form_Type("TC1 ",(/ 6.4056,24.824, 3.5400, 8.611,-0.0366, 1.485, 0.0044/))
18879       Magnetic_j2( 53) = Magnetic_Form_Type("RU0 ",(/ 3.7445,18.613, 3.4749, 7.420,-0.0363, 1.007, 0.0073/))
18880       Magnetic_j2( 54) = Magnetic_Form_Type("RU1 ",(/ 5.2826,23.683, 3.5813, 8.152,-0.0257, 0.426, 0.0131/))
18881       Magnetic_j2( 55) = Magnetic_Form_Type("RH0 ",(/ 3.3651,17.344, 3.2121, 6.804,-0.0350, 0.503, 0.0146/))
18882       Magnetic_j2( 56) = Magnetic_Form_Type("RH1 ",(/ 4.0260,18.950, 3.1663, 7.000,-0.0296, 0.486, 0.0127/))
18883       Magnetic_j2( 57) = Magnetic_Form_Type("PD0 ",(/ 3.3105,14.726, 2.6332, 5.862,-0.0437, 1.130, 0.0053/))
18884       Magnetic_j2( 58) = Magnetic_Form_Type("PD1 ",(/ 4.2749,17.900, 2.7021, 6.354,-0.0258, 0.700, 0.0071/))
18885       Magnetic_j2( 59) = Magnetic_Form_Type("CE2 ",(/ 0.9809,18.063, 1.8413, 7.769, 0.9905, 2.845, 0.0120/))
18886       Magnetic_j2( 60) = Magnetic_Form_Type("ND2 ",(/ 1.4530,18.340, 1.6196, 7.285, 0.8752, 2.622, 0.0126/))
18887       Magnetic_j2( 61) = Magnetic_Form_Type("ND3 ",(/ 0.6751,18.342, 1.6272, 7.260, 0.9644, 2.602, 0.0150/))
18888       Magnetic_j2( 62) = Magnetic_Form_Type("SM2 ",(/ 1.0360,18.425, 1.4769, 7.032, 0.8810, 2.437, 0.0152/))
18889       Magnetic_j2( 63) = Magnetic_Form_Type("SM3 ",(/ 0.4707,18.430, 1.4261, 7.034, 0.9574, 2.439, 0.0182/))
18890       Magnetic_j2( 64) = Magnetic_Form_Type("EU2 ",(/ 0.8970,18.443, 1.3769, 7.005, 0.9060, 2.421, 0.0190/))
18891       Magnetic_j2( 65) = Magnetic_Form_Type("EU3 ",(/ 0.3985,18.451, 1.3307, 6.956, 0.9603, 2.378, 0.0197/))
18892       Magnetic_j2( 66) = Magnetic_Form_Type("GD2 ",(/ 0.7756,18.469, 1.3124, 6.899, 0.8956, 2.338, 0.0199/))
18893       Magnetic_j2( 67) = Magnetic_Form_Type("GD3 ",(/ 0.3347,18.476, 1.2465, 6.877, 0.9537, 2.318, 0.0217/))
18894       Magnetic_j2( 68) = Magnetic_Form_Type("TB2 ",(/ 0.6688,18.491, 1.2487, 6.822, 0.8888, 2.275, 0.0215/))
18895       Magnetic_j2( 69) = Magnetic_Form_Type("TB3 ",(/ 0.2892,18.497, 1.1678, 6.797, 0.9437, 2.257, 0.0232/))
18896       Magnetic_j2( 70) = Magnetic_Form_Type("DY2 ",(/ 0.5917,18.511, 1.1828, 6.747, 0.8801, 2.214, 0.0229/))
18897       Magnetic_j2( 71) = Magnetic_Form_Type("DY3 ",(/ 0.2523,18.517, 1.0914, 6.736, 0.9345, 2.208, 0.0250/))
18898       Magnetic_j2( 72) = Magnetic_Form_Type("HO2 ",(/ 0.5094,18.515, 1.1234, 6.706, 0.8727, 2.159, 0.0242/))
18899       Magnetic_j2( 73) = Magnetic_Form_Type("HO3 ",(/ 0.2188,18.516, 1.0240, 6.707, 0.9251, 2.161, 0.0268/))
18900       Magnetic_j2( 74) = Magnetic_Form_Type("ER2 ",(/ 0.4693,18.528, 1.0545, 6.649, 0.8679, 2.120, 0.0261/))
18901       Magnetic_j2( 75) = Magnetic_Form_Type("ER3 ",(/ 0.1710,18.534, 0.9879, 6.625, 0.9044, 2.100, 0.0278/))
18902       Magnetic_j2( 76) = Magnetic_Form_Type("TM2 ",(/ 0.4198,18.542, 0.9959, 6.600, 0.8593, 2.082, 0.0284/))
18903       Magnetic_j2( 77) = Magnetic_Form_Type("TM3 ",(/ 0.1760,18.542, 0.9105, 6.579, 0.8970, 2.062, 0.0294/))
18904       Magnetic_j2( 78) = Magnetic_Form_Type("YB2 ",(/ 0.3852,18.550, 0.9415, 6.551, 0.8492, 2.043, 0.0301/))
18905       Magnetic_j2( 79) = Magnetic_Form_Type("YB3 ",(/ 0.1570,18.555, 0.8484, 6.540, 0.8880, 2.037, 0.0318/))
18906       Magnetic_j2( 80) = Magnetic_Form_Type("U3  ",(/ 4.1582,16.534, 2.4675, 5.952,-0.0252, 0.765, 0.0057/))
18907       Magnetic_j2( 81) = Magnetic_Form_Type("U4  ",(/ 3.7449,13.894, 2.6453, 4.863,-0.5218, 3.192, 0.0009/))
18908       Magnetic_j2( 82) = Magnetic_Form_Type("U5  ",(/ 3.0724,12.546, 2.3076, 5.231,-0.0644, 1.474, 0.0035/))
18909       Magnetic_j2( 83) = Magnetic_Form_Type("NP3 ",(/ 3.7170,15.133, 2.3216, 5.503,-0.0275, 0.800, 0.0052/))
18910       Magnetic_j2( 84) = Magnetic_Form_Type("NP4 ",(/ 2.9203,14.646, 2.5979, 5.559,-0.0301, 0.367, 0.0141/))
18911       Magnetic_j2( 85) = Magnetic_Form_Type("NP5 ",(/ 2.3308,13.654, 2.7219, 5.494,-0.1357, 0.049, 0.1224/))
18912       Magnetic_j2( 86) = Magnetic_Form_Type("NP6 ",(/ 1.8245,13.180, 2.8508, 5.407,-0.1579, 0.044, 0.1438/))
18913       Magnetic_j2( 87) = Magnetic_Form_Type("PU3 ",(/ 2.0885,12.871, 2.5961, 5.190,-0.1465, 0.039, 0.1343/))
18914       Magnetic_j2( 88) = Magnetic_Form_Type("PU4 ",(/ 2.7244,12.926, 2.3387, 5.163,-0.1300, 0.046, 0.1177/))
18915       Magnetic_j2( 89) = Magnetic_Form_Type("PU5 ",(/ 2.1409,12.832, 2.5664, 5.152,-0.1338, 0.046, 0.1210/))
18916       Magnetic_j2( 90) = Magnetic_Form_Type("PU6 ",(/ 1.7262,12.324, 2.6652, 5.066,-0.1695, 0.041, 0.1550/))
18917       Magnetic_j2( 91) = Magnetic_Form_Type("AM2 ",(/ 3.5237,15.955, 2.2855, 5.195,-0.0142, 0.585, 0.0033/))
18918       Magnetic_j2( 92) = Magnetic_Form_Type("AM3 ",(/ 2.8622,14.733, 2.4099, 5.144,-0.1326, 0.031, 0.1233/))
18919       Magnetic_j2( 93) = Magnetic_Form_Type("AM4 ",(/ 2.4141,12.948, 2.3687, 4.945,-0.2490, 0.022, 0.2371/))
18920       Magnetic_j2( 94) = Magnetic_Form_Type("AM5 ",(/ 2.0109,12.053, 2.4155, 4.836,-0.2264, 0.027, 0.2128/))
18921       Magnetic_j2( 95) = Magnetic_Form_Type("AM6 ",(/ 1.6778,11.337, 2.4531, 4.725,-0.2043, 0.034, 0.1892/))
18922       Magnetic_j2( 96) = Magnetic_Form_Type("AM7 ",(/ 1.8845, 9.161, 2.0746, 4.042,-0.1318, 1.723, 0.0020/))
18923       Magnetic_j2( 97) = Magnetic_Form_Type("PR3 ",(/ 0.8734,18.9876,1.5594,6.0872, 0.8142,2.4150, 0.0111/))
18924
18925       !---- <j4> Coefficients ----!
18926       Magnetic_j4(  1) = Magnetic_Form_Type("SC0 ",(/ 1.3420,10.200, 0.3837, 3.079, 0.0468, 0.118,-0.0328/))
18927       Magnetic_j4(  2) = Magnetic_Form_Type("SC1 ",(/ 7.1167,15.487,-6.6671,18.269, 0.4900, 2.992, 0.0047/))
18928       Magnetic_j4(  3) = Magnetic_Form_Type("SC2 ",(/-1.6684,15.648, 1.7742, 9.062, 0.4075, 2.412, 0.0042/))
18929       Magnetic_j4(  4) = Magnetic_Form_Type("TI0 ",(/-2.1515,11.271, 2.5149, 8.859, 0.3555, 2.149, 0.0045/))
18930       Magnetic_j4(  5) = Magnetic_Form_Type("TI1 ",(/-1.0383,16.190, 1.4699, 8.924, 0.3631, 2.283, 0.0044/))
18931       Magnetic_j4(  6) = Magnetic_Form_Type("TI2 ",(/-1.3242,15.310, 1.2042, 7.899, 0.3976, 2.156, 0.0051/))
18932       Magnetic_j4(  7) = Magnetic_Form_Type("TI3 ",(/-1.1117,14.635, 0.7689, 6.927, 0.4385, 2.089, 0.0060/))
18933       Magnetic_j4(  8) = Magnetic_Form_Type("V0  ",(/-0.9633,15.273, 0.9274, 7.732, 0.3891, 2.053, 0.0063/))
18934       Magnetic_j4(  9) = Magnetic_Form_Type("V1  ",(/-0.9606,15.545, 1.1278, 8.118, 0.3653, 2.097, 0.0056/))
18935       Magnetic_j4( 10) = Magnetic_Form_Type("V2  ",(/-1.1729,14.973, 0.9092, 7.613, 0.4105, 2.039, 0.0067/))
18936       Magnetic_j4( 11) = Magnetic_Form_Type("V3  ",(/-0.9417,14.205, 0.5284, 6.607, 0.4411, 1.967, 0.0076/))
18937       Magnetic_j4( 12) = Magnetic_Form_Type("V4  ",(/-0.7654,13.097, 0.3071, 5.674, 0.4476, 1.871, 0.0081/))
18938       Magnetic_j4( 13) = Magnetic_Form_Type("CR0 ",(/-0.6670,19.613, 0.5342, 6.478, 0.3641, 1.905, 0.0073/))
18939       Magnetic_j4( 14) = Magnetic_Form_Type("CR1 ",(/-0.8309,18.043, 0.7252, 7.531, 0.3828, 2.003, 0.0073/))
18940       Magnetic_j4( 15) = Magnetic_Form_Type("CR2 ",(/-0.8930,15.664, 0.5590, 7.033, 0.4093, 1.924, 0.0081/))
18941       Magnetic_j4( 16) = Magnetic_Form_Type("CR3 ",(/-0.7327,14.073, 0.3268, 5.674, 0.4114, 1.810, 0.0085/))
18942       Magnetic_j4( 17) = Magnetic_Form_Type("CR4 ",(/-0.6748,12.946, 0.1805, 6.753, 0.4526, 1.800, 0.0098/))
18943       Magnetic_j4( 18) = Magnetic_Form_Type("MN0 ",(/-0.5452,15.471, 0.4406, 4.902, 0.2884, 1.543, 0.0059/))
18944       Magnetic_j4( 19) = Magnetic_Form_Type("MN1 ",(/-0.7947,17.867, 0.6078, 7.704, 0.3798, 1.905, 0.0087/))
18945       Magnetic_j4( 20) = Magnetic_Form_Type("MN2 ",(/-0.7416,15.255, 0.3831, 6.469, 0.3935, 1.800, 0.0093/))
18946       Magnetic_j4( 21) = Magnetic_Form_Type("MN3 ",(/-0.6603,13.607, 0.2322, 6.218, 0.4104, 1.740, 0.0101/))
18947       Magnetic_j4( 22) = Magnetic_Form_Type("MN4 ",(/-0.5127,13.461, 0.0313, 7.763, 0.4282, 1.701, 0.0113/))
18948       Magnetic_j4( 23) = Magnetic_Form_Type("MN5 ",(/0.19236,0.32487,1.67062,6.65663,-1.82036,6.19424,-0.04334/))
18949       Magnetic_j4( 24) = Magnetic_Form_Type("FE0 ",(/-0.5029,19.677, 0.2999, 3.776, 0.2576, 1.424, 0.0071/))
18950       Magnetic_j4( 25) = Magnetic_Form_Type("FE1 ",(/-0.5109,19.250, 0.3896, 4.891, 0.2810, 1.526, 0.0069/))
18951       Magnetic_j4( 26) = Magnetic_Form_Type("FE2 ",(/-0.5401,17.227, 0.2865, 3.742, 0.2658, 1.424, 0.0076/))
18952       Magnetic_j4( 27) = Magnetic_Form_Type("FE3 ",(/-0.5507,11.493, 0.2153, 4.906, 0.3468, 1.523, 0.0095/))
18953       Magnetic_j4( 28) = Magnetic_Form_Type("FE4 ",(/-0.5352, 9.507, 0.1783, 5.175, 0.3584, 1.469, 0.0097/))
18954       Magnetic_j4( 29) = Magnetic_Form_Type("CO0 ",(/-0.4221,14.195, 0.2900, 3.979, 0.2469, 1.286, 0.0063/))
18955       Magnetic_j4( 30) = Magnetic_Form_Type("CO1 ",(/-0.4115,14.561, 0.3580, 4.717, 0.2644, 1.418, 0.0074/))
18956       Magnetic_j4( 31) = Magnetic_Form_Type("CO2 ",(/-0.4759,14.046, 0.2747, 3.731, 0.2458, 1.250, 0.0057/))
18957       Magnetic_j4( 32) = Magnetic_Form_Type("CO3 ",(/-0.4466,13.391, 0.1419, 3.011, 0.2773, 1.335, 0.0093/))
18958       Magnetic_j4( 33) = Magnetic_Form_Type("CO4 ",(/-0.4091,13.194,-0.0194, 3.417, 0.3534, 1.421, 0.0112/))
18959       Magnetic_j4( 34) = Magnetic_Form_Type("NI0 ",(/-0.4428,14.485, 0.0870, 3.234, 0.2932, 1.331, 0.0096/))
18960       Magnetic_j4( 35) = Magnetic_Form_Type("NI1 ",(/-0.3836,13.425, 0.3116, 4.462, 0.2471, 1.309, 0.0079/))
18961       Magnetic_j4( 36) = Magnetic_Form_Type("NI2 ",(/-0.3803,10.403, 0.2838, 3.378, 0.2108, 1.104, 0.0050/))
18962       Magnetic_j4( 37) = Magnetic_Form_Type("NI3 ",(/-0.3715, 8.952, 0.1211, 2.940, 0.2526, 1.105, 0.0061/))
18963       Magnetic_j4( 38) = Magnetic_Form_Type("NI4 ",(/-0.3509, 8.157, 0.2220, 2.106, 0.1567, 0.925, 0.0065/))
18964       Magnetic_j4( 39) = Magnetic_Form_Type("CU0 ",(/-0.3204,15.132, 0.2335, 4.021, 0.2312, 1.196, 0.0068/))
18965       Magnetic_j4( 40) = Magnetic_Form_Type("CU1 ",(/-0.3572,15.125, 0.2336, 3.966, 0.2315, 1.197, 0.0070/))
18966       Magnetic_j4( 41) = Magnetic_Form_Type("CU2 ",(/-0.3914,14.740, 0.1275, 3.384, 0.2548, 1.255, 0.0103/))
18967       Magnetic_j4( 42) = Magnetic_Form_Type("CU3 ",(/-0.3671,14.082,-0.0078, 3.315, 0.3154, 1.377, 0.0132/))
18968       Magnetic_j4( 43) = Magnetic_Form_Type("CU4 ",(/-0.2915,14.124,-0.1065, 4.201, 0.3247, 1.352, 0.0148/))
18969       Magnetic_j4( 44) = Magnetic_Form_Type("Y0  ",(/-8.0767,32.201, 7.9197,25.156, 1.4067, 6.827,-0.0001/))
18970       Magnetic_j4( 45) = Magnetic_Form_Type("ZR0 ",(/-5.2697,32.868, 4.1930,24.183, 1.5202, 6.048,-0.0002/))
18971       Magnetic_j4( 46) = Magnetic_Form_Type("ZR1 ",(/-5.6384,33.607, 4.6729,22.338, 1.3258, 5.924,-0.0003/))
18972       Magnetic_j4( 47) = Magnetic_Form_Type("NB0 ",(/-3.1377,25.595, 2.3411,16.569, 1.2304, 4.990,-0.0005/))
18973       Magnetic_j4( 48) = Magnetic_Form_Type("NB1 ",(/-3.3598,25.820, 2.8297,16.427, 1.1203, 4.982,-0.0005/))
18974       Magnetic_j4( 49) = Magnetic_Form_Type("MO0 ",(/-2.8860,20.572, 1.8130,14.628, 1.1899, 4.264,-0.0008/))
18975       Magnetic_j4( 50) = Magnetic_Form_Type("MO1 ",(/-3.2618,25.486, 2.3596,16.462, 1.1164, 4.491,-0.0007/))
18976       Magnetic_j4( 51) = Magnetic_Form_Type("TC0 ",(/-2.7975,20.159, 1.6520,16.261, 1.1726, 3.943,-0.0008/))
18977       Magnetic_j4( 52) = Magnetic_Form_Type("TC1 ",(/-2.0470,19.683, 1.6306,11.592, 0.8698, 3.769,-0.0010/))
18978       Magnetic_j4( 53) = Magnetic_Form_Type("RU0 ",(/-1.5042,17.949, 0.6027, 9.961, 0.9700, 3.393,-0.0010/))
18979       Magnetic_j4( 54) = Magnetic_Form_Type("RU1 ",(/-1.6278,18.506, 1.1828,10.189, 0.8138, 3.418,-0.0009/))
18980       Magnetic_j4( 55) = Magnetic_Form_Type("RH0 ",(/-1.3492,17.577, 0.4527,10.507, 0.9285, 3.155,-0.0009/))
18981       Magnetic_j4( 56) = Magnetic_Form_Type("RH1 ",(/-1.4673,17.957, 0.7381, 9.944, 0.8485, 3.126,-0.0012/))
18982       Magnetic_j4( 57) = Magnetic_Form_Type("PD0 ",(/-1.1955,17.628, 0.3183,11.309, 0.8696, 2.909,-0.0006/))
18983       Magnetic_j4( 58) = Magnetic_Form_Type("PD1 ",(/-1.4098,17.765, 0.7927, 9.999, 0.7710, 2.930,-0.0006/))
18984       Magnetic_j4( 59) = Magnetic_Form_Type("CE2 ",(/-0.6468,10.533, 0.4052, 5.624, 0.3412, 1.535, 0.0080/))
18985       Magnetic_j4( 60) = Magnetic_Form_Type("ND2 ",(/-0.5416,12.204, 0.3571, 6.169, 0.3154, 1.485, 0.0098/))
18986       Magnetic_j4( 61) = Magnetic_Form_Type("ND3 ",(/-0.4053,14.014, 0.0329, 7.005, 0.3759, 1.707, 0.0209/))
18987       Magnetic_j4( 62) = Magnetic_Form_Type("SM2 ",(/-0.4150,14.057, 0.1368, 7.032, 0.3272, 1.582, 0.0192/))
18988       Magnetic_j4( 63) = Magnetic_Form_Type("SM3 ",(/-0.4288,10.052, 0.1782, 5.019, 0.2833, 1.236, 0.0088/))
18989       Magnetic_j4( 64) = Magnetic_Form_Type("EU2 ",(/-0.4145,10.193, 0.2447, 5.164, 0.2661, 1.205, 0.0065/))
18990       Magnetic_j4( 65) = Magnetic_Form_Type("EU3 ",(/-0.4095,10.211, 0.1485, 5.175, 0.2720, 1.237, 0.0131/))
18991       Magnetic_j4( 66) = Magnetic_Form_Type("GD2 ",(/-0.3824,10.344, 0.1955, 5.306, 0.2622, 1.203, 0.0097/))
18992       Magnetic_j4( 67) = Magnetic_Form_Type("GD3 ",(/-0.3621,10.353, 0.1016, 5.310, 0.2649, 1.219, 0.0147/))
18993       Magnetic_j4( 68) = Magnetic_Form_Type("TB2 ",(/-0.3443,10.469, 0.1481, 5.416, 0.2575, 1.182, 0.0104/))
18994       Magnetic_j4( 69) = Magnetic_Form_Type("TB3 ",(/-0.3228,10.476, 0.0638, 5.419, 0.2566, 1.196, 0.0159/))
18995       Magnetic_j4( 70) = Magnetic_Form_Type("DY2 ",(/-0.3206,12.071, 0.0904, 8.026, 0.2616, 1.230, 0.0143/))
18996       Magnetic_j4( 71) = Magnetic_Form_Type("DY3 ",(/-0.2829, 9.525, 0.0565, 4.429, 0.2437, 1.066, 0.0092/))
18997       Magnetic_j4( 72) = Magnetic_Form_Type("HO2 ",(/-0.2976, 9.719, 0.1224, 4.635, 0.2279, 1.005, 0.0063/))
18998       Magnetic_j4( 73) = Magnetic_Form_Type("HO3 ",(/-0.2717, 9.731, 0.0474, 4.638, 0.2292, 1.047, 0.0124/))
18999       Magnetic_j4( 74) = Magnetic_Form_Type("ER2 ",(/-0.2975, 9.829, 0.1189, 4.741, 0.2116, 1.004, 0.0117/))
19000       Magnetic_j4( 75) = Magnetic_Form_Type("ER3 ",(/-0.2568, 9.834, 0.0356, 4.741, 0.2172, 1.028, 0.0148/))
19001       Magnetic_j4( 76) = Magnetic_Form_Type("TM2 ",(/-0.2677, 9.888, 0.0925, 4.784, 0.2056, 0.990, 0.0124/))
19002       Magnetic_j4( 77) = Magnetic_Form_Type("TM3 ",(/-0.2292, 9.895, 0.0124, 4.785, 0.2108, 1.007, 0.0151/))
19003       Magnetic_j4( 78) = Magnetic_Form_Type("YB2 ",(/-0.2393, 9.947, 0.0663, 4.823, 0.2009, 0.965, 0.0122/))
19004       Magnetic_j4( 79) = Magnetic_Form_Type("YB3 ",(/-0.2121, 8.197, 0.0325, 3.153, 0.1975, 0.884, 0.0093/))
19005       Magnetic_j4( 80) = Magnetic_Form_Type("U3  ",(/-0.9859,16.601, 0.6116, 6.515, 0.6020, 2.597,-0.0010/))
19006       Magnetic_j4( 81) = Magnetic_Form_Type("U4  ",(/-1.0540,16.605, 0.4339, 6.512, 0.6746, 2.599,-0.0011/))
19007       Magnetic_j4( 82) = Magnetic_Form_Type("U5  ",(/-0.9588,16.485, 0.1576, 6.440, 0.7785, 2.640,-0.0010/))
19008       Magnetic_j4( 83) = Magnetic_Form_Type("NP3 ",(/-0.9029,16.586, 0.4006, 6.470, 0.6545, 2.563,-0.0004/))
19009       Magnetic_j4( 84) = Magnetic_Form_Type("NP4 ",(/-0.9887,12.441, 0.5918, 5.294, 0.5306, 2.263,-0.0021/))
19010       Magnetic_j4( 85) = Magnetic_Form_Type("NP5 ",(/-0.8146,16.581,-0.0055, 6.475, 0.7956, 2.562,-0.0004/))
19011       Magnetic_j4( 86) = Magnetic_Form_Type("NP6 ",(/-0.6738,16.553,-0.2297, 6.505, 0.8513, 2.553,-0.0003/))
19012       Magnetic_j4( 87) = Magnetic_Form_Type("PU3 ",(/-0.7014,16.369,-0.1162, 6.697, 0.7778, 2.450, 0.0000/))
19013       Magnetic_j4( 88) = Magnetic_Form_Type("PU4 ",(/-0.9160,12.203, 0.4891, 5.127, 0.5290, 2.149,-0.0022/))
19014       Magnetic_j4( 89) = Magnetic_Form_Type("PU5 ",(/-0.7035,16.360,-0.0979, 6.706, 0.7726, 2.447, 0.0000/))
19015       Magnetic_j4( 90) = Magnetic_Form_Type("PU6 ",(/-0.5560,16.322,-0.3046, 6.768, 0.8146, 2.426, 0.0001/))
19016       Magnetic_j4( 91) = Magnetic_Form_Type("AM2 ",(/-0.7433,16.416, 0.3481, 6.788, 0.6014, 2.346, 0.0000/))
19017       Magnetic_j4( 92) = Magnetic_Form_Type("AM3 ",(/-0.8092,12.854, 0.4161, 5.459, 0.5476, 2.172,-0.0011/))
19018       Magnetic_j4( 93) = Magnetic_Form_Type("AM4 ",(/-0.8548,12.226, 0.3037, 5.909, 0.6173, 2.188,-0.0016/))
19019       Magnetic_j4( 94) = Magnetic_Form_Type("AM5 ",(/-0.6538,15.462,-0.0948, 5.997, 0.7295, 2.297, 0.0000/))
19020       Magnetic_j4( 95) = Magnetic_Form_Type("AM6 ",(/-0.5390,15.449,-0.2689, 6.017, 0.7711, 2.297, 0.0002/))
19021       Magnetic_j4( 96) = Magnetic_Form_Type("AM7 ",(/-0.4688,12.019,-0.2692, 7.042, 0.7297, 2.164,-0.0011/))
19022       Magnetic_j4( 97) = Magnetic_Form_Type("PR3 ",(/-0.3970,10.9919, 0.0818, 5.9897, 0.3656, 1.5021, 0.0110/))
19023
19024       !---- <j6> Coefficients ----!
19025       Magnetic_j6(  1) = Magnetic_Form_Type("CE2 ",(/-0.1212, 7.994,-0.0639, 4.024, 0.1519, 1.096, 0.0078/))
19026       Magnetic_j6(  2) = Magnetic_Form_Type("ND2 ",(/-0.1600, 8.009, 0.0272, 4.028, 0.1104, 1.068, 0.0139/))
19027       Magnetic_j6(  3) = Magnetic_Form_Type("ND3 ",(/-0.0416, 8.014,-0.1261, 4.040, 0.1400, 1.087, 0.0102/))
19028       Magnetic_j6(  4) = Magnetic_Form_Type("SM2 ",(/-0.1428, 6.041, 0.0723, 2.033, 0.0550, 0.513, 0.0081/))
19029       Magnetic_j6(  5) = Magnetic_Form_Type("SM3 ",(/-0.0944, 6.030,-0.0498, 2.074, 0.1372, 0.645,-0.0132/))
19030       Magnetic_j6(  6) = Magnetic_Form_Type("EU2 ",(/-0.1252, 6.049, 0.0507, 2.085, 0.0572, 0.646, 0.0132/))
19031       Magnetic_j6(  7) = Magnetic_Form_Type("EU3 ",(/-0.0817, 6.039,-0.0596, 2.120, 0.1243, 0.764,-0.0001/))
19032       Magnetic_j6(  8) = Magnetic_Form_Type("GD2 ",(/-0.1351, 5.030, 0.0828, 2.025, 0.0315, 0.503, 0.0187/))
19033       Magnetic_j6(  9) = Magnetic_Form_Type("GD3 ",(/-0.0662, 6.031,-0.0850, 2.154, 0.1323, 0.891, 0.0048/))
19034       Magnetic_j6( 10) = Magnetic_Form_Type("TB2 ",(/-0.0758, 6.032,-0.0540, 2.158, 0.1199, 0.890, 0.0051/))
19035       Magnetic_j6( 11) = Magnetic_Form_Type("TB3 ",(/-0.0559, 6.031,-0.1020, 2.237, 0.1264, 1.107, 0.0167/))
19036       Magnetic_j6( 12) = Magnetic_Form_Type("DY2 ",(/-0.0568, 6.032,-0.1003, 2.240, 0.1401, 1.106, 0.0109/))
19037       Magnetic_j6( 13) = Magnetic_Form_Type("DY3 ",(/-0.0423, 6.038,-0.1248, 2.244, 0.1359, 1.200, 0.0188/))
19038       Magnetic_j6( 14) = Magnetic_Form_Type("HO2 ",(/-0.0725, 6.045,-0.0318, 2.243, 0.0738, 1.202, 0.0252/))
19039       Magnetic_j6( 15) = Magnetic_Form_Type("HO3 ",(/-0.0289, 6.050,-0.1545, 2.230, 0.1550, 1.260, 0.0177/))
19040       Magnetic_j6( 16) = Magnetic_Form_Type("ER2 ",(/-0.0648, 6.056,-0.0515, 2.230, 0.0825, 1.264, 0.0250/))
19041       Magnetic_j6( 17) = Magnetic_Form_Type("ER3 ",(/-0.0110, 6.061,-0.1954, 2.224, 0.1818, 1.296, 0.0149/))
19042       Magnetic_j6( 18) = Magnetic_Form_Type("TM2 ",(/-0.0842, 4.070, 0.0807, 0.849,-0.2087, 0.039, 0.2095/))
19043       Magnetic_j6( 19) = Magnetic_Form_Type("TM3 ",(/-0.0727, 4.073, 0.0243, 0.689, 3.9459, 0.002,-3.9076/))
19044       Magnetic_j6( 20) = Magnetic_Form_Type("YB2 ",(/-0.0739, 5.031, 0.0140, 2.030, 0.0351, 0.508, 0.0174/))
19045       Magnetic_j6( 21) = Magnetic_Form_Type("YB3 ",(/-0.0345, 5.007,-0.0677, 2.020, 0.0985, 0.549,-0.0076/))
19046       Magnetic_j6( 22) = Magnetic_Form_Type("U3  ",(/-0.3797, 9.953, 0.0459, 5.038, 0.2748, 1.607, 0.0016/))
19047       Magnetic_j6( 23) = Magnetic_Form_Type("U4  ",(/-0.1793,11.896,-0.2269, 5.428, 0.3291, 1.701, 0.0030/))
19048       Magnetic_j6( 24) = Magnetic_Form_Type("U5  ",(/-0.0399,11.891,-0.3458, 5.580, 0.3340, 1.645, 0.0029/))
19049       Magnetic_j6( 25) = Magnetic_Form_Type("NP3 ",(/-0.2427,11.844,-0.1129, 5.377, 0.2848, 1.568, 0.0022/))
19050       Magnetic_j6( 26) = Magnetic_Form_Type("NP4 ",(/-0.2436, 9.599,-0.1317, 4.101, 0.3029, 1.545, 0.0019/))
19051       Magnetic_j6( 27) = Magnetic_Form_Type("NP5 ",(/-0.1157, 9.565,-0.2654, 4.260, 0.3298, 1.549, 0.0025/))
19052       Magnetic_j6( 28) = Magnetic_Form_Type("NP6 ",(/-0.0128, 9.569,-0.3611, 4.304, 0.3419, 1.541, 0.0032/))
19053       Magnetic_j6( 29) = Magnetic_Form_Type("PU3 ",(/-0.0364, 9.572,-0.3181, 4.342, 0.3210, 1.523, 0.0041/))
19054       Magnetic_j6( 30) = Magnetic_Form_Type("PU4 ",(/-0.2394, 7.837,-0.0785, 4.024, 0.2643, 1.378, 0.0012/))
19055       Magnetic_j6( 31) = Magnetic_Form_Type("PU5 ",(/-0.1090, 7.819,-0.2243, 4.100, 0.2947, 1.404, 0.0015/))
19056       Magnetic_j6( 32) = Magnetic_Form_Type("PU6 ",(/-0.0001, 7.820,-0.3354, 4.144, 0.3097, 1.403, 0.0020/))
19057       Magnetic_j6( 33) = Magnetic_Form_Type("AM2 ",(/-0.3176, 7.864, 0.0771, 4.161, 0.2194, 1.339, 0.0018/))
19058       Magnetic_j6( 34) = Magnetic_Form_Type("AM3 ",(/-0.3159, 6.982, 0.0682, 3.995, 0.2141, 1.188,-0.0015/))
19059       Magnetic_j6( 35) = Magnetic_Form_Type("AM4 ",(/-0.1787, 7.880,-0.1274, 4.090, 0.2565, 1.315, 0.0017/))
19060       Magnetic_j6( 36) = Magnetic_Form_Type("AM5 ",(/-0.0927, 6.073,-0.2227, 3.784, 0.2916, 1.372, 0.0026/))
19061       Magnetic_j6( 37) = Magnetic_Form_Type("AM6 ",(/ 0.0152, 6.079,-0.3549, 3.861, 0.3125, 1.403, 0.0036/))
19062       Magnetic_j6( 38) = Magnetic_Form_Type("AM7 ",(/ 0.1292, 6.082,-0.4689, 3.879, 0.3234, 1.393, 0.0042/))
19063       Magnetic_j6( 39) = Magnetic_Form_Type("PR3 ",(/-0.0224, 7.9931,-0.1202, 3.9406, 0.1299, 0.8938, 0.0051/))
19064
19065       return
19066    End Subroutine Set_Magnetic_Form
19067
19068    !!----
19069    !!---- Subroutine Set_Xray_Form()
19070    !!----    Set Xray_Form Array:
19071    !!--<<
19072    !!----        1: Symbol of the Element
19073    !!----        2: Name of the Element
19074    !!----        3: a(4)
19075    !!----        4: b(4)
19076    !!----        5: c
19077    !!----    Coefficients for calculating the X-ray scattering factors
19078    !!----        f(s) = Sum_{i=1,4} { a(i) exp(-b(i)*s^2) } + c
19079    !!----
19080    !!----    where s=sinTheta/Lambda
19081    !!-->>
19082    !!----
19083    !!---- Update: February - 2005
19084    !!
19085    Subroutine Set_Xray_Form()
19086
19087       if (.not. allocated(xray_form)) allocate(xray_form(num_xray_form))
19088
19089       Xray_form( 1:10) = (/ &
19090                          xray_form_type("h   ",  1, (/  0.493002,   0.322912,   0.140191,   0.040810/), &
19091                                                     (/ 10.510900,  26.125700,   3.142360,  57.799698/),  0.003038) , &
19092                          xray_form_type("h-1 ",  1, (/  0.897661,   0.565616,   0.415815,   0.116973/), &
19093                                                     (/ 53.136799,  15.187000, 186.575989,   3.567090/),  0.002389) , &
19094                          xray_form_type("he  ",  2, (/  0.873400,   0.630900,   0.311200,   0.178000/), &
19095                                                     (/  9.103700,   3.356800,  22.927601,   0.982100/),  0.006400) , &
19096                          xray_form_type("li  ",  3, (/  1.128200,   0.750800,   0.617500,   0.465300/), &
19097                                                     (/  3.954600,   1.052400,  85.390503, 168.261002/),  0.037700) , &
19098                          xray_form_type("li+1",  3, (/  0.696800,   0.788800,   0.341400,   0.156300/), &
19099                                                     (/  4.623700,   1.955700,   0.631600,  10.095300/),  0.016700) , &
19100                          xray_form_type("be  ",  4, (/  1.591900,   1.127800,   0.539100,   0.702900/), &
19101                                                     (/ 43.642700,   1.862300, 103.483002,   0.542000/),  0.038500) , &
19102                          xray_form_type("be+2",  4, (/  6.260300,   0.884900,   0.799300,   0.164700/), &
19103                                                     (/  0.002700,   0.831300,   2.275800,   5.114600/), -6.109200) , &
19104                          xray_form_type("b   ",  5, (/  2.054500,   1.332600,   1.097900,   0.706800/), &
19105                                                     (/ 23.218500,   1.021000,  60.349800,   0.140300/), -0.193200) , &
19106                          xray_form_type("c   ",  6, (/  2.310000,   1.020000,   1.588600,   0.865000/), &
19107                                                     (/ 20.843899,  10.207500,   0.568700,  51.651199/),  0.215600) , &
19108                          xray_form_type("cv  ",  6, (/  2.260690,   1.561650,   1.050750,   0.839259/), &
19109                                                     (/ 22.690701,   0.656665,   9.756180,  55.594898/),  0.286977) /)
19110
19111       Xray_form(11:20) = (/ &
19112                          xray_form_type("n   ",  7, (/ 12.212600,   3.132200,   2.012500,   1.166300/), &
19113                                                     (/  0.005700,   9.893300,  28.997499,   0.582600/),-11.528999) , &
19114                          xray_form_type("o   ",  8, (/  3.048500,   2.286800,   1.546300,   0.867000/), &
19115                                                     (/ 13.277100,   5.701100,   0.323900,  32.908897/),  0.250800) , &
19116                          xray_form_type("o-1 ",  8, (/  4.191600,   1.639690,   1.526730, -20.306999/), &
19117                                                     (/ 12.857300,   4.172360,  47.017899,  -0.014040/), 21.941200) , &
19118                          xray_form_type("f   ",  9, (/  3.539200,   2.641200,   1.517000,   1.024300/), &
19119                                                     (/ 10.282499,   4.294400,   0.261500,  26.147600/),  0.277600) , &
19120                          xray_form_type("f-1 ",  9, (/  3.632200,   3.510570,   1.260640,   0.940706/), &
19121                                                     (/  5.277560,  14.735300,   0.442258,  47.343700/),  0.653396) , &
19122                          xray_form_type("ne  ", 10, (/  3.955300,   3.112500,   1.454600,   1.125100/), &
19123                                                     (/  8.404200,   3.426200,   0.230600,  21.718399/),  0.351500) , &
19124                          xray_form_type("na  ", 11, (/  4.762600,   3.173600,   1.267400,   1.112800/), &
19125                                                     (/  3.285000,   8.842199,   0.313600, 129.423996/),  0.676000) , &
19126                          xray_form_type("na+1", 11, (/  3.256500,   3.936200,   1.399800,   1.003200/), &
19127                                                     (/  2.667100,   6.115300,   0.200100,  14.039000/),  0.404000) , &
19128                          xray_form_type("mg  ", 12, (/  5.420400,   2.173500,   1.226900,   2.307300/), &
19129                                                     (/  2.827500,  79.261101,   0.380800,   7.193700/),  0.858400) , &
19130                          xray_form_type("mg+2", 12, (/  3.498800,   3.837800,   1.328400,   0.849700/), &
19131                                                     (/  2.167600,   4.754200,   0.185000,  10.141100/),  0.485300) /)
19132
19133       Xray_form(21:30) = (/ &
19134                          xray_form_type("al  ", 13, (/  6.420200,   1.900200,   1.593600,   1.964600/), &
19135                                                     (/  3.038700,   0.742600,  31.547199,  85.088600/),  1.115100) , &
19136                          xray_form_type("al+3", 13, (/  4.174480,   3.387600,   1.202960,   0.528137/), &
19137                                                     (/  1.938160,   4.145530,   0.228753,   8.285240/),  0.706786) , &
19138                          xray_form_type("si  ", 14, (/  6.291500,   3.035300,   1.989100,   1.541000/), &
19139                                                     (/  2.438600,  32.333698,   0.678500,  81.693695/),  1.140700) , &
19140                          xray_form_type("siv ", 14, (/  5.662690,   3.071640,   2.624460,   1.393200/), &
19141                                                     (/  2.665200,  38.663399,   0.916946,  93.545799/),  1.247070) , &
19142                          xray_form_type("si+4", 14, (/  4.439180,   3.203450,   1.194530,   0.416530/), &
19143                                                     (/  1.641670,   3.437570,   0.214900,   6.653650/),  0.746297) , &
19144                          xray_form_type("p   ", 15, (/  6.434500,   4.179100,   1.780000,   1.490800/), &
19145                                                     (/  1.906700,  27.157000,   0.526000,  68.164497/),  1.114900) , &
19146                          xray_form_type("s   ", 16, (/  6.905300,   5.203400,   1.437900,   1.586300/), &
19147                                                     (/  1.467900,  22.215099,   0.253600,  56.172001/),  0.866900) , &
19148                          xray_form_type("cl  ", 17, (/ 11.460400,   7.196400,   6.255600,   1.645500/), &
19149                                                     (/  0.010400,   1.166200,  18.519400,  47.778400/), -9.557400) , &
19150                          xray_form_type("cl-1", 17, (/ 18.291500,   7.208400,   6.533700,   2.338600/), &
19151                                                     (/  0.006600,   1.171700,  19.542400,  60.448601/),-16.378000) , &
19152                          xray_form_type("ar  ", 18, (/  7.484500,   6.772300,   0.653900,   1.644200/), &
19153                                                     (/  0.907200,  14.840700,  43.898300,  33.392899/),  1.444500) /)
19154
19155       Xray_form(31:40) = (/ &
19156                          xray_form_type("k   ", 19, (/  8.218599,   7.439800,   1.051900,   0.865900/), &
19157                                                     (/ 12.794900,   0.774800, 213.186996,  41.684097/),  1.422800) , &
19158                          xray_form_type("k+1 ", 19, (/  7.957800,   7.491700,   6.359000,   1.191500/), &
19159                                                     (/ 12.633100,   0.767400,  -0.002000,  31.912800/), -4.997800) , &
19160                          xray_form_type("ca  ", 20, (/  8.626600,   7.387300,   1.589900,   1.021100/), &
19161                                                     (/ 10.442100,   0.659900,  85.748398, 178.436996/),  1.375100) , &
19162                          xray_form_type("ca+2", 20, (/ 15.634800,   7.951800,   8.437200,   0.853700/), &
19163                                                     (/ -0.007400,   0.608900,  10.311600,  25.990499/),-14.875000) , &
19164                          xray_form_type("sc  ", 21, (/  9.189000,   7.367900,   1.640900,   1.468000/), &
19165                                                     (/  9.021299,   0.572900, 136.108002,  51.353100/),  1.332900) , &
19166                          xray_form_type("sc+3", 21, (/ 14.400800,   8.027300,   1.659430,   1.579360/), &
19167                                                     (/  0.298540,   7.962900,  -0.286040,  16.066200/), -6.666700) , &
19168                          xray_form_type("ti  ", 22, (/  9.759500,   7.355800,   1.699100,   1.902100/), &
19169                                                     (/  7.850800,   0.500000,  35.633801, 116.104996/),  1.280700) , &
19170                          xray_form_type("ti+2", 22, (/  9.114230,   7.621740,   2.279300,   0.087899/), &
19171                                                     (/  7.524300,   0.457585,  19.536100,  61.655800/),  0.897155) , &
19172                          xray_form_type("ti+3", 22, (/ 17.734400,   8.738160,   5.256910,   1.921340/), &
19173                                                     (/  0.220610,   7.047160,  -0.157620,  15.976800/),-14.652000) , &
19174                          xray_form_type("ti+4", 22, (/ 19.511400,   8.234730,   2.013410,   1.520800/), &
19175                                                     (/  0.178847,   6.670180,  -0.292630,  12.946400/),-13.280000) /)
19176
19177       Xray_form(41:50) = (/ &
19178                          xray_form_type("v   ", 23, (/ 10.297100,   7.351100,   2.070300,   2.057100/), &
19179                                                     (/  6.865700,   0.438500,  26.893799, 102.477997/),  1.219900) , &
19180                          xray_form_type("v+2 ", 23, (/ 10.106000,   7.354100,   2.288400,   0.022300/), &
19181                                                     (/  6.881800,   0.440900,  20.300400, 115.122002/),  1.229800) , &
19182                          xray_form_type("v+3 ", 23, (/  9.431410,   7.741900,   2.153430,   0.016865/), &
19183                                                     (/  6.395350,   0.383349,  15.190800,  63.969002/),  0.656565) , &
19184                          xray_form_type("v+5 ", 23, (/ 15.688700,   8.142080,   2.030810,  -9.576000/), &
19185                                                     (/  0.679003,   5.401350,   9.972780,   0.940464/),  1.714300) , &
19186                          xray_form_type("cr  ", 24, (/ 10.640600,   7.353700,   3.324000,   1.492200/), &
19187                                                     (/  6.103800,   0.392000,  20.262600,  98.739899/),  1.183200) , &
19188                          xray_form_type("cr+2", 24, (/  9.540340,   7.750900,   3.582740,   0.509107/), &
19189                                                     (/  5.660780,   0.344261,  13.307500,  32.422401/),  0.616898) , &
19190                          xray_form_type("cr+3", 24, (/  9.680900,   7.811360,   2.876030,   0.113575/), &
19191                                                     (/  5.594630,   0.334393,  12.828800,  32.876099/),  0.518275) , &
19192                          xray_form_type("mn  ", 25, (/ 11.281900,   7.357300,   3.019300,   2.244100/), &
19193                                                     (/  5.340900,   0.343200,  17.867399,  83.754303/),  1.089600) , &
19194                          xray_form_type("mn+2", 25, (/ 10.806100,   7.362000,   3.526800,   0.218400/), &
19195                                                     (/  5.279600,   0.343500,  14.343000,  41.323502/),  1.087400) , &
19196                          xray_form_type("mn+3", 25, (/  9.845210,   7.871940,   3.565310,   0.323613/), &
19197                                                     (/  4.917970,   0.294393,  10.817100,  24.128099/),  0.393974) /)
19198
19199       Xray_form(51:60) = (/ &
19200                          xray_form_type("mn+4", 25, (/  9.962530,   7.970570,   2.760670,   0.054447/), &
19201                                                     (/  4.848500,   0.283303,  10.485200,  27.573000/),  0.251877) , &
19202                          xray_form_type("fe  ", 26, (/ 11.769500,   7.357300,   3.522200,   2.304500/), &
19203                                                     (/  4.761100,   0.307200,  15.353500,  76.880501/),  1.036900) , &
19204                          xray_form_type("fe+2", 26, (/ 11.042400,   7.374000,   4.134600,   0.439900/), &
19205                                                     (/  4.653800,   0.305300,  12.054600,  31.280899/),  1.009700) , &
19206                          xray_form_type("fe+3", 26, (/ 11.176400,   7.386300,   3.394800,   0.072400/), &
19207                                                     (/  4.614700,   0.300500,  11.672900,  38.556599/),  0.970700) , &
19208                          xray_form_type("co  ", 27, (/ 12.284100,   7.340900,   4.003400,   2.348800/), &
19209                                                     (/  4.279100,   0.278400,  13.535900,  71.169197/),  1.011800) , &
19210                          xray_form_type("co+2", 27, (/ 11.229600,   7.388300,   4.739300,   0.710800/), &
19211                                                     (/  4.123100,   0.272600,  10.244300,  25.646599/),  0.932400) , &
19212                          xray_form_type("co+3", 27, (/ 10.337999,   7.881730,   4.767950,   0.725591/), &
19213                                                     (/  3.909690,   0.238668,   8.355830,  18.349100/),  0.286667) , &
19214                          xray_form_type("ni  ", 28, (/ 12.837600,   7.292000,   4.443800,   2.380000/), &
19215                                                     (/  3.878500,   0.256500,  12.176300,  66.342102/),  1.034100) , &
19216                          xray_form_type("ni+2", 28, (/ 11.416600,   7.400500,   5.344200,   0.977300/), &
19217                                                     (/  3.676600,   0.244900,   8.873000,  22.162600/),  0.861400) , &
19218                          xray_form_type("ni+3", 28, (/ 10.780600,   7.758680,   5.227460,   0.847114/), &
19219                                                     (/  3.547700,   0.223140,   7.644680,  16.967300/),  0.386044) /)
19220
19221       Xray_form(61:70) = (/ &
19222                          xray_form_type("cu  ", 29, (/ 13.337999,   7.167600,   5.615800,   1.673500/), &
19223                                                     (/  3.582800,   0.247000,  11.396600,  64.812599/),  1.191000) , &
19224                          xray_form_type("cu+1", 29, (/ 11.947500,   7.357300,   6.245500,   1.557800/), &
19225                                                     (/  3.366900,   0.227400,   8.662500,  25.848700/),  0.890000) , &
19226                          xray_form_type("cu+2", 29, (/ 11.816800,   7.111810,   5.781350,   1.145230/), &
19227                                                     (/  3.374840,   0.244078,   7.987600,  19.896999/),  1.144310) , &
19228                          xray_form_type("zn  ", 30, (/ 14.074300,   7.031800,   5.162500,   2.410000/), &
19229                                                     (/  3.265500,   0.233300,  10.316299,  58.709702/),  1.304100) , &
19230                          xray_form_type("zn+2", 30, (/ 11.971900,   7.386200,   6.466800,   1.394000/), &
19231                                                     (/  2.994600,   0.203100,   7.082600,  18.099499/),  0.780700) , &
19232                          xray_form_type("ga  ", 31, (/ 15.235400,   6.700600,   4.359100,   2.962300/), &
19233                                                     (/  3.066900,   0.241200,  10.780500,  61.413498/),  1.718900) , &
19234                          xray_form_type("ga+3", 31, (/ 12.691999,   6.698830,   6.066920,   1.006600/), &
19235                                                     (/  2.812620,   0.227890,   6.364410,  14.412200/),  1.535450) , &
19236                          xray_form_type("ge  ", 32, (/ 16.081600,   6.374700,   3.706800,   3.683000/), &
19237                                                     (/  2.850900,   0.251600,  11.446800,  54.762501/),  2.131300) , &
19238                          xray_form_type("ge+4", 32, (/ 12.917200,   6.700030,   6.067910,   0.859041/), &
19239                                                     (/  2.537180,   0.205855,   5.479130,  11.603000/),  1.455720) , &
19240                          xray_form_type("as  ", 33, (/ 16.672300,   6.070100,   3.431300,   4.277900/), &
19241                                                     (/  2.634500,   0.264700,  12.947900,  47.797199/),  2.531000) /)
19242
19243       Xray_form(71:80) = (/ &
19244                          xray_form_type("se  ", 34, (/ 17.000599,   5.819600,   3.973100,   4.354300/), &
19245                                                     (/  2.409800,   0.272600,  15.237200,  43.816299/),  2.840900) , &
19246                          xray_form_type("br  ", 35, (/ 17.178900,   5.235800,   5.637700,   3.985100/), &
19247                                                     (/  2.172300,  16.579599,   0.260900,  41.432800/),  2.955700) , &
19248                          xray_form_type("br-1", 35, (/ 17.171799,   6.333800,   5.575400,   3.727200/), &
19249                                                     (/  2.205900,  19.334499,   0.287100,  58.153500/),  3.177600) , &
19250                          xray_form_type("kr  ", 36, (/ 17.355499,   6.728600,   5.549300,   3.537500/), &
19251                                                     (/  1.938400,  16.562300,   0.226100,  39.397202/),  2.825000) , &
19252                          xray_form_type("rb  ", 37, (/ 17.178400,   9.643499,   5.139900,   1.529200/), &
19253                                                     (/  1.788800,  17.315100,   0.274800, 164.933990/),  3.487300) , &
19254                          xray_form_type("rb+1", 37, (/ 17.581600,   7.659800,   5.898100,   2.781700/), &
19255                                                     (/  1.713900,  14.795700,   0.160300,  31.208700/),  2.078200) , &
19256                          xray_form_type("sr  ", 38, (/ 17.566299,   9.818399,   5.422000,   2.669400/), &
19257                                                     (/  1.556400,  14.098800,   0.166400, 132.376007/),  2.506400) , &
19258                          xray_form_type("sr+2", 38, (/ 18.087400,   8.137300,   2.565400, -34.193001/), &
19259                                                     (/  1.490700,  12.696300,  24.565100,  -0.013800/), 41.402500) , &
19260                          xray_form_type("y   ", 39, (/ 17.775999,  10.294600,   5.726290,   3.265880/), &
19261                                                     (/  1.402900,  12.800600,   0.125599, 104.353996/),  1.912130) , &
19262                          xray_form_type("y+3 ", 39, (/ 17.926800,   9.153100,   1.767950, -33.108002/), &
19263                                                     (/  1.354170,  11.214500,  22.659901,  -0.013190/), 40.260201) /)
19264
19265       Xray_form(81:90) = (/ &
19266                          xray_form_type("zr  ", 40, (/ 17.876499,  10.948000,   5.417320,   3.657210/), &
19267                                                     (/  1.276180,  11.916000,   0.117622,  87.662697/),  2.069290) , &
19268                          xray_form_type("zr+4", 40, (/ 18.166800,  10.056200,   1.011180,  -2.647900/), &
19269                                                     (/  1.214800,  10.148300,  21.605400,  -0.102760/),  9.414539) , &
19270                          xray_form_type("nb  ", 41, (/ 17.614201,  12.014400,   4.041830,   3.533460/), &
19271                                                     (/  1.188650,  11.766000,   0.204785,  69.795700/),  3.755910) , &
19272                          xray_form_type("nb+3", 41, (/ 19.881199,  18.065300,  11.017700,   1.947150/), &
19273                                                     (/  0.019175,   1.133050,  10.162100,  28.338900/),-12.912000) , &
19274                          xray_form_type("nb+5", 41, (/ 17.916300,  13.341700,  10.799000,   0.337905/), &
19275                                                     (/  1.124460,   0.028781,   9.282060,  25.722799/), -6.393400) , &
19276                          xray_form_type("mo  ", 42, (/  3.702500,  17.235600,  12.887600,   3.742900/), &
19277                                                     (/  0.277200,   1.095800,  11.004000,  61.658401/),  4.387500) , &
19278                          xray_form_type("mo+3", 42, (/ 21.166401,  18.201700,  11.742300,   2.309510/), &
19279                                                     (/  0.014734,   1.030310,   9.536590,  26.630699/),-14.421000) , &
19280                          xray_form_type("mo+5", 42, (/ 21.014900,  18.099199,  11.463200,   0.740625/), &
19281                                                     (/  0.014345,   1.022380,   8.788090,  23.345200/),-14.316000) , &
19282                          xray_form_type("mo+6", 42, (/ 17.887100,  11.175000,   6.578910,   0.000000/), &
19283                                                     (/  1.036490,   8.480610,   0.058881,   0.000000/),  0.344941) , &
19284                          xray_form_type("tc  ", 43, (/ 19.130100,  11.094800,   4.649010,   2.712630/), &
19285                                                     (/  0.864132,   8.144870,  21.570700,  86.847198/),  5.404280) /)
19286
19287       Xray_form(91:100)= (/ &
19288                          xray_form_type("ru  ", 44, (/ 19.267399,  12.918200,   4.863370,   1.567560/), &
19289                                                     (/  0.808520,   8.434669,  24.799700,  94.292801/),  5.378740) , &
19290                          xray_form_type("ru+3", 44, (/ 18.563801,  13.288500,   9.326019,   3.009640/), &
19291                                                     (/  0.847329,   8.371640,   0.017662,  22.886999/), -3.189200) , &
19292                          xray_form_type("ru+4", 44, (/ 18.500299,  13.178699,   4.713040,   2.185350/), &
19293                                                     (/  0.844582,   8.125340,   0.364950,  20.850399/),  1.423570) , &
19294                          xray_form_type("rh  ", 45, (/ 19.295700,  14.350100,   4.734250,   1.289180/), &
19295                                                     (/  0.751536,   8.217580,  25.874901,  98.606201/),  5.328000) , &
19296                          xray_form_type("rh+3", 45, (/ 18.878500,  14.125900,   3.325150,  -6.198900/), &
19297                                                     (/  0.764252,   7.844380,  21.248699,  -0.010360/), 11.867800) , &
19298                          xray_form_type("rh+4", 45, (/ 18.854500,  13.980600,   2.534640,  -5.652600/), &
19299                                                     (/  0.760825,   7.624360,  19.331699,  -0.010200/), 11.283500) , &
19300                          xray_form_type("pd  ", 46, (/ 19.331900,  15.501699,   5.295370,   0.605844/), &
19301                                                     (/  0.698655,   7.989290,  25.205200,  76.898598/),  5.265930) , &
19302                          xray_form_type("pd+2", 46, (/ 19.170099,  15.209600,   4.322340,   0.000000/), &
19303                                                     (/  0.696219,   7.555730,  22.505699,   0.000000/),  5.291600) , &
19304                          xray_form_type("pd+4", 46, (/ 19.249300,  14.790000,   2.892890,  -7.949200/), &
19305                                                     (/  0.683839,   7.148330,  17.914400,   0.005127/), 13.017400) , &
19306                          xray_form_type("ag  ", 47, (/ 19.280800,  16.688499,   4.804500,   1.046300/), &
19307                                                     (/  0.644600,   7.472600,  24.660500,  99.815598/),  5.179000) /)
19308
19309       Xray_form(101:110)=(/ &
19310                          xray_form_type("ag+1", 47, (/ 19.181200,  15.971900,   5.274750,   0.357534/), &
19311                                                     (/  0.646179,   7.191230,  21.732599,  66.114700/),  5.215720) , &
19312                          xray_form_type("ag+2", 47, (/ 19.164299,  16.245600,   4.370900,   0.000000/), &
19313                                                     (/  0.645643,   7.185440,  21.407200,   0.000000/),  5.214040) , &
19314                          xray_form_type("cd  ", 48, (/ 19.221399,  17.644400,   4.461000,   1.602900/), &
19315                                                     (/  0.594600,   6.908900,  24.700800,  87.482498/),  5.069400) , &
19316                          xray_form_type("cd+2", 48, (/ 19.151400,  17.253500,   4.471280,   0.000000/), &
19317                                                     (/  0.597922,   6.806390,  20.252100,   0.000000/),  5.119370) , &
19318                          xray_form_type("in  ", 49, (/ 19.162399,  18.559601,   4.294800,   2.039600/), &
19319                                                     (/  0.547600,   6.377600,  25.849899,  92.802902/),  4.939100) , &
19320                          xray_form_type("in+3", 49, (/ 19.104500,  18.110800,   3.788970,   0.000000/), &
19321                                                     (/  0.551522,   6.324700,  17.359501,   0.000000/),  4.996350) , &
19322                          xray_form_type("sn  ", 50, (/ 19.188900,  19.100500,   4.458500,   2.466300/), &
19323                                                     (/  5.830300,   0.503100,  26.890900,  83.957100/),  4.782100) , &
19324                          xray_form_type("sn+2", 50, (/ 19.109400,  19.054800,   4.564800,   0.487000/), &
19325                                                     (/  0.503600,   5.837800,  23.375200,  62.206100/),  4.786100) , &
19326                          xray_form_type("sn+4", 50, (/ 18.933300,  19.713100,   3.418200,   0.019300/), &
19327                                                     (/  5.764000,   0.465500,  14.004900,  -0.758300/),  3.918200) , &
19328                          xray_form_type("sb  ", 51, (/ 19.641800,  19.045500,   5.037100,   2.682700/), &
19329                                                     (/  5.303400,   0.460700,  27.907400,  75.282501/),  4.590900) /)
19330
19331       Xray_form(111:120)=(/ &
19332                          xray_form_type("sb+3", 51, (/ 18.975500,  18.932999,   5.107890,   0.288753/), &
19333                                                     (/  0.467196,   5.221260,  19.590200,  55.511299/),  4.696260) , &
19334                          xray_form_type("sb+5", 51, (/ 19.868500,  19.030199,   2.412530,   0.000000/), &
19335                                                     (/  5.448530,   0.467973,  14.125900,   0.000000/),  4.692630) , &
19336                          xray_form_type("te  ", 52, (/ 19.964399,  19.013800,   6.144870,   2.523900/), &
19337                                                     (/  4.817420,   0.420885,  28.528400,  70.840302/),  4.352000) , &
19338                          xray_form_type("i   ", 53, (/ 20.147200,  18.994900,   7.513800,   2.273500/), &
19339                                                     (/  4.347000,   0.381400,  27.765999,  66.877602/),  4.071200) , &
19340                          xray_form_type("i-1 ", 53, (/ 20.233200,  18.997000,   7.806900,   2.886800/), &
19341                                                     (/  4.357900,   0.381500,  29.525900,  84.930397/),  4.071400) , &
19342                          xray_form_type("xe  ", 54, (/ 20.293301,  19.029800,   8.976700,   1.990000/), &
19343                                                     (/  3.928200,   0.344000,  26.465900,  64.265800/),  3.711800) , &
19344                          xray_form_type("cs  ", 55, (/ 20.389200,  19.106199,  10.662000,   1.495300/), &
19345                                                     (/  3.569000,   0.310700,  24.387899, 213.903992/),  3.335200) , &
19346                          xray_form_type("cs+1", 55, (/ 20.352400,  19.127800,  10.282100,   0.961500/), &
19347                                                     (/  3.552000,   0.308600,  23.712799,  59.456497/),  3.279100) , &
19348                          xray_form_type("ba  ", 56, (/ 20.336100,  19.297001,  10.888000,   2.695900/), &
19349                                                     (/  3.216000,   0.275600,  20.207300, 167.201996/),  2.773100) , &
19350                          xray_form_type("ba+2", 56, (/ 20.180700,  19.113600,  10.905399,   0.776340/), &
19351                                                     (/  3.213670,   0.283310,  20.055799,  51.745998/),  3.029020) /)
19352
19353       Xray_form(121:130)=(/ &
19354                          xray_form_type("la  ", 57, (/ 20.577999,  19.598999,  11.372700,   3.287190/), &
19355                                                     (/  2.948170,   0.244475,  18.772600, 133.123993/),  2.146780) , &
19356                          xray_form_type("la+3", 57, (/ 20.248899,  19.376301,  11.632299,   0.336048/), &
19357                                                     (/  2.920700,   0.250698,  17.821100,  54.945297/),  2.408600) , &
19358                          xray_form_type("ce  ", 58, (/ 21.167099,  19.769501,  11.851299,   3.330490/), &
19359                                                     (/  2.812190,   0.226836,  17.608299, 127.112999/),  1.862640) , &
19360                          xray_form_type("ce+3", 58, (/ 20.803600,  19.559000,  11.936900,   0.612376/), &
19361                                                     (/  2.776910,   0.231540,  16.540800,  43.169201/),  2.090130) , &
19362                          xray_form_type("ce+4", 58, (/ 20.323500,  19.818600,  12.123300,   0.144583/), &
19363                                                     (/  2.659410,   0.218850,  15.799200,  62.235500/),  1.591800) , &
19364                          xray_form_type("pr  ", 59, (/ 22.043999,  19.669701,  12.385600,   2.824280/), &
19365                                                     (/  2.773930,   0.222087,  16.766899, 143.643997/),  2.058300) , &
19366                          xray_form_type("pr+3", 59, (/ 21.372700,  19.749100,  12.132900,   0.975180/), &
19367                                                     (/  2.645200,   0.214299,  15.323000,  36.406502/),  1.771320) , &
19368                          xray_form_type("pr+4", 59, (/ 20.941299,  20.053900,  12.466800,   0.296689/), &
19369                                                     (/  2.544670,   0.202481,  14.813700,  45.464298/),  1.242850) , &
19370                          xray_form_type("nd  ", 60, (/ 22.684500,  19.684700,  12.774000,   2.851370/), &
19371                                                     (/  2.662480,   0.210628,  15.885000, 137.903000/),  1.984860) , &
19372                          xray_form_type("nd+3", 60, (/ 21.961000,  19.933899,  12.120000,   1.510310/), &
19373                                                     (/  2.527220,   0.199237,  14.178300,  30.871700/),  1.475880) /)
19374
19375       Xray_form(131:140)=(/ &
19376                          xray_form_type("pm  ", 61, (/ 23.340500,  19.609501,  13.123500,   2.875160/), &
19377                                                     (/  2.562700,   0.202088,  15.100900, 132.720993/),  2.028760) , &
19378                          xray_form_type("pm+3", 61, (/ 22.552700,  20.110800,  12.067100,   2.074920/), &
19379                                                     (/  2.417400,   0.185769,  13.127500,  27.449100/),  1.194990) , &
19380                          xray_form_type("sm  ", 62, (/ 24.004200,  19.425800,  13.439600,   2.896040/), &
19381                                                     (/  2.472740,   0.196451,  14.399600, 128.007004/),  2.209630) , &
19382                          xray_form_type("sm+3", 62, (/ 23.150400,  20.259899,  11.920200,   2.714880/), &
19383                                                     (/  2.316410,   0.174081,  12.157100,  24.824200/),  0.954586) , &
19384                          xray_form_type("eu  ", 63, (/ 24.627399,  19.088600,  13.760300,   2.922700/), &
19385                                                     (/  2.387900,   0.194200,  13.754600, 123.173996/),  2.574500) , &
19386                          xray_form_type("eu+2", 63, (/ 24.006300,  19.950399,  11.803400,   3.872430/), &
19387                                                     (/  2.277830,   0.173530,  11.609600,  26.515600/),  1.363890) , &
19388                          xray_form_type("eu+3", 63, (/ 23.749699,  20.374500,  11.850900,   3.265030/), &
19389                                                     (/  2.222580,   0.163940,  11.311000,  22.996599/),  0.759344) , &
19390                          xray_form_type("gd  ", 64, (/ 25.070900,  19.079800,  13.851800,   3.545450/), &
19391                                                     (/  2.253410,   0.181951,  12.933100, 101.397995/),  2.419600) , &
19392                          xray_form_type("gd+3", 64, (/ 24.346600,  20.420799,  11.870800,   3.714900/), &
19393                                                     (/  2.135530,   0.155525,  10.578199,  21.702900/),  0.645089) , &
19394                          xray_form_type("tb  ", 65, (/ 25.897600,  18.218500,  14.316700,   2.953540/), &
19395                                                     (/  2.242560,   0.196143,  12.664800, 115.362000/),  3.582240) /)
19396
19397       Xray_form(141:150)=(/ &
19398                          xray_form_type("tb+3", 65, (/ 24.955900,  20.327099,  12.247100,   3.773000/), &
19399                                                     (/  2.056010,   0.149525,  10.049900,  21.277300/),  0.691967) , &
19400                          xray_form_type("dy  ", 66, (/ 26.507000,  17.638300,  14.559600,   2.965770/), &
19401                                                     (/  2.180200,   0.202172,  12.189899, 111.874001/),  4.297280) , &
19402                          xray_form_type("dy+3", 66, (/ 25.539499,  20.286100,  11.981200,   4.500730/), &
19403                                                     (/  1.980400,   0.143384,   9.349720,  19.580999/),  0.689690) , &
19404                          xray_form_type("ho  ", 67, (/ 26.904900,  17.293999,  14.558300,   3.638370/), &
19405                                                     (/  2.070510,   0.197940,  11.440700,  92.656601/),  4.567960) , &
19406                          xray_form_type("ho+3", 67, (/ 26.129601,  20.099400,  11.978800,   4.936760/), &
19407                                                     (/  1.910720,   0.139358,   8.800180,  18.590799/),  0.852795) , &
19408                          xray_form_type("er  ", 68, (/ 27.656300,  16.428499,  14.977900,   2.982330/), &
19409                                                     (/  2.073560,   0.223545,  11.360400, 105.703003/),  5.920460) , &
19410                          xray_form_type("er+3", 68, (/ 26.722000,  19.774799,  12.150600,   5.173790/), &
19411                                                     (/  1.846590,   0.137290,   8.362249,  17.897400/),  1.176130) , &
19412                          xray_form_type("tm  ", 69, (/ 28.181900,  15.885099,  15.154200,   2.987060/), &
19413                                                     (/  2.028590,   0.238849,  10.997499, 102.960999/),  6.756210) , &
19414                          xray_form_type("tm+3", 69, (/ 27.308300,  19.332001,  12.333900,   5.383480/), &
19415                                                     (/  1.787110,   0.136974,   7.967780,  17.292200/),  1.639290) , &
19416                          xray_form_type("yb  ", 70, (/ 28.664101,  15.434500,  15.308700,   2.989630/), &
19417                                                     (/  1.988900,   0.257119,  10.664700, 100.417000/),  7.566720) /)
19418
19419       Xray_form(151:160)=(/ &
19420                          xray_form_type("yb+2", 70, (/ 28.120899,  17.681700,  13.333500,   5.146570/), &
19421                                                     (/  1.785030,   0.159970,   8.183040,  20.389999/),  3.709830) , &
19422                          xray_form_type("yb+3", 70, (/ 27.891701,  18.761400,  12.607200,   5.476470/), &
19423                                                     (/  1.732720,   0.138790,   7.644120,  16.815300/),  2.260010) , &
19424                          xray_form_type("lu  ", 71, (/ 28.947599,  15.220800,  15.100000,   3.716010/), &
19425                                                     (/  1.901820,   9.985189,   0.261033,  84.329803/),  7.976280) , &
19426                          xray_form_type("lu+3", 71, (/ 28.462799,  18.121000,  12.842899,   5.594150/), &
19427                                                     (/  1.682160,   0.142292,   7.337270,  16.353500/),  2.975730) , &
19428                          xray_form_type("hf  ", 72, (/ 29.143999,  15.172600,  14.758600,   4.300130/), &
19429                                                     (/  1.832620,   9.599899,   0.275116,  72.028999/),  8.581540) , &
19430                          xray_form_type("hf+4", 72, (/ 28.813099,  18.460100,  12.728500,   5.599270/), &
19431                                                     (/  1.591360,   0.128903,   6.762320,  14.036600/),  2.396990) , &
19432                          xray_form_type("ta  ", 73, (/ 29.202400,  15.229300,  14.513500,   4.764920/), &
19433                                                     (/  1.773330,   9.370460,   0.295977,  63.364399/),  9.243540) , &
19434                          xray_form_type("ta+5", 73, (/ 29.158699,  18.840700,  12.826799,   5.386950/), &
19435                                                     (/  1.507110,   0.116741,   6.315240,  12.424400/),  1.785550) , &
19436                          xray_form_type("w   ", 74, (/ 29.081800,  15.430000,  14.432700,   5.119820/), &
19437                                                     (/  1.720290,   9.225900,   0.321703,  57.056000/),  9.887500) , &
19438                          xray_form_type("w+6 ", 74, (/ 29.493599,  19.376301,  13.054399,   5.064120/), &
19439                                                     (/  1.427550,   0.104621,   5.936670,  11.197200/),  1.010740) /)
19440
19441       Xray_form(161:170)=(/ &
19442                          xray_form_type("re  ", 75, (/ 28.762100,  15.718900,  14.556400,   5.441740/), &
19443                                                     (/  1.671910,   9.092270,   0.350500,  52.086098/), 10.472000) , &
19444                          xray_form_type("os  ", 76, (/ 28.189400,  16.154999,  14.930500,   5.675890/), &
19445                                                     (/  1.629030,   8.979480,   0.382661,  48.164700/), 11.000500) , &
19446                          xray_form_type("os+4", 76, (/ 30.418999,  15.263700,  14.745800,   5.067950/), &
19447                                                     (/  1.371130,   6.847060,   0.165191,  18.003000/),  6.498040) , &
19448                          xray_form_type("ir  ", 77, (/ 27.304899,  16.729599,  15.611500,   5.833770/), &
19449                                                     (/  1.592790,   8.865530,   0.417916,  45.001099/), 11.472200) , &
19450                          xray_form_type("ir+3", 77, (/ 30.415600,  15.862000,  13.614500,   5.820080/), &
19451                                                     (/  1.343230,   7.109090,   0.204633,  20.325399/),  8.279030) , &
19452                          xray_form_type("ir+4", 77, (/ 30.705799,  15.551200,  14.232600,   5.536720/), &
19453                                                     (/  1.309230,   6.719830,   0.167252,  17.491100/),  6.968240) , &
19454                          xray_form_type("pt  ", 78, (/ 27.005899,  17.763901,  15.713100,   5.783700/), &
19455                                                     (/  1.512930,   8.811740,   0.424593,  38.610298/), 11.688300) , &
19456                          xray_form_type("pt+2", 78, (/ 29.842899,  16.722401,  13.215300,   6.352340/), &
19457                                                     (/  1.329270,   7.389790,   0.263297,  22.942600/),  9.853290) , &
19458                          xray_form_type("pt+4", 78, (/ 30.961201,  15.982900,  13.734800,   5.920340/), &
19459                                                     (/  1.248130,   6.608340,   0.168640,  16.939199/),  7.395340) , &
19460                          xray_form_type("au  ", 79, (/ 16.881901,  18.591299,  25.558201,   5.860000/), &
19461                                                     (/  0.461100,   8.621600,   1.482600,  36.395599/), 12.065800) /)
19462
19463       Xray_form(171:180)=(/ &
19464                          xray_form_type("au+1", 79, (/ 28.010899,  17.820400,  14.335899,   6.580770/), &
19465                                                     (/  1.353210,   7.739500,   0.356752,  26.404301/), 11.229900) , &
19466                          xray_form_type("au+3", 79, (/ 30.688599,  16.902901,  12.780100,   6.523540/), &
19467                                                     (/  1.219900,   6.828720,   0.212867,  18.659000/),  9.096800) , &
19468                          xray_form_type("hg  ", 80, (/ 20.680901,  19.041700,  21.657499,   5.967600/), &
19469                                                     (/  0.545000,   8.448400,   1.572900,  38.324600/), 12.608900) , &
19470                          xray_form_type("hg+1", 80, (/ 25.085300,  18.497299,  16.888300,   6.482160/), &
19471                                                     (/  1.395070,   7.651050,   0.443378,  28.226200/), 12.020500) , &
19472                          xray_form_type("hg+2", 80, (/ 29.564100,  18.059999,  12.837400,   6.899120/), &
19473                                                     (/  1.211520,   7.056390,   0.284738,  20.748199/), 10.626800) , &
19474                          xray_form_type("tl  ", 81, (/ 27.544600,  19.158400,  15.538000,   5.525930/), &
19475                                                     (/  0.655150,   8.707510,   1.963470,  45.814899/), 13.174600) , &
19476                          xray_form_type("tl+1", 81, (/ 21.398500,  20.472300,  18.747799,   6.828470/), &
19477                                                     (/  1.471100,   0.517394,   7.434630,  28.848200/), 12.525800) , &
19478                          xray_form_type("tl+3", 81, (/ 30.869499,  18.384100,  11.932800,   7.005740/), &
19479                                                     (/  1.100800,   6.538520,   0.219074,  17.211399/),  9.802700) , &
19480                          xray_form_type("pb  ", 82, (/ 31.061699,  13.063700,  18.441999,   5.969600/), &
19481                                                     (/  0.690200,   2.357600,   8.618000,  47.257900/), 13.411800) , &
19482                          xray_form_type("pb+2", 82, (/ 21.788601,  19.568199,  19.140600,   7.011070/), &
19483                                                     (/  1.336600,   0.488383,   6.772700,  23.813200/), 12.473400) /)
19484
19485       Xray_form(181:190)=(/ &
19486                          xray_form_type("pb+4", 82, (/ 32.124397,  18.800301,  12.017500,   6.968860/), &
19487                                                     (/  1.005660,   6.109260,   0.147041,  14.714000/),  8.084280) , &
19488                          xray_form_type("bi  ", 83, (/ 33.368900,  12.951000,  16.587700,   6.469200/), &
19489                                                     (/  0.704000,   2.923800,   8.793700,  48.009300/), 13.578199) , &
19490                          xray_form_type("bi+3", 83, (/ 21.805300,  19.502600,  19.105301,   7.102950/), &
19491                                                     (/  1.235600,   6.241490,   0.469999,  20.318501/), 12.471100) , &
19492                          xray_form_type("bi+5", 83, (/ 33.536400,  25.094601,  19.249699,   6.915550/), &
19493                                                     (/  0.916540,   0.390420,   5.714140,  12.828500/), -6.799400) , &
19494                          xray_form_type("po  ", 84, (/ 34.672600,  15.473300,  13.113800,   7.025880/), &
19495                                                     (/  0.700999,   3.550780,   9.556419,  47.004501/), 13.677000) , &
19496                          xray_form_type("at  ", 85, (/ 35.316299,  19.021099,   9.498870,   7.425180/), &
19497                                                     (/  0.685870,   3.974580,  11.382400,  45.471500/), 13.710800) , &
19498                          xray_form_type("rn  ", 86, (/ 35.563099,  21.281601,   8.003700,   7.443300/), &
19499                                                     (/  0.663100,   4.069100,  14.042200,  44.247299/), 13.690500) , &
19500                          xray_form_type("fr  ", 87, (/ 35.929901,  23.054699,  12.143900,   2.112530/), &
19501                                                     (/  0.646453,   4.176190,  23.105200, 150.644989/), 13.724700) , &
19502                          xray_form_type("ra  ", 88, (/ 35.763000,  22.906399,  12.473900,   3.210970/), &
19503                                                     (/  0.616341,   3.871350,  19.988701, 142.324997/), 13.621099) , &
19504                          xray_form_type("ra+2", 88, (/ 35.215000,  21.670000,   7.913420,   7.650780/), &
19505                                                     (/  0.604909,   3.576700,  12.601000,  29.843599/), 13.543100) /)
19506
19507       Xray_form(191:200)=(/ &
19508                          xray_form_type("ac  ", 89, (/ 35.659698,  23.103199,  12.597700,   4.086550/), &
19509                                                     (/  0.589092,   3.651550,  18.598999, 117.019997/), 13.526600) , &
19510                          xray_form_type("ac+3", 89, (/ 35.173599,  22.111200,   8.192160,   7.055450/), &
19511                                                     (/  0.579689,   3.414370,  12.918700,  25.944300/), 13.463699) , &
19512                          xray_form_type("th  ", 90, (/ 35.564499,  23.421900,  12.747300,   4.807030/), &
19513                                                     (/  0.563359,   3.462040,  17.830900,  99.172195/), 13.431400) , &
19514                          xray_form_type("th+4", 90, (/ 35.100700,  22.441799,   9.785540,   5.294440/), &
19515                                                     (/  0.555054,   3.244980,  13.466100,  23.953300/), 13.375999) , &
19516                          xray_form_type("pa  ", 91, (/ 35.884701,  23.294800,  14.189100,   4.172870/), &
19517                                                     (/  0.547751,   3.415190,  16.923500, 105.250999/), 13.428699) , &
19518                          xray_form_type("u   ", 92, (/ 36.022800,  23.412800,  14.949100,   4.188000/), &
19519                                                     (/  0.529300,   3.325300,  16.092699, 100.612999/), 13.396600) , &
19520                          xray_form_type("u+3 ", 92, (/ 35.574699,  22.525900,  12.216499,   5.370730/), &
19521                                                     (/  0.520480,   3.122930,  12.714800,  26.339399/), 13.309200) , &
19522                          xray_form_type("u+4 ", 92, (/ 35.371498,  22.532600,  12.029100,   4.798400/), &
19523                                                    (/  0.516598,   3.050530,  12.572300,  23.458200/), 13.267099) , &
19524                          xray_form_type("u+6 ", 92, (/ 34.850899,  22.758400,  14.009900,   1.214570/), &
19525                                                     (/  0.507079,   2.890300,  13.176700,  25.201700/), 13.166500) , &
19526                          xray_form_type("np  ", 93, (/ 36.187401,  23.596399,  15.640200,   4.185500/), &
19527                                                     (/  0.511929,   3.253960,  15.362200,  97.490799/), 13.357300) /)
19528
19529       Xray_form(201:210)=(/ &
19530                          xray_form_type("np+3", 93, (/ 35.707397,  22.612999,  12.989799,   5.432270/), &
19531                                                     (/  0.502322,   3.038070,  12.144899,  25.492800/), 13.254400) , &
19532                          xray_form_type("np+4", 93, (/ 35.510300,  22.578699,  12.776600,   4.921590/), &
19533                                                     (/  0.498626,   2.966270,  11.948400,  22.750200/), 13.211599) , &
19534                          xray_form_type("np+6", 93, (/ 35.013599,  22.728600,  14.388400,   1.756690/), &
19535                                                     (/  0.489810,   2.810990,  12.330000,  22.658100/), 13.113000) , &
19536                          xray_form_type("pu  ", 94, (/ 36.525398,  23.808300,  16.770700,   3.479470/), &
19537                                                     (/  0.499384,   3.263710,  14.945499, 105.979996/), 13.381200) , &
19538                          xray_form_type("pu+3", 94, (/ 35.840000,  22.716900,  13.580700,   5.660160/), &
19539                                                    (/  0.484936,   2.961180,  11.533100,  24.399200/), 13.199100) , &
19540                          xray_form_type("pu+4", 94, (/ 35.649300,  22.646000,  13.359500,   5.188310/), &
19541                                                     (/  0.481422,   2.890200,  11.316000,  21.830099/), 13.155500) , &
19542                          xray_form_type("pu+6", 94, (/ 35.173599,  22.718100,  14.763500,   2.286780/), &
19543                                                     (/  0.473204,   2.738480,  11.552999,  20.930300/), 13.058200) , &
19544                          xray_form_type("am  ", 95, (/ 36.670601,  24.099199,  17.341499,   3.493310/), &
19545                                                     (/  0.483629,   3.206470,  14.313600, 102.272995/), 13.359200) , &
19546                          xray_form_type("cm  ", 96, (/ 36.648800,  24.409599,  17.399000,   4.216650/), &
19547                                                     (/  0.465154,   3.089970,  13.434600,  88.483398/), 13.288700) , &
19548                          xray_form_type("bk  ", 97, (/ 36.788101,  24.773600,  17.891899,   4.232840/), &
19549                                                     (/  0.451018,   3.046190,  12.894600,  86.002998/), 13.275400) /)
19550
19551       Xray_form(211:214)=(/ &
19552                          xray_form_type("cf  ", 98, (/ 36.918499,  25.199499,  18.331699,   4.243910/), &
19553                                                     (/  0.437533,   3.007750,  12.404400,  83.788101/), 13.267400) , &
19554                          xray_form_type("o-2 ",  8, (/  4.758000,   3.637000,   0.000000,   0.000000/), &
19555                                                     (/  7.831000,  30.049999,   0.000000,   0.000000/), 1.5940000) , &
19556                          xray_form_type("ze  ",  1, (/  0.000000,   0.000000,   0.000000,   0.000000/), &
19557                                                     (/  0.000000,   0.000000,   0.000000,   0.000000/), 0.0000000) , &
19558                          xray_form_type("d   ",  1, (/  0.493002,   0.322912,   0.140191,   0.040810/), &
19559                                                     (/ 10.510900,  26.125700,   3.142360,  57.799698/),  0.003038) /)
19560       return
19561    End  Subroutine Set_Xray_Form
19562
19563 End Module CFML_Scattering_Chemical_Tables
19564
19565!!-------------------------------------------------------
19566!!---- Crystallographic Fortran Modules Library (CrysFML)
19567!!-------------------------------------------------------
19568!!---- The CrysFML project is distributed under LGPL. In agreement with the
19569!!---- Intergovernmental Convention of the ILL, this software cannot be used
19570!!---- in military applications.
19571!!----
19572!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
19573!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
19574!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
19575!!----
19576!!---- Authors: Juan Rodriguez-Carvajal (ILL)
19577!!----          Javier Gonzalez-Platas  (ULL)
19578!!----
19579!!---- Contributors: Laurent Chapon     (ILL)
19580!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
19581!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
19582!!----               Tierry Roisnel     (CDIFX,Rennes France)
19583!!----               Eric Pellegrini    (ILL)
19584!!----
19585!!---- This library is free software; you can redistribute it and/or
19586!!---- modify it under the terms of the GNU Lesser General Public
19587!!---- License as published by the Free Software Foundation; either
19588!!---- version 3.0 of the License, or (at your option) any later version.
19589!!----
19590!!---- This library is distributed in the hope that it will be useful,
19591!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
19592!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19593!!---- Lesser General Public License for more details.
19594!!----
19595!!---- You should have received a copy of the GNU Lesser General Public
19596!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
19597!!----
19598!!----
19599!!---- MODULE: CFML_Crystallographic_Symmetry
19600!!----   INFO: This module constains everything needed for handling symmetry
19601!!----         in Crystallography. Part of the information is obtained from
19602!!----         tabulated items in the module Symmetry_Tables. In particular
19603!!----         the correspondence of non standard settings Hermann-Mauguin
19604!!----         symbols and Hall symbols for space groups.
19605!!----         The construction of variables of the public type Space_Group_Type
19606!!----         is done by using a variety of algorithms and methods.
19607!!----         Many procedures for handling symmetry (symbolic and algebraic)
19608!!----         are provided in this module.
19609!!----
19610!!---- HISTORY
19611!!----    Update: 05/03/2011
19612!!----
19613!!---- DEPENDENCIES
19614!!----
19615!!--++    Use CFML_GlobalDeps,       only: Cp
19616!!--++    Use CFML_Math_General,     only: Trace, Zbelong, Modulo_Lat, equal_matrix, Equal_Vector
19617!!--++    Use CFML_String_Utilities, only: Equal_Sets_Text, Pack_String, Get_Fraction_2Dig, &
19618!!--++                                     Get_Fraction_1Dig, Frac_Trans_1Dig, L_Case,     &
19619!!--++                                     U_case, Ucase, Getnum, Frac_Trans_2Dig
19620!!--++    Use CFML_Math_3D,          only: Determ_A, matrix_inverse, Resolv_Sist_3x3
19621!!--++    Use CFML_Symmetry_Tables
19622!!----
19623!!----
19624!!---- VARIABLES
19625!!----    CUBIC
19626!!--++    EPS_SYMM                     [Private]
19627!!----    ERR_SYMM
19628!!----    ERR_SYMM_MESS
19629!!--++    GENER_OPER_TYPE              [Private]
19630!!----    HEXA
19631!!----    HEXAG
19632!!----    INLAT
19633!!----    Lat_Ch
19634!!----    LATTICE_CENTRING_TYPE
19635!!----    LTR
19636!!----    MONOC
19637!!----    NLAT
19638!!----    NUM_SPGR_INFO
19639!!----    ORTHOR
19640!!----    SPACEG
19641!!----    SYM_OPER_TYPE
19642!!----    WYCK_POS_TYPE
19643!!----    WYCKOFF_TYPE
19644!!----    SPACE_GROUP_TYPE
19645!!----    TETRA
19646!!----    TRIGO
19647!!----
19648!!---- PROCEDURES
19649!!----    Functions:
19650!!----       APPLYSO
19651!!----       AXES_ROTATION
19652!!--++       EQUAL_SYMOP               [Overloaded Operator]
19653!!--++       EQUIV_SYMOP               [Private]
19654!!----       GET_LAUE_NUM
19655!!----       GET_MULTIP_POS
19656!!----       GET_OCC_SITE
19657!!----       GET_POINTGROUP_NUM
19658!!--++       IS_AXIS                   [Private]
19659!!--++       IS_DIGIT                  [Private]
19660!!--++       IS_HEXA                   [Private]
19661!!----       IS_NEW_OP
19662!!--++       IS_PLANE                  [Private]
19663!!--++       IS_XYZ                    [Private]
19664!!----       LATTICE_TRANS
19665!!--++       PRODUCT_SYMOP             [Overloaded Operator]
19666!!----       SPGR_EQUAL
19667!!----       SYM_PROD
19668!!----
19669!!----    Subroutines:
19670!!----       ALLOCATE_LATTICE_CENTRING
19671!!--++       CHECK_SYMBOL_HM           [Private]
19672!!----       CHECK_GENERATOR
19673!!----       COPY_NS_SPG_TO_SPG
19674!!----       DECODMATMAG
19675!!----       GET_CENTRING_VECTORS
19676!!----       GET_CRYSTAL_SYSTEM
19677!!--++       GET_CRYSTAL_SYSTEM_R_OP   [Overloaded]
19678!!--++       GET_CRYSTAL_SYSTEM_R_ST   [Overloaded]
19679!!----       GET_GENSYMB_FROM_GENER
19680!!----       GET_HALLSYMB_FROM_GENER
19681!!----       GET_LATTICE_TYPE
19682!!----       GET_LAUE_PG
19683!!----       GET_LAUE_STR
19684!!----       GET_ORBIT
19685!!----       GET_POINTGROUP_STR
19686!!--++       GET_SEITZ                 [Private]
19687!!--++       GET_SEITZ_SYMBOL
19688!!--++       GET_SETTING_INFO          [Private]
19689!!----       GET_SHUBNIKOV_OPERATOR_SYMBOL
19690!!----       GET_SO_FROM_FIX
19691!!----       GET_SO_FROM_GENER
19692!!----       GET_SO_FROM_HALL
19693!!----       GET_SO_FROM_HMS
19694!!----       GET_STABILIZER
19695!!----       GET_STRING_RESOLV
19696!!----       GET_SUBORBITS
19697!!----       GET_SYMEL
19698!!----       GET_SYMKOV
19699!!----       GET_SYMSYMB
19700!!--++       GET_SYMSYMBI              [Overloaded]
19701!!--++       GET_SYMSYMBR              [Overloaded]
19702!!----       GET_T_SUBGROUPS
19703!!----       GET_TRASFM_SYMBOL
19704!!----       GET_TRANSL_SYMBOL
19705!!----       INIT_ERR_SYMM
19706!!----       INVERSE_SYMM
19707!!----       LATSYM
19708!!--++       MAX_CONV_LATTICE_TYPE     [Private]
19709!!--++       MOD_TRANS                 [Private]
19710!!----       READ_BIN_SPACEGROUP
19711!!----       READ_MSYMM
19712!!----       READ_SYMTRANS_CODE
19713!!----       READ_XSYM
19714!!----       SEARCHOP
19715!!----       SET_SPACEGROUP
19716!!----       SET_SPG_MULT_TABLE
19717!!----       SETTING_CHANGE
19718!!--++       SETTING_CHANGE_CONV       [Overloaded]
19719!!--++       SETTING_CHANGE_NONCONV    [Overloaded]
19720!!----       SIMILAR_TRANSF_SG
19721!!----       SYM_B_RELATIONS
19722!!--++       SYM_B_RELATIONS_OP        [Overloaded]
19723!!--++       SYM_B_RELATIONS_ST        [Overloaded]
19724!!----       SYM_PROD_ST
19725!!----       SYMMETRY_SYMBOL
19726!!--++       SYMMETRY_SYMBOL_OP        [Overloaded]
19727!!--++       SYMMETRY_SYMBOL_STR       [Overloaded]
19728!!--++       SYMMETRY_SYMBOL_XYZ       [Overloaded]
19729!!----       WRITE_BIN_SPACEGROUP
19730!!----       WRITE_SPACEGROUP
19731!!----       WRITE_SYM
19732!!----       WRITE_SYMTRANS_CODE
19733!!----       WRITE_WYCKOFF
19734!!----       WYCKOFF_ORBIT
19735!!----
19736!!--..    Operators:
19737!!--..       (*)
19738!!--..       (==)
19739!!----
19740!!
19741 Module CFML_Crystallographic_Symmetry
19742
19743    !---- Used External Modules ----!
19744    Use CFML_GlobalDeps,       only: cp
19745    Use CFML_Math_General,     only: Trace, Zbelong, Modulo_Lat, equal_matrix,             &
19746                                     Equal_Vector,Sort,Set_Epsg,Set_Epsg_Default
19747    Use CFML_Math_3D,          only: Determ_A, matrix_inverse, Resolv_Sist_3x3
19748    Use CFML_String_Utilities, only: Equal_Sets_Text, Pack_String, Get_Fraction_2Dig,      &
19749                                     Get_Fraction_1Dig, Frac_Trans_1Dig, L_Case,           &
19750                                     U_case, Ucase, Getnum, Frac_trans_2Dig, Get_Num_String
19751    Use CFML_Symmetry_Tables
19752
19753    implicit none
19754
19755    private
19756
19757    !---- List of public variables and types ----!
19758
19759    !---- List of public overloaded operators ----!
19760    public ::  operator (*), operator (==)
19761
19762    !---- List of public functions ----!
19763    public  :: ApplySO, Axes_Rotation, Get_Laue_Num, Get_Multip_Pos, Get_Occ_Site,     &
19764               Get_Pointgroup_Num, Is_New_Op, Lattice_Trans, Spgr_Equal, Sym_Prod
19765
19766    !---- List of public subroutines ----!
19767    public  :: Decodmatmag, Get_Centring_Vectors, Get_Crystal_System, Get_Lattice_Type,              &
19768               Get_Laue_Pg, Get_Laue_Str, Get_orbit, Get_Pointgroup_Str, Get_So_From_Fix,            &
19769               Get_So_From_Gener,Get_So_From_Hall, Get_So_From_Hms, Get_HallSymb_From_Gener,         &
19770               Get_Stabilizer,Get_String_Resolv,Get_SubOrbits,Get_Symel, Get_Symkov, Get_SymSymb,    &
19771               Init_Err_Symm, Inverse_Symm, Latsym, Read_Msymm, Read_Xsym, Searchop,                 &
19772               Set_Spacegroup, Setting_Change, Sym_B_Relations, Sym_Prod_St, Symmetry_Symbol,        &
19773               Write_Spacegroup, Write_Sym, Write_Wyckoff, Wyckoff_Orbit, Get_T_SubGroups,           &
19774               Similar_Transf_SG, Read_SymTrans_Code, Write_SymTrans_Code, Set_SpG_Mult_Table,       &
19775               Get_Seitz_Symbol, Get_Trasfm_Symbol,Get_Shubnikov_Operator_Symbol,                    &
19776               Get_Transl_Symbol, Read_Bin_Spacegroup, Write_Bin_Spacegroup, Get_GenSymb_from_Gener, &
19777               Check_Generator, Copy_NS_SpG_To_SpG, Allocate_Lattice_Centring
19778
19779    !---- List of private Operators ----!
19780    private :: Equal_Symop, Product_Symop
19781
19782    !---- List of private functions ----!
19783    private :: Is_Axis, Is_Digit, Is_Hexa, Is_Plane, Is_Xyz, Equiv_Symop
19784
19785    !---- List of private subroutines ----!
19786    private :: Check_Symbol_Hm, Get_Seitz, Get_SymSymbI, Get_SymSymbR, Mod_Trans, Sym_B_Relations_Op  , &
19787               Sym_B_Relations_St, Symmetry_Symbol_Op, Symmetry_Symbol_Xyz , Symmetry_Symbol_Str,       &
19788               Max_Conv_Lattice_Type,Get_Setting_Info,Get_Crystal_System_R_OP,Get_Crystal_System_R_ST, &
19789               Setting_Change_Conv,Setting_Change_NonConv
19790
19791
19792    !---- Global Variables ----!
19793
19794    !---- Definitions ----!
19795
19796    !!----
19797    !!---- CUBIC
19798    !!----    integer, parameter, public :: Cubic
19799    !!----
19800    !!----    Cubic parameter index: Cubic = 554
19801    !!----
19802    !!---- Update: February - 2005
19803    !!
19804    integer, parameter, public :: Cubic = 554
19805
19806    !!--++
19807    !!--++ eps_symm
19808    !!--++    real(kind=cp), parameter, private :: eps_symm
19809    !!--++
19810    !!--++    (PRIVATE)
19811    !!--++    Epsilon for comparisons within this module
19812    !!--++
19813    !!--++ Update: February - 2005
19814    !!
19815    real(kind=cp), parameter, private :: eps_symm  = 0.0002_cp
19816
19817    !!----
19818    !!---- ERR_SYMM_MESS
19819    !!----    character(len=150), public :: ERR_Symm_Mess
19820    !!----
19821    !!----    String containing information about the last error
19822    !!----
19823    !!---- Update: February - 2005
19824    !!
19825    character(len=150), public :: ERR_Symm_Mess
19826
19827    !!----
19828    !!---- ERR_SYMM
19829    !!----    logical, public :: Err_Symm
19830    !!----
19831    !!----    Logical Variable to indicate an error on this module.
19832    !!----
19833    !!---- Update: February - 2005
19834    !!
19835    logical, public :: Err_Symm
19836
19837    !!--++
19838    !!--++ TYPE :: GENER_OPER_TYPE
19839    !!--..
19840    !!--++ Type, private :: Gener_Oper_Type
19841    !!--++    integer          :: orden
19842    !!--++    character(len=1) :: axes
19843    !!--++    character(len=1) :: axes2
19844    !!--++    character(len=2) :: tras
19845    !!--++ End Type Gener_Oper_Type
19846    !!--++
19847    !!--++ Update: February - 2005
19848    !!
19849    Type, private :: Gener_Oper_Type
19850       integer          :: orden
19851       character(len=1) :: axes
19852       character(len=1) :: axes2
19853       character(len=3) :: tras
19854    End Type Gener_Oper_Type
19855
19856    !!----
19857    !!---- HEXA
19858    !!----    logical, public :: Hexa
19859    !!----
19860    !!----    .false. Rotational part of symmetry operators  belongs to m3m
19861    !!----    .true.  Rotational part of symmetry operators  belongs to 6/mmm
19862    !!----
19863    !!---- Update: February - 2005
19864    !!
19865    logical, public :: Hexa
19866
19867    !!----
19868    !!---- HEXAG
19869    !!----    integer, parameter, public :: Hexag
19870    !!----
19871    !!----    Index parameter for hexagonal Groups: Hexag  = 527
19872    !!----
19873    !!---- Update: February - 2005
19874    !!
19875    integer, parameter, public :: Hexag         = 527
19876
19877    !!----
19878    !!---- INLAT
19879    !!----    integer, public        :: Inlat
19880    !!----
19881    !!----    Ordinal index of the lattice
19882    !!----
19883    !!---- Update: February - 2005
19884    !!
19885    integer, public        :: Inlat
19886
19887    !!----
19888    !!---- Lat_Ch
19889    !!----    character(len= 1), public     :: Lat_Ch
19890    !!----
19891    !!----    First character of the space group symbol
19892    !!----
19893    !!---- Update: February - 2005
19894    !!
19895    character(len= 1), public     :: Lat_Ch
19896
19897    !!----
19898    !!---- TYPE :: Lattice_Centring_Type
19899    !!--..
19900    !!---- Type, public :: Lattice_Centring_Type
19901    !!----    integer                                     :: N_lat
19902    !!----    logical                                     :: set
19903    !!----    real(kind=cp), dimension(:,:),allocatable   :: LTr
19904    !!---- End Type Lattice_Centring_Type
19905    !!----
19906    !!----   Lattice centring translations (including anti-translation)
19907    !!----   symmetry operators defined with respect to arbitrary axes.
19908    !!----   Normally the first translation is the identity element of the translation
19909    !!----   group: Ltr(:,1)=[0,0,0] or [0,0,0,1] if time inversion is considered to take
19910    !!----   into account also the anti-translations.
19911    !!----   For using this type first the program should allocate the arrays by calling
19912    !!----   the subroutine Allocate_Lattice_Centring and then construct totally the object
19913    !!----   by assigning appropriate values and putting set=.true.
19914    !!----
19915    !!---- Update: October - 2014
19916    !!
19917    Type, public :: Lattice_Centring_Type
19918       integer                                     :: N_lat
19919       logical                                     :: set
19920       real(kind=cp), dimension(:,:),allocatable   :: LTr
19921    End Type Lattice_Centring_Type
19922
19923
19924    !!----
19925    !!---- LTR
19926    !!----    real(kind=cp), dimension(3,192), public  :: Ltr
19927    !!----
19928    !!----    Centering Lattice Translations, up to 192 lattice centring
19929    !!----    vectors are allowed. Conventional lattice centring need only 4 vectors
19930    !!----
19931    !!---- Update: February - 2005, January-2014
19932    !!
19933    real(kind=cp), dimension(3,192), public  :: Ltr    ! Centering Lattice Translations
19934
19935    !!----
19936    !!---- MONOC
19937    !!----    integer, parameter, public :: Monoc
19938    !!----
19939    !!----    Index parameter for Monoclinic Groups: Monoc  =  15
19940    !!----
19941    !!---- Update: February - 2005
19942    !!
19943    integer, parameter, public :: Monoc         =  15
19944
19945    !!----
19946    !!---- NLAT
19947    !!----    integer, public      :: Nlat
19948    !!----
19949    !!----    Multiplicity of the lattice
19950    !!----
19951    !!---- Update: February - 2005
19952    !!
19953    integer, public      :: Nlat
19954
19955    !!----
19956    !!---- TYPE :: NS_SYM_OPER_TYPE
19957    !!--..
19958    !!---- Type, public :: NS_Sym_Oper_Type
19959    !!----    real(kind=cp), dimension(3,3) :: Rot     !  Rotational Part of Symmetry Operator
19960    !!----    real(kind=cp), dimension(3)   :: Tr      !  Traslational part of Symmetry Operator
19961    !!---- End Type  NS_Sym_Oper_Type
19962    !!----
19963    !!----   Non-standard symmetry operator. Needed for describing non-standard space groups with
19964    !!----   symmetry operators defined with respect to arbitrary axes
19965    !!----
19966    !!---- Update: January - 2014
19967    !!
19968    Type, public :: NS_Sym_Oper_Type
19969       real(kind=cp), dimension(3,3) :: Rot
19970       real(kind=cp), dimension(3)   :: Tr
19971    End Type NS_Sym_Oper_Type
19972
19973    !!----
19974    !!---- TYPE :: NS_SPACE_GROUP_TYPE
19975    !!--..
19976    !!---- Type, public :: NS_Space_Group_Type
19977    !!----    Integer                                          :: NumSpg        ! Number of the Space Group
19978    !!----    Character(len=20)                                :: SPG_Symb      ! Hermann-Mauguin Symbol
19979    !!----    Character(len=16)                                :: Hall          ! Hall symbol
19980    !!----    Character(len=90)                                :: gHall         ! Generalised Hall symbol
19981    !!----    Character(len=12)                                :: CrystalSys    ! Crystal system
19982    !!----    Character(len= 5)                                :: Laue          ! Laue Class
19983    !!----    Character(len= 5)                                :: PG            ! Point group
19984    !!----    Character(len= 5)                                :: Info          ! Extra information
19985    !!----    Character(len=90)                                :: SG_setting    ! Information about the SG setting
19986    !!----                                                                      ! (IT,KO,ML,ZA,Table,Standard,UnConventional)
19987    !!----    Character(len= 1)                                :: SPG_lat       ! Lattice type
19988    !!----    Character(len= 2)                                :: SPG_latsy     ! Lattice type Symbol
19989    !!----    Integer                                          :: NumLat        ! Number of lattice points in a cell
19990    !!----    real(kind=cp), allocatable, dimension(:,:)       :: Latt_trans    ! Lattice translations
19991    !!----    Character(len=51)                                :: Bravais       ! String with Bravais symbol + translations
19992    !!----    Character(len=80)                                :: Centre        ! Information about Centric or Acentric
19993    !!----    Integer                                          :: Centred       ! =0 Centric(-1 no at origin)
19994    !!----                                                                      ! =1 Acentric
19995    !!----                                                                      ! =2 Centric(-1 at origin)
19996    !!----    real(kind=cp), dimension(3)                      :: Centre_coord  ! Fractional coordinates of the inversion centre
19997    !!----    Integer                                          :: NumOps        ! Number of reduced set of S.O.
19998    !!----    Integer                                          :: Multip        ! Multiplicity of the general position
19999    !!----    Integer                                          :: Num_gen       ! Minimum number of operators to generate the Group
20000    !!----    type(NS_Sym_Oper_Type), allocatable, dimension(:):: SymOp         ! Symmetry operators (192)
20001    !!----    Character(len=50),      allocatable, dimension(:):: SymopSymb     ! Strings form of symmetry operators (192)
20002    !!---- End Type NS_Space_Group_Type
20003    !!----
20004    !!----  Definition of the type NS_Space_Group_Type: Non-standard space group. This type has been created
20005    !!----  in order to be able to describe symmetry operators with non-integer values when they are referred
20006    !!----  to arbitrary settings. They are created only as intermediate variables in some calculations.
20007    !!----
20008    !!---- Updated: February - 2005, January 2014 (JRC to make some components allocatable and change the length of some strings)
20009    !!
20010    Type, public :: NS_Space_Group_Type
20011       integer                                          :: NumSpg=0         ! Number of the Space Group
20012       character(len=20)                                :: SPG_Symb=" "     ! Hermann-Mauguin Symbol
20013       character(len=16)                                :: Hall=" "         ! Hall symbol
20014       character(len=90)                                :: gHall=" "        ! Generalised Hall symbol
20015       character(len=12)                                :: CrystalSys=" "   ! Crystal system
20016       character(len= 5)                                :: Laue=" "         ! Laue Class
20017       character(len= 5)                                :: PG=" "           ! Point group
20018       character(len= 5)                                :: Info=" "         ! Extra information
20019       character(len=90)                                :: SG_setting=" "   ! Information about the SG setting (IT,KO,ML,ZA,Table,Standard,UnConventional)
20020       character(len= 1)                                :: SPG_lat=" "      ! Lattice type
20021       character(len= 2)                                :: SPG_latsy=" "    ! Lattice type Symbol
20022       integer                                          :: NumLat=1         ! Number of lattice points in a cell
20023       real(kind=cp), allocatable,dimension(:,:)        :: Latt_trans       ! Lattice translations (3,12)
20024       character(len=51)                                :: Bravais=" "      ! String with Bravais symbol + translations
20025       character(len=80)                                :: Centre=" "       ! Alphanumeric information about the center of symmetry
20026       integer                                          :: Centred=0        ! Centric or Acentric [ =0 Centric(-1 no at origin),=1 Acentric,=2 Centric(-1 at origin)]
20027       real(kind=cp), dimension(3)                      :: Centre_coord=0.0 ! Fractional coordinates of the inversion centre
20028       integer                                          :: NumOps=0         ! Number of reduced set of S.O.
20029       integer                                          :: Multip=0         ! Multiplicity of the general position
20030       integer                                          :: Num_gen=0        ! Minimum number of operators to generate the Group
20031       type(NS_Sym_Oper_Type), allocatable,dimension(:) :: SymOp            ! Symmetry operators (192)
20032       character(len=50),      allocatable,dimension(:) :: SymopSymb        ! Strings form of symmetry operators
20033    End Type NS_Space_Group_Type
20034
20035    !!----
20036    !!---- NUM_SPGR_INFO
20037    !!----    integer, parameter, public :: Num_Spgr_Info
20038    !!----
20039    !!----    Total dimension of SPGR_INFO: Num_Spgr_Info = 612
20040    !!----
20041    !!---- Update: February - 2005
20042    !!
20043    integer, parameter, public :: Num_Spgr_Info = 612
20044
20045    !!----
20046    !!---- ORTHOR
20047    !!----    integer, parameter, public :: Orthor
20048    !!----
20049    !!----    Index parameter for Orthorhombic Groups: Orthor  = 163
20050    !!----
20051    !!---- Update: February - 2005
20052    !!
20053    integer, parameter, public :: Orthor  = 163
20054
20055    !!----
20056    !!---- SPACEG
20057    !!----     character(len=20), public     :: SpaceG
20058    !!----
20059    !!----     Space group symbol
20060    !!----
20061    !!---- Update: February - 2005
20062    !!
20063    character(len=20), public   :: SpaceG
20064
20065    !!----
20066    !!---- TYPE :: SYM_OPER_TYPE
20067    !!--..
20068    !!---- Type, public :: Sym_Oper_Type
20069    !!----    integer,       dimension(3,3) :: Rot     !  Rotational Part of Symmetry Operator
20070    !!----    real(kind=cp), dimension(3)   :: Tr      !  Traslational part of Symmetry Operator
20071    !!---- End Type  Sym_Oper_Type
20072    !!----
20073    !!----    Definition of Variable
20074    !!----
20075    !!---- Update: February - 2005
20076    !!
20077    Type, public :: Sym_Oper_Type
20078       integer,       dimension(3,3) :: Rot
20079       real(kind=cp), dimension(3)   :: Tr
20080    End Type Sym_Oper_Type
20081
20082    !!----
20083    !!---- TYPE :: WYCK_POS_TYPE
20084    !!--..
20085    !!---- Type, public :: Wyck_Pos_Type
20086    !!----    integer                         :: multp     ! Multiplicity
20087    !!----    character(len= 6)               :: site      ! Site Symmetry
20088    !!----    integer                         :: norb      ! Number of elements in orbit
20089    !!----    character(len=40)               :: orig      ! Orig
20090    !!----    character(len=40),dimension(48) :: str_orbit ! Orbit
20091    !!----    character(len=40),dimension(192):: extra_orbit
20092    !!---- End Type Wyck_Pos_Type
20093    !!----
20094    !!----    Definition of Variable
20095    !!----
20096    !!---- Update: February - 2005
20097    !!
20098    Type, public :: Wyck_Pos_Type
20099       integer                          :: multp
20100       character(len= 6)                :: site
20101       integer                          :: norb
20102       character(len=40)                :: str_orig
20103       character(len=40),dimension(48)  :: str_orbit
20104    End Type Wyck_Pos_Type
20105
20106    !!----
20107    !!---- TYPE :: WYCKOFF_TYPE
20108    !!--..
20109    !!---- Type, public :: Wyckoff_Type
20110    !!----    integer                            :: num_orbit      ! Number of orbits
20111    !!----    type(wyck_pos_type), dimension(26) :: orbit          ! Orbit type
20112    !!---- End Type Wyckoff_Type
20113    !!----
20114    !!----    Definition of Variable
20115    !!----
20116    !!---- Update: February - 2005
20117    !!
20118    Type, public :: Wyckoff_Type
20119       integer                            :: num_orbit
20120       type(wyck_pos_type), dimension(26) :: orbit
20121    End Type Wyckoff_Type
20122
20123    !!----
20124    !!---- TYPE :: SPACE_GROUP_TYPE
20125    !!--..
20126    !!---- Type, public :: Space_Group_Type
20127    !!----    Integer                                         :: NumSpg        ! Number of the Space Group
20128    !!----    Character(len=20)                               :: SPG_Symb      ! Hermann-Mauguin Symbol
20129    !!----    Character(len=16)                               :: Hall          ! Hall symbol
20130    !!----    Character(len=90)                               :: gHall         ! Generalised Hall symbol
20131    !!----    Character(len=12)                               :: CrystalSys    ! Crystal system
20132    !!----    Character(len= 5)                               :: Laue          ! Laue Class
20133    !!----    Character(len= 5)                               :: PG            ! Point group
20134    !!----    Character(len= 5)                               :: Info          ! Extra information
20135    !!----    Character(len=90)                               :: SG_setting    ! Information about the SG setting
20136    !!----                                                                     ! (IT,KO,ML,ZA,Table,Standard,UnConventional)
20137    !!----    Logical                                         :: Hexa          !
20138    !!----    Character(len= 1)                               :: SPG_lat       ! Lattice type
20139    !!----    Character(len= 2)                               :: SPG_latsy     ! Lattice type Symbol
20140    !!----    Integer                                         :: NumLat        ! Number of lattice points in a cell
20141    !!----    real(kind=cp), allocatable, dimension(:,:)      :: Latt_trans    ! Lattice translations
20142    !!----    Character(len=51)                               :: Bravais       ! String with Bravais symbol + translations
20143    !!----    Character(len=80)                               :: Centre        ! Information about Centric or Acentric
20144    !!----    Integer                                         :: Centred       ! =0 Centric(-1 no at origin)
20145    !!----                                                                     ! =1 Acentric
20146    !!----                                                                     ! =2 Centric(-1 at origin)
20147    !!----    real(kind=cp), dimension(3)                     :: Centre_coord  ! Fractional coordinates of the inversion centre
20148    !!----    Integer                                         :: NumOps        ! Number of reduced set of S.O.
20149    !!----    Integer                                         :: Multip        ! Multiplicity of the general position
20150    !!----    Integer                                         :: Num_gen       ! Minimum number of operators to generate the Group
20151    !!----    type(Sym_Oper_Type), allocatable, dimension(:)  :: SymOp         ! Symmetry operators (192)
20152    !!----    Character(len=50),   allocatable, dimension(:)  :: SymopSymb     ! Strings form of symmetry operators (192)
20153    !!----    type(wyckoff_type)                              :: Wyckoff       ! Wyckoff Information
20154    !!----    real(kind=cp), dimension(3,2)                   :: R_Asym_Unit   ! Asymmetric unit in real space
20155    !!---- End Type Space_Group_Type
20156    !!----
20157    !!----     Definition of a variable type Space_Group_Type
20158    !!----
20159    !!---- Updated: February - 2005, January 2014 (JRC to make some components allocatable and change the length of some strings)
20160    !!
20161    Type, public :: Space_Group_Type
20162       integer                                       :: NumSpg=0         ! Number of the Space Group
20163       character(len=20)                             :: SPG_Symb=" "     ! Hermann-Mauguin Symbol
20164       character(len=16)                             :: Hall=" "         ! Hall symbol
20165       character(len=90)                             :: gHall=" "        ! Generalised Hall symbol
20166       character(len=12)                             :: CrystalSys=" "   ! Crystal system
20167       character(len= 5)                             :: Laue=" "         ! Laue Class
20168       character(len= 5)                             :: PG=" "           ! Point group
20169       character(len= 5)                             :: Info=" "         ! Extra information
20170       character(len=90)                             :: SG_setting=" "   ! Information about the SG setting (IT,KO,ML,ZA,Table,Standard,UnConventional)
20171       logical                                       :: Hexa=.false.     !
20172       character(len= 1)                             :: SPG_lat=" "      ! Lattice type
20173       character(len= 2)                             :: SPG_latsy=" "    ! Lattice type Symbol
20174       integer                                       :: NumLat=0         ! Number of lattice points in a cell
20175       real(kind=cp), allocatable,dimension(:,:)     :: Latt_trans       ! Lattice translations (3,12)
20176       character(len=51)                             :: Bravais=" "      ! String with Bravais symbol + translations
20177       character(len=80)                             :: Centre=" "       ! Alphanumeric information about the center of symmetry
20178       integer                                       :: Centred=0        ! Centric or Acentric [ =0 Centric(-1 no at origin),=1 Acentric,=2 Centric(-1 at origin)]
20179       real(kind=cp), dimension(3)                   :: Centre_coord=0.0 ! Fractional coordinates of the inversion centre
20180       integer                                       :: NumOps=0         ! Number of reduced set of S.O.
20181       integer                                       :: Multip=0         ! Multiplicity of the general position
20182       integer                                       :: Num_gen          ! Minimum number of operators to generate the Group
20183       type(Sym_Oper_Type), allocatable,dimension(:) :: SymOp            ! Symmetry operators (192)
20184       character(len=50),   allocatable,dimension(:) :: SymopSymb        ! Strings form of symmetry operators
20185       type(Wyckoff_Type)                            :: Wyckoff          ! Wyckoff Information
20186       real(kind=cp),dimension(3,2)                  :: R_Asym_Unit=0.0  ! Asymmetric unit in real space
20187    End Type Space_Group_Type
20188
20189    !!----
20190    !!---- TETRA
20191    !!----    integer, parameter, public :: Tetra
20192    !!----
20193    !!----    Index parameter for Tetragonal Groups: Tetra = 410
20194    !!----
20195    !!---- Update: February - 2005
20196    !!
20197    integer, parameter, public :: Tetra = 410
20198
20199    !!----
20200    !!---- TRIGO
20201    !!----    integer, parameter, public :: Trigo
20202    !!----
20203    !!----    Index parameter for Trigonal Groups: Trigo = 495
20204    !!----
20205    !!---- Update: February - 2005
20206    !!
20207    integer, parameter, public :: Trigo = 495
20208
20209
20210    !---- Interfaces Definitions for Overload ----!
20211
20212    Interface  Get_Crystal_System
20213       Module Procedure Get_Crystal_System_R_OP
20214       Module Procedure Get_Crystal_System_R_ST
20215    End Interface  Get_Crystal_System
20216
20217    Interface  Get_SymSymb
20218       Module Procedure Get_SymSymbI
20219       Module Procedure Get_SymSymbR
20220    End Interface  Get_SymSymb
20221
20222    Interface  Setting_Change
20223       Module Procedure Setting_Change_Conv
20224       Module Procedure Setting_Change_NonConv
20225    End Interface  Setting_Change
20226
20227    Interface  Sym_B_Relations
20228       Module Procedure Sym_B_Relations_Op
20229       Module Procedure Sym_B_Relations_St
20230    End Interface  Sym_B_Relations
20231
20232    Interface  Symmetry_Symbol
20233       Module Procedure Symmetry_Symbol_Op
20234       Module Procedure Symmetry_Symbol_Str
20235       Module Procedure Symmetry_Symbol_Xyz
20236    End Interface  Symmetry_Symbol
20237
20238    Interface operator (*)
20239       Module Procedure Product_Symop
20240    End Interface
20241
20242    Interface Operator (==)
20243       Module Procedure Equal_Symop
20244    End Interface
20245
20246 Contains
20247
20248    !---- Functions ----!
20249
20250    !!----
20251    !!---- Function Applyso(Op,V) Result(Applysop)
20252    !!----    Type(Sym_Oper_Type),          intent(in) :: Op        !  In -> Symmetry Operator Type
20253    !!----    real(kind=cp), dimension(3) , intent(in) :: v         !  In -> Vector
20254    !!----    real(kind=cp), dimension(3)              :: ApplySOp  ! Out -> Output vector
20255    !!----
20256    !!----    Apply a symmetry operator to a vector:  Vp = ApplySO(Op,v)
20257    !!----
20258    !!---- Update: February - 2005
20259    !!
20260    Function ApplySO(Op,V) Result(Applysop)
20261       !---- Arguments ----!
20262       Type(Sym_Oper_Type),          intent(in) :: Op
20263       real(kind=cp), dimension(3),  intent(in) :: v
20264       real(kind=cp), dimension(3)              :: ApplySOp
20265
20266       ApplySOp = matmul(Op%Rot,v) + Op%tr
20267
20268       return
20269    End Function ApplySO
20270
20271    !!----
20272    !!---- Function Axes_Rotation(R) Result(N)
20273    !!----    integer, dimension(3,3), intent  (in) :: r    !  In -> Rotation part of Symmetry Operator
20274    !!----    integer                               :: n    ! Out -> Orden of the Rotation Part
20275    !!----
20276    !!----    Determine the orden of rotation (valid for all bases). Return a zero
20277    !!----    if any error occurs.
20278    !!----
20279    !!---- Update: February - 2005
20280    !!
20281    Function Axes_Rotation(R) Result(N)
20282       !---- Arguments ----!
20283       integer, dimension(3,3), intent (in) :: r
20284       integer                              :: n
20285
20286       !---- Local Variables ----!
20287       integer :: det,itr
20288
20289       n=0
20290
20291       det=determ_A(r)
20292       itr=trace(r)
20293       select case (itr)
20294          case (-3)
20295             if (det == -1) n=-1
20296
20297          case (-2)
20298             if (det == -1) n=-6
20299
20300          case (-1)
20301             if (det == -1) n=-4
20302             if (det ==  1) n= 2
20303
20304          case ( 0)
20305             if (det == -1) n=-3
20306             if (det ==  1) n= 3
20307
20308          case ( 1)
20309             if (det == -1) n=-2
20310             if (det ==  1) n= 4
20311
20312          case ( 2)
20313             if (det ==  1) n= 6
20314
20315          case ( 3)
20316             if (det ==  1) n= 1
20317       end select
20318
20319       return
20320    End Function Axes_Rotation
20321
20322    !!--++
20323    !!--++ Function Equal_Symop(Syma,Symb) Result (Aeqb)
20324    !!--++    type(Sym_Oper_Type), intent (in) :: syma
20325    !!--++    type(Sym_Oper_Type), intent (in) :: symb
20326    !!--++    logical                          :: aeqb
20327    !!--++
20328    !!--++    (OVERLOADED)
20329    !!--++    The result is .true. if syma == symb, otherwise is .false.
20330    !!--++    It overloads the "==" operator for objects of type Sym_Oper_Type.
20331    !!--++    The calling program can use a statement like: if(syma == symb) then ...
20332    !!--++
20333    !!--++  Update: February - 2005
20334    !!
20335    Function Equal_Symop(Syma,Symb) Result (Aeqb)
20336       !---- Arguments ----!
20337       type(Sym_Oper_Type), intent (in) :: syma
20338       type(Sym_Oper_Type), intent (in) :: symb
20339       logical                          :: aeqb
20340
20341       !---- Local variables ----!
20342       integer :: i,j
20343
20344       aeqb=.false.
20345       do i=1,3
20346          if (abs(Syma%tr(i)-Symb%tr(i)) > eps_symm) return
20347       end do
20348
20349       do i=1,3
20350          do j=1,3
20351             if (abs(Syma%Rot(i,j)-Symb%Rot(i,j)) > eps_symm) return
20352          end do
20353       end do
20354       aeqb=.true.
20355
20356       return
20357    End Function Equal_Symop
20358
20359    !!--++
20360    !!--++ Equiv_Symop(Syma,Symb,Lat) Result (Aeqb)
20361    !!--++    type(Sym_Oper_Type), intent (in) :: syma
20362    !!--++    type(Sym_Oper_Type), intent (in) :: symb
20363    !!--++    character (len=*),   intent (in) :: lat
20364    !!--++    logical                          :: aeqb
20365    !!--++
20366    !!--++    The result is .true. if Syma  differ from Symb just by a lattice
20367    !!--++    translation. This Function is used by the subroutine constructing
20368    !!--++    the multiplication table of the factor group of a space group.
20369    !!--++
20370    !!--++  Update: April - 2005
20371    !!
20372    Function Equiv_Symop(Syma,Symb,Lat) Result (Aeqb)
20373       !---- Arguments ----!
20374       type(Sym_Oper_Type), intent (in) :: syma
20375       type(Sym_Oper_Type), intent (in) :: symb
20376       character (len=*),   intent (in) :: lat
20377       logical                          :: aeqb
20378
20379       !---- Local variables ----!
20380       integer                     :: i,j
20381       real(kind=cp), dimension(3) :: tr
20382
20383       aeqb=.false.
20384       tr= Syma%tr-Symb%tr
20385       if (.not. Lattice_Trans(tr,Lat)) return
20386       do i=1,3
20387          do j=1,3
20388             if (abs(Syma%Rot(i,j)-Symb%Rot(i,j)) > 0) return
20389          end do
20390       end do
20391       aeqb=.true.
20392
20393       return
20394    End Function Equiv_Symop
20395
20396
20397    !!----
20398    !!---- Function Get_Laue_Num(Laueclass) Result(Lnum)
20399    !!----    character(len=*), intent (in) :: laueclass    !  In -> Laue Class string
20400    !!----    integer                       :: lnum         ! Out -> Ordinal number according LAUE_CLASS
20401    !!----
20402    !!----    Obtain the ordinal number corresponding to the Laue-Class
20403    !!----    symbol according to Laue_Class array. Zero if error is present
20404    !!----
20405    !!---- Update: February - 2005
20406    !!
20407    Function Get_Laue_Num(Laueclass) Result(Lnum)
20408       !---- Arguments ----!
20409       character(len=*), intent (in) :: laueclass
20410       integer                       :: lnum
20411
20412       !---- Local Variables ----!
20413       integer                       :: i
20414       character(len=len(laueclass)) :: laue
20415
20416       lnum=0
20417       laue=adjustl(laueclass)
20418
20419       do i=1,16
20420          if (laue(1:5) == laue_class(i)) then
20421             lnum=i
20422             exit
20423          end if
20424       end do
20425       if (lnum==15) lnum=13
20426       if (lnum==16) lnum=14
20427
20428       return
20429    End Function Get_Laue_Num
20430
20431    !!----
20432    !!----  Function Get_Multip_Pos(X,Spg) Result(Mult)
20433    !!----    real(kind=cp), dimension(3), intent (in) :: x        !  In -> Position vector
20434    !!----    type(Space_Group_type),      intent (in) :: spgr     !  In -> Space Group
20435    !!----    integer                                  :: mult     !  Result -> Multiplicity
20436    !!----
20437    !!----    Obtain the multiplicity of a real space point given the space group.
20438    !!----
20439    !!---- Update: February - 2005
20440    !!
20441    Function Get_Multip_Pos(x,Spg) Result(mult)
20442       !---- Arguments ----!
20443       real(kind=cp), dimension(3),  intent (in) :: x
20444       type(Space_Group_type),       intent (in) :: spg
20445       integer                                   :: mult
20446
20447       !---- Local variables ----!
20448       integer                                :: j, nt
20449       real(kind=cp), dimension(3)            :: xx,v
20450       real(kind=cp), dimension(3,Spg%multip) :: u
20451
20452       !> Init Epss
20453       call set_epsg(1.0e-3)
20454
20455       mult=1
20456       u(:,1)=x(:)
20457
20458       ext: do j=2,Spg%multip
20459          xx=ApplySO(Spg%SymOp(j),x)
20460          xx=modulo_lat(xx)
20461          do nt=1,mult
20462             v=u(:,nt)-xx(:)
20463             if (Lattice_trans(v,Spg%spg_lat)) cycle ext
20464          end do
20465          mult=mult+1
20466          u(:,mult)=xx(:)
20467       end do ext
20468
20469       mult=mult*Spg%Numlat
20470
20471       !> Reset value for epss
20472       call set_epsg_default()
20473
20474       return
20475    End Function Get_Multip_Pos
20476
20477    !!----
20478    !!---- Function Get_Occ_Site(Pto,Spg) Result(Occ)
20479    !!----    real(kind=cp),dimension(3),intent (in) :: Pto ! Point for Occupancy calculation
20480    !!----    Type (Space_Group_Type),   intent(in)  :: Spg ! Space Group
20481    !!----    real(kind=cp)                          :: Occ ! Result
20482    !!----
20483    !!----    Obtain the occupancy factor (site multiplicity/multiplicity) for Pto
20484    !!----
20485    !!---- Update: February - 2005
20486    !!
20487    Function Get_Occ_Site(Pto,Spg) Result(Occ)
20488       !---- Arguments ----!
20489       real(kind=cp), dimension(3),intent(in) :: Pto
20490       type (Space_Group_Type),    intent(in) :: Spg
20491       real(kind=cp)                          :: Occ
20492
20493       !---- Local Variables ----!
20494
20495       !> Init Epss
20496       call set_epsg(1.0e-3)
20497
20498       Occ=real(Get_Multip_pos(pto,Spg))/real(Spg%multip)
20499
20500       !> Reset value Epss
20501       call set_epsg_default()
20502
20503       return
20504    End Function Get_Occ_Site
20505
20506    !!----
20507    !!---- Function Get_Pointgroup_Num(Pgname) Result(Ipg)
20508    !!----    character(len=*), intent (in) :: pgname        !  In -> String for PointGroup
20509    !!----    integer                       :: ipg           ! Out -> Ordinal number as POINT_GROUP
20510    !!----
20511    !!----    Obtain the ordinal number corresponding to the Point Group
20512    !!----    symbol according to Point_Group array. Zero if Error is present
20513    !!----
20514    !!---- Update: July - 2014: added m3 and m3m for compatibility with Laue_class
20515    !!
20516    Function Get_Pointgroup_Num(Pgname) Result(Ipg)
20517       !---- Arguments ----!
20518       character(len=*), intent (in) :: pgname
20519       integer                       :: ipg
20520
20521       !---- Local Variables ----!
20522       integer                       :: i
20523       character(len=len(pgname))    :: pg
20524
20525       ipg=0
20526       pg=adjustl(pgname)
20527
20528       do i=1,41                ! was 39, now 41 to accomodate m3 and m3m
20529          if (pg(1:5) == point_group(i)) then
20530             ipg=i
20531             exit
20532          end if
20533       end do
20534
20535       !> return previous numbers for m3 and m3m
20536       if(ipg == 40)ipg=36      ! m3 now m-3
20537       if(ipg == 41)ipg=39      ! m3m now m-3m
20538
20539       return
20540    End Function Get_PointGroup_Num
20541
20542    !!--++
20543    !!--++ Logical Function Is_Axis(Ax) Result(Is_Axiss)
20544    !!--++    character(len=*), intent(in) :: Ax
20545    !!--++
20546    !!--++    (PRIVATE)
20547    !!--++    Detect the presence of a rotation axis
20548    !!--++
20549    !!--++ Update: February - 2005
20550    !!
20551    Function Is_Axis(Ax) Result(Is_Axiss)
20552       !---- Argument ----!
20553       character(len=*), intent(in) :: Ax
20554       logical                      :: Is_axiss
20555
20556       !---- Local Variables ----!
20557       character(len=*), dimension(6), parameter :: axis=(/"1","2","3","4","5","6"/)
20558       integer                                   :: i
20559
20560       Is_axiss=.false.
20561       do i=1,6
20562          if (Ax == axis(i))  then
20563             Is_axiss=.true.
20564             exit
20565          end if
20566       end do
20567
20568       return
20569    End Function Is_Axis
20570
20571    !!--++
20572    !!--++ Logical Function Is_Digit(A) Result(Is_Digitt)
20573    !!--++    character(len=*), intent(in) :: A    !  In ->
20574    !!--++
20575    !!--++    (PRIVATE)
20576    !!--++    Determine if A is a digit
20577    !!--++
20578    !!--++ Update: February - 2005
20579    !!
20580    Function Is_Digit(A) Result(Is_Digitt)
20581       !---- Argument ----!
20582       character(len=*), intent(in) :: A
20583       logical                      :: Is_digitt
20584       character(len=*), parameter  :: digit="0123456789"
20585
20586       Is_digitt=.false.
20587       if (index(digit,a) /= 0 ) Is_digitt=.true.
20588
20589       return
20590    End Function Is_Digit
20591
20592    !!--++
20593    !!--++ Logical Function Is_Hexa(Ng,Ss)
20594    !!--++    integer, intent (in)                  :: ng   !  In -> Number of Symmetry Operators
20595    !!--++    integer, dimension(:,:,:), intent(in) :: ss   !  In -> Rotation part of Symmetry Operators  (3,3,48)
20596    !!--++
20597    !!--++    (PRIVATE)
20598    !!--++    Calculate if the SpaceGroup is HEXAGONAL
20599    !!--++    Valid only for conventional bases
20600    !!--++
20601    !!--++  Update: February - 2005
20602    !!
20603    Function Is_Hexa(Ng,Ss) Result(Is_Hexag)
20604       !---- Argument ----!
20605       integer, intent (in)                   :: ng
20606       integer, dimension(:,:,:), intent(in)  :: ss   !(3,3,48)
20607       logical                                :: is_Hexag
20608
20609       !---- Local Variables ----!
20610       integer :: i
20611
20612       Is_Hexag=.false.
20613       do i=2,ng
20614          if (sum(abs(ss(:,1,i))) > 1) then
20615             Is_hexag=.true.
20616             exit
20617          end if
20618          if (sum(abs(ss(:,2,i))) > 1) then
20619             Is_hexag=.true.
20620             exit
20621          end if
20622       end do
20623
20624       return
20625    End Function Is_Hexa
20626
20627    !!----
20628    !!---- Logical Function Is_New_Op(Op,N,List_Op) Result(Is_New)
20629    !!----    type(Sym_Oper_type), intent(in)               :: op      !  In ->  Symmetry operator
20630    !!----    Integer,             intent(in)               :: n       !  In ->  Integer giving the number of Op i the list
20631    !!----    type(Sym_Oper_type), intent(in), dimension(:) :: list_op !  In ->  List of n symmetry operators
20632    !!----
20633    !!----    Determine if a symmetry operator is or not in a given list
20634    !!----
20635    !!---- Update: February - 2005
20636    !!
20637    Function Is_New_Op(Op,N,List_Op) Result(Is_New)
20638       !---- Argument ----!
20639       type(Sym_Oper_type), intent(in)               :: op
20640       Integer,             intent(in)               :: n
20641       type(Sym_Oper_type), intent(in), dimension(:) :: list_op
20642       logical                                       :: is_new
20643
20644       !---- Local Variables ----!
20645       integer :: i
20646
20647       is_new=.true.
20648       do i=1,n
20649          if (op == list_op(i))  then
20650             is_new=.false.
20651             exit
20652          end if
20653       end do
20654
20655       return
20656    End Function Is_New_Op
20657
20658    !!--++
20659    !!--++  Logical Function Is_Plane(Ax) Result(Is_Planee)
20660    !!--++     character(len=*), intent(in) :: Ax
20661    !!--++
20662    !!--++     (PRIVATE)
20663    !!--++     Detect the presence of a mirror or glide plane
20664    !!--++
20665    !!--++  Update: February - 2005
20666    !!
20667    Function Is_Plane(Ax) Result(Is_Planee)
20668       !---- Argument ----!
20669       character(len=*), intent(in) :: Ax
20670       logical                      :: Is_Planee
20671
20672       !---- Local Variables ----!
20673       character(len=*), dimension(6), parameter :: plane=(/"A","B","C","D","M","N"/)
20674       integer                                   :: i
20675
20676       Is_planee=.false.
20677       do i=1,6
20678          if (Ax == plane(i))  then
20679             Is_planee=.true.
20680             exit
20681          end if
20682       end do
20683
20684       return
20685    End Function Is_Plane
20686
20687    !!--++
20688    !!--++ Logical Function Is_Xyz(A) Result(Iss_Xyz)
20689    !!--++    character(len=*), intent(in) :: A
20690    !!--++
20691    !!--++    (PRIVATE)
20692    !!--++    Determine if A is a character X, Y or Z
20693    !!--++
20694    !!--++ Update: February - 2005
20695    !!
20696    Function Is_Xyz(A) Result(Iss_Xyz)
20697       !---- Argument ----!
20698       character(len=*), intent(in) :: A
20699       logical                      :: Iss_xyz
20700
20701       Iss_xyz=.false.
20702       if (A == "x" .or. A == "X" .or.   &
20703           A == "y" .or. A == "Y" .or.   &
20704           A == "z" .or. A == "Z")  Iss_xyz=.true.
20705
20706       return
20707    End Function Is_Xyz
20708
20709    !!----
20710    !!---- Logical Function Lattice_Trans(V,Lat) Result(Lattice_Transl)
20711    !!----    real(kind=cp), dimension(3), intent( in) :: v              !  In -> Vector
20712    !!----    character(len=*),            intent( in) :: Lat            !  In -> Lattice Character
20713    !!----    logical                                  :: Lattice_Transl ! Out -> .True. or .False.
20714    !!----
20715    !!----    Determine whether a vector is a lattice vector
20716    !!----    depending on the Bravais lattice.
20717    !!----
20718    !!---- Update: February - 2005
20719    !!
20720    Function Lattice_Trans(V,Lat) Result(Lattice_Transl)
20721       !---- Argument ----!
20722       real(kind=cp), dimension(3), intent( in) :: v
20723       character(len=*),            intent( in) :: Lat
20724       logical                                  :: Lattice_Transl
20725
20726       !---- Local variables ----!
20727       real(kind=cp)   , dimension(3) :: vec
20728       integer                        :: i
20729
20730       Lattice_Transl=.false.
20731
20732       if (Zbelong(v)) then                      ! if v is an integral vector =>  v is a lattice vector
20733          Lattice_Transl=.true.
20734       else                                      ! if not look for lattice type
20735          select case (Lat)
20736             case("A","a")
20737                vec=Ltr_a(:,2)-v
20738                if (Zbelong(vec)) Lattice_Transl=.true.
20739             case("B","b")
20740                vec=Ltr_b(:,2)-v
20741                if (Zbelong(vec)) Lattice_Transl=.true.
20742             case("C","c")
20743                vec=Ltr_c(:,2)-v
20744                if (Zbelong(vec)) Lattice_Transl=.true.
20745             case("I","i")
20746                vec=Ltr_i(:,2)-v
20747                if (Zbelong(vec)) Lattice_Transl=.true.
20748             case("R","r")
20749                vec=Ltr_r(:,2)-v
20750                if (Zbelong(vec)) Lattice_Transl=.true.
20751                vec=Ltr_r(:,3)-v
20752                if (Zbelong(vec)) Lattice_Transl=.true.
20753             case("F","f")
20754                vec=Ltr_f(:,2)-v
20755                if (Zbelong(vec)) Lattice_Transl=.true.
20756                vec=Ltr_f(:,3)-v
20757                if (Zbelong(vec)) Lattice_Transl=.true.
20758                vec=Ltr_f(:,4)-v
20759                if (Zbelong(vec)) Lattice_Transl=.true.
20760             case("Z")
20761                do i=2,nlat
20762                  vec=Ltr(:,i)-v
20763                  if (Zbelong(vec)) then
20764                    Lattice_Transl=.true.
20765                    exit
20766                  end if
20767                end do
20768          end select
20769       end if
20770
20771       return
20772    End Function  Lattice_Trans
20773
20774    !!--++
20775    !!--++ Function Product_Symop(Syma,Symb) Result (Symab)
20776    !!--++    type(Sym_Oper_Type), intent (in) :: syma
20777    !!--++    type(Sym_Oper_Type), intent (in) :: symb
20778    !!--++    type(Sym_Oper_Type)              :: symab
20779    !!--++
20780    !!--++    (OVERLOADED)
20781    !!--++    Obtain the symmetry operation corresponding
20782    !!--++    to the product of two operators by using the * operator.
20783    !!--++    The calling program can use a statement like: symab=syma*symb
20784    !!--++
20785    !!--++  Update: February - 2005
20786    !!
20787    Function Product_Symop(Syma,Symb) Result (Symab)
20788       !---- Arguments ----!
20789       type(Sym_Oper_Type), intent (in) :: syma
20790       type(Sym_Oper_Type), intent (in) :: symb
20791       type(Sym_Oper_Type)              :: symab
20792
20793       symab%tr  = Syma%tr + matmul(real(Syma%Rot),Symb%tr)
20794       Symab%Rot = matmul(Syma%Rot,Symb%Rot)
20795
20796       return
20797    End Function Product_Symop
20798
20799    !!----
20800    !!---- Logical Function Spgr_Equal(Spacegroup1,Spacegroup2) Result(Ispgr_Equal)
20801    !!----    Type (Space_Group_Type),  intent(in) :: SpaceGroup1   ! In ->
20802    !!----    Type (Space_Group_Type),  intent(in) :: SpaceGroup2   ! In ->
20803    !!----
20804    !!----    Determine if two SpaceGroups are equal
20805    !!----
20806    !!---- Update: February - 2005
20807    !!
20808    Function Spgr_Equal(Spacegroup1, Spacegroup2) Result(Ispgr_Equal)
20809       !---- Arguments ----!
20810       type (Space_Group_Type),  intent(in) :: SpaceGroup1, SpaceGroup2
20811       logical                              :: iSpGr_Equal
20812
20813       !---- Trivial tests----!
20814       iSpGr_Equal=.false.
20815       if (SpaceGroup1%multip == 0 .or. SpaceGroup2%multip == 0) return
20816       if (SpaceGroup1%multip /= SpaceGroup2%multip) return
20817
20818       iSpGr_Equal=Equal_sets_text(SpaceGroup1%SymopSymb,SpaceGroup1%multip, &
20819                                   SpaceGroup2%SymopSymb,SpaceGroup2%multip)
20820
20821       return
20822    End Function Spgr_Equal
20823
20824    !!----
20825    !!---- Function Sym_Prod(Syma,Symb,Modlat) Result (Symab)
20826    !!----    type(Sym_Oper_Type), intent (in) :: syma
20827    !!----    type(Sym_Oper_Type), intent (in) :: symb
20828    !!----    logical,optional,    intent (in) :: modlat
20829    !!----    type(Sym_Oper_Type)              :: symab
20830    !!----
20831    !!----    Obtain the symmetry operation corresponding to the product of
20832    !!----    two operators.
20833    !!----    If modlat=.true. or it is not present, the traslation
20834    !!----    part of the resulting operator is reduced to have components <1.0
20835    !!----
20836    !!---- Update: February - 2005
20837    !!
20838    Function Sym_Prod(Syma,Symb,Modlat) Result (Symab)
20839       !---- Arguments ----!
20840       type(Sym_Oper_Type), intent (in) :: syma
20841       type(Sym_Oper_Type), intent (in) :: symb
20842       logical,optional,    intent (in) :: modlat
20843       type(Sym_Oper_Type)              :: symab
20844
20845       if (present(modlat)) then
20846          if (.not. modlat) then
20847             symab%tr = Syma%tr + matmul(real(Syma%Rot),Symb%tr)
20848          else
20849             symab%tr = modulo_lat(Syma%tr + matmul(real(Syma%Rot),Symb%tr))
20850          end if
20851       else
20852          symab%tr = modulo_lat(Syma%tr + matmul(real(Syma%Rot),Symb%tr))
20853       end if
20854       Symab%Rot = matmul(Syma%Rot,Symb%Rot)
20855
20856       return
20857    End Function Sym_Prod
20858
20859    !!---- Subroutine Allocate_Lattice_Centring(Latt,n,tinv)
20860    !!----   Type(Lattice_Centring_Type), intent(out)  :: Latt
20861    !!----   integer,                     intent(in)   :: n
20862    !!----   logical,  optional,          intent(in)   :: tinv
20863    !!----
20864    !!----  Allocates a Lattice_Centring_Type object. If tinv is present and tinv=.true.
20865    !!----  four indices are selected for the first dimension for storing the presence or
20866    !!----  absence of time inversion once the object is constructed.
20867    !!----
20868    !!----  Updated: October 2014
20869    !!----
20870    !!
20871    Subroutine Allocate_Lattice_Centring(Latt,n,tinv)
20872      Type(Lattice_Centring_Type), intent(out)  :: Latt
20873      integer,                     intent(in)   :: n
20874      logical,  optional,          intent(in)   :: tinv
20875      !--- Local variables ---!
20876      if(present(tinv)) then
20877        if(tinv) then
20878           allocate(Latt%Ltr(4,n))
20879        else
20880           allocate(Latt%Ltr(3,n))
20881        end if
20882      else
20883        allocate(Latt%Ltr(3,n))
20884      end if
20885      Latt%Ltr=0.0
20886      Latt%N_lat=n
20887      Latt%set=.false.
20888      return
20889    End Subroutine Allocate_Lattice_Centring
20890
20891    !!---- Subroutine Check_Generator(gen,ok,symbol)
20892    !!----   Character(len=*),         intent(in)  :: gen
20893    !!----   logical,                  intent(out) :: ok
20894    !!----   character(len=*),optional,intent(out) :: symbol
20895    !!----
20896    !!----  Check that the string containing a generator, contains a legal symmetry operator
20897    !!----  Only integer coefficients and determinant of the rotational part equal to +1 or -1
20898    !!----  are allowed. In the optional argument "symbol" the nature of the operator is provided.
20899    !!----
20900    !!----  Updated: January 2014
20901    !!----
20902    !!
20903    Subroutine Check_Generator(gen,ok,symbol)
20904      Character(len=*),         intent(in)  :: gen
20905      logical,                  intent(out) :: ok
20906      character(len=*),optional,intent(out) :: symbol
20907      !--- Local variables ---!
20908      integer :: i,j,k,n,itr,idet
20909      character(len=len(gen)), dimension(3) :: split
20910      character(len=len(gen))  :: symb
20911      character(len=*), dimension(3), parameter :: code=(/"x","y","z"/)
20912      real(kind=cp)  :: det
20913      real(kind=cp), dimension(3,3) :: Mat,iMat
20914      logical :: esta
20915
20916      call Init_Err_Symm()
20917      ok=.false.
20918      i=index(gen,",")
20919      j=index(gen,",",back=.true.)
20920      split(1)= l_case(pack_string(gen(1:i-1)))
20921      split(2)= l_case(pack_string(gen(i+1:j-1)))
20922      split(3)= l_case(pack_string(gen(j+1:)))
20923      !Remove the translation part if it exists
20924      !write(*,"(4a)") " => Initial split: ", (trim(split(i))//"   ",i=1,3)
20925      do i=1,3
20926        n=len_trim(split(i))
20927        j=index(split(i),"+",back=.true.)
20928        if(j /= 0) then
20929          symb=split(i)(j+1:)
20930          esta=.false.
20931          do k=1,len_trim(symb)
20932            if(symb(k:k) == code(1) .or. symb(k:k) == code(2) .or. symb(k:k) == code(3) ) then
20933               esta = .true.  !A translation is not provided after the matrix
20934               exit
20935            end if
20936          end do
20937          if(.not. esta) then ! a translation is given in that part of the string, so remove it!
20938             split(i)=split(i)(1:j-1)
20939          else ! we have to check starting from the left of the string
20940             j=index(split(i),"+") !look for the first appearance of "+"
20941             !Check if there are x,y,z on the left of "+"
20942             if(j > 1) then
20943                symb=split(i)(1:j-1)
20944                esta=.false.
20945                do k=1,len_trim(symb)
20946                  if(symb(k:k) == code(1) .or. symb(k:k) == code(2) .or. symb(k:k) == code(3) ) then
20947                     esta = .true.  !A translation is not provided before the matrix
20948                     exit
20949                  end if
20950                end do
20951                if(.not. esta) then   !A translation exists
20952                  split(i)=split(i)(j+1:)
20953                end if
20954             end if
20955          end if
20956        end if
20957        if(len_trim(split(i)) == n) then !Check now if instead of "+" the translation is given with "-" sign
20958          j=index(split(i),"-",back=.true.)
20959          if(j /= 0) then
20960            symb=split(i)(j+1:)
20961            esta=.false.
20962            do k=1,len_trim(symb)
20963              if(symb(k:k) == code(1) .or. symb(k:k) == code(2) .or. symb(k:k) == code(3) ) then
20964                 esta = .true.  !A translation is not provided after the matrix
20965                 exit
20966              end if
20967            end do
20968            if(.not. esta) then ! a translation is given in that part of the string, so remove it!
20969               split(i)=split(i)(1:j-1)
20970            else ! we have to check "-" starting from the left of the string
20971               j=index(split(i),"-") !look for the first appearance of "+"
20972               !Check if there are x,y,z on the left of "-"
20973               if(j > 1) then
20974                  symb=split(i)(1:j-1)
20975                  esta=.false.
20976                  do k=1,len_trim(symb)
20977                    if(symb(k:k) == code(1) .or. symb(k:k) == code(2) .or. symb(k:k) == code(3) ) then
20978                       esta = .true.  !A translation is not provided before the matrix
20979                       exit
20980                    end if
20981                  end do
20982                  if(.not. esta) then   !A translation exists
20983                    split(i)=split(i)(j+1:)
20984                  end if
20985               end if
20986            end if
20987          end if
20988        end if
20989      end do
20990      !write(*,"(4a)") " => Final split: ", (trim(split(i))//"   ",i=1,3)
20991      do i=1,3
20992       call Get_Num_String(trim(split(i)), Mat(i,:),code)
20993      end do
20994      !Now determine if the matrix has integer components
20995      iMat=real(nint(Mat))
20996      !now calculate the determinant ... it should be equal to +/-1!
20997      det=determ_A(Mat)
20998      idet=nint(det)
20999      det=abs(det)
21000      if(present(symbol)) then
21001        itr=nint(trace(Mat))
21002        n=0
21003        select case (itr)
21004           case (-3)
21005              if (idet == -1) symbol="-1"
21006           case (-2)
21007              if (idet == -1) symbol="-6"
21008           case (-1)
21009              if (idet == -1) symbol="-4"
21010              if (idet ==  1) symbol="2 or 21"
21011           case ( 0)
21012              if (idet == -1) symbol="-3"
21013              if (idet ==  1) symbol="3 or 31/32"
21014           case ( 1)
21015              if (idet == -1) symbol="m or g"
21016              if (idet ==  1) symbol="4 or 41,42..."
21017           case ( 2)
21018              if (idet ==  1) symbol="6 or 61,62,..."
21019           case ( 3)
21020              if (idet ==  1) symbol="1"
21021           case default
21022              n=0
21023        end select
21024        symbol=trim(symbol)//"  [undet. loc.]"
21025      end if
21026      iMat=iMat-Mat
21027      if(sum(abs(iMat)) > eps_symm) then
21028        err_symm=.true.
21029        err_symm_mess="The matrix corresponding to a generator has non-integer values!"
21030        return
21031      else
21032        if(abs(det-1.0) > eps_symm) then
21033          err_symm=.true.
21034          err_symm_mess="The matrix corresponding to a generator has a determinant with absolute value different of 1.0"
21035          return
21036        end if
21037      end if
21038      ok=.true.  !arriving here the generator is ok!
21039      return
21040    End Subroutine Check_Generator
21041
21042    !---- Subroutines ----!
21043
21044    !!--++
21045    !!--++ Subroutine Check_Symbol_Hm(Hms)
21046    !!--++    character (len=1), dimension(3,4), intent( in):: HMS   ! In -> Hermann-Mauguin Symbol
21047    !!--++
21048    !!--++    (PRIVATE)
21049    !!--++    Subroutine used by Get_SO_from_HMS.
21050    !!--++    Check the correctness of the Herman-Mauguin Symbol (not all!!!).
21051    !!--++    Logical "hexa" must be defined and control error is present.
21052    !!--++
21053    !!--++
21054    !!--++ Update: February - 2005
21055    !!
21056    Subroutine Check_Symbol_Hm(Hms)
21057       !---- Argument ----!
21058       character (len=1), dimension(3,4), intent( in):: HMS
21059
21060       !---- Local Variables ----!
21061       logical          :: is_there,axis,plane
21062       character(len=1) :: Item_SP
21063       character(len=*), dimension(16), parameter ::                    &
21064                         good=(/"1","2","3","4","5","6","A","B","C","D","M","N","P","/","-"," "/)
21065       integer          :: ncount,five,i,j,l
21066
21067       !---- Check for missprinted symbols ----!
21068       call init_err_symm()
21069       do i=1,3
21070          do j=1,4
21071             is_there=.false.
21072             five=0
21073             if (HMS(i,j) == "5") five=j
21074             do L=1,16
21075                if (HMS(i,j) == good(L)) is_there=.true.
21076             end do
21077             if (.not. is_there) then
21078                err_symm=.true.
21079                ERR_Symm_Mess=" The symbol: "//HMS(i,j)//" is not allowed"
21080                return
21081             else if (five == 1) then
21082                err_symm=.true.
21083                ERR_Symm_Mess=" The fivefold axis is not allowed"
21084                return
21085             end if
21086          end do
21087       end do
21088
21089       !---- Check for repetitions and axes followed by planes (and viceversa) ----!
21090       do i=1,3
21091          do j=1,3
21092             Item_SP=HMS(i,j)
21093             if (Item_SP == " ") cycle
21094             is_there=.false.
21095             axis=Is_axis(Item_SP)
21096             plane=Is_plane(Item_SP)
21097             do L=j+1,4
21098                if (HMS(i,L) == Item_SP)  is_there=.true.
21099             end do
21100             if (is_there) then
21101                err_symm=.true.
21102                ERR_Symm_Mess=" The symbol: "//HMS(i,j)// &
21103                              " has been repeated within the same symmetry direction"
21104                return
21105             end if
21106             if (axis .and. Is_plane(HMS(i,j+1))) then
21107                err_symm=.true.
21108                ERR_Symm_Mess=" A rotation axis cannot be immediately followed by a plane"//char(13)//&
21109                              " within the same symmetry direction"
21110                return
21111             end if
21112             if (plane .and. Is_axis(HMS(i,j+1))) then
21113                err_symm=.true.
21114                ERR_Symm_Mess=" A mirror plane cannot be immediately followed by a rotation axis"//char(13)//&
21115                              " within the same symmetry direction"
21116                return
21117             end if
21118          end do
21119       end do
21120
21121       !---- Check for two planes in the same symmetry direction ----!
21122       do i=1,3
21123          ncount=0
21124          do j=1,4
21125             Item_SP=HMS(i,j)
21126             do L=7,12
21127                if (good(L) == Item_SP) ncount=ncount+1
21128             end do
21129          end do
21130          if (ncount > 1) then
21131             err_symm=.true.
21132             ERR_Symm_Mess=" There is more than one plane within the same symmetry direction"
21133             return
21134          end if
21135       end do
21136
21137       !---- Check for ILLEGAL screw axes ----!
21138       do i=1,3
21139          ncount=0
21140          do j=1,4
21141             Item_SP=HMS(i,j)
21142             if (Item_SP == " ") cycle
21143             do L=1,6
21144                if (good(L) == Item_SP) ncount=ncount+1
21145             end do
21146          end do
21147          if (ncount > 1) then  !there is more than one axis-symbol -> Screw
21148          !   if (iachar(HMS(i,1)) < iachar(HMS(i,2))) then
21149             if (HMS(i,1) <  HMS(i,2) ) then
21150                err_symm=.true.
21151                ERR_Symm_Mess=" Screw axis: "//HMS(i,1)//" "//HMS(i,2)//" not allowed"
21152                return
21153             end if
21154          end if
21155       end do
21156
21157       return
21158    End Subroutine Check_Symbol_HM
21159
21160    !!----
21161    !!---- Subroutine Decodmatmag(Sim,Xyzstring)
21162    !!----    integer, dimension(3,3), intent(in)  :: sim          !  In -> Rotation matrix
21163    !!----    character (len=*),       intent(out) :: XYZstring    ! Out -> String (Mx,My,Mz)
21164    !!----
21165    !!----    Supplies a string of the form (Mx,My,Mz) for the rotation matrix Sim.
21166    !!----    Logical "hexa" must be defined.
21167    !!----
21168    !!---- Update: February - 2005
21169    !!
21170    Subroutine Decodmatmag(Sim,Xyzstring)
21171       !---- Arguments ----!
21172       integer,dimension (3,3), intent( in) :: sim
21173       character (len=*),       intent(out) :: XYZstring
21174
21175       !---- Local variables ----!
21176       integer :: Iu,j,ihex
21177
21178       call SearchOp(sim,1,36,Iu)
21179
21180       if (.not. hexa) then
21181          j=abs(Iu)
21182          if (Iu < 0) j=j+24
21183          XYZstring= MAGmat(j)
21184       else
21185          j=abs(Iu)-24
21186          ihex=2
21187          if ( j < 0 ) then
21188             j=j+24
21189             ihex=1
21190          end if
21191          if (Iu < 0) j=j+24/ihex
21192          XYZstring= MAGmat(j+(ihex-1)*48)
21193       end if
21194
21195       return
21196    End Subroutine DecodMatMag
21197
21198    !!----
21199    !!---- Subroutine Get_Centring_Vectors(L,Latc,LatSymb)
21200    !!----    integer,                        intent (in out) :: L       ! Number of centring vectors
21201    !!----    real(kind=cp), dimension(:,:),  intent (in out) :: latc    ! Centering vectors
21202    !!----    character(len=1),               intent (   out) :: LatSymb ! Lattice symbol
21203    !!----
21204    !!----    Subroutine to complete the centring vectors of a centered lattice and to provide a lattice symbol.
21205    !!----    It is useful when non-conventional lattices are used to obtain all lattice
21206    !!----    translations with components in the range [0.0 1.0). The (0,0,0) translation
21207    !!----    is removed in case it comes on input.
21208    !!----
21209    !!---- Update: February - 2005, January-2014 (JRC)
21210    !!
21211    Subroutine Get_Centring_Vectors(L,Latc,LatSymb)
21212       !---- Arguments ----!
21213       integer,                       intent (in out) :: L
21214       real(kind=cp), dimension(:,:), intent (in out) :: latc  !(3,n)
21215       character(len=*),              intent (out)    :: LatSymb
21216       !---- Local variables ----!
21217       logical                                  :: isnew
21218       real(kind=cp), dimension(3,size(latc,2)) :: latinv,newlat
21219       real(kind=cp), dimension(3)              :: v,v1,v2
21220       integer                                  :: i,j,k1,k2,n,lat_ini,lm
21221       real(kind=cp), parameter                 :: teps=3.0*eps_symm
21222
21223       LatSymb="P"
21224       if(L == 0) return
21225       newlat=latc
21226       !Purge the translations
21227       do i=1,L-1
21228         v=newlat(:,i)
21229         if(sum(v) < teps) cycle
21230         do j=i+1,L
21231            if(sum(abs(newlat(:,j)-v)) < teps) newlat(:,j)=0.0
21232         end do
21233       end do
21234       n=0
21235       do i=1,L
21236         if(sum(abs(newlat(:,i))) < teps) cycle
21237         n=n+1
21238         latc(:,n)=newlat(:,i)
21239       end do
21240       L=n  !normally n < L_initial
21241
21242       latinv=0.0
21243       where (abs(latc)> teps)
21244          latinv=1.0/latc
21245       end where
21246       do
21247          lat_ini=L
21248          do i=1,L    !Even for a single centring vector this loop is executed
21249            v1=latc(:,i)
21250            do j=i,L  !start on i to ensure that for a single centring vector the internal loops are executed
21251              v2=latc(:,j)
21252              do k1=0,maxval(nint(latinv(:,i)))
21253                do k2=0,maxval(nint(latinv(:,j)))
21254                  v=modulo_lat(k1*v1+k2*v2)
21255                  if(sum(abs(v)) < teps) cycle
21256                  if( any(v > 1.0-teps) ) cycle
21257                  isnew=.true.
21258                  do lm=1,L
21259                    if (sum(abs(v-latc(:,lm))) < teps) then
21260                       isnew=.false.
21261                       exit
21262                    end if
21263                  end do
21264                  if(isnew) then
21265                     L=L+1
21266                     latc(:,L)=v
21267                  end if
21268                end do
21269              end do
21270            end do
21271          end do
21272          If(L == Lat_ini) exit !No more vectors have been generated
21273       end do
21274
21275       !Recognize the type of Lattice
21276       Select Case(L)
21277
21278         Case(1) !Test I, A, B, C
21279            if(sum(abs(latc(:,1)-Ltr_i(:,2))) < teps) then
21280              LatSymb="I"
21281              return
21282            end if
21283            if(sum(abs(latc(:,1)-Ltr_a(:,2))) < teps) then
21284              LatSymb="A"
21285              return
21286            end if
21287            if(sum(abs(latc(:,1)-Ltr_b(:,2))) < teps) then
21288              LatSymb="B"
21289              return
21290            end if
21291            if(sum(abs(latc(:,1)-Ltr_c(:,2))) < teps) then
21292              LatSymb="C"
21293              return
21294            end if
21295
21296         Case(2)  !Test R
21297             isnew=.false.
21298             if(sum(abs(latc(:,1)-Ltr_r(:,2))) < teps .or. sum(abs(latc(:,1)-Ltr_r(:,3))) < teps) isnew=.true.
21299             if(isnew) then
21300               if(sum(abs(latc(:,2)-Ltr_r(:,2))) < teps .or. sum(abs(latc(:,2)-Ltr_r(:,3))) < teps) then
21301                 LatSymb="R"
21302                 return
21303               end if
21304             end if
21305
21306         Case(3)
21307             isnew=.false.
21308             do i=2,4
21309                if (  sum(abs(latc(:,1)-Ltr_f(:,i))) < teps  ) then
21310                   isnew=.true.
21311                   exit
21312                end if
21313             end do
21314             if(isnew) then
21315                isnew=.false.
21316                do i=2,4
21317                   if (  sum(abs(latc(:,2)-Ltr_f(:,i))) < teps  ) then
21318                      isnew=.true.
21319                      exit
21320                   end if
21321                end do
21322             end if
21323             if(isnew) then
21324                isnew=.false.
21325                do i=2,4
21326                   if (  sum(abs(latc(:,3)-Ltr_f(:,i))) < teps  ) then
21327                       LatSymb="F"
21328                       return
21329                   end if
21330                end do
21331             end if
21332
21333       End Select
21334       LatSymb="Z"
21335       return
21336    End Subroutine Get_Centring_Vectors
21337
21338    !!----
21339    !!---- Subroutine Get_Crystal_System(Ng, Ss / Gen, Isystm, Crys)
21340    !!----    integer,                      intent(in) :: Ng     !  In -> Number of Operators (not related by
21341    !!----                                                                inversion and lattice traslations)
21342    !!----    integer, dimension(:,:,:),    intent(in) :: Ss     !  In -> Rotation Part   (3,3,48)
21343    !!----    or
21344    !!----    character(len=*),dimension(:),intent(in) :: gen    !  In -> Jones Faithful form of symmetry operators
21345    !!----    integer,                      intent(out):: ISystm ! Out -> Number for Crystal System
21346    !!----                                                                 1: Triclinic       2: Monoclinic
21347    !!----                                                                 3: Orthorrombic    4: Tetragonal
21348    !!----                                                                 5: Trigonal        6: Hexagonal
21349    !!----                                                                 7: Cubic
21350    !!----    character(len=1),             intent(out):: Crys   ! Out -> Symbol of Crystal family
21351    !!----
21352    !!----    Obtain the number and string of the Crystal System from a set of operators
21353    !!----
21354    !!---- Update: February - 2005
21355    !!
21356
21357    !!--++
21358    !!--++ Subroutine Get_Crystal_System_R_OP(Ng, Ss, Isystm, Crys)
21359    !!--++    integer,                   intent(in) :: Ng       !  In -> Number of Operators (not related by
21360    !!--++                                                               inversion and lattice traslations)
21361    !!--++    integer, dimension(:,:,:), intent(in) :: Ss       !  In -> Rotation Part   (3,3,48)
21362    !!--++    integer,                   intent(out):: ISystm   ! Out -> Number for Crystal System
21363    !!--++                                                                1: Triclinic       2: Monoclinic
21364    !!--++                                                                3: Orthorrombic    4: Tetragonal
21365    !!--++                                                                5: Trigonal        6: Hexagonal
21366    !!--++                                                                7: Cubic
21367    !!--++    character(len=1),          intent(out):: Crys     ! Out -> Symbol of Crystal family
21368    !!--++
21369    !!--++    (OVERLOADED)
21370    !!--++    Obtain the number and string of the Crystal System from a set of operators
21371    !!--++
21372    !!--++ Update: February - 2005
21373    !!
21374    Subroutine Get_Crystal_System_R_OP(Ng,Ss, Isystm, Crys)
21375       !---- Arguments ----!
21376       integer,                   intent(in) :: Ng
21377       integer, dimension(:,:,:), intent(in) :: Ss    !(3,3,48)
21378       integer,                   intent(out):: ISystm
21379       character(len=1),          intent(out):: Crys
21380
21381       !---- Local variables ----!
21382       integer   :: i, ndet
21383       integer   :: nrot_1, nrot_2, nrot_3, nrot_4, nrot_6
21384       integer   :: nrot_1b, nrot_2b, nrot_3b, nrot_4b, nrot_6b
21385
21386       nrot_1  = 0
21387       nrot_2  = 0
21388       nrot_3  = 0
21389       nrot_4  = 0
21390       nrot_6  = 0
21391       nrot_1b = 0
21392       nrot_2b = 0
21393       nrot_3b = 0
21394       nrot_4b = 0
21395       nrot_6b = 0
21396
21397       do i=1,ng
21398          ndet= Axes_Rotation(ss(:,:,i))
21399          select case (ndet)
21400              case (-6)
21401                 nrot_6b=nrot_6b +1
21402              case (-4)
21403                 nrot_4b=nrot_4b +1
21404              case (-3)
21405                 nrot_3b=nrot_3b +1
21406              case (-2)
21407                 nrot_2b=nrot_2b +1
21408              case (-1)
21409                 nrot_1b=nrot_1b +1
21410              case ( 1)
21411                 nrot_1 =nrot_1  +1
21412              case ( 2)
21413                 nrot_2 =nrot_2  +1
21414              case ( 3)
21415                 nrot_3 =nrot_3  +1
21416              case ( 4)
21417                 nrot_4 =nrot_4  +1
21418              case ( 6)
21419                 nrot_6 =nrot_6  +1
21420              case default
21421                 err_symm=.true.
21422                 ERR_Symm_Mess= " Axes rotation wrong"
21423                 return
21424          end select
21425       end do
21426
21427       !---- Cubic ----!
21428       if ( (nrot_3 + nrot_3b == 8) ) then
21429          isystm = 7
21430          crys="c"
21431
21432       !---- Hexagonal ----!
21433       else if ( (nrot_6 + nrot_6b == 2) ) then
21434          isystm = 6
21435          crys="h"
21436
21437       !---- Trigonal ----!
21438       else if ( (nrot_3 + nrot_3b == 2) ) then
21439          isystm = 5
21440          crys="h"
21441
21442       !---- Tetragonal ----!
21443       else if ( (nrot_4 + nrot_4b == 2) ) then
21444          isystm = 4
21445          crys="t"
21446
21447       !---- Orthorhombic ----!
21448       else if ( (nrot_2 + nrot_2b == 3) ) then
21449          isystm = 3
21450          crys="o"
21451
21452       !---- Monoclinic  ----!
21453       else if ( (nrot_2 + nrot_2b == 1) ) then
21454          isystm = 2
21455          crys="m"
21456
21457       !---- Triclinic  ----!
21458       else
21459          isystm = 1
21460          crys="a"
21461
21462       end if
21463
21464       return
21465    End Subroutine Get_Crystal_System_R_OP
21466
21467    !!--++
21468    !!--++ Subroutine Get_Crystal_System_R_ST(Ng,Gen,Isystm, Crys)
21469    !!--++    integer,                      intent(in) :: Ng     !  In -> Number of Operators
21470    !!--++    character(len=*),dimension(:),intent(in) :: gen    !  In -> Jones Faithful form of symmetry operators
21471    !!--++    integer,                      intent(out):: ISystm ! Out -> Number for Crystal System
21472    !!--++                                                                1: Triclinic       2: Monoclinic
21473    !!--++                                                                3: Orthorrombic    4: Tetragonal
21474    !!--++                                                                5: Trigonal        6: Hexagonal
21475    !!--++                                                                7: Cubic
21476    !!--++    character(len=1),             intent(out):: Crys   ! Out -> Symbol of Crystal family
21477    !!--++
21478    !!--++    (OVERLOADED)
21479    !!--++    Obtain the number and string of the Crystal System from a set of operators
21480    !!--++
21481    !!--++ Update: February - 2005
21482    !!
21483    Subroutine Get_Crystal_System_R_ST(Ng,gen, Isystm, Crys)
21484       !---- Arguments ----!
21485       integer,                        intent(in) :: Ng
21486       character(len=*), dimension(:), intent(in) :: Gen
21487       integer,                        intent(out):: ISystm
21488       character(len=1),               intent(out):: Crys
21489
21490       !---- Local variables ----!
21491       integer, dimension(3,3,Ng) :: Ss    !(3,3,48)
21492       integer                    :: i
21493
21494       do i=1,Ng
21495          call Read_Xsym(gen(i),1,Ss(:,:,i))
21496       end do
21497       call Get_Crystal_System_R_OP(Ng,Ss, Isystm, Crys)
21498
21499       return
21500    End Subroutine Get_Crystal_System_R_ST
21501
21502    !!----
21503    !!---- Subroutine Get_GenSymb_from_Gener(gen,ngen, SpaceH)
21504    !!----    character(len=*),dimension(:),  intent(in) :: gen     !  In -> list of generators is string mode
21505    !!----    integer,                        intent(in) :: ngen    !  In -> number of generators provided
21506    !!----    character(len=*),              intent(out) :: SpaceH  ! Out -> Generalised Hall Symbol
21507    !!----
21508    !!----    Determines a generalised Hall symbol for a space group formed by the symmetry symbols of
21509    !!----    the provided generators.
21510    !!----
21511    !!---- Updated: January - 2014 (JRC)
21512    !!
21513    Subroutine Get_GenSymb_from_Gener(gen,ngen,SpaceH)
21514       !---- Arguments ----!
21515       character(len=*),dimension(:),  intent(in) :: gen
21516       integer,                        intent(in) :: ngen
21517       character(len=*),              intent(out) :: SpaceH
21518
21519       !----Local variables ----!
21520       character(len= 1)          :: LatSymb
21521       character(len=20)          :: centr
21522       character(len=40)          :: gen_symb
21523       integer                    :: ng, ini, i, orden,L,j
21524       integer, dimension(3,3,24) :: ss
21525       integer, dimension(3,3)    :: nulo,unitm
21526
21527       real(kind=cp), dimension(3,24)  :: ts
21528       real(kind=cp), dimension(3,192) :: latc
21529       real(kind=cp), dimension(3)     :: ts_centre
21530       logical                         :: centred
21531
21532       !---- Initial Values ----!
21533       nulo=0
21534       unitm=0
21535       unitm(1,1)=1;  unitm(2,2)=1;  unitm(3,3)=1
21536       latc=0.0
21537       centred=.false.
21538       centr=" "
21539       SpaceH=" "
21540
21541       ! --- Test if lattice translations are provide with a symbol in the first generator
21542       if(index(gen(1),"-I") /= 0) then       !Centric with -1 at 000
21543         SpaceH="-I"
21544       else if(index(gen(1),"-A") /= 0) then
21545         SpaceH="-A"
21546       else if(index(gen(1),"-B") /= 0) then
21547         SpaceH="-B"
21548       else if(index(gen(1),"-C") /= 0) then
21549         SpaceH="-C"
21550       else if(index(gen(1),"-R") /= 0) then
21551         SpaceH="-R"
21552       else if(index(gen(1),"-F") /= 0) then
21553         SpaceH="-F"
21554       else if(index(gen(1),"-Z") /= 0) then
21555         SpaceH="-Z"
21556       else if(index(gen(1),"-P") /= 0) then
21557         SpaceH="-P"
21558       end if
21559       if(len_trim(SpaceH) == 0) then           !centric with -1 out of 000 or acentric
21560           if(index(gen(1),"I") /= 0) then
21561             SpaceH="I"
21562           else if(index(gen(1),"A") /= 0) then
21563             SpaceH="A"
21564           else if(index(gen(1),"B") /= 0) then
21565             SpaceH="B"
21566           else if(index(gen(1),"C") /= 0) then
21567             SpaceH="C"
21568           else if(index(gen(1),"R") /= 0) then
21569             SpaceH="R"
21570           else if(index(gen(1),"F") /= 0) then
21571             SpaceH="F"
21572           else if(index(gen(1),"P") /= 0) then
21573             SpaceH="P"
21574           else if(index(gen(1),"Z") /= 0) then
21575             SpaceH="Z"
21576           end if
21577       end if
21578       LatSymb="P"
21579       if(len_trim(SpaceH) == 0) then
21580         ini=1  !If there is a centring lattice it must be given in the list of the generators
21581       else
21582         ini=2
21583         if(len_trim(SpaceH)==1) LatSymb=trim(SpaceH)
21584       end if
21585       ng=0
21586       do i=ini,ngen
21587         ng=ng+1
21588         call Read_Xsym(gen(i),1,ss(:,:,ng),ts(:,ng))
21589       end do
21590       !Look for lattice translations as generators
21591       if(ini == 1) then
21592         L=0
21593         do i=1,ng
21594           if(equal_matrix(ss(:,:,i),unitm,3)) then
21595             L=L+1
21596             latc(:,L)=ts(:,i)
21597             ss(:,:,i)=0
21598           end if
21599         end do
21600         if(L > 0) then !There are lattice translations
21601           call Get_Centring_Vectors(L,latc,LatSymb)
21602         end if
21603       end if
21604       !Look for centre of symmetry as generator
21605       do i=1,ng
21606         if(equal_matrix(ss(:,:,i),-unitm,3)) then !Centre of symmetry
21607           ts_centre=ts(:,i)
21608           ss(:,:,i)=0
21609           centred=.true.
21610           exit
21611         end if
21612       end do
21613       if(centred) then
21614         if(sum(abs(ts_centre)) < eps_symm) then
21615             SpaceH="-"//LatSymb
21616          else
21617            ts_centre=0.5*ts_centre
21618            call Frac_Trans_2Dig(ts_centre,centr)
21619            centr="-1"//trim(centr)
21620          end if
21621       else
21622         if(ini ==1) SpaceH=LatSymb
21623       end if
21624       !Construct the symbol
21625       do i=1,ng
21626          if(equal_matrix(ss(:,:,i), nulo,3)) cycle
21627          call symmetry_symbol(ss(:,:,i),ts(:,i),gen_symb)
21628
21629          if(len_trim(gen_symb) == 0) then
21630            orden=axes_rotation(ss(:,:,i))
21631            write(unit=gen_symb,fmt="(i2)") orden
21632            gen_symb=adjustl(gen_symb)//"[]"
21633          else
21634            j=index(gen_symb,")")
21635            if( j /= 0) then
21636               gen_symb=gen_symb(1:j)
21637               j=index(gen_symb,"+")
21638               gen_symb(j:j)=" "
21639               gen_symb=pack_string(gen_symb)
21640            else
21641               j=index(gen_symb," ")
21642               gen_symb=gen_symb(1:j)
21643               j=index(gen_symb,"+")
21644               gen_symb=gen_symb(1:j-1)
21645            end if
21646          end if
21647          SpaceH=trim(SpaceH)//" "//trim(gen_symb)
21648       end do
21649       SpaceH=trim(SpaceH)//" "//trim(centr)
21650       return
21651    End Subroutine Get_GenSymb_from_Gener
21652
21653    !!----
21654    !!---- Subroutine Get_HallSymb_From_Gener(Spacegroup, Spaceh)
21655    !!----    type(Space_Group_Type),   intent(in out) :: SpaceGroup   !  In -> SpaceGroup type variable
21656    !!----                                                               Out -> SpaceGroup type variable
21657    !!----    character(len=*), intent(out), optional  :: SpaceH       ! Out -> Hall Symbol
21658    !!----
21659    !!----    Determines the Hall symbol. In general this routine try to obtain
21660    !!----    the Hall symbol from generators so you need call Get_So_from_Gener
21661    !!----    before and call Set_Spgr_Info.It doesn't work for arbitrary settings.
21662    !!----    If one wants to use arbitrary settings the subroutine Get_GenSymb_from_Gener
21663    !!----
21664    !!---- Update: February - 2005
21665    !!
21666    Subroutine Get_HallSymb_from_Gener(SpaceGroup,SpaceH)
21667       !---- Arguments ----!
21668       type(Space_Group_Type), intent(in out)        :: SpaceGroup
21669       character(len=*),       intent(out), optional :: SpaceH
21670
21671       !----Local variables ----!
21672       character(len= 1)        :: axes,axes2
21673       character(len= 3)        :: tras
21674       character(len=20)        :: Hall
21675       character(len=*), dimension(13), parameter :: traslacion =&
21676                           (/"N","A","B","C","D","U","V","W","1","2","3","4","5"/)
21677
21678       integer                    :: ng,ngen, ini, i, j, k, orden, nt, npos
21679       integer, dimension(3)      :: tt, tt1, tt2, tt3
21680       integer, dimension(6)      :: norden
21681       integer, dimension(3,3,24) :: ss
21682       integer, dimension(3,3)    :: ss1
21683       integer, dimension(3,6), parameter :: lattice=reshape((/0,6,6, 6,0,6, &
21684                                                     6,6,0, 6,6,6, 8,4,4, 4,8,8/),(/3,6/))
21685       integer, dimension(3,13), parameter :: tras_val=reshape((/6,6,6, 6,0,0, &
21686                                       0,6,0, 0,0,6, 3,3,3, 3,0,0, 0,3,0, 0,0,3, &
21687                                       1,0,0, 2,0,0, 3,0,0, 4,0,0, 5,0,0/),(/3,13/))
21688       integer, dimension(3,3), parameter  :: x_1   = reshape( &
21689                                 (/ 1, 0, 0,  0, 1, 0,  0, 0, 1/),(/3,3/))
21690       integer, dimension(3,3), parameter  :: z_1   = reshape( &
21691                                 (/ 1, 0, 0,  0, 1, 0,  0, 0, 1/),(/3,3/))
21692       integer, dimension(3,3), parameter  :: x_2   = reshape( &
21693                                 (/ 1, 0, 0,  0,-1, 0,  0, 0,-1/),(/3,3/))
21694       integer, dimension(3,3), parameter  :: y_2   = reshape( &
21695                                 (/-1, 0, 0,  0, 1, 0,  0, 0,-1/),(/3,3/))
21696       integer, dimension(3,3), parameter  :: z_2   = reshape( &
21697                                 (/-1, 0, 0,  0,-1, 0,  0, 0, 1/),(/3,3/))
21698       integer, dimension(3,3), parameter  :: x_3   = reshape( &
21699                                 (/ 1, 0, 0,  0, 0, 1,  0,-1,-1/),(/3,3/))
21700       integer, dimension(3,3), parameter  :: y_3   = reshape( &
21701                                 (/-1, 0,-1,  0, 1, 0,  1, 0, 0/),(/3,3/))
21702       integer, dimension(3,3), parameter  :: z_3   = reshape( &
21703                                 (/ 0, 1, 0, -1,-1, 0,  0, 0, 1/),(/3,3/))
21704       integer, dimension(3,3), parameter  :: x_4   = reshape( &
21705                                 (/ 1, 0, 0,  0, 0, 1,  0,-1, 0/),(/3,3/))
21706       integer, dimension(3,3), parameter  :: y_4   = reshape( &
21707                                 (/ 0, 0,-1,  0, 1, 0,  1, 0, 0/),(/3,3/))
21708       integer, dimension(3,3), parameter  :: z_4   = reshape( &
21709                                 (/ 0, 1, 0, -1, 0, 0,  0, 0, 1/),(/3,3/))
21710       integer, dimension(3,3), parameter  :: x_6   = reshape( &
21711                                 (/ 1, 0, 0,  0, 1, 1,  0,-1, 0/),(/3,3/))
21712       integer, dimension(3,3), parameter  :: y_6   = reshape( &
21713                                 (/ 0, 0,-1,  0, 1, 0,  1, 0, 1/),(/3,3/))
21714       integer, dimension(3,3), parameter  :: z_6   = reshape( &
21715                                 (/ 1, 1, 0, -1, 0, 0,  0, 0, 1/),(/3,3/))
21716       integer, dimension(3,3), parameter  :: x_2p  = reshape( &
21717                                 (/-1, 0, 0,  0, 0,-1,  0,-1, 0/),(/3,3/))
21718       integer, dimension(3,3), parameter  :: y_2p  = reshape( &
21719                                 (/ 0, 0,-1,  0,-1, 0, -1, 0, 0/),(/3,3/))
21720       integer, dimension(3,3), parameter  :: z_2p  = reshape( &
21721                                 (/ 0,-1, 0, -1, 0, 0,  0, 0,-1/),(/3,3/))
21722       integer, dimension(3,3), parameter  :: x_2pp = reshape( &
21723                                 (/-1, 0, 0,  0, 0, 1,  0, 1, 0/),(/3,3/))
21724       integer, dimension(3,3), parameter  :: y_2pp = reshape( &
21725                                 (/ 0, 0, 1,  0,-1, 0,  1, 0, 0/),(/3,3/))
21726       integer, dimension(3,3), parameter  :: z_2pp = reshape( &
21727                                 (/ 0, 1, 0,  1, 0, 0,  0, 0,-1/),(/3,3/))
21728       integer, dimension(3,3), parameter  :: xyz_3 = reshape( &
21729                                 (/ 0, 1, 0,  0, 0, 1,  1, 0, 0/),(/3,3/))
21730       integer, dimension(4,4), parameter :: nulo      = reshape((/0, 0, 0, 0, &
21731                                                                   0, 0, 0, 0, &
21732                                                                   0, 0, 0, 0, &
21733                                                                   0, 0, 0, 0/),(/4,4/))
21734
21735       real(kind=cp), dimension(3,24)          :: ts
21736       real(kind=cp), dimension(3)             :: ts1
21737       type (Gener_Oper_Type),dimension(5) :: generador
21738
21739       !---- Initial Values ----!
21740       Hall          = " "
21741       ngen          = 0
21742       generador = gener_oper_type(0," "," "," ")
21743
21744       !---- Load Operators ----!
21745       ng=SpaceGroup%NumOps
21746       do i=1,ng
21747          ss(:,:,i) = SpaceGroup%Symop(i)%rot
21748          ts(:,  i) = SpaceGroup%Symop(i)%tr
21749       end do
21750
21751       !---- Tipo de Red ----!
21752       select case (SpaceGroup%centred)
21753          case (0,1)
21754             hall(1:1)=SpaceGroup%SPG_lat
21755          case (2)
21756             hall(1:2)="-"//SpaceGroup%SPG_lat
21757       end select
21758
21759       !---- Origen del Centro de inversion ----!
21760       if (SpaceGroup%centred == 0) then
21761          ngen=ngen+1
21762          ini=1
21763          tras=" "
21764          tt=nint(12.0*2.0*SpaceGroup%centre_coord)
21765
21766          select case (SpaceGroup%Bravais)
21767             case ("A")
21768                tt1=mod(tt-lattice(:,1)+48,12)
21769                if (sum(tt1) < sum(tt) ) tt=tt1
21770
21771             case ("B")
21772                tt1=mod(tt-lattice(:,2)+48,12)
21773                if (sum(tt1) < sum(tt) ) tt=tt1
21774
21775             case ("C")
21776                tt1=mod(tt-lattice(:,3)+48,12)
21777                if (sum(tt1) < sum(tt) ) tt=tt1
21778
21779             case ("I")
21780                tt1=mod(tt-lattice(:,4)+48,12)
21781                if (sum(tt1) < sum(tt) ) tt=tt1
21782
21783             case ("R")
21784                tt1=mod(tt-lattice(:,5)+48,12)
21785                tt2=mod(tt-lattice(:,6)+48,12)
21786                if (sum(tt1) < sum(tt) ) tt=tt1
21787                if (sum(tt2) < sum(tt) ) tt=tt2
21788
21789             case ("F")
21790                tt1=mod(tt-lattice(:,3)+48,12)
21791                tt2=mod(tt-lattice(:,2)+48,12)
21792                tt3=mod(tt-lattice(:,1)+48,12)
21793                if (sum(tt1) < sum(tt) ) tt=tt1
21794                if (sum(tt2) < sum(tt) ) tt=tt2
21795                if (sum(tt3) < sum(tt) ) tt=tt3
21796
21797          end select
21798
21799          do k=1,3     ! 3 pasadas
21800             if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) exit
21801             do j=1,8
21802                tt1=tt-tras_val(:,j)
21803                if ( all(tt1 >= 0) ) then
21804                   tras(ini:ini)=l_case(traslacion(j))
21805                   tt=tt1
21806                   ini=ini+1
21807                   exit
21808                end if
21809             end do
21810          end do
21811
21812          generador(ngen)%orden= -1
21813          generador(ngen)%axes = "z"
21814          generador(ngen)%tras=tras
21815       end if
21816
21817       !---- Suppress non needed contributions ----!
21818       do i=1,ng
21819          if (equal_matrix(ss(1:3,1:3,i), x_2,3) .or.  equal_matrix(ss(1:3,1:3,i),-x_2,3) .or. &
21820              equal_matrix(ss(1:3,1:3,i), y_2,3) .or.  equal_matrix(ss(1:3,1:3,i),-y_2,3) .or. &
21821              equal_matrix(ss(1:3,1:3,i), z_2,3) .or.  equal_matrix(ss(1:3,1:3,i),-z_2,3) .or. &
21822              equal_matrix(ss(1:3,1:3,i), x_3,3) .or.  equal_matrix(ss(1:3,1:3,i),-x_3,3) .or. &
21823              equal_matrix(ss(1:3,1:3,i), y_3,3) .or.  equal_matrix(ss(1:3,1:3,i),-y_3,3) .or. &
21824              equal_matrix(ss(1:3,1:3,i), z_3,3) .or.  equal_matrix(ss(1:3,1:3,i),-z_3,3) .or. &
21825              equal_matrix(ss(1:3,1:3,i), x_4,3) .or.  equal_matrix(ss(1:3,1:3,i),-x_4,3) .or. &
21826              equal_matrix(ss(1:3,1:3,i), y_4,3) .or.  equal_matrix(ss(1:3,1:3,i),-y_4,3) .or. &
21827              equal_matrix(ss(1:3,1:3,i), z_4,3) .or.  equal_matrix(ss(1:3,1:3,i),-z_4,3) .or. &
21828              equal_matrix(ss(1:3,1:3,i), x_6,3) .or.  equal_matrix(ss(1:3,1:3,i),-x_6,3) .or. &
21829              equal_matrix(ss(1:3,1:3,i), y_6,3) .or.  equal_matrix(ss(1:3,1:3,i),-y_6,3) .or. &
21830              equal_matrix(ss(1:3,1:3,i), z_6,3) .or.  equal_matrix(ss(1:3,1:3,i),-z_6,3) .or. &
21831              equal_matrix(ss(1:3,1:3,i), x_2p,3).or.  equal_matrix(ss(1:3,1:3,i),-x_2p,3).or. &
21832              equal_matrix(ss(1:3,1:3,i), y_2p,3).or.  equal_matrix(ss(1:3,1:3,i),-y_2p,3).or. &
21833              equal_matrix(ss(1:3,1:3,i), z_2p,3).or.  equal_matrix(ss(1:3,1:3,i),-z_2p,3).or. &
21834              equal_matrix(ss(1:3,1:3,i), x_2pp,3).or. equal_matrix(ss(1:3,1:3,i),-x_2pp,3).or. &
21835              equal_matrix(ss(1:3,1:3,i), y_2pp,3).or. equal_matrix(ss(1:3,1:3,i),-y_2pp,3).or. &
21836              equal_matrix(ss(1:3,1:3,i), z_2pp,3).or. equal_matrix(ss(1:3,1:3,i),-z_2pp,3).or. &
21837              equal_matrix(ss(1:3,1:3,i), xyz_3,3).or. equal_matrix(ss(1:3,1:3,i),-xyz_3,3) ) cycle
21838
21839              ss(:,:,i)=0
21840       end do
21841
21842       !---- Ordering following Order of rotations ----!
21843       norden=0
21844       do i=1,ng
21845          if (equal_matrix(ss(1:3,1:3,i),nulo(1:3,1:3),3)) cycle
21846           orden=axes_rotation(ss(1:3,1:3,i))
21847          norden(abs(orden))=norden(abs(orden))+1
21848       end do
21849
21850       npos=0
21851       do j=6,1,-1
21852          if (norden(j) == 0) cycle
21853          do i=1,ng
21854             if (equal_matrix(ss(1:3,1:3,i),nulo(1:3,1:3),3)) cycle
21855              orden=axes_rotation(ss(1:3,1:3,i))
21856             if (abs(orden) == j) then
21857                ss1=ss(:,:,i)
21858                ts1=ts(:,i)
21859                npos=npos+1
21860                ss(:,:,i)=ss(:,:,npos)
21861                ts(:,i)  =ts(:,npos)
21862                ss(:,:,npos)=ss1
21863                ts(:,npos)  =ts1
21864             end if
21865          end do
21866       end do
21867       nt=npos
21868
21869       if (nt == 0) then
21870          ngen=ngen+1
21871          generador(ngen)%orden= 1
21872          generador(ngen)%axes = "z"
21873          generador(ngen)%tras= " "
21874       end if
21875
21876       !---- Ordering following axes Direction ----!
21877       norden=0
21878       do i=1,nt
21879          if (equal_matrix(ss(1:3,1:3,i),nulo(1:3,1:3),3)) cycle
21880          orden=axes_rotation(ss(1:3,1:3,i))
21881          norden(abs(orden))=norden(abs(orden))+1
21882       end do
21883       if (norden(6) > 0) norden(3)=0
21884
21885       do i=1,nt
21886          orden=0
21887          axes =" "
21888          axes2=" "
21889          tras ="  "
21890          orden=axes_rotation(ss(1:3,1:3,i))
21891          if (norden(abs(orden)) == 0) cycle
21892          select case (abs(orden))
21893              case (1)
21894                 if (orden > 0) then
21895                    if (equal_matrix(ss(1:3,1:3,i),z_1,3)) then
21896                       axes="z"
21897                    end if
21898                 else
21899                    if (equal_matrix(ss(1:3,1:3,i),-z_1,3)) then
21900                       axes="z"
21901                    end if
21902                 end if
21903
21904              case (2)
21905                 if (orden > 0) then
21906                    if (equal_matrix(ss(1:3,1:3,i),x_2,3)) then
21907                       axes="x"
21908                    else if (equal_matrix(ss(1:3,1:3,i),y_2,3)) then
21909                       axes="y"
21910                    else if (equal_matrix(ss(1:3,1:3,i),z_2,3)) then
21911                       axes="z"
21912                    else if (equal_matrix(ss(1:3,1:3,i),x_2p,3)) then
21913                       axes="'"
21914                       axes2="x"
21915                    else if (equal_matrix(ss(1:3,1:3,i),y_2p,3)) then
21916                       axes="'"
21917                       axes2="y"
21918                    else if (equal_matrix(ss(1:3,1:3,i),z_2p,3)) then
21919                       axes="'"
21920                       axes2="z"
21921                    else if (equal_matrix(ss(1:3,1:3,i),x_2pp,3)) then
21922                       axes=""""
21923                       axes2="x"
21924                    else if (equal_matrix(ss(1:3,1:3,i),y_2pp,3)) then
21925                       axes=""""
21926                       axes2="y"
21927                    else if (equal_matrix(ss(1:3,1:3,i),z_2pp,3)) then
21928                       axes=""""
21929                       axes2="z"
21930                    end if
21931                 else
21932                    if (equal_matrix(ss(1:3,1:3,i),-x_2,3)) then
21933                       axes="x"
21934                    else if (equal_matrix(ss(1:3,1:3,i),-y_2,3)) then
21935                       axes="y"
21936                    else if (equal_matrix(ss(1:3,1:3,i),-z_2,3)) then
21937                       axes="z"
21938                    else if (equal_matrix(ss(1:3,1:3,i),-x_2p,3)) then
21939                       axes="'"
21940                       axes2="x"
21941                    else if (equal_matrix(ss(1:3,1:3,i),-y_2p,3)) then
21942                       axes="'"
21943                       axes2="y"
21944                    else if (equal_matrix(ss(1:3,1:3,i),-z_2p,3)) then
21945                       axes="'"
21946                       axes2="z"
21947                    else if (equal_matrix(ss(1:3,1:3,i),-x_2pp,3)) then
21948                       axes=""""
21949                       axes2="x"
21950                    else if (equal_matrix(ss(1:3,1:3,i),-y_2pp,3)) then
21951                       axes=""""
21952                       axes2="y"
21953                    else if (equal_matrix(ss(1:3,1:3,i),-z_2pp,3)) then
21954                       axes=""""
21955                       axes2="z"
21956                    end if
21957                 end if
21958
21959              case (3)
21960                 if (orden > 0) then
21961                    if (equal_matrix(ss(1:3,1:3,i),x_3,3)) then
21962                       axes="x"
21963                    else if (equal_matrix(ss(1:3,1:3,i),y_3,3)) then
21964                       axes="y"
21965                    else if (equal_matrix(ss(1:3,1:3,i),z_3,3)) then
21966                       axes="z"
21967                    else if (equal_matrix(ss(1:3,1:3,i),xyz_3,3)) then
21968                       axes="*"
21969                    end if
21970                 else
21971                    if (equal_matrix(ss(1:3,1:3,i),-x_3,3)) then
21972                       axes="x"
21973                    else if (equal_matrix(ss(1:3,1:3,i),-y_3,3)) then
21974                       axes="y"
21975                    else if (equal_matrix(ss(1:3,1:3,i),-z_3,3)) then
21976                       axes="z"
21977                    else if (equal_matrix(ss(1:3,1:3,i),-xyz_3,3)) then
21978                       axes="*"
21979                    end if
21980                 end if
21981
21982              case (4)
21983                 if (orden > 0) then
21984                    if (equal_matrix(ss(1:3,1:3,i),x_4,3)) then
21985                       axes="x"
21986                    else if (equal_matrix(ss(1:3,1:3,i),y_4,3)) then
21987                       axes="y"
21988                    else if (equal_matrix(ss(1:3,1:3,i),z_4,3)) then
21989                       axes="z"
21990                    end if
21991                 else
21992                    if (equal_matrix(ss(1:3,1:3,i),-x_1,3)) then
21993                       axes="x"
21994                    else if (equal_matrix(ss(1:3,1:3,i),-y_4,3)) then
21995                       axes="y"
21996                    else if (equal_matrix(ss(1:3,1:3,i),-z_4,3)) then
21997                       axes="z"
21998                    end if
21999                 end if
22000
22001              case (6)
22002                 if (orden > 0) then
22003                    if (equal_matrix(ss(1:3,1:3,i),x_6,3)) then
22004                       axes="x"
22005                    else if (equal_matrix(ss(1:3,1:3,i),y_6,3)) then
22006                       axes="y"
22007                    else if (equal_matrix(ss(1:3,1:3,i),z_6,3)) then
22008                       axes="z"
22009                    end if
22010                 else
22011                    if (equal_matrix(ss(1:3,1:3,i),-x_6,3)) then
22012                       axes="x"
22013                    else if (equal_matrix(ss(1:3,1:3,i),-y_6,3)) then
22014                       axes="y"
22015                    else if (equal_matrix(ss(1:3,1:3,i),-z_6,3)) then
22016                       axes="z"
22017                    end if
22018                 end if
22019
22020          end select
22021
22022          !---- Translations ----!
22023          tt=mod(nint(ts(:,i)*12.0)+48,12)
22024
22025           select case (SpaceGroup%Bravais)
22026             case ("A")
22027                tt1=mod(tt-lattice(:,1)+48,12)
22028                if (sum(tt1) < sum(tt) ) tt=tt1
22029
22030             case ("B")
22031                tt1=mod(tt-lattice(:,2)+48,12)
22032                if (sum(tt1) < sum(tt) ) tt=tt1
22033
22034             case ("C")
22035                tt1=mod(tt-lattice(:,3)+48,12)
22036                if (sum(tt1) < sum(tt) ) tt=tt1
22037
22038             case ("I")
22039                tt1=mod(tt-lattice(:,4)+48,12)
22040                if (sum(tt1) < sum(tt) ) tt=tt1
22041
22042             case ("R")
22043                tt1=mod(tt-lattice(:,5)+48,12)
22044                tt2=mod(tt-lattice(:,6)+48,12)
22045                if (sum(tt1) < sum(tt) ) tt=tt1
22046                if (sum(tt2) < sum(tt) ) tt=tt2
22047
22048             case ("F")
22049                tt1=mod(tt-lattice(:,3)+48,12)
22050                tt2=mod(tt-lattice(:,2)+48,12)
22051                tt3=mod(tt-lattice(:,1)+48,12)
22052                if (sum(tt1) < sum(tt) ) tt=tt1
22053                if (sum(tt2) < sum(tt) ) tt=tt2
22054                if (sum(tt3) < sum(tt) ) tt=tt3
22055
22056          end select
22057
22058          ini=1
22059
22060          !---- Fractional translation ----!
22061          select case (abs(orden))
22062              case (3)
22063                 select case (axes)
22064                     case ("x")
22065                        if (tt(2) == 0 .and. tt(3) == 0) then
22066                           select case (tt(1))
22067                              case (4)              ! 31
22068                                 tras(ini:ini)="1"
22069                                 tt(1)=0
22070
22071                              case (8)              ! 32
22072                                 tras(ini:ini)="2"
22073                                 tt(1)=0
22074                           end select
22075                        end if
22076
22077                     case ("y")
22078                        if (tt(1) == 0 .and. tt(3) == 0) then
22079                           select case (tt(2))
22080                              case (4)              ! 31
22081                                 tras(ini:ini)="1"
22082                                 tt(2)=0
22083
22084                              case (8)              ! 32
22085                                 tras(ini:ini)="2"
22086                                 tt(2)=0
22087                           end select
22088                        end if
22089                     case ("z")
22090                        if (tt(1) == 0 .and. tt(2) == 0) then
22091                           select case (tt(3))
22092                              case (4)              ! 31
22093                                 tras(ini:ini)="1"
22094                                 tt(3)=0
22095
22096                              case (8)              ! 32
22097                                 tras(ini:ini)="2"
22098                                 tt(3)=0
22099                           end select
22100                        end if
22101
22102                 end select
22103
22104              case (6)
22105                 select case (axes)
22106                     case ("x")
22107                        if (tt(2) == 0 .and. tt(3) ==0) then
22108                           select case (tt(1))
22109                              case (2)              ! 61
22110                                 tras(ini:ini)="1"
22111                                 tt(1)=0
22112
22113                              case (4)              ! 62
22114                                 tras(ini:ini)="2"
22115                                 tt(1)=0
22116
22117                              case (8)              ! 64
22118                                 tras(ini:ini)="4"
22119                                 tt(1)=0
22120
22121                              case(10)
22122                                 tras(ini:ini)="5"  ! 65
22123                                 tt(1)=0
22124
22125                           end select
22126                        end if
22127
22128                     case ("y")
22129                        if (tt(1) == 0 .and. tt(3) == 0) then
22130                           select case (tt(2))
22131                              case (2)              ! 61
22132                                 tras(ini:ini)="1"
22133                                 tt(2)=0
22134
22135                              case (4)              ! 62
22136                                 tras(ini:ini)="2"
22137                                 tt(2)=0
22138
22139                              case (8)              ! 64
22140                                 tras(ini:ini)="4"
22141                                 tt(2)=0
22142
22143                              case(10)
22144                                 tras(ini:ini)="5"  ! 65
22145                                 tt(2)=0
22146
22147                           end select
22148                        end if
22149
22150                     case ("z")
22151                        if (tt(1) == 0 .and. tt(2) == 0) then
22152                           select case (tt(3))
22153                              case (2)              ! 61
22154                                 tras(ini:ini)="1"
22155                                 tt(3)=0
22156
22157                              case (4)              ! 62
22158                                 tras(ini:ini)="2"
22159                                 tt(3)=0
22160
22161                              case (8)              ! 64
22162                                 tras(ini:ini)="4"
22163                                 tt(3)=0
22164
22165                              case(10)
22166                                 tras(ini:ini)="5"  ! 65
22167                                 tt(3)=0
22168
22169                           end select
22170                        end if
22171
22172                 end select
22173          end select
22174
22175          !---- Translation vector ----!
22176          do k=1,3     ! 3 pasadas
22177             if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) exit
22178
22179             do j=1,8
22180                tt1=tt-tras_val(:,j)
22181                if ( all(tt1 >= 0) ) then
22182                   tras(ini:ini)=l_case(traslacion(j))
22183                   tt(:)=tt1(:)
22184                   ini=ini+1
22185                   exit
22186                end if
22187             end do
22188
22189          end do
22190
22191          !---- Last check ----!
22192          if (nt == 1) then
22193             ngen=ngen+1
22194             generador(ngen)%orden= orden
22195             generador(ngen)%axes = axes
22196             generador(ngen)%tras = tras
22197          else
22198             if (norden(6) > 0) then
22199                if (abs(orden) == 6 .and. axes =="z") then
22200                   ngen=ngen+1
22201
22202                   if (ngen > 4) then
22203                      err_symm=.true.
22204                      ERR_Symm_Mess=" Error in generators"
22205                      return
22206                   end if
22207                   generador(ngen)%orden= orden
22208                   generador(ngen)%axes = axes
22209                   generador(ngen)%tras = tras
22210                end if
22211
22212                if (abs(orden) == 2 .and. (axes == "'" .or. axes =="""") .and. &
22213                    axes2 == "z") then
22214                   ngen=ngen+1
22215
22216                   if (ngen > 4) then
22217                      err_symm=.true.
22218                      ERR_Symm_Mess=" Error in generators"
22219                      return
22220                   end if
22221                   generador(ngen)%orden= orden
22222                   generador(ngen)%axes = axes
22223                   generador(ngen)%axes2= axes2
22224                   generador(ngen)%tras = tras
22225                end if
22226             end if
22227
22228             if (norden(4) > 0) then
22229                if (abs(orden) == 4 .and. axes =="z") then
22230                   ngen=ngen+1
22231
22232                   if (ngen > 4) then
22233                      err_symm=.true.
22234                      ERR_Symm_Mess=" Error in generators"
22235                      return
22236                   end if
22237                   generador(ngen)%orden= orden
22238                   generador(ngen)%axes = axes
22239                   generador(ngen)%tras = tras
22240                end if
22241
22242                if (abs(orden) == 3 .and. axes == "*") then
22243                   ngen=ngen+1
22244
22245                   if (ngen > 4) then
22246                      err_symm=.true.
22247                      ERR_Symm_Mess=" Error in generators"
22248                      return
22249                   end if
22250                   generador(ngen)%orden= orden
22251                   generador(ngen)%axes = axes
22252                   generador(ngen)%tras = tras
22253                end if
22254
22255                if (abs(orden) == 2 .and. axes == "x") then
22256                   ngen=ngen+1
22257
22258                   if (ngen > 4) then
22259                      err_symm=.true.
22260                      ERR_Symm_Mess=" Error in generators"
22261                      return
22262                   end if
22263                   generador(ngen)%orden= orden
22264                   generador(ngen)%axes = axes
22265                   generador(ngen)%tras = tras
22266                end if
22267             end if
22268
22269             if (norden(3) > 0 .and. norden(4) == 0) then
22270                if (abs(orden) == 3 .and. (axes =="z" .or. axes == "*")) then
22271                   ngen=ngen+1
22272
22273                   if (ngen > 4) then
22274                      err_symm=.true.
22275                      ERR_Symm_Mess=" Error in generators"
22276                      return
22277                   end if
22278                   generador(ngen)%orden= orden
22279                   generador(ngen)%axes = axes
22280                   generador(ngen)%tras = tras
22281                end if
22282
22283                if ( (abs(orden) == 2 .and. axes == "z")  .or. &
22284                     (abs(orden) == 2 .and. axes == "x")  .or. &
22285                     (abs(orden) == 2 .and. axes == "'")  .or. &
22286                     (abs(orden) == 2 .and. axes == """")) then
22287                   ngen=ngen+1
22288
22289                   if (ngen > 4) then
22290                      err_symm=.true.
22291                      ERR_Symm_Mess=" Error in generators"
22292                      return
22293                   end if
22294                   generador(ngen)%orden= orden
22295                   generador(ngen)%axes = axes
22296                   generador(ngen)%axes2= axes2
22297                   generador(ngen)%tras = tras
22298                end if
22299             end if
22300
22301             if (norden(2) > 0 .and. norden(3) == 0 .and. norden(4) == 0  &
22302                .and. norden(6) == 0) then
22303                if (abs(orden) == 2 .and. axes == "z") then
22304                   ngen=ngen+1
22305
22306                   if (ngen > 4) then
22307                      err_symm=.true.
22308                      ERR_Symm_Mess=" Error in generators"
22309                      return
22310                   end if
22311                   generador(ngen)%orden= orden
22312                   generador(ngen)%axes = axes
22313                   generador(ngen)%tras = tras
22314                end if
22315                if (abs(orden) == 2 .and. axes == "x") then
22316                   ngen=ngen+1
22317
22318                   if (ngen > 4) then
22319                      err_symm=.true.
22320                      ERR_Symm_Mess=" Error in generators"
22321                      return
22322                   end if
22323                   generador(ngen)%orden= orden
22324                   generador(ngen)%axes = axes
22325                   generador(ngen)%tras = tras
22326                end if
22327             end if
22328
22329          end if
22330       end do
22331
22332       !---- Purge Generators ----!
22333       j=0
22334       k=0
22335       if (ngen > 1) then
22336          do i=1,ngen
22337             if (generador(i)%axes =="'") j=i
22338             if (generador(i)%axes =="""") k=i
22339          end do
22340          if (j /= 0 .and. k /=0) then
22341             if (generador(j)%axes2 =="z") then
22342                do i=k+1,ngen
22343                   generador(i-1)=generador(i)
22344                end do
22345                ngen=ngen-1
22346             else
22347                do i=j+1,ngen
22348                   generador(i-1)=generador(i)
22349                end do
22350                ngen=ngen-1
22351             end if
22352          end if
22353       end if
22354
22355       !---- Order Generators ----!
22356       select case (ngen)
22357          case (2)
22358             if (abs(generador(1)%orden) < abs(generador(2)%orden)) then
22359                generador(5)=generador(1)
22360                generador(1)=generador(2)
22361                generador(2)=generador(5)
22362             else if (abs(generador(1)%orden) == abs(generador(2)%orden)) then
22363                if (generador(2)%axes == "z") then
22364                   generador(5)=generador(1)
22365                   generador(1)=generador(2)
22366                   generador(2)=generador(5)
22367                end if
22368             end if
22369          case (3)
22370             do i=1,3
22371                if (abs(generador(i)%orden) == 1 .or. abs(generador(i)%orden) == 3) then
22372                   generador(5)=generador(i)
22373                   do j=i+1,3
22374                      generador(j-1)=generador(j)
22375                   end do
22376                   generador(3)=generador(5)
22377                end if
22378             end do
22379             if (abs(generador(1)%orden) < abs(generador(2)%orden)) then
22380                generador(5)=generador(1)
22381                generador(1)=generador(2)
22382                generador(2)=generador(5)
22383             else if (abs(generador(1)%orden) == abs(generador(2)%orden)) then
22384                if (generador(2)%axes == "z") then
22385                   generador(5)=generador(1)
22386                   generador(1)=generador(2)
22387                   generador(2)=generador(5)
22388                end if
22389             end if
22390
22391          case (4)
22392             do i=1,4
22393                if (abs(generador(i)%orden) == 1) then
22394                   generador(5)=generador(i)
22395                   do j=i+1,4
22396                      generador(j-1)=generador(j)
22397                   end do
22398                   generador(4)=generador(5)
22399                end if
22400             end do
22401             do i=1,3
22402                if (abs(generador(i)%orden) == 3) then
22403                   generador(5)=generador(i)
22404                   do j=i+1,3
22405                      generador(j-1)=generador(j)
22406                   end do
22407                   generador(3)=generador(5)
22408                end if
22409             end do
22410             if (abs(generador(1)%orden) < abs(generador(2)%orden)) then
22411                generador(5)=generador(1)
22412                generador(1)=generador(2)
22413                generador(2)=generador(5)
22414             else if (abs(generador(1)%orden) == abs(generador(2)%orden)) then
22415                if (generador(2)%axes == "z") then
22416                   generador(5)=generador(1)
22417                   generador(1)=generador(2)
22418                   generador(2)=generador(5)
22419                end if
22420             end if
22421
22422       end select
22423
22424       !---- Hall Symbol ----!
22425       ini=len_trim(hall)
22426       ini=ini+1
22427
22428       do i=1,ngen
22429          !---- Rotation ----!
22430          if (generador(i)%orden >0) then
22431             ini=ini+1
22432             write(unit=hall(ini:ini),fmt="(i1)") generador(i)%orden
22433          else
22434             ini=ini+1
22435             write(unit=hall(ini:ini+1),fmt="(i2)") generador(i)%orden
22436             ini=ini+1
22437          end if
22438
22439          !---- Axis ----!
22440          select case (i)
22441             case (1)
22442                if (generador(i)%axes /= "z") then
22443                   ini=ini+1
22444                   hall(ini:ini)=generador(i)%axes
22445                end if
22446
22447             case (2)
22448                if (abs(generador(i)%orden) == 2) then
22449                   if (abs(generador(1)%orden) == 2 .or. abs(generador(1)%orden) == 4) then
22450                      if (generador(i)%axes /= "x") then
22451                         ini=ini+1
22452                         hall(ini:ini)=generador(i)%axes
22453                      end if
22454                   else if (abs(generador(1)%orden) == 3 .or. abs(generador(1)%orden) == 6) then
22455                      if (generador(i)%axes /= "'") then
22456                         ini=ini+1
22457                         hall(ini:ini)=generador(i)%axes
22458                      end if
22459                   end if
22460
22461                else
22462                   if (abs(generador(i)%orden) /= 1) then
22463                      ini=ini+1
22464                      hall(ini:ini)=generador(i)%axes
22465                   end if
22466                end if
22467
22468             case (3)
22469                if (abs(generador(i)%orden) /= 3 .and. abs(generador(i)%orden) /= 1) then
22470                   ini=ini+1
22471                   hall(ini:ini)=generador(i)%axes
22472                end if
22473
22474             case (4)
22475
22476          end select
22477
22478          !---- Translation ----!
22479          select case (len_trim(generador(i)%tras))
22480             case (1)
22481                ini=ini+1
22482                hall(ini:ini)=generador(i)%tras
22483
22484             case (2)
22485                ini=ini+1
22486                hall(ini:ini+1)=generador(i)%tras
22487                ini=ini+1
22488
22489             case (3)
22490                ini=ini+1
22491                hall(ini:ini+2)=generador(i)%tras
22492                ini=ini+2
22493
22494          end select
22495          ini=ini+1
22496       end do
22497
22498       !---- Check the Hall Symbol for repetitions of minus sign ----!
22499
22500       i=index(hall,"-")
22501       if(i /= 0 ) then
22502         k=index(hall,"-",back=.true.)
22503         if(k /= i ) then
22504           hall=hall(1:k-1)//hall(k+1:)
22505         end if
22506       end if
22507
22508       !---- Is the Hall Symbol in the table? ----!
22509       k=0
22510       do i=1,num_spgr_info
22511          if (hall(1:16) == spgr_info(i)%hall) then
22512             k=i
22513             exit
22514          end if
22515       end do
22516
22517       if(hall(1:1) /= "-") hall=" "//hall
22518       Spacegroup%Hall=hall
22519
22520       if (k /= 0) then
22521          SpaceGroup%NumSpg       = spgr_info(k)%n
22522          SpaceGroup%Spg_Symb     = spgr_info(k)%hm
22523                call get_laue_str(spgr_info(k)%laue,SpaceGroup%Laue)
22524                call get_PointGroup_str(spgr_info(k)%pg,SpaceGroup%PG)
22525          SpaceGroup%Info         = spgr_info(k)%inf_extra
22526          SpaceGroup%R_Asym_Unit(1,1) = real(spgr_info(k)%asu(1))/24.0
22527          SpaceGroup%R_Asym_Unit(2,1) = real(spgr_info(k)%asu(2))/24.0
22528          SpaceGroup%R_Asym_Unit(3,1) = real(spgr_info(k)%asu(3))/24.0
22529          SpaceGroup%R_Asym_Unit(1,2) = real(spgr_info(k)%asu(4))/24.0
22530          SpaceGroup%R_Asym_Unit(2,2) = real(spgr_info(k)%asu(5))/24.0
22531          SpaceGroup%R_Asym_Unit(3,2) = real(spgr_info(k)%asu(6))/24.0
22532       else
22533          SpaceGroup%Spg_Symb     = "Unknown"
22534          SpaceGroup%Info         = "User-provided generators "
22535
22536       end if
22537
22538       if (present(SpaceH) ) SpaceH=hall
22539
22540       return
22541    End Subroutine Get_HallSymb_from_Gener
22542
22543    !!----
22544    !!---- Subroutine Get_Lattice_Type(L, Latc, Lattyp)
22545    !!----    integer,                        intent(in)  :: L         !  number of centring vectors
22546    !!----    real(kind=cp), dimension(:,:),  intent(in)  :: Latc      ! (3,11) centring vectors
22547    !!----    character(len=*),               intent(out) :: lattyp    ! Lattice symbol
22548    !!----
22549    !!----    Subroutine to get the lattice symbol from a set of centring vectors.
22550    !!----
22551    !!---- Update: February - 2005
22552    !!
22553    Subroutine Get_Lattice_Type(L, Latc, lattyp)
22554       !---- Arguments ----!
22555       integer,                        intent( in) :: L
22556       real(kind=cp), dimension(:,:),  intent( in) :: Latc
22557       character(len=*),               intent(out) :: lattyp
22558
22559       !---- Local variables ----!
22560       logical :: latt_p, latt_a, latt_b, latt_c, latt_i, latt_r, latt_f, latt_z
22561       integer, dimension(6) :: latt_given
22562       integer, dimension(3) :: tt
22563       integer               :: i, j
22564       integer, dimension(3,6), parameter :: lattice=reshape((/0,6,6, 6,0,6, &
22565                                                     6,6,0, 6,6,6, 8,4,4, 4,8,8/),(/3,6/))
22566
22567       if (l > 3) then  !non conventional centring
22568          lattyp="Z"
22569          return
22570       else if(l == 0) then !primitive lattice
22571          lattyp="P"
22572          return
22573       end if
22574
22575       latt_p=.true.
22576       latt_a=.false.
22577       latt_b=.false.
22578       latt_c=.false.
22579       latt_i=.false.
22580       latt_r=.false.
22581       latt_f=.false.
22582       latt_z=.false.
22583
22584       do i=1,L
22585          tt(1:3)=nint(12.0 * Latc(1:3,i))   ! Translations x 12
22586
22587          !---- Compare the translation part of the operator with tabulated array ----!
22588          latt_given(:) = 0
22589          do j=1,6
22590             if (equal_vector(tt,lattice(:,j),3)) then
22591                latt_given(j) = 1
22592                select case (j)
22593                   case (1)
22594                      latt_a=.true.
22595                   case (2)
22596                      latt_b=.true.
22597                   case (3)
22598                      latt_c=.true.
22599                   case (4)
22600                      latt_i=.true.
22601                   case (5,6)
22602                      latt_r=.true.
22603                end select
22604                exit
22605             end if
22606          end do
22607          if (sum(latt_given) == 0) then
22608             latt_z = .true.
22609             exit
22610          end if
22611       end do
22612
22613       !---- Lattice Type ----!
22614       if (latt_z) then
22615           lattyp="Z"
22616           return
22617       end if
22618       if ( (latt_a .and. latt_b .and. latt_c) .or. (latt_a .and. latt_b) .or. &
22619            (latt_a .and. latt_c) .or. (latt_b .and. latt_c) ) then
22620            latt_f=.true.
22621            latt_a=.false.
22622            latt_b=.false.
22623            latt_c=.false.
22624            latt_p=.false.
22625            latt_i=.false.
22626       end if
22627       if (latt_p) lattyp="P"
22628       if (latt_a) lattyp="A"
22629       if (latt_b) lattyp="B"
22630       if (latt_c) lattyp="C"
22631       if (latt_i) lattyp="I"
22632       if (latt_r) lattyp="R"
22633       if (latt_f) lattyp="F"
22634
22635       return
22636    End Subroutine Get_Lattice_Type
22637
22638    !!----
22639    !!---- Subroutine Get_Laue_Pg(Spacegroup, Laue_Car, Point_Car)
22640    !!----    type (Space_Group_Type),  intent( in) :: SpaceGroup   !  In -> Space Group type variable
22641    !!----    character(len=*),         intent(out) :: Laue_car     ! Out -> String with Laue symbol
22642    !!----    character(len=*),         intent(out) :: Point_car    ! Out -> String with Point Group symbol
22643    !!----
22644    !!----    Subroutine to get the information of Laue and Point Group.
22645    !!----    Vvalid only for conventional bases for Point Group
22646    !!----
22647    !!---- Update: February - 2005
22648    !!
22649    Subroutine Get_Laue_PG(SpaceGroup, Laue_car, Point_car)
22650       !---- Arguments ----!
22651       type (Space_Group_Type),  intent( in) :: SpaceGroup
22652       character (len=*),        intent(out) :: Laue_car
22653       character (len=*),        intent(out) :: Point_car
22654
22655       !---- Local variables ----!
22656       integer :: nrot_1, nrot_1b
22657       integer :: nrot_2, nrot_2b
22658       integer :: nrot_3, nrot_3b
22659       integer :: nrot_4, nrot_4b
22660       integer :: nrot_6, nrot_6b
22661       integer :: i,n_m,ndet,ind
22662
22663       !---- Initializing ----!
22664       point_car=" "
22665       laue_car=" "
22666
22667       nrot_1  = 0
22668       nrot_2  = 0
22669       nrot_3  = 0
22670       nrot_4  = 0
22671       nrot_6  = 0
22672       nrot_1b = 0
22673       nrot_2b = 0
22674       nrot_3b = 0
22675       nrot_4b = 0
22676       nrot_6b = 0
22677       n_m = 0
22678
22679       call init_err_symm()
22680       if (spacegroup%numops == 0) then
22681          err_symm=.true.
22682          ERR_Symm_Mess=" No symmetry operators are given"
22683          return
22684       end if
22685       do i=1,spacegroup%numops
22686          ndet= Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22687          select case (ndet)
22688             case (-6)
22689                nrot_6b=nrot_6b +1
22690             case (-4)
22691                nrot_4b=nrot_4b +1
22692             case (-3)
22693                nrot_3b=nrot_3b +1
22694             case (-2)
22695                nrot_2b=nrot_2b +1
22696             case (-1)
22697                nrot_1b=nrot_1b +1
22698             case ( 1)
22699                nrot_1 =nrot_1  +1
22700             case ( 2)
22701                nrot_2 =nrot_2  +1
22702             case ( 3)
22703                nrot_3 =nrot_3  +1
22704             case ( 4)
22705                nrot_4 =nrot_4  +1
22706             case ( 6)
22707                nrot_6 =nrot_6  +1
22708             case default
22709                err_symm=.true.
22710                ERR_Symm_Mess=" Rotation Not Determined"
22711                return
22712          end select
22713       end do
22714
22715       n_m = nrot_1  + nrot_2  + nrot_3  + nrot_4  + nrot_6  + &
22716             nrot_1b + nrot_2b + nrot_3b + nrot_4b + nrot_6b
22717
22718       !---- Cubic ----!
22719       if ( (nrot_3 + nrot_3b == 8) ) then
22720          select case (n_m)
22721             case (12)
22722                if (SpaceGroup%Centred ==1) then
22723                   point_car="23"
22724                else
22725                   point_car="m-3"
22726                end if
22727                laue_car="m-3"
22728
22729             case (24)
22730                if (SpaceGroup%Centred /=1) then
22731                   point_car="m-3m"
22732                else
22733                   if (nrot_4  == 6) point_car="432"
22734                   if (nrot_4b == 6) point_car="-43m"
22735                end if
22736                laue_car="m-3m"
22737          end select
22738
22739       !---- Hexagonal ----!
22740       else if ( (nrot_6 + nrot_6b == 2) ) then
22741          select case (n_m)
22742             case (6)
22743                if (SpaceGroup%Centred /=1) then
22744                   point_car="6/m"
22745                else
22746                   if (nrot_6  == 2) point_car="6"
22747                   if (nrot_6b == 2) point_car="-6"
22748                end if
22749                laue_car="6/m"
22750
22751             case (12)
22752                if (SpaceGroup%Centred /=1) then
22753                   point_car="6/mmm"
22754                else
22755                   if (nrot_6b == 2) then
22756                      do i=1,spacegroup%numops
22757                         ndet= Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22758                         if (ndet /= 2) cycle
22759                         !---- This is only valid for conventional bases ---!
22760                         call SearchOp(SpaceGroup%Symop(i)%Rot(:,:),25,36,ind)
22761                         if (ind < 0) then
22762                            ind=-ind-12
22763                         end if
22764                         select case (ind)
22765                            case (31)
22766                               point_car="-62m"
22767                            case default
22768                               point_car="-6m2"
22769                         end select
22770                         exit
22771                      end do
22772                   end if
22773                   if ( (nrot_6  == 2 .and. nrot_2 == 7) ) point_car="622"
22774                   if ( (nrot_6  == 2 .and. nrot_2b== 6) ) point_car="6mm"
22775                end if
22776                laue_car="6/mmm"
22777          end select
22778
22779       !---- Trigonal ----!
22780       else if ( (nrot_3 + nrot_3b == 2) ) then
22781          select case (n_m)
22782             case (3)
22783                if (SpaceGroup%Centred /=1) then
22784                   point_car="-3"
22785                else
22786                   point_car="3"
22787                end if
22788                laue_car="-3"
22789
22790             case (6)
22791                if (SpaceGroup%Hexa) then
22792                   if (SpaceGroup%Centred /=1) then
22793                      do i=1,spacegroup%numops
22794                           ndet=Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22795                           if (ndet /= -2) cycle
22796                         !---- This is only valid for conventional bases ---!
22797                         call SearchOp(SpaceGroup%Symop(i)%Rot(:,:),25,36,ind)
22798                         if (ind < 0) then
22799                            ind=-ind-12
22800                         end if
22801                         select case (ind)
22802                            case (22)
22803                               point_car="-31m"
22804                               laue_car ="-31m"
22805                            case default
22806                               point_car="-3m"
22807                               laue_car ="-3m"
22808                         end select
22809                         exit
22810                      end do
22811                   else
22812                      if (nrot_2  == 3 ) then
22813                         do i=1,spacegroup%numops
22814                            ndet=Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22815                            if (ndet /= 2) cycle
22816                            !---- This is only valid for conventional bases ---!
22817                            call SearchOp(SpaceGroup%Symop(i)%Rot(:,:),25,36,ind)
22818                            if (ind < 0) then
22819                               ind=-ind-12
22820                            end if
22821                            select case (ind)
22822                               case (34)
22823                                  point_car="-312"
22824                                  laue_car ="-31m"
22825                               case default
22826                                  point_car="-32"
22827                                  laue_car ="-3m"
22828                            end select
22829                            exit
22830                         end do
22831                      end if
22832
22833                      if (nrot_2b == 3 ) then
22834                         do i=1,spacegroup%numops
22835                            ndet=Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22836                            if (ndet /= -2) cycle
22837                            !---- This is only valid for conventional bases ---!
22838                            call SearchOp(SpaceGroup%Symop(i)%Rot(:,:),25,36,ind)
22839                            if (ind < 0) then
22840                               ind=-ind-12
22841                            end if
22842                            select case (ind)
22843                               case (22)
22844                                  point_car="31m"
22845                                  laue_car ="-31m"
22846                               case default
22847                                  point_car="3m"
22848                                  laue_car ="-3m"
22849                            end select
22850                            exit
22851                         end do
22852                      end if
22853                   end if
22854                else
22855                   if (SpaceGroup%Centred /=1) then
22856                      point_car="-3m"
22857                   else
22858                      if (nrot_2  == 3 ) point_car="32"
22859                      if (nrot_2b == 3 ) point_car="3m"
22860                   end if
22861                   laue_car="-3m"
22862                end if
22863
22864          end select
22865
22866       !---- Tetragonal ----!
22867       else if ( (nrot_4 + nrot_4b == 2) ) then
22868          select case (n_m)
22869             case (4)
22870                if (SpaceGroup%Centred /=1) then
22871                   point_car="4/m"
22872                else
22873                   if (nrot_4  == 2 ) point_car="4"
22874                   if (nrot_4b == 2 ) point_car="-4"
22875                end if
22876                laue_car="4/m"
22877
22878             case (8)
22879                if (SpaceGroup%Centred /=1) then
22880                   point_car="4/mmm"
22881                else
22882                   if (nrot_4b == 2 ) then
22883                   do i=1,spacegroup%numops
22884                         ndet=Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22885                      if (ndet /= -2) cycle
22886                      !---- This is only valid for conventional bases ---!
22887                      call SearchOp(SpaceGroup%Symop(i)%Rot(:,:),1,24,ind)
22888                      if (ind < 0) then
22889                         ind=24-ind
22890                      end if
22891                      select case (ind)
22892                         case (28)
22893                            point_car="-4m2"
22894                         case default
22895                            point_car="-42m"
22896                      end select
22897                      exit
22898                   end do
22899                end if
22900                if ( (nrot_4  == 2 .and. nrot_2 == 5) ) point_car="422"
22901                if ( (nrot_4  == 2 .and. nrot_2b== 4) ) point_car="4mm"
22902             end if
22903             laue_car="4/mmm"
22904
22905          end select
22906
22907       !---- Orthorhombic ----!
22908       else if ( (nrot_2 + nrot_2b == 3) ) then
22909          if (SpaceGroup%Centred /=1) then
22910             point_car="mmm"
22911          else
22912             if (nrot_2  == 3 ) point_car="222"
22913             if (nrot_2b == 2 ) then
22914                do i=1,spacegroup%numops
22915                       ndet=Axes_Rotation(SpaceGroup%Symop(i)%Rot(:,:))
22916                   if (ndet /= 2) cycle
22917                   !---- This is only valid for conventional bases ---!
22918                   call SearchOp(SpaceGroup%Symop(i)%Rot(:,:),1,24,ind)
22919                   select case (ind)
22920                      case (4)
22921                         point_car="2mm"
22922                      case (3)
22923                         point_car="m2m"
22924                      case default
22925                         point_car="mm2"
22926                   end select
22927                   exit
22928                end do
22929             end if
22930          end if
22931          laue_car="mmm"
22932
22933       !---- Monoclinic ----!
22934       else if ( (nrot_2 + nrot_2b == 1)  ) then
22935          if (SpaceGroup%Centred /=1) then
22936             point_car="2/m"
22937          else
22938             if (nrot_2  == 1 ) point_car="2"
22939             if (nrot_2b == 1 ) point_car="m"
22940          end if
22941          laue_car="2/m"
22942
22943       !---- Triclinic ----!
22944       else if (n_m == 1) then
22945          if (SpaceGroup%Centred /=1) then
22946             point_car="-1"
22947          else
22948             point_car="1"
22949          end if
22950          laue_car="-1"
22951
22952       end if
22953
22954       return
22955    End Subroutine Get_Laue_PG
22956
22957    !!----
22958    !!---- Subroutine Get_Laue_Str(Ilaue,Laue_Str)
22959    !!----    integer,          intent( in) :: ilaue         !  In -> Ordinal number in LAUE_CLASS
22960    !!----    character(len=*), intent(out) :: Laue_Str      ! Out -> String with the Laue class
22961    !!----
22962    !!----    Obtain the string for the Laue-Class. Control of error is
22963    !!----    present
22964    !!----
22965    !!---- Update: February - 2005
22966    !!
22967    Subroutine Get_Laue_Str(Ilaue,Str)
22968       !---- Arguments ----!
22969       integer,          intent( in) :: ilaue
22970       character(len=*), intent(out) :: str
22971
22972       call init_err_symm()
22973       if (ilaue < 1 .or. ilaue > 16) then
22974          err_symm=.true.
22975          ERR_Symm_Mess=" Laue Number Incorrect"
22976       else
22977          str=laue_class(ilaue)
22978       end if
22979
22980       return
22981    End Subroutine Get_Laue_Str
22982
22983    !!----
22984    !!----  Subroutine Get_Orbit(X,Spg,Mult,orb,ptr,prim,symm)
22985    !!----    real(kind=cp), dimension(3),  intent (in) :: x     !  In -> Position vector
22986    !!----    type(Space_Group_type),       intent (in) :: spgr  !  In -> Space Group
22987    !!----    integer,                      intent(out) :: mult  !  Out -> Multiplicity
22988    !!----    real(kind=cp), dimension(:,:),intent(out) :: orb   !  Out -> List of equivalent positions
22989    !!----    integer,dimension(:),optional,intent(out) :: ptr   !  Out -> Pointer to the symmetry elements
22990    !!----    character(len=*),    optional,intent( in) :: prim  !  In  -> If given, only the primitive cell is considered
22991    !!----    character(len=*),    optional,intent( in) :: symm  !  In  -> If given, the coordinates are normalized as to be -1/2 <= x <1/2
22992    !!----
22993    !!----    Obtain the multiplicity and list of equivalent positions
22994    !!----    (including centring!) modulo integer lattice translations or within the range [-1/2,1/2) if symm is given.
22995    !!----
22996    !!---- Update: June - 2011 (JRC - removing pointer to stabilizer)
22997    !!
22998    Subroutine Get_Orbit(x,Spg,Mult,orb,ptr,prim,symm)
22999       !---- Arguments ----!
23000       real(kind=cp), dimension(3),  intent (in) :: x
23001       type(Space_Group_type),       intent (in) :: spg
23002       integer,                      intent(out) :: mult
23003       real(kind=cp),dimension(:,:), intent(out) :: orb
23004       integer,dimension(:),optional,intent(out) :: ptr
23005       character(len=*),    optional,intent( in) :: prim
23006       character(len=*),    optional,intent( in) :: symm
23007
23008       !---- Local variables ----!
23009       integer                                :: j, nt
23010       real(kind=cp), dimension(3)            :: xx,v
23011       character(len=1)                       :: laty
23012
23013       laty="P"
23014       if(present(prim)) laty=Spg%spg_lat
23015       mult=1
23016       orb(:,1)=x(:)
23017       if(present(ptr)) ptr(mult) = 1
23018       ext: do j=2,Spg%multip
23019          xx=ApplySO(Spg%SymOp(j),x)
23020          xx=modulo_lat(xx)
23021          do nt=1,mult
23022             v=orb(:,nt)-xx(:)
23023             if (Lattice_trans(v,Spg%spg_lat)) then
23024               if (.not. Lattice_trans(v,laty)) cycle  !Count in orbit the centred related atoms
23025               cycle ext
23026             end if
23027          end do
23028          mult=mult+1
23029          orb(:,mult)=xx(:)
23030          if(present(ptr)) ptr(mult) = j   !Effective symop
23031       end do ext
23032
23033       if(present(symm)) then
23034         !Normalize the coordinates to be -1/2 <= x < 1/2
23035         do j=1,Mult
23036           do nt=1,3
23037              if(Orb(nt,j) >= 0.5) Orb(nt,j)= Orb(nt,j) - 1.0
23038           end do
23039         end do
23040       end if
23041
23042       return
23043    End Subroutine Get_Orbit
23044
23045    !!----
23046    !!---- Subroutine Get_Pointgroup_Str(Ipg,Str)
23047    !!----    integer,          intent( in) :: ipg        !  In -> Ordinal number for POINT_GROUP
23048    !!----    character(len=*), intent(out) :: Str        ! Out -> String for Point Group
23049    !!----
23050    !!----    Obtain the string for the Point Group. Error control is present
23051    !!----
23052    !!---- Update: Update: July - 2014: added m3 and m3m for compatibility with Laue_class
23053    !!
23054    Subroutine Get_Pointgroup_Str(Ipg,Str)
23055       !---- Arguments ----!
23056       integer,          intent( in) :: ipg
23057       character(len=*), intent(out) :: str
23058
23059       call init_err_symm()
23060       if (ipg < 1 .or. ipg > 41) then
23061          err_symm=.true.
23062          ERR_Symm_Mess=" Point Group Number Incorrect"
23063       else
23064          str=point_group(ipg)
23065       end if
23066
23067       return
23068    End Subroutine Get_PointGroup_Str
23069
23070    !!--++
23071    !!--++ Subroutine Get_Seitz(N_Op,Tt,Seitz_Symb)
23072    !!--++    integer,                     intent( in) :: n_op          !  In -> Number of the rotational matrix
23073    !!--++    real(kind=cp), dimension(3), intent( in) :: tt            !  In -> Translation part
23074    !!--++    character (len=*),           intent(out) :: Seitz_symb    ! Out -> Seitz Symbol
23075    !!--++
23076    !!--++    (PRIVATE)
23077    !!--++    Provide the Seitz symbol of a symmetry operator.
23078    !!--++    This is mainly for internal use in the module.
23079    !!--++    Run before SearchOp.
23080    !!--++
23081    !!--++ Update: February - 2005
23082    !!
23083    Subroutine Get_Seitz(n_op,tt,Seitz_symb)
23084       !---- Arguments ----!
23085       integer,                     intent( in) :: n_op
23086       real(kind=cp), dimension(3), intent( in) :: tt
23087       character (len=*),           intent(out) :: Seitz_symb
23088
23089       !---- Local variables ----!
23090       character (len=*), dimension(16), parameter  :: fracc =(/" 0 ","1/2","1/3","2/3",    &
23091                        "1/4","3/4","1/6","5/6","1/8","3/8","5/8","7/8","1  ","2  ","3  ","4  "/)
23092       integer :: i,j,ini
23093       real(kind=cp), dimension(16), parameter :: frac= (/0.0, 0.5,1.0/3.0,2.0/3.0,0.25,0.75, &
23094                                                  1.0/6.0,5.0/6.0,0.125,0.375,0.625,0.875,1.0,2.0,3.0,4.0/)
23095
23096       if (hexa) then
23097          Seitz_symb(1:14) ="{"//X_d6h(n_op)(2:13)//"|"
23098          ini=15
23099       else
23100          Seitz_symb(1:10) ="{"//X_Oh(n_op)(2:9)//"|"
23101          ini=11
23102       end if
23103       xyz:do i=1,3
23104          do j=1,16
23105             if (abs(frac(j)-abs(tt(i))) < eps_symm) then
23106                if (tt(i) < 0.0) then
23107                   Seitz_symb(ini:ini+3)="-"//fracc(j)
23108                else
23109                   Seitz_symb(ini:ini+3)=" "//fracc(j)
23110                end if
23111                ini=ini+4
23112                cycle xyz
23113             end if
23114          end do
23115       end do xyz
23116
23117       Seitz_symb(ini:ini)="}"
23118
23119       return
23120    End Subroutine Get_Seitz
23121
23122    !!----
23123    !!---- Subroutine Get_Seitz_Symbol(iop,itim,tr,Seitz_symb)
23124    !!----    integer,                   intent(in) :: iop,itim      !  In -> Number of the rotational matrix, time inversion
23125    !!----    real(kind=cp),dimension(3),intent(in) :: tr            !  In -> Translation part
23126    !!----    character(len=*),          intent(out):: Seitz_symb    ! Out -> Seitz Symbol
23127    !!----
23128    !!----    Provide the Seitz symbol of a symmetry operator. It uses the Litvin notation and
23129    !!----    the ordering is that of Table given by Harold T. Stokes and Branton J. Campbell.
23130    !!----    Hexa should be defined before using this subroutine. This subroutine is intended
23131    !!----    to be used with the reading of Magnetic Space Groups (see CFML_Magnetic_Symmetry)
23132    !!----
23133    !!---- Update: November 2012
23134    !!
23135    Subroutine Get_Seitz_Symbol(iop,itim,tr,Seitz_symb)
23136      integer,                     intent(in) :: iop,itim
23137      real(kind=cp), dimension(3), intent(in) :: tr
23138      character(len=*),            intent(out):: Seitz_symb
23139      !---- Local variables ----!
23140      integer :: i
23141      character(len=25) :: transl
23142      character(len=8)  :: operator_symb
23143      character(len=6)  :: Fracc
23144
23145      if(hexa) then
23146        Operator_symb=Litvin_point_op_hex_label(iop)
23147      else
23148        Operator_symb=Litvin_point_op_label(iop)
23149      end if
23150      transl=" "
23151      do i=1,3
23152        call Get_Fraction_2Dig(tr(i),Fracc)
23153        transl=trim(transl)//trim(Fracc)//","
23154      end do
23155      i=len_trim(transl)
23156      transl(i:i)=" "
23157      do i=1,len_trim(transl)
23158        if(transl(i:i) == "+") transl(i:i)=" "
23159      end do
23160      Seitz_symb="("//trim(operator_symb)//" | "//trim(transl)//")"
23161      Seitz_symb=Pack_String(Seitz_symb)
23162      if(itim == -1)  Seitz_symb=trim(Seitz_symb)//"'"
23163      return
23164    End Subroutine Get_Seitz_Symbol
23165
23166
23167    !!--++
23168    !!--++ Subroutine Get_Setting_Info(Mat,orig,setting,matkind)
23169    !!--++    real(kind=cp), dimension (3,3),intent( in)    :: Mat     ! Matrix transforming the basis
23170    !!--++    real(kind=cp), dimension (  3),intent( in)    :: orig    ! Coordinates of the new origin
23171    !!--++    character (len=*),             intent(out)    :: setting ! String with the new setting
23172    !!--++    character (len=*), optional,   intent( in)    :: matkind ! Type of the input matrix
23173    !!--++
23174    !!--++    (PRIVATE)
23175    !!--++    Subroutine to construct a string with the transformation of the basis
23176    !!--++    corresponding to the matrix "Mat" and new origin "orig"
23177    !!--++    If matkind is given and matkind="it"/"IT", the input matrix is given
23178    !!--++    as in International Tables: (a' b' c') = (a b c) Mat
23179    !!--++    If matkind is not given or if it is not equal to "it"/"IT" the input matrix
23180    !!--++    is the transpose of the International convention (column matrices for basis vectors)
23181    !!--++    An example of the output is: a'=a+c, b'=2b, c'=-a+c  -> Origin: (0,1/4,0)
23182    !!--++
23183    !!--++ Update: February - 2005
23184    !!
23185    Subroutine Get_Setting_Info(Mat,orig,setting,matkind)
23186       !---- Arguments ----!
23187       real(kind=cp), dimension (3,3),intent( in)    :: Mat
23188       real(kind=cp), dimension (  3),intent( in)    :: orig
23189       character (len=*),             intent(out)    :: setting
23190       character (len=*), optional,   intent( in)    :: matkind
23191
23192       !---- local variables ----!
23193       real(kind=cp), dimension (  3), parameter  :: nul = (/ 0.0, 0.0, 0.0/)
23194       real(kind=cp), dimension (3,3)  :: S
23195       character (len=22)     :: tro
23196       integer                :: i
23197
23198       if (present(matkind)) then
23199          if (matkind(1:2) == "it" .or. matkind(1:2) == "IT" ) then
23200             S=transpose(Mat)
23201          else
23202             S=Mat
23203          end if
23204       else
23205          S=Mat
23206       end if
23207
23208       call Get_SymSymb(S,nul,setting)
23209       i=index(setting,",")
23210       setting="a'="//setting(1:i)//" b'="//setting(i+1:)
23211       i=index(setting,",",back=.true.)
23212       setting=setting(1:i)//" c'="//setting(i+1:)
23213       do i=1,len_trim(setting)
23214          if (setting(i:i) == "x")  setting(i:i) = "a"
23215          if (setting(i:i) == "y")  setting(i:i) = "b"
23216          if (setting(i:i) == "z")  setting(i:i) = "c"
23217       end do
23218
23219       call Frac_Trans_2Dig(Orig,tro)
23220       i=len_trim(setting)
23221       setting(i+2:)=" -> Origin: "//trim(tro)
23222
23223       return
23224    End Subroutine Get_Setting_Info
23225
23226    !!----
23227    !!---- Subroutine Get_Shubnikov_Operator_Symbol(Mat,Rot,tr,ShOp_symb,mcif)
23228    !!----   integer, dimension(3,3), intent(in) :: Mat,Rot     ! Symmetry operators for positions and magnetic moments
23229    !!----   real,    dimension(3),   intent(in) :: tr          ! Translation associated to the symmetry operator
23230    !!----   character(len=*),        intent(out):: ShOp_symb   ! String with the Shubnikov operator symbol
23231    !!----   logical,  optional,      intent(in) :: mcif        ! if present the Shubnikov operator is like in mcif: -x,y+1/2,z  mx,-my,-mz +1
23232    !!----
23233    !!---- Subroutine to construct a string with the Shubnikov operator
23234    !!---- in the following form: (-x,y+1/2,-z;u,-v,w)
23235    !!---- It also working for Wyckoff positions, when the matrices Mat and Rot
23236    !!---- are not symmetry operators (det=0). It is extensively used when reading
23237    !!---- the database containing the Magnetic Space Groups provided by
23238    !!---- < Harold T. Stokes and Branton J. Campbell
23239    !!----   Brigham Young University, Provo, Utah, USA
23240    !!----   June 2010 >
23241    !!----
23242    !!---- Updated: November 2012, January 2014
23243    !!----
23244    Subroutine Get_Shubnikov_Operator_Symbol(Mat,Rot,tr,ShOp_symb,mcif)
23245      integer,       dimension(3,3), intent(in) :: Mat,Rot
23246      real(kind=cp), dimension(3),   intent(in) :: tr
23247      character(len=*),              intent(out):: ShOp_symb
23248      logical, optional,             intent(in) :: mcif
23249      !---- Local variables ----!
23250      integer                 :: i,i1,i2,idet
23251      integer, dimension(3,3) :: sMat
23252      character(len=25)       :: xyz_op, uvw_op, mxmymz_op
23253      character(len=2)        :: time_inv
23254
23255      call Get_SymSymb(Mat,tr,xyz_op)
23256      call Get_SymSymb(Rot,(/0.0_cp,0.0_cp,0.0_cp/),uvw_op)
23257
23258      do i=1,len_trim(uvw_op)
23259        if(uvw_op(i:i) == "x")  uvw_op(i:i)="u"
23260        if(uvw_op(i:i) == "y")  uvw_op(i:i)="v"
23261        if(uvw_op(i:i) == "z")  uvw_op(i:i)="w"
23262      end do
23263      i1=index(xyz_op,",")
23264      if(i1 == 1) xyz_op="0"//trim(xyz_op)
23265      i2=index(xyz_op,",",back=.true.)
23266      if(i2 == len_trim(xyz_op)) xyz_op=trim(xyz_op)//"0"
23267      i1=index(xyz_op,",,")
23268      if(i1 /= 0) xyz_op=xyz_op(1:i1)//"0"//xyz_op(i1+1:)
23269
23270      i1=index(uvw_op,",")
23271      if(i1 == 1) uvw_op="0"//trim(uvw_op)
23272      i2=index(uvw_op,",",back=.true.)
23273      if(i2 == len_trim(uvw_op)) uvw_op=trim(uvw_op)//"0"
23274      i1=index(uvw_op,",,")
23275      if(i1 /= 0) uvw_op=uvw_op(1:i1)//"0"//uvw_op(i1+1:)
23276      xyz_op=Pack_string(xyz_op)
23277      uvw_op=Pack_string(uvw_op)
23278      if(present(mcif)) then
23279        idet=determ_A(Mat)
23280        sMat=(idet*Mat-Rot)
23281        if(sum(sMat) == 0) then
23282          time_inv="+1"
23283        else
23284          time_inv="-1"
23285        end if
23286        !Expand the operator uvw_op to convert it to mx,my,mz like
23287        mxmymz_op=" "
23288        do i=1,len_trim(uvw_op)
23289          Select Case(uvw_op(i:i))
23290            case("u")
23291               mxmymz_op=trim(mxmymz_op)//"mx"
23292            case("v")
23293               mxmymz_op=trim(mxmymz_op)//"my"
23294            case("w")
23295               mxmymz_op=trim(mxmymz_op)//"mz"
23296            case default
23297               mxmymz_op=trim(mxmymz_op)//uvw_op(i:i)
23298          End Select
23299        end do
23300        ShOp_symb=trim(xyz_op)//" "//trim(mxmymz_op)//" "//time_inv
23301      else
23302        ShOp_symb="("//trim(xyz_op)//";"//trim(uvw_op)//")"
23303      end if
23304      return
23305    End Subroutine Get_Shubnikov_Operator_Symbol
23306
23307    !!----
23308    !!---- Subroutine Get_So_From_Fix(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Co,Spacegen,lsym)
23309    !!----    integer,                     intent(out) :: ISYSTM    ! Out -> Number of the crystalline system
23310    !!----                                                          ! Out    (1:T, 2:M, 3:O, 4:T, 5:R-Trg, 6:H, 7:C)
23311    !!----    integer,                     intent(out) :: ISYMCE    ! Out -> 0 Centric (-1 not at origin)
23312    !!----                                                                   1 Acentric
23313    !!----                                                                   2 Centric (-1 at origin)
23314    !!----    integer,                     intent(out) :: IBRAVL    ! Out -> Index of the Bravais Lattice type
23315    !!----                                                                   1   2   3   4   5   6   7   8
23316    !!----                                                                   "P","A","B","C","I","R","F","Z"
23317    !!----    integer,                     intent(in ) :: NG        !  In -> Number of symmetry operators
23318    !!----    real(kind=cp),dimension(:,:),intent(in ) :: TS        !  In -> Translation parts of the symmetry operators(3,48)
23319    !!----    integer, dimension(:,:,:),   intent(in ) :: SS        !  In -> Rotation parts of the symmetry operators (3,3,48)
23320    !!----    character (len=2),           intent(out) :: latsy     ! Out -> Bravais Lattice symbol
23321    !!----    real(kind=cp),dimension(3)  ,intent(out) :: Co        ! Out -> Coordinates of origin
23322    !!----    character (len=1),           intent(out) :: SpaceGen  ! Out -> Type of Cell
23323    !!----    character (len=1),           intent(in)  :: lsym      ! In  -> Type of Cell forced
23324    !!----
23325    !!----    Determines some of items of the object Space_Group_Type from FIXed
23326    !!----    symmetry operators given by user.
23327    !!----
23328    !!---- Update: February - 2005
23329    !!
23330    Subroutine Get_SO_from_FIX(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Co,SpaceGen,lsym)
23331       !---- Arguments ----!
23332       integer,                      intent(out) :: Isystm
23333       integer,                      intent(out) :: Isymce
23334       integer,                      intent(out) :: Ibravl
23335       integer,                      intent(in ) :: Ng
23336       integer, dimension(:,:,:),    intent(in ) :: Ss  !(3,3,48)
23337       real(kind=cp),dimension(:,:), intent(in ) :: Ts  !(3  ,48)
23338       character (len= 2),           intent(out) :: Latsy
23339       real(kind=cp),dimension(3),   intent(out) :: Co
23340       character (len= 1),           intent(out) :: SpaceGen
23341       character (len= 1),optional,  intent(in ) :: lsym
23342
23343       !---- Local Variables ----!
23344       logical :: latt_p, latt_a, latt_b, latt_c, latt_i, latt_r, latt_f, latt_z
23345
23346       character(len=*), dimension(8),  parameter :: red = &
23347                         (/"P","A","B","C","I","R","F","Z"/)
23348
23349       integer, dimension(3,6), parameter :: lattice=reshape((/0,6,6, 6,0,6, &
23350                                                   6,6,0, 6,6,6, 8,4,4, 4,8,8/),(/3,6/))
23351
23352       integer, dimension(4,4), parameter :: identidad = reshape((/1, 0, 0, 0, &
23353                                                                   0, 1, 0, 0, &
23354                                                                   0, 0, 1, 0, &
23355                                                                   0, 0, 0, 1/),(/4,4/))
23356       integer, dimension(6)          :: latt_given
23357       real(kind=cp), dimension(3,11) :: latc
23358       integer, dimension(3)          :: tt
23359       integer                        :: i,j,l
23360
23361       !---- Initializing ----!
23362
23363       isystm  = 0
23364       isymce  = 1
23365       ibravl  = 0
23366       co      = 0.0
23367       latsy   = " "
23368       SpaceGen= " "
23369       if(present(lsym)) then
23370         if(.not. (lsym == "P" .or. lsym=="p")) SpaceGen=lsym
23371       end if
23372
23373       if(len_trim(SpaceGen) == 0) then  !Test lattice translation only if lsym has not been provided
23374          latt_p=.true.                  !or if lsym="P"
23375          latt_a=.false.
23376          latt_b=.false.
23377          latt_c=.false.
23378          latt_i=.false.
23379          latt_r=.false.
23380          latt_f=.false.
23381          latt_z=.false.
23382
23383
23384          !---- Determine the type of lattice ----!
23385          !---- This is only in case an explicit translation generator is given.
23386          l=0
23387          do i=1,ng
23388             if (equal_matrix(ss(:,:,i),identidad(1:3,1:3),3)) then
23389                tt(1)=nint(12.0 * ts(1,i))   ! Translations x 12
23390                tt(2)=nint(12.0 * ts(2,i))
23391                tt(3)=nint(12.0 * ts(3,i))
23392
23393                !---- Identity (I,0) is being processed ----!
23394                if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) cycle
23395
23396                !---- Compare the translation part of the operator with tabulated array ----!
23397                l=l+1  !counts the number of non trivial centring vectors
23398                latt_given(:) = 0
23399                do j=1,6
23400                   if (equal_vector(tt,lattice(:,j),3)) then
23401                      latt_given(j)=1
23402                      select case (j)
23403                         case (1)
23404                            latt_a=.true.
23405                         case (2)
23406                            latt_b=.true.
23407                         case (3)
23408                            latt_c=.true.
23409                         case (4)
23410                            latt_i=.true.
23411                         case (5,6)
23412                            latt_r=.true.
23413                      end select
23414                      exit
23415                   end if
23416                end do
23417                latc(:,L) = ts(:,i)
23418                if(sum(latt_given) == 0) latt_z=.true.
23419             end if
23420          end do
23421
23422          !---- Lattice Type ----!
23423          if ( (latt_a .and. latt_b .and. latt_c) .or. (latt_a .and. latt_b) .or. &
23424               (latt_a .and. latt_c) .or. (latt_b .and. latt_c) ) then
23425             latt_f=.true.
23426             latt_a=.false.
23427             latt_b=.false.
23428             latt_c=.false.
23429             latt_p=.false.
23430             latt_i=.false.
23431          end if
23432
23433          if (latt_p) then
23434             SpaceGen="P"
23435             Ibravl  = 1
23436          end if
23437          if (latt_a) then
23438             SpaceGen="A"
23439             Ibravl  = 2
23440          end if
23441          if (latt_b) then
23442             SpaceGen="B"
23443             Ibravl  = 3
23444          end if
23445          if (latt_c) then
23446             SpaceGen="C"
23447             Ibravl  = 4
23448          end if
23449          if (latt_i) then
23450             SpaceGen="I"
23451             Ibravl  = 5
23452          end if
23453          if (latt_r) then
23454             SpaceGen="R"
23455             Ibravl  = 6
23456          end if
23457          if (latt_f) then
23458             SpaceGen="F"
23459             Ibravl  = 7
23460          end if
23461          if (latt_z) then
23462             SpaceGen="Z"
23463             Ibravl  = 8
23464          end if
23465       end if
23466
23467       if (len_trim(SpaceGen) /= 0) then
23468          call latsym(SpaceGen,L,latc)
23469       else
23470          err_symm=.true.
23471          ERR_Symm_Mess=" Lattice Type couldn't be determined"
23472          return
23473       end if
23474
23475       !---- Centre of symmetry ? ----!
23476       do i=1,ng
23477          if (equal_matrix(ss(:,:,i),-identidad(1:3,1:3),3)) then
23478             tt(1)=nint(12.0 * ts(1,i))
23479             tt(2)=nint(12.0 * ts(2,i))
23480             tt(3)=nint(12.0 * ts(3,i))
23481
23482             if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) then
23483                isymce=2       ! Centric with -1 at origin
23484             else
23485                isymce=0       ! Centric without -1 at origin
23486                co=0.5*ts(:,i)
23487             end if
23488          end if
23489       end do
23490
23491       !---- Determination of the crystalline system and Bravais lattice ----!
23492       call get_crystal_System(ng,ss,isystm,latsy(1:1))
23493       latsy(2:)=red(ibravl)
23494
23495       return
23496    End Subroutine Get_So_From_Fix
23497
23498    !!----
23499    !!---- Subroutine Get_So_From_Gener(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Co,Num_G,Spacegen)
23500    !!----    integer,                      intent(out)   :: ISYSTM    ! Out -> Number of the crystalline system
23501    !!----                                                                      (1:T, 2:M, 3:O, 4:T, 5:R-Trg, 6:H, 7:C)
23502    !!----    integer,                      intent(out)   :: ISYMCE    ! Out -> 0 Centric (-1 not at origin)
23503    !!----                                                                      1 Acentric
23504    !!----                                                                      2 Centric (-1 at origin)
23505    !!----    integer,                      intent(out)   :: IBRAVL    ! Out -> Index of the Bravais Lattice type
23506    !!----                                                                      1   2   3   4   5   6   7   8
23507    !!----                                                                      "P","A","B","C","I","R","F","Z"
23508    !!----    integer,                      intent(in out):: NG        !  In -> Number of defined generators
23509    !!----                                                             ! Out -> Number of symmetry operators
23510    !!----    integer, dimension(:,:,:),    intent(in out):: SS        !  In -> Rotation parts of the given generators  (3,3,48)
23511    !!----                                                             ! Out -> Rotation parts of the symmetry operators
23512    !!----    real(kind=cp),dimension(:,:), intent(in out):: TS        !  In -> Translation parts of the given generators  (3,48)
23513    !!----                                                             ! Out -> Translation parts of the symmetry operators
23514    !!----    character (len=2),            intent(out)   :: latsy     ! Out -> Bravais Lattice symbol
23515    !!----    real(kind=cp),dimension(3),   intent(out)   :: Co        ! Out -> Coordinates of origin
23516    !!----    integer,                      intent(out)   :: Num_g     ! Out -> Minimum number of generators
23517    !!----    character (len=1),            intent(out)   :: SpaceGen  ! Out -> Type of Cell
23518    !!----
23519    !!----    Calculates the whole set of symmetry operators from a set of given generators.
23520    !!----
23521    !!---- Update: February - 2005, February-2014 (JRC)
23522    !!
23523    Subroutine Get_SO_from_Gener(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Co,Num_g,SpaceGen,num_lat,lat_cent)
23524       !---- Arguments ----!
23525       integer,                                              intent(   out) :: Isystm
23526       integer,                                              intent(   out) :: Isymce
23527       integer,                                              intent(   out) :: Ibravl
23528       integer,                                              intent(in out) :: Ng
23529       integer, dimension(:,:,:),                            intent(in out) :: Ss ! (3,3,48)
23530       real(kind=cp),dimension(:,:),                         intent(in out) :: Ts ! (3  ,48)
23531       character (len=*),                                    intent(   out) :: Latsy
23532       real(kind=cp),dimension(3),                           intent(   out) :: Co
23533       integer,                                              intent(   out) :: Num_g
23534       character (len=*),                                    intent(   out) :: SpaceGen
23535       integer, optional,                                    intent(   out) :: num_lat
23536       real(kind=cp), dimension(:,:), allocatable, optional, intent(   out) :: lat_cent
23537
23538       !---- Local Variables ----!
23539       real(kind=cp),dimension(3,192)  :: latc
23540       integer                         :: nlat_t
23541       logical :: latt_p, latt_a, latt_b, latt_c, latt_i, latt_r, latt_f, latt_z
23542       integer, dimension(6) :: latt_given
23543       character(len=*), dimension(8),  parameter :: red = &
23544                           (/"P","A","B","C","I","R","F","Z"/)
23545       integer, dimension(3,192)          :: lat_trans
23546       integer, dimension(3)              :: txyz
23547       integer, dimension(3,6), parameter :: lattice=reshape((/0,6,6, 6,0,6, &
23548                                                     6,6,0, 6,6,6, 8,4,4, 4,8,8/),(/3,6/))
23549       integer, dimension(4,4), parameter :: identidad = reshape((/1, 0, 0, 0, &
23550                                                                   0, 1, 0, 0, &
23551                                                                   0, 0, 1, 0, &
23552                                                                   0, 0, 0, 1/),(/4,4/))
23553       integer, dimension(4,4), parameter :: nulo      = reshape((/0, 0, 0, 0, &
23554                                                                   0, 0, 0, 0, &
23555                                                                   0, 0, 0, 0, &
23556                                                                   0, 0, 0, 0/),(/4,4/))
23557       integer, parameter             :: num_tab=24
23558       integer, dimension(4,4,num_tab):: tabla
23559       integer, dimension(4,4)        :: m1,m2
23560       integer, dimension(3)          :: tt,tt1
23561       real(kind=cp), parameter       :: lat_norm=12.0  !a multiple of 12 is compulsory
23562       integer,       parameter       :: ilat_norm=12, ilat_fact=ilat_norm*4
23563       integer :: i,j,k,n,nop,nopp,ipos,nt,ntp,L,jcen
23564       integer :: tx, ty, tz
23565       logical :: cen_found
23566
23567       !---- Initializing ----!
23568       nop     = ng
23569       isystm  = 0
23570       isymce  = 1
23571       ibravl  = 0
23572       co      = 0.0
23573       latsy   = " "
23574       SpaceGen=" "
23575
23576       latt_p=.true.
23577       latt_a=.false.
23578       latt_b=.false.
23579       latt_c=.false.
23580       latt_i=.false.
23581       latt_r=.false.
23582       latt_f=.false.
23583       latt_z=.false.
23584       !Set to zero all previous centring vectors
23585       nlat=0
23586       Ltr=0.0_cp
23587
23588       !---- Redundances ----!
23589       do i=1,nop
23590          if (equal_matrix(ss(:,:,i),      nulo(1:3,1:3),3)) cycle  !ignore zero matrices
23591          if (equal_matrix(ss(:,:,i), identidad(1:3,1:3),3)) cycle  !Do not consider lattice translations
23592          if (equal_matrix(ss(:,:,i),-identidad(1:3,1:3),3)) cycle  !Do not consider inversion centre
23593          do j=i+1,nop
23594             if (equal_matrix(ss(:,:,j),      nulo(1:3,1:3),3)) cycle
23595             if (equal_matrix(ss(:,:,j), identidad(1:3,1:3),3)) cycle
23596             if (equal_matrix(ss(:,:,j),-identidad(1:3,1:3),3)) cycle
23597
23598             !---- Traslation part ----!
23599             if (equal_matrix(ss(:,:,i),ss(:,:,j),3)) then
23600                tt =nint(lat_norm * ts(:,i))
23601                tt1=nint(lat_norm * ts(:,j))
23602
23603                tx=mod(tt(1)-tt1(1)+ilat_fact,ilat_norm)        !?????????
23604                ty=mod(tt(2)-tt1(2)+ilat_fact,ilat_norm)
23605                tz=mod(tt(3)-tt1(3)+ilat_fact,ilat_norm)
23606
23607                if (tx == 0 .and. ty == 0 .and. tz == 0) then
23608                   ss(:,:,j)=0
23609                   ts(:,j)=0.0
23610                   cycle
23611                else
23612                   tx=mod(tt(1)+tt1(1)+ilat_fact,ilat_norm)
23613                   ty=mod(tt(2)+tt1(2)+ilat_fact,ilat_norm)
23614                   tz=mod(tt(3)+tt1(3)+ilat_fact,ilat_norm)
23615
23616                   if (tx == 0 .and. ty == 0 .and. tz == 0) then
23617                      ss(:,:,j)=0
23618                      ts(:,j)=0.0
23619                      cycle
23620                   else
23621                      ss(:,:,j)=identidad(1:3,1:3)
23622                      ts(1,j)=real(tx)/lat_norm
23623                      ts(2,j)=real(ty)/lat_norm
23624                      ts(3,j)=real(tz)/lat_norm
23625                      cycle
23626                   end if
23627                end if
23628             end if
23629
23630             !---- Inversion part ----!
23631             if (equal_matrix(ss(:,:,i),-ss(:,:,j),3)) then
23632                tt =nint(lat_norm * ts(:,i))
23633                tt1=nint(lat_norm * ts(:,j))
23634
23635                tx=mod(tt(1)-tt1(1)+ilat_fact,ilat_norm)        !?????????
23636                ty=mod(tt(2)-tt1(2)+ilat_fact,ilat_norm)
23637                tz=mod(tt(3)-tt1(3)+ilat_fact,ilat_norm)
23638
23639                if (tx == 0 .and. ty == 0 .and. tz == 0) then
23640                   ss(:,:,j)=-identidad(1:3,1:3)
23641                   ts(:,j)=0.0
23642                   cycle
23643                else
23644                   tx=mod(tt(1)+tt1(1)+ilat_fact,ilat_norm)
23645                   ty=mod(tt(2)+tt1(2)+ilat_fact,ilat_norm)
23646                   tz=mod(tt(3)+tt1(3)+ilat_fact,ilat_norm)
23647
23648                   if (tx == 0 .and. ty == 0 .and. tz == 0) then
23649                      ss(:,:,j)=-identidad(1:3,1:3)
23650                      ts(:,j)=0.0
23651                      cycle
23652                   else
23653                      ss(:,:,j)=-identidad(1:3,1:3)
23654                      ts(1,j)=real(tx)/lat_norm
23655                      ts(2,j)=real(ty)/lat_norm
23656                      ts(3,j)=real(tz)/lat_norm
23657                      cycle
23658                   end if
23659                end if
23660             end if
23661
23662          end do
23663       end do
23664
23665       !---- Determine the type of lattice before starting generation ----!
23666       !---- This is only in case an explicit translation generator is given.
23667       !---- This block construct the lattice vectors and remove the corresponding operators
23668       L=0
23669       do i=1,nop
23670          if (equal_matrix(ss(:,:,i),identidad(1:3,1:3),3)) then
23671             tt=nint(lat_norm * ts(:,i))   ! Translations x 12
23672
23673             !---- Identity (I,0) is being processed ----!
23674             if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) then
23675                ss(:,:,i)=0
23676                ts(:,i)=0.0
23677                cycle
23678             end if
23679             !---- Compare the translation part of the operator with tabulated array ----!
23680             L=L+1  !counts the number of non trivial centring vectors
23681             latt_given(:) = 0
23682             do j=1,6
23683                if (equal_vector(tt,(ilat_norm/12)*lattice(:,j),3)) then
23684                   latt_given(j) = 1
23685                   select case (j)
23686                      case (1)
23687                         latt_a=.true.
23688                      case (2)
23689                         latt_b=.true.
23690                      case (3)
23691                         latt_c=.true.
23692                      case (4)
23693                         latt_i=.true.
23694                      case (5,6)
23695                         latt_r=.true.
23696                   end select
23697                   exit
23698                end if
23699             end do
23700             latc(:,L) = ts(:,i)
23701             ss(:,:,i)=0   !Removing the operators with pure translations
23702             ts(:,i)=0.0
23703             if(sum(latt_given) == 0) latt_z = .true.
23704          end if
23705       end do
23706
23707       !---- Lattice Type ----!
23708       if ( (latt_a .and. latt_b .and. latt_c) .or. (latt_a .and. latt_b) .or. &
23709            (latt_a .and. latt_c) .or. (latt_b .and. latt_c) ) then
23710          latt_f=.true.
23711          latt_a=.false.
23712          latt_b=.false.
23713          latt_c=.false.
23714          latt_p=.false.
23715          latt_i=.false.
23716       end if
23717       if(latt_f .and. latt_r) latt_z=.true.
23718       if(latt_i .and. latt_r) latt_z=.true.
23719       if(latt_a .and. latt_r) latt_z=.true.
23720       if(latt_b .and. latt_r) latt_z=.true.
23721       if(latt_c .and. latt_r) latt_z=.true.
23722
23723       if(latt_z) then
23724          latt_f=.false.
23725          latt_a=.false.
23726          latt_b=.false.
23727          latt_c=.false.
23728          latt_p=.false.
23729          latt_i=.false.
23730          latt_r=.false.
23731       end if
23732
23733       if (latt_p) then
23734          SpaceGen="P"
23735          Ibravl  = 1
23736          nlat_t=0
23737       end if
23738       if (latt_a) then
23739          SpaceGen="A"
23740          Ibravl  = 2
23741          nlat_t=1
23742          latc(:,1)=(/0.0,0.5,0.5/)
23743       end if
23744       if (latt_b) then
23745          SpaceGen="B"
23746          Ibravl  = 3
23747          nlat_t=1
23748          latc(:,1)=(/0.5,0.0,0.5/)
23749       end if
23750       if (latt_c) then
23751          SpaceGen="C"
23752          Ibravl  = 4
23753          nlat_t=1
23754          latc(:,1)=(/0.5,0.5,0.0/)
23755       end if
23756       if (latt_i) then
23757          SpaceGen="I"
23758          Ibravl  = 5
23759          nlat_t=1
23760          latc(:,1)=(/0.5,0.5,0.5/)
23761       end if
23762       if (latt_r) then
23763          SpaceGen="R"
23764          Ibravl  = 6
23765          nlat_t=2
23766          latc(:,1)=(/ 2.0/3.0, 1.0/3.0, 1.0/3.0 /)
23767          latc(:,2)=(/ 1.0/3.0, 2.0/3.0, 2.0/3.0 /)
23768       end if
23769       if (latt_f) then
23770          SpaceGen="F"
23771          Ibravl  = 7
23772          nlat_t=3
23773          latc(:,1)=(/0.5,0.5,0.0/)
23774          latc(:,2)=(/0.5,0.0,0.5/)
23775          latc(:,3)=(/0.0,0.5,0.5/)
23776       end if
23777       if (latt_z) then
23778          Ibravl  = 8
23779          !Determine here the total number of non-trivial centring vectors
23780          call get_centring_vectors(L,latc,SpaceGen)
23781          nlat_t=L
23782          do i=1,nlat_t
23783             lat_trans(:,i)=maxval(nint(lat_norm*latc(:,i)))
23784          end do
23785       end if
23786
23787       if(present(num_lat) .and. present(lat_cent)) then
23788         num_lat=nlat_t
23789         if(allocated(lat_cent)) deallocate(lat_cent)
23790         allocate(lat_cent(3,num_lat))
23791         lat_cent(:,1:num_lat)=latc(:,1:num_lat)
23792       end if
23793
23794       if (len_trim(SpaceGen) /= 0) then
23795          !write(*,"(a)") " => Lattice centrings at Get_SO_from_Gener: "
23796          !do i=1,nlat_t
23797          !   write(*,"(i8,3f14.5)")i,latc(:,i)
23798          !end do
23799          call latsym(SpaceGen,nlat_t,latc)
23800       else
23801          err_symm=.true.
23802          ERR_Symm_Mess=" Lattice Type couldn't be determined"
23803          return
23804       end if
23805
23806       !---- Removing Centre of symmetry if found ----!
23807       do i=1,nop
23808          if (equal_matrix(ss(:,:,i),-identidad(1:3,1:3),3)) then
23809             tt=nint(lat_norm * ts(:,i))
23810
23811             if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) then
23812                isymce=2       ! Centric with -1 at origin
23813             else
23814                if(isymce /= 2) then !do that only if a centre has not been found at the origin
23815                  isymce=0       ! Centric without -1 at origin
23816                  co=0.5*ts(:,i)
23817                end if
23818             end if
23819             ss(:,:,i)=0
23820             ts(:,i)=0.0
23821          end if
23822       end do
23823
23824       !---- Purge the starting list of generators ----!
23825       !     by diminishing the number of generators to the strictly
23826       !     assymmetric block without translations and centre
23827       nopp=nop
23828       ipos=1
23829       do
23830          do i=ipos,nopp
23831             if (equal_matrix(ss(:,:,i),nulo(1:3,1:3),3)) then
23832                do j=i+1,nopp
23833                   ss(:,:,j-1)= ss(:,:,j)
23834                   ts(:,j-1)  = ts(:,j)
23835                end do
23836                ss(:,:,nopp)=0
23837                ts(:,nopp)=0.0
23838                nopp=nopp-1
23839                ipos=i
23840                exit
23841             end if
23842          end do
23843          if (i >= nopp) exit
23844       end do
23845       if (equal_matrix(ss(:,:,nopp),nulo(1:3,1:3),3)) nopp=nopp-1
23846       nop=nopp    !nop is the number of generators without centre of symmetry
23847                   !and lattice centrings
23848
23849       !---- Now we have an eventually shorter list of generators and we
23850       !---- know if a centre of symmetry or lattice centrings were
23851       !---- among the given generators.
23852
23853       !---- Creation of the symmetry operators table ----!
23854       !write(*,"(a,i6)") " => Number of generators (no centre/no lattice) to start the table: ",nop
23855       !do i=1,nop
23856       !  write(*,"(9i4,3f8.4)") ss(:,:,i), ts(:,i)
23857       !end do
23858       !---- Initializing ----!
23859       nt=1
23860       tabla=0
23861       tabla(4,4,:)=1
23862       do i=1,4               !---- Identity operator is the first one ----!
23863          tabla(i,i,1)=1
23864       end do
23865
23866       !---- Put operators in the table ----!
23867       do i=1,nop
23868          nt=nt+1
23869          tabla(1:3,1:3,nt)= ss(:,:,i)
23870          tabla(1:3,4,nt)  = mod(nint(lat_norm*ts(1:3,i))+ilat_fact,ilat_norm)
23871       end do
23872
23873       num_g=nop   !Minimum number of generators (except inversion)
23874
23875       !---- Generate power operations from generators ----!
23876       do i=2,nt
23877             ntp=axes_rotation(tabla(1:3,1:3,i))    ! Determine the order of the generator
23878          if (ntp == -1 .or. ntp == -3) then
23879             ntp=-2*ntp
23880          else
23881             ntp=abs(ntp)
23882          end if
23883
23884          m1=tabla(:,:,i)
23885          m2=identidad
23886
23887          p1:do j=1,ntp-1
23888             m2=matmul(m2,m1)
23889             m2(:,4)=mod(m2(:,4)+ilat_fact,ilat_norm)
23890
23891             !---- Check if the generated operation is already in the table
23892             do k=1,nt
23893                if (equal_matrix(tabla(:,:,k),m2,4)) cycle p1
23894             end do
23895
23896             !---- Eliminating lattice contribution if necessary ----!
23897             select case (ibravl)
23898                 case (2)
23899                    ty=m2(2,4)
23900                    tz=m2(3,4)
23901                    if (ty >= 6 .and. tz >= 6) then
23902                       ty=mod(m2(2,4),6)
23903                       tz=mod(m2(3,4),6)
23904
23905                       if (ty == 0 .and. tz == 0) then
23906                          cycle p1
23907                       else
23908                          m2(2,4)=ty
23909                          m2(3,4)=tz
23910                       end if
23911                    end if
23912
23913                 case (3)
23914                    tx=m2(1,4)
23915                    tz=m2(3,4)
23916                    if (tx >= 6 .and. tz >=6) then
23917                       tx=mod(m2(1,4),6)
23918                       tz=mod(m2(3,4),6)
23919
23920                       if (tx == 0 .and. tz == 0) then
23921                          cycle p1
23922                       else
23923                          m2(1,4)=tx
23924                          m2(3,4)=tz
23925                       end if
23926                    end if
23927
23928                 case (4)
23929                    tx=m2(1,4)
23930                    ty=m2(2,4)
23931                    if (tx >=6 .and. ty >= 6) then
23932                       tx=mod(m2(1,4),6)
23933                       ty=mod(m2(2,4),6)
23934
23935                       if (tx == 0 .and. ty == 0) then
23936                          cycle p1
23937                       else
23938                          m2(1,4)=tx
23939                          m2(2,4)=ty
23940                       end if
23941                    end if
23942
23943                 case (5)
23944                    tx=m2(1,4)
23945                    ty=m2(2,4)
23946                    tz=m2(3,4)
23947                    if (tx >=6 .and. ty >=6 .and. tz >=6) then
23948                       tx=mod(m2(1,4),6)
23949                       ty=mod(m2(2,4),6)
23950                       tz=mod(m2(3,4),6)
23951
23952                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
23953                          cycle p1
23954                       else
23955                          m2(1,4)=tx
23956                          m2(2,4)=ty
23957                          m2(3,4)=tz
23958                       end if
23959                    end if
23960
23961                 case (6)
23962                    tx=m2(1,4)
23963                    ty=m2(2,4)
23964                    tz=m2(3,4)
23965                    if (tx >=8 .and. ty >=4 .and. tz >=4) then
23966                       tx=mod(m2(1,4),8)
23967                       ty=mod(m2(2,4),4)
23968                       tz=mod(m2(3,4),4)
23969                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
23970                          cycle p1
23971                       else
23972                          m2(1,4)=tx
23973                          m2(2,4)=ty
23974                          m2(3,4)=tz
23975                       end if
23976
23977                    else if (tx >=4 .and. ty >=8 .and. tz >=8) then
23978                       tx=mod(m2(1,4),4)
23979                       ty=mod(m2(2,4),8)
23980                       tz=mod(m2(3,4),8)
23981                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
23982                          cycle p1
23983                       else
23984                          m2(1,4)=tx
23985                          m2(2,4)=ty
23986                          m2(3,4)=tz
23987                       end if
23988                    end if
23989
23990                 case (7)
23991                    tx=m2(1,4)
23992                    ty=m2(2,4)
23993                    tz=m2(3,4)
23994                    if (ty >= 6 .and. tz >=6) then
23995                       ty=mod(m2(2,4),6)
23996                       tz=mod(m2(3,4),6)
23997                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
23998                          cycle p1
23999                       else
24000                          m2(2,4)=ty
24001                          m2(3,4)=tz
24002                       end if
24003                    else if (tx >=6 .and. tz >=6) then
24004                       tx=mod(m2(1,4),6)
24005                       tz=mod(m2(3,4),6)
24006                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24007                          cycle p1
24008                       else
24009                          m2(1,4)=tx
24010                          m2(3,4)=tz
24011                       end if
24012                    else if (tx >=6 .and. ty >=6) then
24013                       tx=mod(m2(1,4),6)
24014                       ty=mod(m2(2,4),6)
24015                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24016                          cycle p1
24017                       else
24018                          m2(1,4)=tx
24019                          m2(2,4)=ty
24020                       end if
24021                    end if
24022
24023                 Case(8)
24024                    !eliminate translations
24025                    txyz=m2(1:3,4)
24026                    do k=1,nlat_t
24027                       if(txyz(1) >= lat_trans(1,k) .and. txyz(2) >= lat_trans(2,k) .and. txyz(3) >= lat_trans(3,k)) then
24028                          txyz(:)=mod(m2(1:3,4), lat_trans(:,k))
24029                          if(txyz(1) == 0 .and. txyz(2) == 0 .and.txyz(3) == 0 ) then
24030                             cycle p1
24031                          else
24032                              m2(1:3,4)=txyz(:)
24033                          end if
24034                       end if
24035                    end do
24036
24037             end select
24038
24039             nt=nt+1
24040             if (nt > num_tab) then
24041                err_symm=.true.
24042                ERR_Symm_Mess=" Dimension of Table exceeded (I)"
24043                return
24044             end if
24045             tabla(:,:,nt)=m2
24046          end do p1
24047
24048       end do
24049
24050       !write(*,"(a,i6)") " => Number of terms in the table at stage I: ",nt
24051       !do i=1,nt
24052       !  write(*,"(9i3,3i6)") tabla(1:3,1:3,i),tabla(1:3,4,i)
24053       !end do
24054       !write(*,"(//a//)") " => MULTIPLICATION OF GENERATORS: "
24055
24056       !---- Multiplications between generators ----!
24057       do
24058          if (nt == 1) exit
24059          n=nt
24060
24061          do i=1,n
24062             p2:do j=i,n
24063
24064                m2=matmul(tabla(:,:,i),tabla(:,:,j))
24065                m2(:,4)=mod(m2(:,4)+ilat_fact,ilat_norm)
24066
24067                !---- Eliminating lattice contribution if necessary ----!
24068                select case (ibravl)
24069                   case (2)
24070                      ty=m2(2,4)
24071                      tz=m2(3,4)
24072                      if (ty >= 6 .and. tz >= 6) then
24073                         m2(2,4)=mod(m2(2,4),6)
24074                         m2(3,4)=mod(m2(3,4),6)
24075                      end if
24076
24077                   case (3)
24078                      tx=m2(1,4)
24079                      tz=m2(3,4)
24080                      if (tx >= 6 .and. tz >= 6) then
24081                         m2(1,4)=mod(m2(1,4),6)
24082                         m2(3,4)=mod(m2(3,4),6)
24083                      end if
24084
24085                   case (4)
24086                      tx=m2(1,4)
24087                      ty=m2(2,4)
24088                      if (tx >= 6 .and. ty >= 6) then
24089                         m2(1,4)=mod(m2(1,4),6)
24090                         m2(2,4)=mod(m2(2,4),6)
24091                      end if
24092
24093                   case (5)
24094                      tx=m2(1,4)
24095                      ty=m2(2,4)
24096                      tz=m2(3,4)
24097                      if (tx >= 6 .and. ty >= 6 .and. tz >= 6) then
24098                         m2(1,4)=mod(m2(1,4),6)
24099                         m2(2,4)=mod(m2(2,4),6)
24100                         m2(3,4)=mod(m2(3,4),6)
24101                      end if
24102
24103                   case (6)
24104                      tx=m2(1,4)
24105                      ty=m2(2,4)
24106                      tz=m2(3,4)
24107                      if (tx >=8 .and. ty >=4 .and. tz >=4) then
24108                         m2(1,4)=mod(m2(1,4),8)
24109                         m2(2,4)=mod(m2(2,4),4)
24110                         m2(3,4)=mod(m2(3,4),4)
24111                      else if (tx >=4 .and. ty >=8 .and. tz >=8) then
24112                         m2(1,4)=mod(m2(1,4),4)
24113                         m2(2,4)=mod(m2(2,4),8)
24114                         m2(3,4)=mod(m2(3,4),8)
24115                      end if
24116
24117                   case (7)
24118                      tx=m2(1,4)
24119                      ty=m2(2,4)
24120                      tz=m2(3,4)
24121                      if (ty >= 6 .and. tz >=6) then
24122                         m2(2,4)=mod(m2(2,4),6)
24123                         m2(3,4)=mod(m2(3,4),6)
24124                      else if (tx >=6 .and. tz >=6) then
24125                         m2(1,4)=mod(m2(1,4),6)
24126                         m2(3,4)=mod(m2(3,4),6)
24127                      else if (tx >=6 .and. ty >=6) then
24128                         m2(1,4)=mod(m2(1,4),6)
24129                         m2(2,4)=mod(m2(2,4),6)
24130                      end if
24131
24132                   case(8)
24133
24134                      txyz=m2(1:3,4)
24135                      do k=1,nlat_t
24136                         if(txyz(1) >= lat_trans(1,k) .and. txyz(2) >= lat_trans(2,k) .and. txyz(3) >= lat_trans(3,k)) then
24137                            m2(1:3,4)=mod(m2(1:3,4), lat_trans(:,k))
24138                         end if
24139                      end do
24140
24141                end select
24142
24143                do k=1,nt
24144                   if ( equal_matrix(m2(:,:),tabla(:,:,k),4) ) cycle p2
24145                   if ( equal_matrix(m2(:,:),tabla(:,:,k),3) ) then
24146                      tx=m2(1,4)+tabla(1,4,k)
24147                      ty=m2(2,4)+tabla(2,4,k)
24148                      tz=m2(3,4)+tabla(3,4,k)
24149                      tx=mod(tx,ilat_norm)
24150                      ty=mod(ty,ilat_norm)
24151                      tz=mod(tz,ilat_norm)
24152                      select case (ibravl)
24153                          case (2)
24154                             if (ty == 6 .and. tz == 6) cycle p2
24155                             if (ty == 0 .and. tz == 0) cycle p2
24156
24157                          case (3)
24158                             if (tx == 6 .and. tz == 6) cycle p2
24159                             if (tx == 0 .and. tz == 0) cycle p2
24160
24161                          case (4)
24162                             if (tx == 6 .and. ty == 6) cycle p2
24163                             if (tx == 0 .and. ty == 0) cycle p2
24164
24165                          case (5)
24166                             if (tx == 6 .and. ty == 6 .and. tz == 6) cycle p2
24167                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
24168
24169                          case (6)
24170                             if (tx == 8 .and. ty == 4 .and. tz == 4) cycle p2
24171                             if (tx == 4 .and. ty == 8 .and. tz == 8) cycle p2
24172                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
24173
24174                          case (7)
24175                             if (ty == 6 .and. tz == 6) cycle p2
24176                             if (tx == 6 .and. tz == 6) cycle p2
24177                             if (tx == 6 .and. ty == 6) cycle p2
24178
24179                             if (ty == 0 .and. tz == 0) cycle p2
24180                             if (tx == 0 .and. tz == 0) cycle p2
24181                             if (tx == 0 .and. ty == 0) cycle p2
24182
24183                          case (8)
24184                             txyz=(/tx,ty,tz/)
24185                             if(txyz(1) == 0 .and. txyz(2) == 0 .and. txyz(3) == 0) cycle p2
24186                             do l=1,nlat_t
24187                               if(txyz(1)==lat_trans(1,l) .and. txyz(2)==lat_trans(2,l) .and. txyz(3)==lat_trans(3,l)) cycle p2
24188                             end do
24189
24190                      end select
24191
24192                      tx=m2(1,4)-tabla(1,4,k)
24193                      ty=m2(2,4)-tabla(2,4,k)
24194                      tz=m2(3,4)-tabla(3,4,k)
24195                      tx=mod(tx+ilat_fact,ilat_norm)
24196                      ty=mod(ty+ilat_fact,ilat_norm)
24197                      tz=mod(tz+ilat_fact,ilat_norm)
24198
24199                      select case (ibravl)
24200                          case (2)
24201                             if (ty == 6 .and. tz == 6) cycle p2
24202                             if (ty == 0 .and. tz == 0) cycle p2
24203
24204                          case (3)
24205                             if (tx == 6 .and. tz == 6) cycle p2
24206                             if (tx == 0 .and. tz == 0) cycle p2
24207
24208                          case (4)
24209                             if (tx == 6 .and. ty == 6) cycle p2
24210                             if (tx == 0 .and. ty == 0) cycle p2
24211
24212                          case (5)
24213                             if (tx == 6 .and. ty == 6 .and. tz == 6) cycle p2
24214                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
24215
24216                          case (6)
24217                             if (tx == 8 .and. ty == 4 .and. tz == 4) cycle p2
24218                             if (tx == 4 .and. ty == 8 .and. tz == 8) cycle p2
24219                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
24220
24221                          case (7)
24222                             if (ty == 6 .and. tz == 6) cycle p2
24223                             if (tx == 6 .and. tz == 6) cycle p2
24224                             if (tx == 6 .and. ty == 6) cycle p2
24225
24226                             if (ty == 0 .and. tz == 0) cycle p2
24227                             if (tx == 0 .and. tz == 0) cycle p2
24228                             if (tx == 0 .and. ty == 0) cycle p2
24229
24230                          case (8)
24231                             txyz=(/tx,ty,tz/)
24232                             if(txyz(1) == 0 .and. txyz(2) == 0 .and. txyz(3) == 0) cycle p2
24233                             do l=1,nlat_t
24234                               if(txyz(1)==lat_trans(1,l) .and. txyz(2)==lat_trans(2,l) .and. txyz(3)==lat_trans(3,l)) cycle p2
24235                             end do
24236
24237                      end select
24238                   end if
24239                end do
24240
24241                nt=nt+1
24242                if (nt > num_tab) then
24243                   err_symm=.true.
24244                   write(unit=ERR_Symm_Mess,fmt="(a,i5)") " Dimension of Table exceeded (II): ",nt
24245                   return
24246                end if
24247                !new operator
24248                tabla(:,:,nt)=m2
24249                !write(*,"(a,i4,a,9i3,3i6)")  "  Op:",nt," -> ", tabla(1:3,1:3,nt),tabla(1:3,4,nt)
24250             end do p2
24251          end do
24252
24253          if (n == nt) exit
24254
24255       end do
24256
24257       !---- Carga Final ----!
24258       ng=nt
24259       do i=1,nt
24260          ss(:,:,i)=tabla(1:3,1:3,i)
24261          ts(:,i)  = real(tabla(1:3,4,i))/lat_norm
24262       end do
24263
24264       ! Check anomalous cases where the order of generators has produced
24265       ! a centre of symmetry at the end.
24266       ! In some cases the number of operators were wrong => the list of
24267       ! operators contained centrosymmetric related items.
24268
24269       cen_found = .false.
24270       do i=1,nt
24271          if ( equal_matrix(ss(:,:,i),-identidad,3) ) then
24272             cen_found=.true.
24273             jcen=i
24274             exit
24275          end if
24276       end do
24277
24278       if(cen_found) then
24279           ng=nt/2     !in all cases only half operators are needed
24280           if (isymce == 1) then
24281              tt=tabla(1:3,4,jcen)
24282              if (tt(1) == 0 .and. tt(2) == 0 .and. tt(3) == 0) then
24283                 isymce=2       ! Centric with -1 at origin
24284              else
24285                 isymce=0       ! Centric without -1 at origin
24286                 co=0.5*ts(:,jcen)
24287              end if
24288           end if
24289       end if
24290
24291       !---- Determination of the crystalline system and Bravais lattice ----!
24292       call get_crystal_System(ng,ss,isystm,latsy(1:1))
24293       latsy(2:)=red(ibravl)
24294
24295       return
24296    End Subroutine Get_SO_from_Gener
24297
24298    !!----
24299    !!---- Subroutine Get_So_From_Hall(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Co,Num_G,Hall)
24300    !!----    integer,                   intent(out)  :: ISYSTM    ! Out -> Number of the crystalline system
24301    !!----                                                                  (1:T, 2:M, 3:O, 4:T, 5:R-Trg, 6:H, 7:C)
24302    !!----    integer,                   intent(out)  :: ISYMCE    ! Out -> 0 Centric (-1 not at origin)
24303    !!----                                                                  1 Acentric
24304    !!----                                                                  2 Centric (-1 at origin)
24305    !!----    integer,                   intent(out)  :: IBRAVL    ! Out -> Index of the Bravais Lattice type
24306    !!----                                                                  1   2   3   4   5   6   7
24307    !!----                                                                 "P","A","B","C","I","R","F"
24308    !!----    integer,                   intent(out)  :: NG        ! Out -> Number of symmetry operators
24309    !!----    real(kind=cp),    dimension(:,:),   intent(out)  :: TS        ! Out -> Translation parts of the symmetry operators  (3,48)
24310    !!----    integer, dimension(:,:,:), intent(out)  :: SS        ! Out -> Rotation parts of the symmetry operators     (3,3,48)
24311    !!----    character (len=2),         intent(out)  :: latsy     ! Out -> Bravais lattice symbol
24312    !!----    real(kind=cp), dimension(3),        intent(out)  :: Co        ! Out -> Coordinates of symmetry center
24313    !!----    integer,                   intent(out)  :: num_g     ! Out -> Number of generators
24314    !!----    character (len=20),        intent( in)  :: Hall      !  In -> Hall Spacegroup symbol
24315    !!----
24316    !!----    Subroutine to get all the information contained in the Hall symbol. This
24317    !!----    routine to interpret the Hall symbol for a space group.
24318    !!--..    (Author:Javier Gonzalez-Platas)
24319    !!----
24320    !!---- Update: February - 2005
24321    !!
24322    Subroutine Get_SO_from_Hall(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Co,Num_g,Hall)
24323       !---- Arguments ----!
24324       integer,                   intent(out) :: Isystm
24325       integer,                   intent(out) :: Isymce
24326       integer,                   intent(out) :: Ibravl
24327       integer,                   intent(out) :: Ng
24328       integer, dimension(:,:,:), intent(out) :: Ss  !(3,3,48)
24329       real(kind=cp),    dimension(:,:),   intent(out) :: Ts  !(3,48)
24330       character (len= 2),        intent(out) :: Latsy
24331       real(kind=cp),    dimension(3),     intent(out) :: Co
24332       integer,                   intent(out) :: Num_g
24333       character (len=*),         intent( in) :: Hall
24334
24335       !----Local variables ----!
24336       character (len=16)                         :: group
24337       character(len=*), dimension(7),  parameter :: red = &
24338                         (/"P","A","B","C","I","R","F"/)
24339       character(len=*), dimension(13), parameter :: traslacion =&
24340                         (/"A","B","C","N","U","V","W","D","1","2","3","4","5"/)
24341       character(len=*), dimension(6),  parameter :: ejes_rotacion = &
24342                         (/"X","Y","Z","'","""","*"/)
24343       character(len=*), dimension(5),  parameter :: rotacion=(/"1","2","3","4","6"/)
24344       character(len=*), dimension(5),  parameter :: shift=(/"1","2","3","4","5"/)
24345       integer, dimension(3,13), parameter :: tras_val=reshape((/6,0,0, 0,6,0, &
24346                                       0,0,6, 6,6,6, 3,0,0, 0,3,0, 0,0,3, 3,3,3, &
24347                                       1,0,0, 2,0,0, 3,0,0, 4,0,0, 5,0,0/),(/3,13/))
24348       integer, dimension(3,3), parameter  :: x_1   = reshape( &
24349                                 (/ 1, 0, 0,  0, 1, 0,  0, 0, 1/),(/3,3/))
24350       integer, dimension(3,3), parameter  :: y_1   = reshape( &
24351                                 (/ 1, 0, 0,  0, 1, 0,  0, 0, 1/),(/3,3/))
24352       integer, dimension(3,3), parameter  :: z_1   = reshape( &
24353                                 (/ 1, 0, 0,  0, 1, 0,  0, 0, 1/),(/3,3/))
24354       integer, dimension(3,3), parameter  :: x_2   = reshape( &
24355                                 (/ 1, 0, 0,  0,-1, 0,  0, 0,-1/),(/3,3/))
24356       integer, dimension(3,3), parameter  :: y_2   = reshape( &
24357                                 (/-1, 0, 0,  0, 1, 0,  0, 0,-1/),(/3,3/))
24358       integer, dimension(3,3), parameter  :: z_2   = reshape( &
24359                                 (/-1, 0, 0,  0,-1, 0,  0, 0, 1/),(/3,3/))
24360       integer, dimension(3,3), parameter  :: x_3   = reshape( &
24361                                 (/ 1, 0, 0,  0, 0, 1,  0,-1,-1/),(/3,3/))
24362       integer, dimension(3,3), parameter  :: y_3   = reshape( &
24363                                 (/-1, 0,-1,  0, 1, 0,  1, 0, 0/),(/3,3/))
24364       integer, dimension(3,3), parameter  :: z_3   = reshape( &
24365                                 (/ 0, 1, 0, -1,-1, 0,  0, 0, 1/),(/3,3/))
24366       integer, dimension(3,3), parameter  :: x_4   = reshape( &
24367                                 (/ 1, 0, 0,  0, 0, 1,  0,-1, 0/),(/3,3/))
24368       integer, dimension(3,3), parameter  :: y_4   = reshape( &
24369                                 (/ 0, 0,-1,  0, 1, 0,  1, 0, 0/),(/3,3/))
24370       integer, dimension(3,3), parameter  :: z_4   = reshape( &
24371                                 (/ 0, 1, 0, -1, 0, 0,  0, 0, 1/),(/3,3/))
24372       integer, dimension(3,3), parameter  :: x_6   = reshape( &
24373                                 (/ 1, 0, 0,  0, 1, 1,  0,-1, 0/),(/3,3/))
24374       integer, dimension(3,3), parameter  :: y_6   = reshape( &
24375                                 (/ 0, 0,-1,  0, 1, 0,  1, 0, 1/),(/3,3/))
24376       integer, dimension(3,3), parameter  :: z_6   = reshape( &
24377                                 (/ 1, 1, 0, -1, 0, 0,  0, 0, 1/),(/3,3/))
24378       integer, dimension(3,3), parameter  :: x_2p  = reshape( &
24379                                 (/-1, 0, 0,  0, 0,-1,  0,-1, 0/),(/3,3/))
24380       integer, dimension(3,3), parameter  :: y_2p  = reshape( &
24381                                 (/ 0, 0,-1,  0,-1, 0, -1, 0, 0/),(/3,3/))
24382       integer, dimension(3,3), parameter  :: z_2p  = reshape( &
24383                                 (/ 0,-1, 0, -1, 0, 0,  0, 0,-1/),(/3,3/))
24384       integer, dimension(3,3), parameter  :: x_2pp = reshape( &
24385                                 (/-1, 0, 0,  0, 0, 1,  0, 1, 0/),(/3,3/))
24386       integer, dimension(3,3), parameter  :: y_2pp = reshape( &
24387                                 (/ 0, 0, 1,  0,-1, 0,  1, 0, 0/),(/3,3/))
24388       integer, dimension(3,3), parameter  :: z_2pp = reshape( &
24389                                 (/ 0, 1, 0,  1, 0, 0,  0, 0,-1/),(/3,3/))
24390       integer, dimension(3,3), parameter  :: xyz_3 = reshape( &
24391                                 (/ 0, 1, 0,  0, 0, 1,  1, 0, 0/),(/3,3/))
24392       integer, dimension(4,4), parameter :: identidad = reshape((/1, 0, 0, 0, &
24393                                                                     0, 1, 0, 0, &
24394                                                                     0, 0, 1, 0, &
24395                                                                     0, 0, 0, 1/),(/4,4/))
24396       integer, parameter             :: num_tab=24
24397       integer, dimension(4,4,num_tab):: tabla
24398       integer, dimension(4,4,4) :: gener
24399       integer, dimension(4,4)   :: sn, snp
24400       integer, dimension(4,4)   :: m1,m2
24401       integer, dimension(4)     :: num_rot
24402       integer, dimension(4)     :: num_eje
24403       integer, dimension(4)     :: num_tras
24404       integer, dimension(3)     :: vtras
24405
24406       logical                   :: only_rot
24407       integer                   :: i,j,k,n,nt,ntp,npos
24408       integer                   :: pos_ini,pos_act,pos_fin,ini,fin
24409       integer                   :: ngen, neje, nrot, signo
24410       integer                   :: tx,ty,tz
24411
24412       !---- Inicio ----!
24413       isystm=0
24414       isymce=1
24415       ibravl=0
24416       ng=0
24417       ss=0
24418       ts=0.0
24419       co=0.0
24420       latsy=" "
24421       num_g=1
24422       call init_err_symm()
24423
24424       !---- Convert to Upper case ----!
24425       group = hall
24426       call ucase(group)
24427       group=adjustl(group)
24428
24429       pos_ini=1
24430       pos_act=1
24431       pos_fin=len_trim(group)
24432
24433       !---- Centric / Acentric ----!
24434       if (group(pos_ini:pos_ini) == "-") then
24435          isymce=2
24436          pos_ini=pos_ini+1
24437       else
24438       !
24439       ! Determine first if there are parenthesis
24440       !
24441          i=index(group(1:pos_fin),"(")
24442          if(i == 0) then
24443             npos=index(group(1:pos_fin),"-1",back=.true.)
24444          else
24445             npos=index(group(1:i),"-1",back=.true.)
24446          end if
24447          if (npos /= 0) then
24448             vtras=0
24449             do i=npos+2,pos_fin
24450                do j=1,13
24451                   if (group(i:i) == traslacion(j)) then
24452                      if (j < 9) then       ! a b c n u v w d
24453                         vtras=vtras+tras_val(:,j)
24454                      end if
24455                   end if
24456                end do
24457             end do
24458
24459             vtras=mod(vtras,12)
24460             co=real(vtras)/12.0
24461             co=0.5*co
24462             if (vtras(1) == 0 .and. vtras(2) == 0 .and. vtras(3) == 0) then
24463                isymce=2
24464             else
24465                isymce=0
24466                pos_fin=npos-2
24467             end if
24468          end if
24469       end if
24470
24471       !---- Tipo de Celda ----!
24472       ibravl=0
24473       do i=1,7
24474          if (group(pos_ini:pos_ini) /= red(i)) cycle
24475          ibravl=i
24476          exit
24477       end do
24478       if (ibravl == 0) then
24479          err_symm=.true.
24480          ERR_Symm_Mess=" IBRAVL is Equal Zero"
24481          return
24482       end if
24483       pos_ini=pos_ini+2
24484
24485       !---- Determinacion de Generadores ----!
24486       gener=0
24487       gener(4,4,:)=1
24488
24489       num_rot=0
24490       num_eje=0
24491       num_tras=1
24492       ngen=0
24493
24494       do
24495          if (pos_ini > pos_fin) exit        ! Fin de caracterizacion
24496
24497          pos_act=index(group(pos_ini:pos_fin)," ")
24498
24499          only_rot=.false.
24500          nrot=0
24501          vtras=0
24502          signo=1
24503          neje=0
24504          if (ngen==0) neje=3                ! Eje C
24505
24506          if (pos_act /=0) then
24507             ini=pos_ini
24508             if (pos_act /= 1) then
24509                fin=pos_ini+pos_act-2
24510             else
24511                fin=pos_ini+pos_act-1
24512             end if
24513          else
24514             ini=pos_ini
24515             fin=pos_fin
24516          end if
24517
24518          !---- Desplazamiento del origen ----!
24519          if (group(ini:ini)=="(") then
24520             npos=0
24521             do i=ini+1,pos_fin-1            ! Eliminamos parentesis
24522                if (group(i:i)==" ") cycle
24523                if (group(i:i)=="-") then
24524                   signo=-1
24525                   cycle
24526                end if
24527
24528                npos=npos+1
24529                do j=1,5
24530                   if (group(i:i)==shift(j)) then
24531                      vtras(npos)=j*signo
24532                      signo=1
24533                      exit
24534                   end if
24535                end do
24536
24537             end do
24538
24539             sn=0
24540             snp=0
24541             do i=1,4
24542                sn(i,i)=1
24543                snp(i,i)=1
24544             end do
24545             do i=1,3
24546                sn(i,4) =  vtras(i)
24547                snp(i,4)= -vtras(i)
24548             end do
24549
24550             gener(:,:,ngen)=matmul(sn,gener(:,:,ngen))
24551             gener(:,:,ngen)=matmul(gener(:,:,ngen),snp)
24552
24553             exit         ! Fin de busqueda
24554          end if
24555
24556          !---- Eje de rotacion Propio/Impropio ----!
24557          if (group(ini:ini)=="-") then
24558             signo=-1
24559             ini=ini+1
24560          end if
24561
24562          !---- Eje de rotacion ----!
24563          do j=1,5
24564             if (group(ini:ini) /= rotacion(j)) cycle
24565             nrot=j
24566             exit
24567          end do
24568          if (nrot==0) then
24569             err_symm=.true.
24570             return
24571          end if
24572
24573          if (ini ==fin) only_rot=.true.
24574          ini=ini+1
24575          ini=min(ini,fin)
24576
24577          !---- Direccion de Rotacion y Traslaciones ----!
24578          do i=ini,fin
24579             do j=1,6
24580                if (group(i:i) /= ejes_rotacion(j)) cycle
24581                neje=j
24582                exit
24583             end do
24584
24585             if (neje == 0) then
24586                select case (ngen)
24587                    case (0)
24588                       neje=3
24589                    case (1)
24590                       neje=1
24591                       if (nrot == 2) then
24592                          if (num_rot(1)==2 .or. num_rot(1)==4) neje=1
24593                          if (num_rot(1)==3 .or. num_rot(1)==5) neje=4
24594                       end if
24595                    case (2)
24596                       neje=1
24597                       if (nrot == 3) neje=6
24598                    case (3)
24599                       neje=1
24600                end select
24601             end if
24602
24603
24604             if (only_rot) cycle    ! Solo eje de rotacion
24605
24606             do j=1,13
24607                if (group(i:i) == traslacion(j)) then
24608                   if (j < 9) then       ! a b c n u v w d
24609                      vtras=vtras+tras_val(:,j)
24610                      select case (j)
24611                          case (5:8)
24612                          num_tras(ngen+1)=num_tras(ngen+1)*3
24613                      end select
24614
24615                   else                  ! 1 2 3 4 6
24616                      if (nrot ==3 .or. nrot==4 .or. nrot==5) then
24617                         n=j-8
24618                         if (nrot==5) then
24619                            n=n*2
24620                         else
24621                            n=n*12/nrot
24622                         end if
24623                         vtras=0
24624                         vtras(neje)=n
24625
24626                         num_tras(ngen+1)=num_tras(ngen+1)*(nrot-1)
24627                      else
24628                         err_symm=.true.
24629                         return
24630                      end if
24631                   end if
24632                end if
24633             end do
24634
24635          end do
24636
24637          !---- Cargando informacion ----!
24638          ngen=ngen+1
24639          num_rot(ngen)=nrot
24640          num_eje(ngen)=neje
24641
24642          select case (nrot)
24643              case (1)
24644                 select case (neje)
24645                     case (1)
24646                        gener(1:3,1:3,ngen)=x_1*signo
24647                     case (2)
24648                        gener(1:3,1:3,ngen)=y_1*signo
24649                     case (3)
24650                        gener(1:3,1:3,ngen)=z_1*signo
24651                     case (4:6)
24652                        err_symm=.true.
24653                        return
24654                 end select
24655                 gener(1:3,4,ngen)=vtras
24656
24657              case (2)
24658                 select case (neje)
24659                     case (1)
24660                        gener(1:3,1:3,ngen)=x_2*signo
24661                     case (2)
24662                        gener(1:3,1:3,ngen)=y_2*signo
24663                     case (3)
24664                        gener(1:3,1:3,ngen)=z_2*signo
24665                     case (4)
24666                        select case (num_eje(1))
24667                            case (1)
24668                               gener(1:3,1:3,ngen)=x_2p*signo
24669                            case (2)
24670                               gener(1:3,1:3,ngen)=y_2p*signo
24671                            case (3)
24672                               gener(1:3,1:3,ngen)=z_2p*signo
24673                            case (6)
24674                               gener(1:3,1:3,ngen)=z_2p*signo
24675                            case default
24676                               err_symm=.true.
24677                               return
24678                        end select
24679                     case (5)
24680                        select case (num_eje(1))
24681                            case (1)
24682                               gener(1:3,1:3,ngen)=x_2pp*signo
24683                            case (2)
24684                               gener(1:3,1:3,ngen)=y_2pp*signo
24685                            case (3)
24686                               gener(1:3,1:3,ngen)=z_2pp*signo
24687                            case default
24688                               err_symm=.true.
24689                               return
24690                        end select
24691                     case (6)
24692                        err_symm=.true.
24693                        return
24694                 end select
24695                 gener(1:3,4,ngen)=vtras
24696
24697              case (3)
24698                 select case (neje)
24699                     case (1)
24700                        gener(1:3,1:3,ngen)=x_3*signo
24701                     case (2)
24702                        gener(1:3,1:3,ngen)=y_3*signo
24703                     case (3)
24704                        gener(1:3,1:3,ngen)=z_3*signo
24705                     case (4:5)
24706                        err_symm=.true.
24707                        return
24708                     case (6)
24709                        gener(1:3,1:3,ngen)=xyz_3*signo
24710                 end select
24711                 gener(1:3,4,ngen)=vtras
24712
24713              case (4)
24714                 select case (neje)
24715                     case (1)
24716                        gener(1:3,1:3,ngen)=x_4*signo
24717                     case (2)
24718                        gener(1:3,1:3,ngen)=y_4*signo
24719                     case (3)
24720                        gener(1:3,1:3,ngen)=z_4*signo
24721                     case (4:6)
24722                        err_symm=.true.
24723                        return
24724                 end select
24725                 gener(1:3,4,ngen)=vtras
24726
24727              case (5)
24728                 select case (neje)
24729                     case (1)
24730                        gener(1:3,1:3,ngen)=x_6*signo
24731                     case (2)
24732                        gener(1:3,1:3,ngen)=y_6*signo
24733                     case (3)
24734                        gener(1:3,1:3,ngen)=z_6*signo
24735                     case (4:6)
24736                        err_symm=.true.
24737                        return
24738                 end select
24739                 gener(1:3,4,ngen)=vtras
24740
24741          end select
24742
24743          pos_ini=fin+2
24744       end do
24745
24746       !---- Tabla de caracteres ----!
24747       tabla=0
24748       tabla(:,:,1)=identidad
24749
24750       !---- Put Generators on the table ----!
24751       nt=1
24752       do i=1,ngen
24753          if (ngen == 1 .and. num_rot(1)==1) exit    ! only triclinic
24754          nt=nt+1
24755          tabla(:,:,nt)=gener(:,:,i)
24756          tabla(:,4,nt)=mod(tabla(:,4,nt)+48,12)
24757       end do
24758
24759       !num_g=nt-1 !Minimum number of generators
24760        num_g=ngen
24761
24762            !---- Generate power operations from generators ----!
24763       do i=2,nt
24764           ntp=axes_rotation(tabla(:,:,i))    ! Determine the order of the generator
24765          if (ntp == -1 .or. ntp == -3) then
24766             ntp=-2*ntp
24767          else
24768             ntp=abs(ntp)
24769          end if
24770
24771          m1=tabla(:,:,i)
24772          m2=identidad
24773
24774          p1:do j=1,ntp-1
24775             m2=matmul(m2,m1)
24776             m2(:,4)=mod(m2(:,4)+48,12)
24777
24778             !---- Check if the generated operation is already in the table
24779             do k=1,nt
24780                if (equal_matrix(tabla(:,:,k),m2,4)) cycle p1
24781             end do
24782
24783             !---- Eliminating lattice contribution if necessary ----!
24784             select case (ibravl)
24785                 case (2)
24786                    ty=m2(2,4)
24787                    tz=m2(3,4)
24788                    if (ty >= 6 .and. tz >= 6) then
24789                       ty=mod(m2(2,4),6)
24790                       tz=mod(m2(3,4),6)
24791
24792                       if (ty == 0 .and. tz == 0) then
24793                          cycle p1
24794                       else
24795                          m2(2,4)=ty
24796                          m2(3,4)=tz
24797                       end if
24798                    end if
24799
24800                 case (3)
24801                    tx=m2(1,4)
24802                    tz=m2(3,4)
24803                    if (tx >= 6 .and. tz >=6) then
24804                       tx=mod(m2(1,4),6)
24805                       tz=mod(m2(3,4),6)
24806
24807                       if (tx == 0 .and. tz == 0) then
24808                          cycle p1
24809                       else
24810                          m2(1,4)=tx
24811                          m2(3,4)=tz
24812                       end if
24813                    end if
24814
24815                 case (4)
24816                    tx=m2(1,4)
24817                    ty=m2(2,4)
24818                    if (tx >=6 .and. ty >= 6) then
24819                       tx=mod(m2(1,4),6)
24820                       ty=mod(m2(2,4),6)
24821
24822                       if (tx == 0 .and. ty == 0) then
24823                          cycle p1
24824                       else
24825                          m2(1,4)=tx
24826                          m2(2,4)=ty
24827                       end if
24828                    end if
24829
24830                 case (5)
24831                    tx=m2(1,4)
24832                    ty=m2(2,4)
24833                    tz=m2(3,4)
24834                    if (tx >=6 .and. ty >=6 .and. tz >=6) then
24835                       tx=mod(m2(1,4),6)
24836                       ty=mod(m2(2,4),6)
24837                       tz=mod(m2(3,4),6)
24838
24839                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24840                          cycle p1
24841                       else
24842                          m2(1,4)=tx
24843                          m2(2,4)=ty
24844                          m2(3,4)=tz
24845                       end if
24846                    end if
24847
24848                 case (6)
24849                    tx=m2(1,4)
24850                    ty=m2(2,4)
24851                    tz=m2(3,4)
24852                    if (tx >=8 .and. ty >=4 .and. tz >=4) then
24853                       tx=mod(m2(1,4),8)
24854                       ty=mod(m2(2,4),4)
24855                       tz=mod(m2(3,4),4)
24856                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24857                          cycle p1
24858                       else
24859                          m2(1,4)=tx
24860                          m2(2,4)=ty
24861                          m2(3,4)=tz
24862                       end if
24863
24864                    else if (tx >=4 .and. ty >=8 .and. tz >=8) then
24865                       tx=mod(m2(1,4),4)
24866                       ty=mod(m2(2,4),8)
24867                       tz=mod(m2(3,4),8)
24868                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24869                          cycle p1
24870                       else
24871                          m2(1,4)=tx
24872                          m2(2,4)=ty
24873                          m2(3,4)=tz
24874                       end if
24875                    end if
24876
24877                 case (7)
24878                    tx=m2(1,4)
24879                    ty=m2(2,4)
24880                    tz=m2(3,4)
24881                    if (ty >= 6 .and. tz >=6) then
24882                       ty=mod(m2(2,4),6)
24883                       tz=mod(m2(3,4),6)
24884                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24885                          cycle p1
24886                       else
24887                          m2(2,4)=ty
24888                          m2(3,4)=tz
24889                       end if
24890                    else if (tx >=6 .and. tz >=6) then
24891                       tx=mod(m2(1,4),6)
24892                       tz=mod(m2(3,4),6)
24893                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24894                          cycle p1
24895                       else
24896                          m2(1,4)=tx
24897                          m2(3,4)=tz
24898                       end if
24899                    else if (tx >=6 .and. ty >=6) then
24900                       tx=mod(m2(1,4),6)
24901                       ty=mod(m2(2,4),6)
24902                       if (tx == 0 .and. ty == 0 .and. tz == 0) then
24903                          cycle p1
24904                       else
24905                          m2(1,4)=tx
24906                          m2(2,4)=ty
24907                       end if
24908                    end if
24909             end select
24910
24911             nt=nt+1
24912             if (nt > num_tab) then
24913                err_symm=.true.
24914                ERR_Symm_Mess=" Dimension of Table exceeded (I)"
24915                return
24916             end if
24917             tabla(:,:,nt)=m2
24918          end do p1
24919       end do
24920
24921       !---- Multiplications between generators ----!
24922       do
24923          if (nt == 1) exit
24924          n=nt
24925
24926          do i=1,n
24927             p2:do j=i,n
24928
24929                m2=matmul(tabla(:,:,i),tabla(:,:,j))
24930                m2(:,4)=mod(m2(:,4)+48,12)
24931
24932                !---- Eliminating lattice contribution if necessary ----!
24933                select case (ibravl)
24934                   case (2)
24935                      ty=m2(2,4)
24936                      tz=m2(3,4)
24937                      if (ty >= 6 .and. tz >= 6) then
24938                         ty=mod(m2(2,4),6)
24939                         tz=mod(m2(3,4),6)
24940                         m2(2,4)=ty
24941                         m2(3,4)=tz
24942                      end if
24943
24944                   case (3)
24945                      tx=m2(1,4)
24946                      tz=m2(3,4)
24947                      if (tx >= 6 .and. tz >= 6) then
24948                         tx=mod(m2(1,4),6)
24949                         tz=mod(m2(3,4),6)
24950                         m2(1,4)=tx
24951                         m2(3,4)=tz
24952                      end if
24953
24954                   case (4)
24955                      tx=m2(1,4)
24956                      ty=m2(2,4)
24957                      if (tx >= 6 .and. ty >= 6) then
24958                         tx=mod(m2(1,4),6)
24959                         ty=mod(m2(2,4),6)
24960                         m2(1,4)=tx
24961                         m2(2,4)=ty
24962                      end if
24963
24964                   case (5)
24965                      tx=m2(1,4)
24966                      ty=m2(2,4)
24967                      tz=m2(3,4)
24968                      if (tx >= 6 .and. ty >= 6 .and. tz >= 6) then
24969                         tx=mod(m2(1,4),6)
24970                         ty=mod(m2(2,4),6)
24971                         tz=mod(m2(3,4),6)
24972                         m2(1,4)=tx
24973                         m2(2,4)=ty
24974                         m2(3,4)=ty
24975                      end if
24976
24977                   case (6)
24978                      tx=m2(1,4)
24979                      ty=m2(2,4)
24980                      tz=m2(3,4)
24981                      if (tx >=8 .and. ty >=4 .and. tz >=4) then
24982                         tx=mod(m2(1,4),8)
24983                         ty=mod(m2(2,4),4)
24984                         tz=mod(m2(3,4),4)
24985                         m2(1,4)=tx
24986                         m2(2,4)=ty
24987                         m2(3,4)=tz
24988                      else if (tx >=4 .and. ty >=8 .and. tz >=8) then
24989                         tx=mod(m2(1,4),4)
24990                         ty=mod(m2(2,4),8)
24991                         tz=mod(m2(3,4),8)
24992                         m2(1,4)=tx
24993                         m2(2,4)=ty
24994                         m2(3,4)=tz
24995                      end if
24996
24997                   case (7)
24998                      tx=m2(1,4)
24999                      ty=m2(2,4)
25000                      tz=m2(3,4)
25001                      if (ty >= 6 .and. tz >=6) then
25002                         ty=mod(m2(2,4),6)
25003                         tz=mod(m2(3,4),6)
25004                         m2(2,4)=ty
25005                         m2(3,4)=tz
25006                      else if (tx >=6 .and. tz >=6) then
25007                         tx=mod(m2(1,4),6)
25008                         tz=mod(m2(3,4),6)
25009                         m2(1,4)=tx
25010                         m2(3,4)=tz
25011                      else if (tx >=6 .and. ty >=6) then
25012                         tx=mod(m2(1,4),6)
25013                         ty=mod(m2(2,4),6)
25014                         m2(1,4)=tx
25015                         m2(2,4)=ty
25016                      end if
25017                end select
25018
25019                do k=1,nt
25020                   if ( equal_matrix(m2(:,:),tabla(:,:,k),4) ) cycle p2
25021                   if ( equal_matrix(m2(:,:),tabla(:,:,k),3) ) then
25022                      tx=m2(1,4)+tabla(1,4,k)
25023                      ty=m2(2,4)+tabla(2,4,k)
25024                      tz=m2(3,4)+tabla(3,4,k)
25025                      tx=mod(tx,12)
25026                      ty=mod(ty,12)
25027                      tz=mod(tz,12)
25028                      select case (ibravl)
25029                          case (2)
25030                             if (ty == 6 .and. tz == 6) cycle p2
25031                             if (ty == 0 .and. tz == 0) cycle p2
25032
25033                          case (3)
25034                             if (tx == 6 .and. tz == 6) cycle p2
25035                             if (tx == 0 .and. tz == 0) cycle p2
25036
25037                          case (4)
25038                             if (tx == 6 .and. ty == 6) cycle p2
25039                             if (tx == 0 .and. ty == 0) cycle p2
25040
25041                          case (5)
25042                             if (tx == 6 .and. ty == 6 .and. tz == 6) cycle p2
25043                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
25044
25045                          case (6)
25046                             if (tx == 8 .and. ty == 4 .and. tz == 4) cycle p2
25047                             if (tx == 4 .and. ty == 8 .and. tz == 8) cycle p2
25048                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
25049
25050                          case (7)
25051                             if (ty == 6 .and. tz == 6) cycle p2
25052                             if (tx == 6 .and. tz == 6) cycle p2
25053                             if (tx == 6 .and. ty == 6) cycle p2
25054
25055                             if (ty == 0 .and. tz == 0) cycle p2
25056                             if (tx == 0 .and. tz == 0) cycle p2
25057                             if (tx == 0 .and. ty == 0) cycle p2
25058
25059                      end select
25060
25061                      tx=m2(1,4)-tabla(1,4,k)
25062                      ty=m2(2,4)-tabla(2,4,k)
25063                      tz=m2(3,4)-tabla(3,4,k)
25064                      tx=mod(tx+48,12)
25065                      ty=mod(ty+48,12)
25066                      tz=mod(tz+48,12)
25067
25068                      select case (ibravl)
25069                          case (2)
25070                             if (ty == 6 .and. tz == 6) cycle p2
25071                             if (ty == 0 .and. tz == 0) cycle p2
25072
25073                          case (3)
25074                             if (tx == 6 .and. tz == 6) cycle p2
25075                             if (tx == 0 .and. tz == 0) cycle p2
25076
25077                          case (4)
25078                             if (tx == 6 .and. ty == 6) cycle p2
25079                             if (tx == 0 .and. ty == 0) cycle p2
25080
25081                          case (5)
25082                             if (tx == 6 .and. ty == 6 .and. tz == 6) cycle p2
25083                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
25084
25085                          case (6)
25086                             if (tx == 8 .and. ty == 4 .and. tz == 4) cycle p2
25087                             if (tx == 4 .and. ty == 8 .and. tz == 8) cycle p2
25088                             if (tx == 0 .and. ty == 0 .and. tz == 0) cycle p2
25089
25090                          case (7)
25091                             if (ty == 6 .and. tz == 6) cycle p2
25092                             if (tx == 6 .and. tz == 6) cycle p2
25093                             if (tx == 6 .and. ty == 6) cycle p2
25094
25095                             if (ty == 0 .and. tz == 0) cycle p2
25096                             if (tx == 0 .and. tz == 0) cycle p2
25097                             if (tx == 0 .and. ty == 0) cycle p2
25098                      end select
25099                   end if
25100                end do
25101
25102                nt=nt+1
25103                if (nt > num_tab) then
25104                   err_symm=.true.
25105                   ERR_Symm_Mess=" Dimension of Table exceeded (II)"
25106                   return
25107                end if
25108                tabla(:,:,nt)=m2
25109
25110             end do p2
25111          end do
25112
25113          if (n == nt) exit
25114
25115       end do
25116
25117       !---- Carga Final ----!
25118       ng=nt
25119       do i=1,nt
25120          ss(:,:,i)=tabla(1:3,1:3,i)
25121          ts(:,i)  = real(tabla(1:3,4,i))/12.0
25122       end do
25123
25124       !---- Determination of the crystalline system and Bravais lattice ----!
25125       call get_crystal_System(ng,ss,isystm,latsy(1:1))
25126       latsy(2:)=red(ibravl)
25127       call latsym(red(ibravl))
25128
25129       return
25130    End Subroutine Get_SO_from_Hall
25131
25132    !!----
25133    !!---- Subroutine Get_So_From_Hms(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,Spaceh)
25134    !!----    integer,                        intent(out)  :: ISYSTM    ! Out -> Number of the crystalline system
25135    !!----                                                                       (1:T, 2:M, 3:O, 4:T, 5:R-Trg, 6:H, 7:C)
25136    !!----    integer,                        intent(out)  :: ISYMCE    ! Out -> 0 Centric (-1 not at origin)
25137    !!----                                                                       1 Acentric
25138    !!----                                                                       2 Centric (-1 at origin)
25139    !!----    integer,                        intent(out)  :: IBRAVL    ! Out -> Index of the Bravais Lattice type
25140    !!----                                                                       1   2   3   4   5   6   7
25141    !!----                                                                      "P","A","B","C","F","I","R"
25142    !!----    integer,                        intent(out)  :: NG        ! Out -> Number of symmetry operators
25143    !!----    real(kind=cp),dimension(:,:),   intent(out)  :: TS        ! Out -> Translation parts of the symmetry operators
25144    !!----    integer, dimension(:,:,:),      intent(out)  :: SS        ! Out -> Rotation parts of the symmetry operators
25145    !!----    character (len=2),              intent(out)  :: latsy     ! Out -> Bravais lattice symbol
25146    !!----    character (len=20),             intent( in)  :: SpaceH    !  In -> H-M Spacegroup symbol
25147    !!----
25148    !!----    Subroutine to get all the information contained in the H-M symbol.
25149    !!----    Routine to interpret Hermann-Mauguin symbol for space group.
25150    !!--..    This routine has been adapted from a program supplied by prof. Burzlaff,
25151    !!--..    University of Erlangen, Germany.
25152    !!--..    (Author:Juan Rodriguez-Carvajal)
25153    !!----
25154    !!---- Update: February - 2005
25155    !!
25156    Subroutine Get_SO_from_HMS(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy,SpaceH)
25157       !---- Arguments ----!
25158       integer,                   intent(out) :: ISYSTM
25159       integer,                   intent(out) :: ISYMCE
25160       integer,                   intent(out) :: IBRAVL
25161       integer,                   intent(out) :: NG
25162       integer, dimension(:,:,:), intent(out) :: Ss  !(3,3,48)
25163       real(kind=cp),    dimension(:,:),   intent(out) :: Ts  !(3,48)
25164       character (len= 2),        intent(out) :: Latsy
25165       character (len=*),         intent( in) :: SpaceH
25166
25167       !---- Local variables ----!
25168       character (len=20):: GROUP
25169       character (len=1) :: M,N, Item_SP
25170       character (len=1), dimension(3,4) :: HMS
25171       character (len=*), dimension(7), parameter :: IBRA=(/"P","A","B","C","F","I","R"/)
25172       integer :: SYS,i,j,k,l,NBR,NE,MM,ID,IC,NS,IND,NBL,NLQ,MA
25173       integer, dimension(3) ::  NMA
25174       integer, dimension(3,3) :: E
25175       real(kind=cp) :: TC
25176       real(kind=cp), dimension(   3):: TE, SH
25177
25178       NMA = 0
25179       SH  = 0.25
25180
25181       !---- Convert to upper case  SpaceG -> GROUP ----!
25182       group=adjustl(SpaceH)
25183       call ucase(group)
25184
25185       NBL=-1
25186       NG=1
25187       NS=1
25188       IBRAVL=0
25189       TE(1:3) = 0.0
25190       TS(1:3,1:24) = 0.0
25191       E(1:3 ,1:3) = 0
25192       SS(1:3,1:3,1:24) = 0
25193       SS(1,1,1) = 1
25194       SS(2,2,1) = 1
25195       SS(3,3,1) = 1
25196       HMS(1:3,1:4) = " "
25197       call init_err_symm()
25198
25199       do i=1,len_trim(group)         !scanning the Upper-ed case space group symbol
25200          item_sp=group(i:i)
25201          if (item_sp == " ") then     !If blank cycle after initializing the indices
25202             nlq=0                     !for HMS
25203             ic=0
25204             cycle
25205          end if
25206
25207          if (nbl < 0) then
25208             do j=1,7
25209                nbr=j
25210                if (item_sp == ibra(j)) then
25211                   nbl=0
25212                   ibravl=nbr        !Bravais Lattice symbol (first non-blank item of GROUP)
25213                   exit
25214                end if
25215             end do
25216
25217             if (ibravl == 0) then
25218                err_symm=.true.
25219                ERR_Symm_Mess=" Wrong space-group symbol: "//SpaceH
25220                return
25221             else if (IBRAVL == 5) then     !These changes are to conform with
25222                IBRAVL=7                    !the definition of LAT in SYMMETRY
25223             else if (IBRAVL == 6) then     !modules
25224                IBRAVL=5
25225             else if (IBRAVL == 7) THEN
25226                IBRAVL=6
25227             end if                         !                1   2   3   4   5   6   7
25228             cycle                          !               "P","A","B","C","F","I","R"
25229          end if                            !                p   a   b   c   i   r   f
25230
25231          if (nlq == 0) nbl=nbl+1      !New blank separating symmetry directions
25232          ic=ic+1                      !Maximum =4  eg. 63/m
25233          if (ic > 4) ic=4             !Protection against bad typing of
25234          if (nbl > 3) nbl=3           !space group symbol
25235          hms(nbl,ic)=item_sp
25236          nlq=1
25237          if (item_sp == "/") ns=0
25238       end do                          !End loop of Scanning the Upper-ed case space group symbol
25239
25240       !---- Determination of the crystal system ----!
25241       SYS=0
25242       do i=1,4
25243          if (hms(2,i) == "3") then    !cubic
25244             sys=6
25245             isystm=7
25246             latsy="c"//ibra(NBR)
25247             exit
25248          else if (hms(1,i) == "3") then
25249             sys=5                        !trigonal (rhombohedral)
25250             isystm=5
25251             latsy="h"//ibra(NBR)
25252             exit
25253          else if (hms(1,i) == "6") then
25254             sys=5                        !hexagonal (same block as trigonal)
25255             isystm=6
25256             latsy="hP"
25257             exit
25258          else if(hms(1,i) == "4") then
25259             sys=4                        !tetragonal
25260             isystm=4
25261             latsy="t"//ibra(NBR)
25262             exit
25263          end if
25264       end do
25265
25266       if (nbl <= 1 .and. sys==0) then
25267          if (hms(1,1) == "1" .or. hms(1,1) == "-") then
25268             sys=1           !triclinic
25269             isystm=1
25270             latsy="a"//ibra(nbr)
25271          else
25272             sys=2           !monoclinic
25273             isystm=2
25274             latsy="m"//ibra(nbr)
25275             do i=1,4
25276                hms(2,i)=hms(1,i)  ! put the symbol in the form l 1 2/m 1
25277                hms(1,i)=" "
25278             end do
25279             hms(1,1)="1"   !complete the symbol with 1 along a and c
25280             hms(3,1)="1"
25281          end if
25282       end if
25283
25284       if (nbl > 1 .and. sys==0) then
25285          sys=3     !orthorhombic
25286          isystm=3
25287          latsy="o"//ibra(nbr)
25288          if (hms(1,1) == "1".or.hms(2,1) == "1") then
25289             sys=2
25290             isystm=2
25291             latsy="m"//ibra(nbr)
25292          end if
25293       end if
25294
25295       call check_symbol_hm(HMS)
25296       if (err_symm) return
25297       call latsym(ibra(nbr))
25298
25299
25300       SELECT CASE (SYS)     !SYS is the crystal family
25301          CASE (1)      !  TRICLINIC
25302             IF (HMS(1,1) == "-") NS=0
25303
25304          CASE (2)      !  MONOCLINIC
25305             NG=2
25306             DO I=1,3
25307                IF (HMS(I,1)/="1") IND=I
25308             END DO
25309             ID=1
25310             IF (HMS(IND,1) == "2") ID=-1
25311             DO I=1,3
25312                SS(I,I,2)=SS(I,I,1)*ID
25313             END DO
25314             SS(IND,IND,2)=-SS(IND,IND,2)
25315             DO I=1,3
25316                IF (HMS(I,1) == "2".AND.HMS(I,2) == "1") TS(I,2)=0.5
25317                DO J=1,4
25318                   IF (HMS(I,J) == "A") TS(1,2)=0.5
25319                   IF (HMS(I,J) == "B") TS(2,2)=0.5
25320                   IF (HMS(I,J) == "C") TS(3,2)=0.5
25321                   IF (HMS(I,J) == "N") THEN
25322                      K=I+1
25323                      IF (K > 3) K=K-3
25324                      TS(K    ,2)=0.5
25325                      TS(6-K-I,2)=0.5
25326                   END IF
25327                END DO
25328             END DO
25329
25330          CASE (3)   !  ORTHORHOMBIC
25331             NG=4
25332             IC=0
25333             IND=1
25334             IF (HMS(1,1)/="2".AND.HMS(2,1)/="2".AND.HMS(3,1) /= "2") IND=-1
25335             IF (IND == -1) NS=0
25336             DO I=1,3
25337                ID=1
25338                IF (HMS(I,1) == "2") ID=-1
25339                DO J=1,3
25340                   SS(J,J,1+I)=SS(J,J,1)*ID*IND
25341                END DO
25342                SS(I,I,1+I)=-SS(I,I,1+I)
25343             END DO
25344             DO I=1,3
25345                IF (HMS(I,1) == "2" .AND. HMS(I,2) == "1") TS(I,1+I)=0.5
25346                DO J=1,4
25347                   IF (HMS(I,J) == "A") TS(1,1+I)=0.5
25348                   IF (HMS(I,J) == "B") TS(2,1+I)=0.5
25349                   IF (HMS(I,J) == "C") TS(3,1+I)=0.5
25350                   IF (HMS(I,J) == "N" .OR. HMS(I,J) == "D") THEN
25351                      K=I+1
25352                      IF (K > 3) K=K-3
25353                      IF (HMS(I,J) == "D") THEN
25354                         IC=1
25355                         IF (NS == 1) THEN
25356                            TS(1,1+I)=0.25
25357                            TS(2,1+I)=0.25
25358                            TS(3,1+I)=0.25
25359                         ELSE                !was missing
25360                            TS(    K,1+I)=0.25
25361                            TS(6-K-I,1+I)=0.25
25362                         END IF
25363                      ELSE                   !was missing
25364                        TS(K    ,1+I)=0.5
25365                        TS(6-K-I,1+I)=0.5
25366                      END IF
25367                   END IF
25368                END DO
25369             END DO
25370
25371             if (ic == 1) then
25372                call mod_trans(ng,ns,ts,isymce)
25373                return
25374             end if
25375
25376             if (ns == 1) then
25377                ic=0
25378                do i=1,3
25379                   if (ss(1,1,1+i)*ss(2,2,1+i)*ss(3,3,1+i) == -1) ic=1  !there are planes
25380                end do
25381
25382                if (ic == 1) then
25383                   do i=1,3
25384                      if (ss(1,1,1+i)*ss(2,2,1+i)*ss(3,3,1+i) == 1) id=i
25385                   end do
25386                   do i=1,3
25387                      tc=ts(i,2)+ts(i,3)+ts(i,4)
25388                      if (abs(tc) < eps_symm .or. abs(tc-1.0) < eps_symm) cycle
25389                      IF (HMS(1,1) == "M" .AND. HMS(2,1) == "N".OR.         &
25390                          HMS(2,1) == "M" .AND. HMS(3,1) == "N".OR.         &
25391                          HMS(3,1) == "M" .AND. HMS(1,1) == "N")    THEN
25392                         k=i-1
25393                         if (k == 0) k=k+3
25394                         ts(i,1+k)=0.5
25395                         cycle !was missing
25396                      end if
25397                      do j=1,3
25398                         if (id/=j) then
25399                            if (abs(ts(i,1+j)-0.5) > eps_symm) ts(i,1+j)=0.5
25400                         end if
25401                      end do
25402                   end do
25403                      call mod_trans(ng,ns,ts,isymce)
25404                      return
25405                end if   ! it was else
25406
25407                   tc=ts(1,2)+ts(2,3)+ts(3,4)
25408                   if (abs(tc) < eps_symm) then
25409                      call mod_trans(ng,ns,ts,isymce)
25410                      return
25411                   end if
25412                   do i=1,3
25413                      k=i+1
25414                      if (k > 3) k=k-3
25415                      if (tc > 0.5) then
25416                         if (tc > 1.0) then
25417                            ts(k,1+i)=0.5
25418                            cycle
25419                         end if
25420                         if (abs(ts(i,1+i)) >=0.000001) cycle
25421                         l=k+1
25422                         if (l > 3) l=l-3
25423                         ts(l,1+k)=0.5
25424                         ts(k,1+l)=0.5
25425                         cycle
25426                      end if
25427                      if (abs(ts(i,1+i)) < eps_symm) cycle
25428                      mm=i-1
25429                      if (mm == 0) mm=mm+3
25430                      ts(i,1+mm)=0.5
25431                   end do
25432                   call mod_trans(ng,ns,ts,isymce)
25433                   return
25434             end if
25435
25436                do i=1,3
25437                   k=1+i
25438                   if (k > 3) k=k-3
25439                   tc=ts(i,1+k)+ts(i,1+6-i-k)
25440                   if (abs(tc-1.0) < eps_symm) tc=0.0
25441                   ts(i,1+i)=tc
25442                end do
25443
25444                !---- special treatment of c m m a, c m c a, i m m a ---- !
25445                if (nbr == 1 .or. nbr == 5) then
25446                   call mod_trans(ng,ns,ts,isymce)
25447                   return
25448                end if
25449                ma=0
25450                do i=1,3
25451                   do j=1,4
25452                      IF (HMS(I,J) == "M") NMA(I)=1
25453                   end do
25454                   ma=ma+nma(i)
25455                end do
25456
25457                if (.not. (nbr == 6 .and. ma == 2) ) then
25458
25459                   if (ma == 0 .or. ma == 3 .or. nbr == 6) then
25460                      call mod_trans(ng,ns,ts,isymce)
25461                      return
25462                   end if
25463                   do i=1,3
25464                      if (nma(nbr-1) == 1) then
25465                         call mod_trans(ng,ns,ts,isymce)
25466                         return
25467                      end if
25468                      sh(nbr-1)=0.0
25469                   end do
25470
25471                end if
25472
25473                   !---- origin shift ----!
25474                   do i=1,ng
25475                      do j=1,3
25476                         do k=1,3
25477                            id=1
25478                            if (j/=k) id=0
25479                            ts(j,i)=ts(j,i)+(id-ss(j,k,i))*sh(k)
25480                         end do
25481                         if (ts(j,i) > 1.0) ts(j,i)=ts(j,i)-1.0
25482                         if (ts(j,i) < 0.0) ts(j,i)=ts(j,i)+1.0
25483                      end do
25484                   end do
25485                   call mod_trans(ng,ns,ts,isymce)
25486                   return
25487
25488          CASE (4)   !  TETRAGONAL
25489             NG=4
25490             IF (NBL == 3) NG=8
25491             SS(1,2,2)=-1
25492             SS(2,1,2)=1
25493             SS(3,3,2)=1
25494             M=HMS(1,1)
25495             N=HMS(1,2)
25496             DO I=1,3
25497                DO J=1,3
25498                   IF (M == "-") SS(I,J,2)=-SS(I,J,2)
25499                END DO
25500             END DO
25501             IF (M/="-") THEN
25502                IF (N == "1") TS(3,2)=0.25
25503                IF (N == "2") TS(3,2)=0.5
25504                IF (N == "3") TS(3,2)=0.75
25505                IF (HMS(1,3) == "N" .OR. (HMS(1,4) =="N" .AND. NBL == 3)) TS(1,2)=0.5
25506                IF ((HMS(1,4) == "N" .AND. NBL == 1).OR.(N == "1" .AND.     &
25507                     NS == 1 .AND. NBR == 6)) TS(2,2)=0.5
25508                IF (N == "1" .AND. NS == 0 .AND. NBR == 6) THEN
25509                   TS(1,2)=0.25
25510                   TS(2,2)=0.75
25511                   IF (NBL == 1) TS(1,2)=0.75
25512                   IF (NBL == 1) TS(2,2)=0.25
25513                ELSE IF (HMS(2,2) == "1".OR.(HMS(1,4)/="N" .AND. HMS(2,1)    &
25514                                 ==   "N" .AND. HMS(3,1) == "M")) THEN
25515                   TS(1,2)=0.5
25516                   TS(2,2)=0.5
25517                END IF
25518             END IF
25519             ss(1,1,3)=-1
25520             ss(2,2,3)=-1
25521             ss(3,3,3)=1
25522             ts(1,3)=ss(1,2,2)*ts(2,2)+ts(1,2)
25523             ts(2,3)=ss(2,1,2)*ts(1,2)+ts(2,2)
25524             ts(3,3)=ss(3,3,2)*ts(3,2)+ts(3,2)
25525             do i=1,3
25526                if (nbr == 6                                 &
25527                            .and. abs(ts(1,3)-0.5) < eps_symm     &
25528                            .and. abs(ts(2,3)-0.5) < eps_symm     &
25529                            .and. abs(ts(3,3)-0.5) < eps_symm) ts(i,3)=0.0
25530             end do
25531             do i=1,3
25532                ts(i,4)=ts(i,2)
25533                do j=1,3
25534                   ts(i,4)=ts(i,4)+ss(i,j,2)*ts(j,3)
25535                   do k=1,3
25536                      ss(i,j,4)=ss(i,j,4)+ss(i,k,2)*ss(k,j,3)
25537                   end do
25538                end do
25539             end do
25540             if (nbl == 1) then
25541                call mod_trans(ng,ns,ts,isymce)
25542                return
25543             end if
25544             m=hms(2,1)
25545             n=hms(3,1)
25546             ne=4
25547             IF (NS == 0) THEN
25548                E(1,1)=-1
25549                E(2,2)=1
25550                E(3,3)=1
25551                IF (M == "C".OR.M == "N") TE(3)=0.5
25552                IF (M == "B".OR.M == "N") TE(2)=0.5
25553                IF (M == "B".OR.M == "N") TE(1)=0.5
25554                IF (HMS(1,3) == "N".OR.HMS(1,4) == "N") TE(1)=TE(1)+0.5
25555             ELSE IF (M/="2".AND.N/="2")  THEN
25556                M=HMS(2,1)
25557                E(1,1)=-1
25558                E(2,2)=1
25559                E(3,3)=1
25560                IF (M == "C".OR.M == "N") TE(3)=0.5
25561                IF (M == "N".OR.M == "B") TE(1)=0.5
25562                IF (M == "N".OR.M == "B") TE(2)=0.5
25563             ELSE IF (M == "2".AND.N == "2") THEN
25564                E(1,2)=1
25565                E(2,1)=1
25566                E(3,3)=-1
25567    !            IF (.NOT.(HMS(2,2)/="0" .OR. NBR == 6 .OR. HMS(1,2) == "0")) THEN
25568                IF (.NOT.(HMS(2,2)/=" " .OR. NBR == 6 .OR. HMS(1,2) == " ")) THEN
25569                   IF (HMS(1,2) == "1") TE(3)=0.75
25570                   IF (HMS(1,2) == "2") TE(3)=0.5
25571                   IF (HMS(1,2) == "3") TE(3)=0.25
25572                END IF
25573             ELSE IF (M == "2") THEN
25574                E(1,1)=1
25575                E(2,2)=-1
25576                E(3,3)=-1
25577                IF (N == "C") TE(3)=0.5
25578                IF (N == "D") TE(3)=0.25
25579                IF (N == "D") TE(2)=0.5
25580                IF (.NOT. (HMS(2,2) /= "1")) THEN
25581                   TE(1)=0.5
25582                   TE(2)=0.5
25583                END IF
25584             ELSE
25585                IF (M == "C" .OR. M == "N") TE(3)=0.5
25586                E(1,1)=-1
25587                E(2,2)=1
25588                E(3,3)=1
25589                IF (.NOT.(M /= "N" .AND. M /= "B") ) THEN
25590                   TE(1)=0.5
25591                   TE(2)=0.5
25592                END IF
25593             END IF
25594
25595          CASE(5)   !  HEXAGONAL  and TRIGONAL (RHOMBOHEDRAL)
25596             NG=3
25597             NE=6
25598             IF (HMS(1,1) == "3".OR.(HMS(1,2) == "3".AND.HMS(1,1) == "-")) NE=3
25599             M=HMS(1,1)
25600             N=HMS(1,2)
25601             IF (M == "-".AND.N == "3") NS=0
25602             IF (M == "6") THEN
25603                NG=NG+NG
25604                SS(1,1,2)=1
25605                SS(1,2,2)=-1
25606                SS(2,1,2)=1
25607                SS(3,3,2)=1
25608                IF (N == "1") TS(3,2)=1.0/6.0
25609                IF (N == "2") TS(3,2)=2.0/6.0
25610                IF (N == "3") TS(3,2)=3.0/6.0
25611                IF (N == "4") TS(3,2)=4.0/6.0
25612                IF (N == "5") TS(3,2)=5.0/6.0
25613                DO I=1,4
25614                   DO J=1,3
25615                      TS(J,2+I)=TS(J,2)
25616                      DO K=1,3
25617                         TS(J,2+I)=TS(J,2+I)+SS(J,K,2)*TS(K,1+I)
25618                         IF (TS(J,2+I) > 1.0) TS(J,2+I)=TS(J,2+I)-1.0
25619                         DO L=1,3
25620                            SS(J,K,2+I)=SS(J,K,2+I)+SS(J,L,2)*SS(L,K,1+I)
25621                         END DO
25622                      END DO
25623                   END DO
25624                END DO
25625                IF (NBL == 1) THEN
25626                   CALL MOD_TRANS(NG,NS,TS,ISYMCE)
25627                   RETURN
25628                END IF
25629
25630             ELSE
25631
25632                SS(1,2,2)=-1
25633                SS(2,1,2)=1
25634                SS(2,2,2)=-1
25635                SS(3,3,2)=1
25636                IF (N == "1") TS(3,2)=1.0/3.0
25637                IF (N == "2") TS(3,2)=2.0/3.0
25638                SS(1,1,3)=-1
25639                SS(2,1,3)=-1
25640                SS(1,2,3)=1
25641                SS(3,3,3)=1
25642                TS(3,3)=2.0*TS(3,2)
25643                IF (TS(3,3) >= 1.0) TS(3,3)=TS(3,3)-1.0
25644                IF (NBL == 1 .AND. N /= "6") THEN
25645                   CALL MOD_TRANS(NG,NS,TS,ISYMCE)
25646                   RETURN
25647                END IF
25648                IF (N == "6") THEN
25649                   NG=NG+NG
25650                   DO I=1,3
25651                      DO J=1,3
25652                         DO K=1,3
25653                            SS(J,K,3+I)=SS(J,K,I)
25654                            SS(3,3,3+I)=-1
25655                         END DO
25656                      END DO
25657                   END DO
25658                END IF
25659                IF (NBL == 1) THEN
25660                   CALL MOD_TRANS(NG,NS,TS,ISYMCE)
25661                   RETURN
25662                END IF
25663                IF (.NOT.(HMS(2,1)/="C".AND.HMS(3,1)/="C"))  THEN
25664                   TS(3,4)=0.5
25665                   TS(3,5)=0.5
25666                   TS(3,6)=0.5
25667                END IF
25668             END IF
25669
25670             NG=NG+NG
25671             M=HMS(2,1)
25672             N=HMS(3,1)
25673             IF (M == "1") THEN
25674                IF (N == "2") THEN
25675                   E(1,2)=-1
25676                   E(2,1)=-1
25677                   E(3,3)=-1
25678                   TE(3)=2.0*TS(3,2)
25679                   IF (TE(3) > 1.0) TE(3)=TE(3)-1.0
25680                ELSE
25681                   E(1,2)=1
25682                   E(2,1)=1
25683                   E(3,3)=1
25684                   IF (N == "C") TE(3)=0.5
25685                END IF
25686             ELSE IF (M == "2") THEN
25687                E(1,2)=1
25688                E(2,1)=1
25689                E(3,3)=-1
25690                TE(3)=2.0*TS(3,2)
25691                !---- GROUP P 31 I 2 AND P 32 I 2 ----!
25692                IF(HMS(1,1)=="3".AND.(HMS(1,2)=="1".OR.HMS(1,2)=="2")) TE(3)=0.0
25693             ELSE
25694                E(1,2)=-1
25695                E(2,1)=-1
25696                E(3,3)=1
25697                IF (M == "C") TE(3)=0.5
25698             END IF
25699
25700          CASE (6)    !  CUBIC
25701             NG=12
25702             IF (NBL == 3) NG=24
25703             IF (HMS(1,1)/="2".AND.HMS(1,1)/="4".AND.HMS(1,1)/="-") NS=0
25704             DO I=1,3
25705                DO J=1,3
25706                   SS(J,J,1+I)=1
25707                   IF (I/=J) THEN
25708                      SS(J,J,1+I)=-1
25709                      IF (HMS(1,1) == "N") TS(J,1+I)=0.5
25710                      IF (HMS(1,1) == "D") TS(J,1+I)=0.25
25711                   END IF
25712                END DO
25713             END DO
25714             IF (.NOT.((HMS(1,1) /="A".AND.HMS(3,1)/="D".AND.HMS(1,2)    &
25715                                 /="3" .AND.HMS(1,2)/="1".OR.NBR == 5))) THEN
25716                DO I=1,3
25717                   TS(I,1+I)=0.5
25718                   K=I+1
25719                   IF (K == 4) K=1
25720                   TS(K,1+I)=0.5
25721                END DO
25722             END IF
25723             DO I=1,4
25724                DO J=1,3
25725                   DO K=1,3
25726                      L=J+1
25727                      IF (L == 4) L=1
25728                      MM=J-1
25729                      IF (MM == 0) MM=3
25730                      SS(J,K,4+I)=SS(L,K ,I)
25731                      SS(J,K,8+I)=SS(MM,K,I)
25732                      TS(J,4+I)=TS(L ,I)
25733                      TS(J,8+I)=TS(MM,I)
25734                   END DO
25735                END DO
25736             END DO
25737             IF (NG == 12) THEN
25738                CALL MOD_TRANS(NG,NS,TS,ISYMCE)
25739                RETURN
25740             END IF
25741             NE=12
25742             E(1,2)=1
25743             E(2,1)=1
25744             E(3,3)=1
25745             IF (HMS(3,1) == "2") E(3,3)=-1
25746             IF (HMS(3,1) == "C") TE(3)=0.5
25747             DO I=1,3
25748                IF (HMS(3,1)=="N".OR.HMS(1,2)=="2") TE(I)=0.5
25749                IF (HMS(3,1)=="D".OR.HMS(1,2)=="1".OR.HMS(1,2)=="3") TE(I)=0.25
25750             END DO
25751             IF (HMS(1,2) == "1".AND.NBR == 1) TE(1)=0.75
25752             IF (.NOT.((HMS(1,2) /="1".OR.NBR/=6).AND.(HMS(1,2)   &
25753                                 /="3" .OR.NBR/=1))) THEN
25754                TE(2)=0.75
25755                TE(3)=0.75
25756             END IF
25757       END SELECT     ! On crystal system
25758
25759       if (sys == 4 .or. sys == 5 .or. sys == 6) then
25760          do i=1,ne
25761             do j=1,3
25762                ts(j,ne+i)=te(j)
25763                do k=1,3
25764                   ts(j,ne+i)=ts(j,ne+i)+e(j,k)*ts(k,i)
25765                   do l=1,3
25766                      ss(j,k,ne+i)=ss(j,k,ne+i)+e(j,l)*ss(l,k,i)
25767                   end do
25768                end do
25769             end do
25770          end do
25771       end if
25772
25773       call mod_trans(ng,ns,ts,isymce)
25774
25775       return
25776    End Subroutine Get_SO_from_HMS
25777
25778    !!----
25779    !!---- Subroutine Get_Stabilizer(X,Spg,Order,Ptr,Atr)
25780    !!----    real(kind=cp), dimension(3),  intent (in)  :: x     ! real(kind=cp) space position (fractional coordinates)
25781    !!----    type(Space_Group_type),       intent (in)  :: Spg   ! Space group
25782    !!----    integer,                      intent(out)  :: order ! Number of sym.op. keeping invariant the position x
25783    !!----    integer, dimension(:),        intent(out)  :: ptr   ! Array pointing to the symmetry operators numbers
25784    !!----                                                        ! of the stabilizer (point group) of x
25785    !!----    real(kind=cp), dimension(:,:),intent(out)  :: atr   ! Associated additional translation to the symmetry operator
25786    !!----
25787    !!----    Subroutine to obtain the list of symmetry operator of a space group that leaves
25788    !!----    invariant an atomic position. This subroutine provides a pointer to the symmetry
25789    !!----    operators of the site point group and the additional translation with respect to
25790    !!----    the canonical representant.
25791    !!----
25792    !!---- Update: June - 2011 (JRC)
25793    !!
25794    Subroutine Get_Stabilizer(X,Spg,Order,Ptr,Atr)
25795       !---- Arguments ----!
25796       real(kind=cp), dimension(3),  intent (in)  :: x     ! real space position (fractional coordinates)
25797       type(Space_Group_type),       intent (in)  :: Spg   ! Space group
25798       integer,                      intent(out)  :: order ! Number of sym.op. keeping invariant the position x
25799       integer, dimension(:),        intent(out)  :: ptr   ! Array pointing to the symmetry operators numbers
25800                                                           ! of the stabilizer of x
25801       real(kind=cp), dimension(:,:),intent(out)  :: atr   ! Associated additional translation to the symmetry operator
25802       !---- Local variables ----!
25803       real(kind=cp), dimension(3)    :: xx, tr
25804
25805       integer                        :: j,n1,n2,n3
25806
25807       order    = 1    !Identity belongs always to the stabilizer
25808       ptr(:)   = 0
25809       atr(:,:) = 0.0
25810       ptr(1)   = 1
25811
25812       do n1=-1,1
25813        do n2=-1,1
25814          do n3=-1,1
25815            tr=real((/n1,n2,n3/))
25816             do j=2,Spg%multip
25817                xx=ApplySO(Spg%SymOp(j),x)+tr-x
25818                if (sum(abs(xx)) > 2.0 * eps_symm) cycle
25819                order=order+1
25820                ptr(order)=j
25821                atr(:,order)=tr
25822             end do
25823          end do
25824        end do
25825       end do
25826
25827       return
25828    End Subroutine Get_Stabilizer
25829
25830    !!----
25831    !!---- Subroutine Get_String_Resolv(T,X,Ix,Symb)
25832    !!----    real(kind=cp), dimension(3), intent( in) :: t      !  In -> Traslation part
25833    !!----    real(kind=cp), dimension(3), intent( in) :: x      !  In -> real(kind=cp) part of variable
25834    !!----    integer, dimension(3),       intent( in) :: ix     !  In -> Frags: 1:x, 2:y, 3:z
25835    !!----    character (len=*),           intent(out) :: symb   ! Out -> String
25836    !!----
25837    !!----    Returning a string for point, axes or plane give as
25838    !!----    written in fractional form from Resolv_sist procedures.
25839    !!----
25840    !!---- Update: February - 2005
25841    !!
25842    Subroutine Get_String_Resolv(t,x,ix,symb)
25843       !---- Arguments ----!
25844       real(kind=cp), dimension(3),      intent( in) :: t
25845       real(kind=cp), dimension(3),      intent( in) :: x
25846       integer, dimension(3),   intent( in) :: ix
25847       character (len=*),       intent(out) :: symb
25848
25849       !---- Local Variables ----!
25850       character(len=60) :: car
25851       integer           :: i, np, npos
25852       real(kind=cp),dimension(3) :: xx
25853
25854       !---- Main ----!
25855       xx=x
25856       do i=1,3
25857          call get_fraction_2dig(x(i),car)
25858          np=index(car,"1/2")
25859          if (np > 0) then
25860             xx=2.0*x
25861             exit
25862          end if
25863       end do
25864
25865       symb=" "
25866       npos=1
25867       do i=1,3
25868          !---- Only t value ----!
25869          if (abs(xx(i)) <= eps_symm) then
25870             call get_fraction_2dig(t(i),car)
25871             car=adjustl(car)
25872             if (car(1:1) == "+") car=car(2:)
25873             np=len_trim(car)
25874             if (i < 3) then
25875                symb(npos:)=car(1:np)//", "
25876                npos=npos+np+2
25877             else
25878                symb(npos:)=car(1:np)
25879             end if
25880             cycle
25881          end if
25882
25883          call get_fraction_2dig(xx(i),car)
25884          car=adjustl(car)
25885          if (abs(abs(xx(i)) - 1.0) <= eps_symm) then
25886             if (car(1:2) == "+1") car=car(3:)
25887             if (car(1:2) == "-1") car(2:)=car(3:)
25888          else
25889             if (car(1:1) == "+") car=car(2:)
25890          end if
25891          np=len_trim(car)
25892          symb(npos:)=car(1:np)
25893          npos=npos+np
25894          select case (ix(i))
25895             case (1)
25896                symb(npos:)="x"
25897             case (2)
25898                symb(npos:)="y"
25899             case (3)
25900                symb(npos:)="z"
25901          end select
25902          npos=npos+1
25903          if (abs(t(i)) > 0.0 ) then
25904             call get_fraction_2dig(t(i),car)
25905             car=adjustl(car)
25906             np=len_trim(car)
25907             symb(npos:)=car(1:np)
25908             npos=npos+np
25909          end if
25910          if (i < 3) then
25911             symb(npos:)=", "
25912             npos=npos+2
25913          end if
25914
25915       end do
25916       symb=pack_string(symb)
25917
25918       return
25919    End Subroutine Get_String_Resolv
25920
25921    !!----
25922    !!----  Subroutine Get_SubOrbits(X,Spg,ptr,Mult,orb,ind,conv)
25923    !!----    real(kind=cp), dimension(3),  intent (in) :: x     !  In -> Position vector
25924    !!----    type(Space_Group_type),       intent (in) :: spgr  !  In -> Space Group
25925    !!----    integer,dimension(:),         intent( in) :: ptr   !  In -> Pointer to symops of a subgroup
25926    !!----    integer,                      intent(out) :: mult  !  Out -> Multiplicity
25927    !!----    real, dimension(:,:),         intent(out) :: orb   !  Out -> List of equivalent positions
25928    !!----    integer,dimension(:),         intent(out) :: ind   !  Out -> Integer giving the number of the suborbits
25929    !!----    character(len=*), optional,   intent( in) :: conv  !  In  -> If present centring transl. are considered
25930    !!----
25931    !!----    Obtain the multiplicity and list of equivalent positions
25932    !!----    modulo lattice translations (including centring!) of a
25933    !!----    position. When symmetry operators of a subgroup of Spg is given
25934    !!----    an index vector (ind) gives the division in subOrbits.
25935    !!----    The pointer ptr indicates the symmetry operators of Spg belonging
25936    !!----    to the subgroup. The first zero value of ptr terminates the search.
25937    !!----    If the optional argument "conv" is given the centring translations
25938    !!----    are considered. The orbits are formed by all atoms within a
25939    !!----    conventional unit cell. Otherwise the orbit is formed only with
25940    !!----    the content of a primitive cell.
25941    !!----
25942    !!---- Update: February - 2005
25943    !!
25944    Subroutine Get_SubOrbits(x,Spg,ptr,mult,orb,ind,conv)
25945       !---- Arguments ----!
25946       real(kind=cp), dimension(3),    intent (in) :: x
25947       type(Space_Group_type),         intent (in) :: spg
25948       integer,dimension(:),           intent( in) :: ptr
25949       integer,                        intent(out) :: mult
25950       real(kind=cp),dimension(:,:),   intent(out) :: orb
25951       integer,dimension(:),           intent(out) :: ind
25952       character(len=*), optional,     intent( in) :: conv
25953
25954       !---- Local variables ----!
25955       integer                                 :: i,j, nt,is, numorb
25956       real(kind=cp), dimension(3)             :: xx,v,xi
25957       character(len=1)                        :: laty
25958
25959       laty=Spg%spg_lat
25960       if(present(conv)) laty="P"
25961       ! First obtain the equivalent positions in the full group
25962       mult=1
25963       orb(:,1)=x(:)
25964       ext: do j=2,Spg%multip
25965          xx=ApplySO(Spg%SymOp(j),x)
25966          xx=modulo_lat(xx)
25967          do nt=1,mult
25968             v=orb(:,nt)-xx(:)
25969             if (Lattice_trans(v,laty)) cycle ext
25970          end do
25971          mult=mult+1
25972          orb(:,mult)=xx(:)
25973       end do ext
25974
25975       numorb=1
25976       ind=0
25977       do i=1,mult
25978        if(ind(i) /= 0) cycle
25979        xi=orb(:,i)
25980        do j=1,Spg%multip
25981           is= ptr(j)
25982           if(is == 0) exit
25983           xx=ApplySO(Spg%SymOp(is),xi)
25984           xx=modulo_lat(xx)
25985           do nt=1,mult
25986              if(ind(nt) /= 0) cycle
25987              v=orb(:,nt)-xx(:)
25988              if (Lattice_trans(v,laty)) then
25989                ind(nt)=numorb
25990                exit
25991              end if
25992           end do
25993        end do !j
25994        numorb=numorb+1
25995       end do !i
25996
25997       return
25998    End Subroutine Get_SubOrbits
25999
26000    !!----
26001    !!---- Subroutine Get_Symel(Sim,Xyzstring)
26002    !!----    integer, dimension(3,3), intent( in) :: sim         !  In -> Rotational part
26003    !!----    character (len=*),       intent(out) :: XYZstring   ! Out -> String
26004    !!----
26005    !!----    Supplies a string with the "symmetry element" (I.T.) for the
26006    !!----    rotation matrix Sim. They correspond to the symbols given in
26007    !!----    I.T. for space groups Pm3m and P6/mmm.
26008    !!----    Logical "hexa" must be defined
26009    !!----
26010    !!---- Update: February - 2005
26011    !!
26012    Subroutine Get_SymEl(Sim,Xyzstring)
26013       !---- Arguments ----!
26014       integer,dimension (3,3), intent( in) :: sim
26015       character (len=*),       intent(out) :: XYZstring
26016
26017       !---- Local Variables ----!
26018       integer :: Iu,i1,i2,j
26019
26020       if (.not. hexa) then
26021          i1=1
26022          i2=24
26023       else
26024          i1=25
26025          i2=36
26026       end if
26027       call SearchOp(sim,i1,i2,Iu)
26028
26029       if (.not. hexa) then
26030          j=abs(Iu)
26031          if (Iu < 0) j=j+24
26032          XYZstring=IntSymOh(j)
26033       else
26034          j=abs(Iu)-24
26035          if (Iu < 0) j=j+12
26036          XYZstring=IntSymD6h(j)
26037       end if
26038
26039       return
26040    End Subroutine Get_SymEl
26041
26042    !!----
26043    !!---- Subroutine Get_Symkov(Sim,Xyzstring)
26044    !!----    integer, dimension(3,3), intent( in) :: sim        !  In -> Rotational part
26045    !!----    character (len=*),       intent(out) :: XYZstring
26046    !!----
26047    !!----    Supplies a string with the "symmetry element" (I.T.) for the rotation
26048    !!----    matrix Sim. They correspond to the symbols Kovalev.
26049    !!----    Logical "hexa" must be defined
26050    !!----
26051    !!---- Update: February - 2005
26052    !!
26053    Subroutine Get_SymKov(Sim,Xyzstring)
26054       !---- Arguments ----!
26055       integer,dimension (3,3), intent( in) :: sim
26056       character (len=*),       intent(out) :: XYZstring
26057
26058       !---- Local variables ----!
26059       integer :: Iu,i1,i2,j
26060
26061       if (.not. hexa) then
26062          i1=1
26063          i2=24
26064       else
26065          i1=25
26066          i2=36
26067       end if
26068       call SearchOp(sim,i1,i2,Iu)
26069
26070       if (.not. hexa) then
26071          j=abs(Iu)
26072          if (Iu < 0) j=j+24
26073          XYZstring=IntSymOh(j)//" -> "//Kov_Oh(j)
26074       else
26075          j=abs(Iu)-24
26076          if (Iu < 0) j=j+12
26077          XYZstring=IntSymD6h(j)//" -> "//Kov_D6h(j)
26078       end if
26079
26080       return
26081    End Subroutine Get_SymKov
26082
26083    !!----
26084    !!---- Subroutine Get_SymSymb(Sim,Tt,Strsym)
26085    !!----    real(kind=cp)/integer, dimension(3,3), intent( in)    :: sim      !  In -> Rotational part of the S.O.
26086    !!----    real(kind=cp), dimension( 3),          intent( in)    :: tt       !  In -> Translational part of the S.O.
26087    !!----    character (len=*),                     intent(out)    :: Strsym   ! Out -> String in th form X,Y,-Z, ...
26088    !!----
26089    !!----    Obtain the Jones Faithful representation of a symmetry operator
26090    !!----
26091    !!---- Update: February - 2005
26092    !!
26093
26094    !!--++
26095    !!--++ Subroutine Get_SymsymbI(Sim,Tt,Strsym)
26096    !!--++    integer, dimension(3,3),      intent( in)    :: sim      !  In -> Rotational part of the S.O.
26097    !!--++    real(kind=cp), dimension( 3), intent( in)    :: tt       !  In -> Translational part of the S.O.
26098    !!--++    character (len=*),            intent(out)    :: Strsym   ! Out -> String in th form X,Y,-Z, ...
26099    !!--++
26100    !!--++    (OVERLOADED)
26101    !!--++    Obtain the Jones Faithful representation of a symmetry operator
26102    !!--++
26103    !!--++ Update: February - 2005, January-2014 (changed for a more robust algorithm,JRC)
26104    !!
26105    Subroutine Get_SymSymbI(X,T,Symb)
26106       !---- Arguments ----!
26107       integer,       dimension(3,3), intent( in) :: x
26108       real(kind=cp), dimension(3),   intent( in) :: t
26109       character (len=*),          intent(out) :: symb
26110
26111       !---- Local Variables ----!
26112       character(len=*),dimension(3),parameter :: xyz=(/"x","y","z"/)
26113       character(len= 25)              :: car
26114       character(len= 25),dimension(3) :: sym
26115       integer           :: i,j
26116
26117       !---- Main ----!
26118       symb=" "
26119       do i=1,3
26120          sym(i)=" "
26121          do j=1,3
26122             if(x(i,j) == 1) then
26123                sym(i) = trim(sym(i))//"+"//xyz(j)
26124             else if(x(i,j) == -1) then
26125                sym(i) =  trim(sym(i))//"-"//xyz(j)
26126             else if(x(i,j) /= 0) then
26127               car=" "
26128               write(unit=car,fmt="(i3,a)") x(i,j),xyz(j)
26129               if(x(i,j) > 0) car="+"//trim(car)
26130               sym(i)=trim(sym(i))//pack_string(car)
26131             end if
26132          end do
26133          if (abs(t(i)) > eps_symm ) then
26134             call get_fraction_2dig(t(i),car)
26135             sym(i)=trim(sym(i))//trim(car)
26136          end if
26137          sym(i)=adjustl(sym(i))
26138          if(sym(i)(1:1) == "+")  then
26139            sym(i)(1:1) = " "
26140            sym(i)=adjustl(sym(i))
26141          end if
26142          sym(i)=pack_string(sym(i))
26143       end do
26144       symb=trim(sym(1))//","//trim(sym(2))//","//trim(sym(3))
26145       return
26146    End Subroutine Get_SymSymbI
26147
26148    !!--++
26149    !!--++  Subroutine Get_SymSymbR(X,T,Symb)
26150    !!--++     real(kind=cp),    dimension(3,3),    intent( in) :: x
26151    !!--++     real(kind=cp),    dimension(3),      intent( in) :: t
26152    !!--++     character (len=*),                   intent(out) :: symb
26153    !!--++
26154    !!--++     (OVERLOADED)
26155    !!--++     Returning a string for symmetry operators or for points, axes or plane give as
26156    !!--++     written in fractional form
26157    !!--++
26158    !!--++ Update: February - 2005
26159    !!
26160    Subroutine Get_SymSymbR(X,T,Symb)
26161       !---- Arguments ----!
26162       real(kind=cp),    dimension(3,3), intent( in) :: x
26163       real(kind=cp),    dimension(3),   intent( in) :: t
26164       character (len=*),                intent(out) :: symb
26165
26166       !---- Local Variables ----!
26167       character(len= 25):: car
26168       integer           :: i,j,k, np,npp,npos
26169       real(kind=cp)     :: suma
26170
26171       !---- Main ----!
26172       symb=" "
26173       npos=1
26174       do i=1,3
26175          npp=0
26176          do j=1,3
26177             if (abs(x(i,j)) > 0.0 ) then
26178                call get_fraction_2dig(x(i,j),car)
26179                car=adjustl(car)
26180                if (abs(abs(x(i,j))-1.0) <= eps_symm) then
26181                     if (npp == 0) then
26182                        select case (car(1:2))
26183                           case ("-1")
26184                              car(2:)=car(3:)//"  "
26185                           case ("+1")
26186                              car=car(3:)//"  "
26187                        end select
26188                     else
26189                        car(2:)=car(3:)//"  "
26190                     end if
26191                else
26192                   if (npp == 0) then
26193                      if (car(1:1) =="+") then
26194                         car=car(2:)//"  "
26195                      end if
26196                   end if
26197                end if
26198
26199                np=len_trim(car)
26200                select case (j)
26201                   case (1)
26202                      k=index(car(1:np),"/")
26203                      if( k /= 0) then
26204                        if(car(k-1:k-1) == "1") then
26205                          car(k-1:k-1) = "x"
26206                          symb(npos:)=car(1:np)
26207                        else
26208                          symb(npos:)=car(1:k-1)//"x"//car(k:np)
26209                        end if
26210                      else
26211                        symb(npos:)=car(1:np)//"x"
26212                      end if
26213                   case (2)
26214                      k=index(car(1:np),"/")
26215                      if( k /= 0) then
26216                        if(car(k-1:k-1) == "1") then
26217                          car(k-1:k-1) = "y"
26218                          symb(npos:)=car(1:np)
26219                        else
26220                          symb(npos:)=car(1:k-1)//"y"//car(k:np)
26221                        end if
26222                      else
26223                        symb(npos:)=car(1:np)//"y"
26224                      end if
26225                   case (3)
26226                      k=index(car(1:np),"/")
26227                      if( k /= 0) then
26228                        if(car(k-1:k-1) == "1") then
26229                          car(k-1:k-1) = "z"
26230                          symb(npos:)=car(1:np)
26231                        else
26232                          symb(npos:)=car(1:k-1)//"z"//car(k:np)
26233                        end if
26234                      else
26235                        symb(npos:)=car(1:np)//"z"
26236                      end if
26237                end select
26238                npos=len_trim(symb)+1
26239                npp=npos
26240             end if
26241          end do
26242
26243          if (abs(t(i)) <= eps_symm .and. npp /= 0) then
26244             if (i < 3) then
26245                symb(npos:)=", "
26246                npos=len_trim(symb)+2
26247             end if
26248             cycle
26249          end if
26250
26251          call get_fraction_2dig(t(i),car)
26252          car=adjustl(car)
26253          suma=0.0
26254          do j=1,3
26255             suma=suma+abs(x(i,j))
26256          end do
26257          np=len_trim(car)
26258          if (suma <= 3.0*eps_symm) then
26259             if (car(1:1) == "+") car=car(2:np)//" "
26260          end if
26261
26262          if (i < 3) then
26263             symb(npos:)=car(1:np)//", "
26264             npos=len_trim(symb)+2
26265          else
26266             symb(npos:)=car(1:np)
26267          end if
26268       end do
26269
26270       symb=pack_string(symb)
26271
26272       return
26273    End Subroutine Get_SymSymbR
26274
26275    !!----
26276    !!---- Subroutine Get_T_SubGroups(SpG,SubG,nsg,point)
26277    !!----    type (Space_Group_Type) ,             intent( in) :: SpG
26278    !!----    type (Space_Group_Type) ,dimension(:),intent(out) :: SubG
26279    !!----    integer,                              intent(out) :: nsg
26280    !!----    logical, dimension(:,:), optional,    intent(out) :: point
26281    !!----
26282    !!----    Subroutine to obtain the list of all non-trivial translationengleiche
26283    !!----    subgroups (t-subgroups) of a given space group. The unit cell setting
26284    !!----    is supposed to be the same as that of the input space group "SpG"
26285    !!----    The search of space sub-groups is performed using a systematic combination
26286    !!----    of the symmetry operators of the group.
26287    !!----    The optional argument point has dimensions (SpG%multip,nsg) and contains
26288    !!----    true point(i,j)=.true. if the operator i of the space group SpG belongs
26289    !!----    to the subgroup SubG(j).
26290    !!----
26291    !!---- Update: February - 2005, April 2015
26292    !!
26293    Subroutine Get_T_SubGroups(SpG,SubG,nsg,point)
26294       !---- Arguments ----!
26295       type (Space_Group_Type) ,             intent( in) :: SpG
26296       type (Space_Group_Type) ,dimension(:),intent(out) :: SubG
26297       integer,                              intent(out) :: nsg
26298       logical, dimension(:,:), optional,    intent(out) :: point
26299       !--- Local variables ---!
26300       integer                            :: i,L,j,k, nc, maxg,ng , nla, i1,i2,nop
26301       character (len=30), dimension(192) :: gen
26302       logical                            :: newg, cen_added
26303
26304       maxg=size(SubG)
26305       !---- Construct first the generators of centring translations ----!
26306       ng=0
26307       nop=SpG%numops !number of symmetry operators excluding lattice centrings
26308       if (SpG%centred /= 1) nop=nop*2
26309       do i=2,SpG%numlat
26310          ng=ng+1
26311          gen(ng)= SpG%SymopSymb(1+nop*(i-1))
26312       end do
26313
26314       nla=ng
26315       nc=SpG%Numops+1  !Position of the centre of symmetry if it exist
26316       L=0
26317       !---- Determine first the triclinic subgroups
26318       cen_added=.false.
26319       do
26320           L=L+1
26321           newg=.true.
26322           call set_spacegroup(" ",SubG(L),gen,ng,"gen")
26323           do j=1,L-1
26324              if (SpGr_Equal(SubG(L), SubG(j))) then
26325                 newg=.false.
26326                 exit
26327              end if
26328           end do
26329           if (newg) then
26330              call get_HallSymb_from_gener(SubG(L))
26331           else
26332              L=L-1
26333           end if
26334           if (SpG%centred /= 1 .and. newg .and. .not. cen_added) then !add the centre of symmetry if needed
26335              ng=ng+1
26336              gen(ng)=SpG%SymopSymb(nc)
26337              cen_added=.true.
26338           else
26339              exit
26340           end if
26341       end do
26342
26343       !---- Determine first the groups with only one rotational generator
26344       do i=2,nop
26345          ng=nla+1
26346          gen(ng) = SpG%SymopSymb(i)
26347          cen_added=.false.
26348          do
26349             L=L+1
26350             if (L > maxg) then
26351                nsg=maxg
26352                return
26353             end if
26354             newg=.true.
26355             call set_spacegroup(" ",SubG(L),gen,ng,"gen")
26356             do j=1,L-1
26357                if (SpGr_Equal(SubG(L), SubG(j))) then
26358                   newg=.false.
26359                   exit
26360                end if
26361             end do
26362             if (newg) then
26363                call get_HallSymb_from_gener(SubG(L))
26364             else
26365                L=L-1
26366             end if
26367             if (SpG%centred /= 1 .and. newg .and. .not. cen_added) then !add the centre of symmetry if needed
26368                ng=ng+1
26369                gen(ng)=SpG%SymopSymb(nc)
26370                cen_added=.true.
26371             else
26372                exit
26373             end if
26374          end do
26375       end do
26376
26377       !---- Determine now the groups with two rotational generator ----!
26378
26379       do i1=2,nop-1
26380          gen(nla+1) = SpG%SymopSymb(i1)
26381          do i2 = i1+1,nop
26382             gen(nla+2) = SpG%SymopSymb(i2)
26383             ng=nla+2
26384             cen_added=.false.
26385             do
26386                L=L+1
26387                if (L > maxg) then
26388                   nsg=maxg
26389                   return
26390                end if
26391                newg=.true.
26392                call set_spacegroup(" ",SubG(L),gen,ng,"gen")
26393                do j=1,L-1
26394                   if (SpGr_Equal(SubG(L), SubG(j))) then
26395                      newg=.false.
26396                      exit
26397                   end if
26398                end do
26399                if (newg) then
26400                   call get_HallSymb_from_gener(SubG(L))
26401                else
26402                   L=L-1
26403                end if
26404                if (SpG%centred /= 1 .and. newg .and. .not. cen_added) then !add the centre of symmetry if needed
26405                   ng=ng+1
26406                   gen(ng)=SpG%SymopSymb(nc)
26407                   cen_added=.true.
26408                else
26409                   exit
26410                end if
26411             end do
26412          end do
26413       end do
26414       nsg=L
26415       if(present(point)) then
26416         point=.false.
26417         do j=1,nsg
26418           L=1
26419           do i=1,SpG%multip
26420              do k=L,SubG(j)%multip
26421               if(SubG(j)%SymopSymb(k) == SpG%SymopSymb(i)) then
26422                  point(i,j) = .true.
26423                  L=k+1
26424                  exit
26425               end if
26426              end do
26427           end do
26428         end do
26429       end if
26430
26431       return
26432    End Subroutine Get_T_SubGroups
26433
26434    !!----
26435    !!---- Subroutine Get_Trasfm_Symbol(Mat,tr,abc_symb,oposite)
26436    !!----    integer, dimension(3,3), intent(in) :: Mat
26437    !!----    real,    dimension(3),   intent(in) :: tr
26438    !!----    character(len=*),        intent(out):: abc_symb
26439    !!----    logical,optional,        intent(in) :: oposite
26440    !!----
26441    !!----    Provides the short symbol for a setting change defined by
26442    !!----    the transfomation matrix Mat and origin given by the translation
26443    !!----    vector tr. For instance given the matrix:
26444    !!----
26445    !!----     1  0 -1                      a'=a-c
26446    !!----     0  2  0   corresponding to   b'=2b
26447    !!----     1  0  1                      c'=a+c
26448    !!----     And the change of origin given by (0.5,0.0,0.5)
26449    !!----     The subroutine provide the symbol: (1/2,0,1/2; a-c,2b,a+c)
26450    !!----     If "oposite" is provided theh the symbol: (a-c,2b,a+c; 1/2,0,1/2)
26451    !!----
26452    !!----
26453    !!---- Update: November - 2012, February 2016 (optional argument)
26454    !!
26455    Subroutine Get_Trasfm_Symbol(Mat,tr,abc_symb,oposite)
26456      integer,       dimension(3,3), intent(in) :: Mat
26457      real(kind=cp), dimension(3),   intent(in) :: tr
26458      character(len=*),              intent(out):: abc_symb
26459      logical,optional,              intent(in) :: oposite
26460      !---- Local variables ----!
26461      integer :: i
26462      character(len=25) :: xyz_op, transl
26463      character(len=6)  :: Fracc
26464      call Get_SymSymb(Mat,(/0.0_cp,0.0_cp,0.0_cp/),xyz_op)
26465      do i=1,len_trim(xyz_op)
26466        if(xyz_op(i:i) == "x")  xyz_op(i:i)="a"
26467        if(xyz_op(i:i) == "y")  xyz_op(i:i)="b"
26468        if(xyz_op(i:i) == "z")  xyz_op(i:i)="c"
26469      end do
26470      transl=" "
26471      do i=1,3
26472        call Get_Fraction_2Dig(tr(i),Fracc)
26473        transl=trim(transl)//trim(Fracc)//","
26474      end do
26475      i=len_trim(transl)
26476      transl(i:i)=";"
26477      do i=1,len_trim(transl)-2
26478        if(transl(i:i) == "+") transl(i:i)=" "
26479      end do
26480      transl=Pack_string(transl)
26481      abc_symb="("//trim(transl)//" "//trim(xyz_op)//")"
26482      if(present(oposite)) then
26483        i=len_trim(transl)
26484        abc_symb="("//trim(xyz_op)//"; "//transl(1:i-1)//")"
26485      end if
26486      return
26487    End Subroutine Get_Trasfm_Symbol
26488
26489    !!----
26490    !!---- Subroutine Get_Transl_Symbol(tr,Transl_symb)
26491    !!----   real,    dimension(3),   intent(in) :: tr
26492    !!----   character(len=*),        intent(out):: Transl_symb
26493    !!----
26494    !!----    Provides the short symbol for a translation vector
26495    !!----    for which the coordinates are given as fractional symbols
26496    !!----
26497    !!---- Update: November - 2012
26498    !!
26499    Subroutine Get_Transl_Symbol(tr,Transl_symb)
26500      real(kind=cp), dimension(3),   intent(in) :: tr
26501      character(len=*),              intent(out):: Transl_symb
26502      !---- Local variables ----!
26503      integer :: i
26504      character(len=25) :: transl
26505      character(len=6)  :: Fracc
26506
26507      transl=" "
26508      do i=1,3
26509        call Get_Fraction_2Dig(tr(i),Fracc)
26510        transl=trim(transl)//trim(Fracc)//","
26511      end do
26512      i=len_trim(transl)
26513      transl(i:i)=" "
26514      do i=1,len_trim(transl)
26515        if(transl(i:i) == "+") transl(i:i)=" "
26516      end do
26517      Transl_symb="("//trim(transl)//")"
26518      return
26519    End Subroutine Get_Transl_Symbol
26520
26521    !!----
26522    !!---- Subroutine Init_Err_Symm()
26523    !!----
26524    !!----    Initialize the errors flags in this Module
26525    !!----
26526    !!---- Update: February - 2005
26527    !!
26528    Subroutine Init_Err_Symm()
26529
26530       err_symm=.false.
26531       ERR_Symm_Mess=" "
26532
26533       return
26534    End Subroutine Init_Err_Symm
26535
26536    !!----
26537    !!---- Subroutine Inverse_Symm(R,T,S,U)
26538    !!----    integer, dimension(3,3),     intent(in)  :: R     !  In -> Rotational Part
26539    !!----    real(kind=cp), dimension(3), intent(in)  :: t     !  In -> Traslational part
26540    !!----    integer, dimension(3,3),     intent(out) :: S     ! Out -> New Rotational part
26541    !!----    real(kind=cp), dimension(3), intent(out) :: u     ! Out -> new traslational part
26542    !!----
26543    !!----    Calculates the inverse of the symmetry operator (R,t)
26544    !!----
26545    !!---- Update: February - 2005
26546    !!
26547    Subroutine Inverse_Symm(R,t,S,u)
26548       !---- Arguments ----!
26549       integer, dimension(3,3),     intent(in)  :: R
26550       real(kind=cp), dimension(3), intent(in)  :: t
26551       integer, dimension(3,3),     intent(out) :: S
26552       real(kind=cp), dimension(3), intent(out) :: u
26553
26554       !---- Local variables ----!
26555       integer                        :: ifail
26556       real(kind=cp), dimension(3,3)  :: a,b
26557
26558       call init_err_symm()
26559       a=real(r)
26560       s=0
26561       u=0.0
26562
26563       call matrix_inverse(a,b,ifail)
26564       if (ifail /= 0) then
26565          err_symm=.true.
26566          ERR_Symm_Mess= "Inversion Matrix Failed"
26567          return
26568       end if
26569       s=nint(b)
26570       u=matmul(-b,t)
26571
26572       return
26573    End Subroutine Inverse_Symm
26574
26575    !!----
26576    !!---- Subroutine Latsym(Symb,Numl,Latc)
26577    !!----    character (len=*),                       intent(in)  :: SYMB  !  In -> Space Group H-M/Hall symbol
26578    !!----    integer, optional,                       intent(in)  :: numL  !  Number of centring vectors
26579    !!----    real(kind=cp),optional, dimension(:,:),  intent(in)  :: latc  !  Centering vectors
26580    !!----
26581    !!--<<        Inlat  Lattice type & associated translations
26582    !!----          1     P: { 000 }
26583    !!----          2     A: { 000;  0  1/2 1/2 }+
26584    !!----          3     B: { 000; 1/2  0  1/2 }+
26585    !!----          4     C: { 000; 1/2 1/2  0  }+
26586    !!----          5     I: { 000; 1/2 1/2 1/2 }+
26587    !!----          6     R: { 000; 2/3 1/3 1/3; 1/3 2/3 2/3   } +
26588    !!----          7     F: { 000;  0  1/2 1/2; 1/2  0  1/2; 1/2 1/2  0 } +
26589    !!----          8     Z: { 000;  user-given centring vectors } +
26590    !!-->>
26591    !!----    Provides the Lattice type of the S.G. SYMB. Also gives the index (Inlat)
26592    !!----    of the lattice, the multiplicity (Nlat) and the fractionnal lattice translations
26593    !!----    ((Ltr(in,j)j=1,3),in=1,Nlat) and Lat_Ch.
26594    !!----
26595    !!---- Update: February - 2005, January 2014 (JRC)
26596    !!
26597    Subroutine LatSym(SYMB,numL,latc)
26598       !---- Argument ----!
26599       character(len=*),                        intent(in)  :: SYMB
26600       integer, optional,                       intent(in)  :: numL
26601       real(kind=cp),optional, dimension(:,:),  intent(in)  :: latc  !general vector (JRC, Jan2014)
26602
26603       !---- Local variables ----!
26604       character(len=1)                        :: LAT
26605       character(len=len(symb))                :: SYMBB
26606       integer                                 :: i
26607
26608       call init_err_symm()
26609       symbb=adjustl(symb)
26610       do i=1,len_trim(symbb)
26611          if (symbb(i:i) == "-" .or. symbb(i:i) == " ") cycle
26612          lat=symbb(i:i)
26613          exit
26614       end do
26615
26616       nlat=1
26617       ltr(:,1)=0.0
26618       select case (lat)
26619          case ("P","p")
26620             lat="P"
26621             nlat=1
26622             inlat=1
26623
26624          case ("A","a")
26625             lat="A"
26626             nlat=2
26627             inlat=2
26628             ltr(1,2)=0.0
26629             ltr(2,2)=0.5
26630             ltr(3,2)=0.5
26631
26632          case ("B","b")
26633             lat="B"
26634             nlat=2
26635             inlat=3
26636             ltr(1,2)=0.5
26637             ltr(2,2)=0.0
26638             ltr(3,2)=0.5
26639
26640          case ("C","c")
26641             lat="C"
26642             nlat=2
26643             inlat=4
26644             ltr(1,2)=0.5
26645             ltr(2,2)=0.5
26646             ltr(3,2)=0.0
26647
26648          case ("I","i")
26649             lat="I"
26650             nlat=2
26651             inlat=5
26652             ltr(:,2)=0.5
26653
26654          case ("R","r")
26655             lat="R"
26656             nlat=3
26657             inlat=6
26658             ltr(1,2)=2.0/3.0
26659             ltr(2,2)=1.0/3.0
26660             ltr(3,2)=1.0/3.0
26661             ltr(1,3)=1.0/3.0
26662             ltr(2,3)=2.0/3.0
26663             ltr(3,3)=2.0/3.0
26664
26665          case ("F","f")
26666             lat="F"
26667             nlat=4
26668             inlat=7
26669             ltr(1,2)=0.5
26670             ltr(2,2)=0.5
26671             ltr(3,2)=0.0
26672             ltr(1,3)=0.5
26673             ltr(2,3)=0.0
26674             ltr(3,3)=0.5
26675             ltr(1,4)=0.0
26676             ltr(2,4)=0.5
26677             ltr(3,4)=0.5
26678
26679          case ("Z","z","X","x")
26680             if(present(numL) .and. present(latc)) then
26681              lat="Z"
26682              nlat=numL+1
26683              !nlat=min(nlat,12) !restriction removed in January 2014
26684              inlat=8
26685              do i=2,nlat
26686                ltr(:,i)=latc(:,i-1)
26687              end do
26688             else
26689               err_symm=.true.
26690               ERR_Symm_Mess="Unconventional Lattice Symbol Z needs centring vectors"
26691             end if
26692          case default
26693             err_symm=.true.
26694             ERR_Symm_Mess="Wrong Lattice Symbol "//LAT
26695       end select
26696
26697       Lat_Ch=LAT
26698
26699       return
26700    End Subroutine Latsym
26701
26702    !!--++
26703    !!--++ Subroutine Max_Conv_Lattice_Type(L, Latc, Lattyp)
26704    !!--++    integer,                        intent(in)  :: L         !  number of centring vectors
26705    !!--++    real(kind=cp), dimension(:,:),  intent(in)  :: Latc      ! (3,11) centring vectors
26706    !!--++    character(len=*),               intent(out) :: lattyp    ! Lattice symbol
26707    !!--++
26708    !!--++    (PRIVATE)
26709    !!--++    Subroutine to get the maximum conventional lattice symbol from
26710    !!--++    a set of possible centring vectors.
26711    !!--++    Used by subroutine: Similar_Transf_SG
26712    !!--++
26713    !!--++ Update: February - 2005
26714    !!
26715    Subroutine Max_Conv_Lattice_Type(L, Latc, lattyp)
26716       !---- Arguments ----!
26717       integer,                        intent( in) :: L
26718       real(kind=cp), dimension(:,:),  intent( in) :: Latc
26719       character(len=*),               intent(out) :: lattyp
26720
26721       !---- Local variables ----!
26722       logical                            :: latt_p, latt_a, latt_b, latt_c, latt_i, latt_r, latt_f
26723       integer, dimension(3)              :: tt
26724       integer                            :: i, j
26725       integer, dimension(3,6), parameter :: lattice=reshape((/0,6,6, 6,0,6, &
26726                                                     6,6,0, 6,6,6, 8,4,4, 4,8,8/),(/3,6/))
26727
26728       if (l == 0) then !primitive lattice
26729          lattyp="P"
26730          return
26731       end if
26732
26733       latt_p=.true.
26734       latt_a=.false.
26735       latt_b=.false.
26736       latt_c=.false.
26737       latt_i=.false.
26738       latt_r=.false.
26739       latt_f=.false.
26740
26741       do i=1,L
26742          tt(1:3)=nint(12.0 * Latc(1:3,i))   ! Translations x 12
26743
26744          !---- Compare the translation part of the operator with tabulated array ----!
26745          do j=1,6
26746             if (equal_vector(tt,lattice(:,j),3)) then
26747                select case (j)
26748                   case (1)
26749                      latt_a=.true.
26750                   case (2)
26751                      latt_b=.true.
26752                   case (3)
26753                      latt_c=.true.
26754                   case (4)
26755                      latt_i=.true.
26756                   case (5,6)
26757                      latt_r=.true.
26758                end select
26759                exit
26760             end if
26761          end do
26762       end do
26763
26764       !---- Lattice Type ----!
26765       if ( (latt_a .and. latt_b .and. latt_c) .or. (latt_a .and. latt_b) .or. &
26766            (latt_a .and. latt_c) .or. (latt_b .and. latt_c) ) then
26767            latt_f=.true.
26768            latt_a=.false.
26769            latt_b=.false.
26770            latt_c=.false.
26771            latt_p=.false.
26772            latt_i=.false.
26773       end if
26774       if (latt_p) lattyp="P"
26775       if (latt_a) lattyp="A"
26776       if (latt_b) lattyp="B"
26777       if (latt_c) lattyp="C"
26778       if (latt_i) lattyp="I"
26779       if (latt_r) lattyp="R"
26780       if (latt_f) lattyp="F"
26781
26782       return
26783    End Subroutine Max_Conv_Lattice_Type
26784
26785    !!--++
26786    !!--++ Subroutine Mod_Trans(Ng, Ns, Ts, Isymce)
26787    !!--++    integer, intent( in)                           :: ng      ! In -> Number of operators
26788    !!--++    integer, intent( in)                           :: ns      ! In ->
26789    !!--++    real(kind=cp), dimension(3,24), intent(in out) :: ts      ! In -> Traslation part
26790    !!--++                                                                Out ->
26791    !!--++    integer, intent(out),optional                  :: isymce  ! Out -> Origin information
26792    !!--++                                                                0= Ccenter of Inversion in the Origin
26793    !!--++                                                                1= Non centrosymmetric
26794    !!--++                                                                2= Center of Inversion out of origin
26795    !!--++
26796    !!--++    (PRIVATE)
26797    !!--++    Subroutine used by Get_SO_from_HMS.
26798    !!--++    Put all tranlations in conventional form (positive and less than 1)
26799    !!--++    Provides Isymce
26800    !!--++
26801    !!--++ Update: February - 2005
26802    !!
26803    Subroutine Mod_Trans(Ng,Ns,Ts,Isymce)
26804       !---- Arguments ----!
26805       integer, intent(          in)                  :: ng,ns
26806       real(kind=cp), dimension(3,24), intent(in out) :: ts
26807       integer, intent(out),optional                  :: isymce
26808
26809       !---- Local Variables ----!
26810       integer :: i
26811
26812       do i=1,ng
26813          ts(:,i)=modulo_lat(ts(:,i))
26814       end do
26815       if (present(isymce)) isymce=2-ns
26816
26817       return
26818    End Subroutine Mod_Trans
26819
26820    !!----
26821    !!---- Subroutine Read_Bin_Spacegroup(SpG,Lun,ok)
26822    !!----    type (Space_Group),  intent(out) :: SpG   !  Out -> SpaceGroup Variable
26823    !!----    integer,             intent(in)  :: Lun   !  In -> Logical unit of the file
26824    !!----    logical,             intent(out) :: ok    !  .true. if everything is OK
26825    !!----
26826    !!----    Reading in file of logical unit "lun" the full structure of Space_Group_Type, SpG
26827    !!----    The file should have been opened with the access="stream" attribute. The procedure
26828    !!----    reads in the given order a series of bytes corresponding to the components of the
26829    !!----    type SpG.
26830    !!----
26831    !!---- Update: February - 2013
26832    !!
26833    Subroutine Read_Bin_SpaceGroup(SpG,lun,ok)
26834       !---- Arguments ----!
26835       type (Space_Group_Type),intent(out) :: SpG
26836       integer,                intent(in)  :: lun
26837       logical,                intent(out) :: ok
26838
26839       !---- Local variables ----!
26840       integer                           :: i,j,ier
26841
26842       ok=.true.
26843       read(unit=Lun,iostat=ier) SpG%NumSpg,        &   ! Number of the Space Group
26844                                 SpG%SPG_Symb,      &   ! Hermann-Mauguin Symbol
26845                                 SpG%Hall,          &   ! Hall symbol
26846                                 SpG%CrystalSys,    &   ! Crystal system
26847                                 SpG%Laue,          &   ! Laue Class
26848                                 SpG%PG,            &   ! Point group
26849                                 SpG%Info,          &   ! Extra information
26850                                 SpG%SG_setting,    &   ! Information about the SG setting (IT,KO,ML,ZA,Table,Standard,UnConventional)
26851                                 SpG%Hexa,          &   !
26852                                 SpG%SPG_lat,       &   ! Lattice type
26853                                 SpG%SPG_latsy,     &   ! Lattice type Symbol
26854                                 SpG%NumLat             ! Number of lattice points in a cell
26855       if(ier /= 0) then
26856        ok=.false.
26857        return
26858       end if
26859
26860       if(allocated(SpG%Latt_trans)) deallocate(SpG%Latt_trans)
26861       allocate(SpG%Latt_trans(3,SpG%NumLat))
26862
26863       read(unit=Lun,iostat=ier) SpG%Latt_trans,    &   ! Lattice translations
26864                                 SpG%Bravais,       &   ! String with Bravais symbol + translations
26865                                 SpG%Centre,        &   ! Alphanumeric information about the center of symmetry
26866                                 SpG%Centred,       &   ! Centric or Acentric [ =0 Centric(-1 no at origin),=1 Acentric,=2 Centric(-1 at origin)]
26867                                 SpG%Centre_coord,  &   ! Fractional coordinates of the inversion centre
26868                                 SpG%NumOps,        &   ! Number of reduced set of S.O.
26869                                 SpG%Multip,        &   ! Multiplicity of the general position
26870                                 SpG%Num_gen            ! Minimum number of operators to generate the Group
26871       if(ier /= 0) then
26872        ok=.false.
26873        return
26874       end if
26875
26876       if(allocated(SpG%SymOp)) deallocate(SpG%SymOp)
26877       allocate(SpG%SymOp(SpG%Multip))
26878       if(allocated(SpG%SymOpSymb)) deallocate(SpG%SymOpSymb)
26879       allocate(SpG%SymOpSymb(SpG%Multip))
26880
26881       do i=1,SpG%Multip
26882         read(unit=Lun,iostat=ier) SpG%SymOp(i)%Rot,SpG%SymOp(i)%tr, & ! Symmetry operators
26883                                   SpG%SymopSymb(i)                    ! Strings form of symmetry operators
26884         if(ier /= 0) then
26885          ok=.false.
26886          return
26887         end if
26888       end do
26889       read(unit=Lun,iostat=ier) SpG%R_Asym_Unit      ! Asymmetric unit in real space
26890       if(ier /= 0) then
26891         ok=.false.
26892         return
26893       end if
26894       read(unit=Lun,iostat=ier) SpG%Wyckoff%num_orbit              ! Wyckoff Information
26895       if(ier /= 0) then
26896        ok=.false.
26897        return
26898       end if
26899       if (SpG%Wyckoff%num_orbit == 0) return
26900       do i=1,SpG%Wyckoff%num_orbit
26901         read(unit=Lun,iostat=ier) SpG%Wyckoff%orbit(i)%norb
26902         read(unit=Lun,iostat=ier) SpG%Wyckoff%orbit(i)%str_Orig
26903         do j=1,SpG%Wyckoff%orbit(i)%norb
26904           read(unit=Lun,iostat=ier) SpG%Wyckoff%orbit(i)%str_orbit(j)
26905         end do
26906         if(ier /= 0) then
26907          ok=.false.
26908          return
26909         end if
26910       end do
26911       return
26912    End Subroutine Read_Bin_SpaceGroup
26913
26914    !!----
26915    !!---- Subroutine Read_Msymm(Info,Sim,P_Mag,ctrl)
26916    !!----    character (len=*),       intent( in) :: Info   !  In -> Input string with S.Op.
26917    !!----                                                            in the form: MSYM  u,w,w,p_mag
26918    !!----    integer, dimension(3,3), intent(out) :: sim    ! Out -> Rotation matrix
26919    !!----    real(kind=cp),           intent(out) :: p_mag  ! Out -> magnetic phase
26920    !!----    logical, optional,       intent(in)  :: ctrl   ! in  -> If provided and .true. an error condition
26921    !!----                                                            is raised if the det(Sim)=0
26922    !!----    Read magnetic symmetry operators in the form U,V,W, etc...
26923    !!----    Provides the magnetic rotational matrix and phase associated to a MSYM symbol
26924    !!----
26925    !!---- Update: February - 2005
26926    !!
26927    Subroutine Read_Msymm(Info,Sim,P_Mag,ctrl)
26928       !---- Arguments ----!
26929       character (len=*),       intent( in) :: Info
26930       integer, dimension(3,3), intent(out) :: sim
26931       real(kind=cp),           intent(out) :: p_mag
26932       logical, optional,       intent(in)  :: ctrl
26933
26934       !---- Local variables ----!
26935       integer ::  i,imax,nop,s,ifound,j,ioerr,istart,mod_istart
26936       character(len=len(info)) :: aux
26937       logical :: control
26938
26939       control=.false.
26940       if(present(ctrl)) control=ctrl
26941       call init_err_symm()
26942       do j=len(Info),1,-1
26943          if (info(j:j) == ",") exit
26944       end do
26945       p_mag=0.0
26946       imax=j-1
26947       read(unit=info(j+1:),fmt=*,iostat=ioerr) p_mag
26948       if (ioerr /= 0) then
26949          p_mag=0.0
26950       end if
26951       sim = 0
26952       aux=adjustl(l_case(Info))
26953       if(aux(1:4) == "msym" .or. aux(1:4) == "dsym") then
26954         istart=6
26955       else
26956         istart=1
26957       end if
26958
26959       do nop=1,3
26960          s=1
26961          mod_istart=0
26962          ifound=0
26963          do i=istart,imax
26964             if (aux(i:i) == " ") cycle
26965             if (aux(i:i) == "," .or. info(i:i) == "*") then
26966                mod_istart=1
26967                exit
26968             end if
26969             ifound=1
26970             if (aux(i:i) == "u" ) then
26971                sim(nop,1)=s
26972                s=1
26973             else if (aux(i:i) == "v") then
26974                sim(nop,2)=s
26975                s=1
26976             else if(aux(i:i) == "w") then
26977                sim(nop,3)=s
26978                s=1
26979             else if(aux(i:i) == "+") then
26980                s=1
26981             else if(aux(i:i) == "-") then
26982                s=-1
26983             else
26984                err_symm=.true.
26985                ERR_Symm_Mess=" Invalid character... "//aux(I:I)//" in Sym. Op."
26986                return
26987             end if
26988          end do    !End loop through the string
26989
26990          if (mod_istart == 1) then
26991            istart=i+1
26992          end if
26993
26994          if (ifound == 0) then
26995             err_symm=.true.
26996             ERR_Symm_Mess=" Blank operator field "//info
26997             return
26998          end if
26999       end do    !End external loop over the three expected items
27000
27001       if (determ_A(sim) == 0 .and. control) then      !Verify it is a suitable s.o.
27002          err_symm=.true.
27003          ERR_Symm_Mess=" The above operator is wrong "//info
27004          return
27005       end if
27006
27007       if (ifound == 1) return
27008
27009       err_symm=.true.
27010       ERR_Symm_Mess=" The above operator is wrong "//info
27011
27012       return
27013    End Subroutine Read_Msymm
27014
27015    !!----
27016    !!---- Subroutine Read_SymTrans_Code(Code,N,Tr)
27017    !!----    character (len=*),          intent( in) :: Code
27018    !!----    integer,                    intent(out) :: N
27019    !!----    real(kind=cp),dimension(3), intent(out) :: Tr
27020    !!----
27021    !!----    Read a Code string for reference the symmetry operator and the
27022    !!----    Traslation applied.
27023    !!--<<        _2.555     : N_Op = 2, Tr=( 0.0, 0.0, 0.0)
27024    !!----        _3.456     : N_Op = 3, Tr=(-1.0, 0.0, 1.0)
27025    !!-->>
27026    !!----
27027    !!---- Update: April - 2005
27028    !!
27029    Subroutine Read_SymTrans_Code(Code,N,Tr)
27030       !---- Arguments ----!
27031       character (len=*),          intent( in) :: Code
27032       integer,                    intent(out) :: N
27033       real(kind=cp),dimension(3), intent(out) :: Tr
27034
27035       !---- Local variables ----!
27036       character(len=20) :: car
27037       integer          :: i,j,k,n_ini,n_end,nt
27038
27039       N=1
27040       Tr=0.0
27041       if (len_trim(code) <= 0) return
27042
27043       car=adjustl(code)
27044       n_ini=index(car,"_")
27045       n_ini=n_ini+1
27046
27047       !---- Found Number of Symmetry Operator ----!
27048       n_end=index(car,".")
27049       if (n_end ==0) n_end=len_trim(car)+1
27050       read (unit=car(n_ini:n_end-1),fmt=*) n
27051
27052       !---- Found the Traslation ----!
27053       n_ini=index(car,".")
27054       if (n_ini /= 0) then
27055          n_ini=n_ini+1
27056          n_end=len_trim(car)
27057          read (unit=car(n_ini:n_end),fmt=*) nt
27058          i=nt/100
27059          j=mod(nt,100)/10
27060          k=nt-(i*100+j*10)
27061          i=i-5
27062          j=j-5
27063          k=k-5
27064          tr(1)=real(i)
27065          tr(2)=real(j)
27066          tr(3)=real(k)
27067       end if
27068
27069       return
27070    End Subroutine Read_SymTrans_Code
27071
27072    !!----
27073    !!---- Subroutine Read_Xsym(Info,Istart,Sim,Tt,ctrl)
27074    !!----    character (len=*),                     intent( in)    :: Info   !  In -> String with the symmetry symbol
27075    !!----                                                                             in the form: SYMM  x,-y+1/2,z
27076    !!----    integer,                               intent(in)     :: istart !  In -> Starting index of info to read in.
27077    !!----    integer, dimension(3,3),               intent(out)    :: sim    ! Out -> Rotational part of S.O.
27078    !!----    real(kind=cp), optional, dimension(3), intent(out)    :: tt     ! Out -> Traslational part of S.O.
27079    !!----
27080    !!----
27081    !!----    Read symmetry or transformation operators in the form X,Y,Z, etc...
27082    !!----    Provides the rotational matrix and translation associated a to SYMM symbol
27083    !!----    in the Jones Faithful representation.
27084    !!----
27085    !!---- Update: June - 2011 (JRC, adding ctrl for controlling if a real symmetry operator is needed)
27086    !!
27087    Subroutine Read_Xsym(Info,Istart,Sim,Tt,ctrl)
27088       !---- Arguments ----!
27089       character (len=*),                     intent(in)     :: Info
27090       integer,                               intent(in)     :: istart
27091       integer, dimension(3,3),               intent(out)    :: sim
27092       real(kind=cp), optional, dimension(3), intent(out)    :: tt
27093       logical,       optional,               intent(in)     :: ctrl
27094
27095       !---- Local variables ----!
27096       character (len=*), dimension(10), parameter :: ANUM=(/"1","2","3","4","5","6","7","8","9","0"/)
27097       integer, dimension(10), parameter           :: NUM =(/1,2,3,4,5,6,7,8,9,0/)
27098       integer :: i,imax,nop,s,np,isl,ifound,ip,k,mod_istart,ST=0,I_P,ist
27099       real(kind=cp) :: t,a
27100       logical       :: control
27101
27102       control=.true.
27103       if(present(ctrl)) control=ctrl
27104       call init_err_symm()
27105       imax=len_trim(info)
27106       if (present(tt)) tt=0.0
27107       sim = 0
27108       ist=istart
27109       do nop=1,3
27110          s=1
27111          t=0.0
27112          ip=0
27113          i_p=1
27114          np=0
27115          isl=0
27116          ifound=0
27117          mod_istart=0
27118          loop_string: do i=ist,imax
27119             if (info(i:i) == " ") cycle
27120             if (info(i:i) == "," .or. info(i:i) == "*") then
27121                mod_istart=1
27122                exit
27123             end if
27124             ifound=1
27125             if (info(i:i) == "X" .or. info(i:i) == "x") then
27126                sim(nop,1)=s*i_p
27127                i_p=1
27128                s=1
27129             else if (info(i:i) == "Y" .or. info(i:i) == "y") then
27130                sim(nop,2)=s*i_p
27131                i_p=1
27132                s=1
27133             else if(info(i:i) == "Z" .or. info(i:i) == "z") then
27134                sim(nop,3)=s*i_p
27135                i_p=1
27136                s=1
27137             else if(info(i:i) == "+") then
27138                s=1
27139             else if(info(i:i) == "-") then
27140                s=-1
27141             else if(info(i:i) == "/") then
27142                isl=1
27143             else if(info(i:i) == ".") then
27144                ip=1
27145             else
27146                st=s
27147                do k=1,10
27148                   if (info(i:i) == anum(k))  then
27149                      if (is_xyz(info(i+1:i+1))) then
27150                         i_p=num(k)
27151                         cycle loop_string
27152                      else
27153                         a=num(k)
27154                         if (isl == 1) then
27155                            t=t/a
27156                         else if(ip == 1) then
27157                            np=np+1
27158                            t=t+a/10**np
27159                         else
27160                            t=10.0*t+a
27161                         end if
27162                         cycle loop_string
27163                      end if
27164                   end if
27165                end do
27166                err_symm=.true.
27167                ERR_Symm_Mess=" Invalid character... "//INFO(I:I)//" in operator string"
27168                return
27169             end if
27170          end do  loop_string   !end loop through the string (index:i= ist,imax)
27171
27172          if (mod_istart == 1) then
27173             ist=i+1
27174          end if
27175
27176          t=t*st
27177          if (present(tt)) tt(nop)=t
27178
27179          if (ifound == 0) then
27180             err_symm=.true.
27181             ERR_Symm_Mess=" Blank operator field"
27182             return
27183          end if
27184
27185       end do    !End external loop over the three expected items (index:NOP)
27186
27187       if (determ_A(sim) == 0 .and. control) then      !Verify it is a suitable s.o.
27188          err_symm=.true.
27189          ERR_Symm_Mess=" The above operator is wrong: "//info
27190          return
27191       end if
27192
27193       if (ifound == 1) return
27194
27195       err_symm=.true.
27196       ERR_Symm_Mess=" The above operator is wrong: "//info
27197
27198       return
27199    End Subroutine Read_Xsym
27200
27201    !!----
27202    !!---- Subroutine Searchop(Sim,I1,I2,Isl)
27203    !!----    integer , dimension(3,3), Intent(in)  :: sim      !  In -> Rotational part of a symmetry operator
27204    !!----    integer ,                 Intent(in)  :: i1       !  In -> i1=1,  i2=24  if not hexagonal  (matrices of m3m )
27205    !!----    integer ,                 Intent(in)  :: i2       !  In -> i1=25, i2=36  if     hexagonal  (matrices of 6/mmm)
27206    !!----    integer ,                 Intent(out) :: Isl      ! Out -> Index of the matrix Mod6(Isl,:,:)=sim.
27207    !!----                                                               This index allow to get the corresponding tabulated symmetry symbol.
27208    !!----
27209    !!---- Update: February - 2005
27210    !!
27211    Subroutine Searchop(Sim,I1,I2,Isl)
27212       !---- Arguments ----!
27213       integer , dimension(3,3), Intent(in) :: sim
27214       integer , Intent(in)                 :: i1,i2
27215       integer , Intent(out)                :: Isl
27216
27217       !---- Local variables ----!
27218       integer               :: iss,ipass,j,k,im
27219
27220       iss=1
27221       ipass=0
27222       call init_err_symm()
27223       do
27224          ipass=ipass+1
27225          imdo:  do im=i1,i2
27226             Isl=0
27227             do j=1,3
27228                do k=1,3
27229                   if (sim(j,k) /= iss*Mod6(im,j,k)) cycle imdo
27230                end do
27231             end do
27232             Isl=iss*im
27233             exit
27234          end do imdo
27235
27236          if (Isl /= 0) return
27237
27238          if (ipass >=2 ) then
27239             ERR_Symm_Mess=" Try to re-write your S.O. using a rotational part"
27240             if (i1 == 1 .and.  i2 == 24) then
27241                ERR_Symm_Mess=trim(ERR_Symm_Mess)//" identical to a S.O. of the space group P m -3 m"
27242             else if(i1 == 25 .and.  i2 == 36) then
27243                ERR_Symm_Mess=trim(ERR_Symm_Mess)//" identical to a S.O. of the space group P 6/m m m"
27244             else
27245                ERR_Symm_Mess=trim(ERR_Symm_Mess)//" identical to a S.O. of the space group P m -3 m or P 6/m m m"
27246             end if
27247             err_symm=.true.
27248             return
27249          end if
27250          iss=-1
27251       end do
27252
27253       return
27254    End Subroutine Searchop
27255
27256    !!----
27257    !!---- Subroutine Set_Spacegroup(Spacegen, Spacegroup, Gen, Ngen, Mode, Force_Hall)
27258    !!----    character (len=*),                       intent(in)     :: SpaceGen     !  In -> String with Number, Hall or Hermman-Mauguin
27259    !!----    Type (Space_Group),                         intent(out) :: SpaceGroup   ! Out -> SpaceGroup variable
27260    !!----    character (len=*), dimension(:),  intent(in ), optional :: gen          !  In -> String Generators
27261    !!----    Integer,                          intent(in ), optional :: ngen         !  In -> Number of Generators
27262    !!----    character (len=*),                intent(in ), optional :: Mode         !  In -> HMS, ITC, Hall, Gen, Fix
27263    !!----    character (len=*),                intent(in ), optional :: force_hall   !  In -> f_hall (if present force generation from Hall)
27264    !!----
27265    !!----    Subroutine that construct the object SpaceGroup from the H-M or Hall symbol.
27266    !!----    Expand the set of operators including centre of symmetry and non integer
27267    !!----    translations for centred cells.
27268    !!----    If the optional argument Gen is given, then Ngen and Mode="GEN" should be given.
27269    !!----    If the optional argument mode="ITC", the space group will be generated using the
27270    !!----    the generators given in the International Tables for the standard setting. In this
27271    !!----    case the string in SpaceGen should correspond to the Hermann-Mauguin symbol.
27272    !!----    If the optional argument mode="HMS","HALL" is given the string in SpaceGen
27273    !!----    should correspond to the desired symbol.
27274    !!----    If Gen,NGen and Mode are not given but force_hall="f_hall" is given, the generation
27275    !!----    of the symmetry operators from the symbol of the space group is according to the Hall
27276    !!----    symbol even if the provided symbol is of Hermann-Maugin type.
27277    !!----    The use of the different options give rise to different ordering of the symmetry
27278    !!----    operators or different origins and settings for the same space group.
27279    !!----
27280    !!----
27281    !!---- Update: February - 2005
27282    !!
27283    Subroutine Set_SpaceGroup(Spacegen,Spacegroup,Gen,Ngen,Mode,Force_Hall)
27284       !----Arguments ----!
27285       character (len=*),                intent(in )           :: SpaceGen
27286       Type (Space_Group_Type),          intent(out)           :: SpaceGroup
27287       character (len=*), dimension(:),  intent(in ), optional :: gen
27288       Integer,                          intent(in ), optional :: ngen
27289       character (len=*),                intent(in ), optional :: Mode
27290       character (len=*),                intent(in ), optional :: force_hall
27291
27292       !---- Local variables ----!
27293       character (len=*),dimension(0:2), parameter  :: Centro = &
27294                                          (/"Centric (-1 not at origin)", &
27295                                            "Acentric                  ", &
27296                                            "Centric (-1 at origin)    "/)
27297       character (len=20)               :: Spgm
27298       character (len=20)               :: ssymb
27299       character (len=130)              :: gener
27300       character (len=3)                :: opcion
27301       character (len=2)                :: Latsy
27302       integer                          :: num, i, j, iv, istart
27303       integer,      dimension(1)       :: ivet
27304       integer,      dimension(5)       :: poscol
27305       integer                          :: isystm,isymce,ibravl,Num_g
27306       integer                          :: m,l,ngm,k,ier
27307       integer                          :: ng
27308       integer,      dimension(3,3,384) :: ss
27309       real(kind=cp),dimension(3,384)   :: ts
27310       real(kind=cp),dimension(3)       :: co
27311       real(kind=cp),dimension(1)       :: vet
27312       real(kind=cp),dimension(3)       :: vec
27313       logical                          :: ok
27314
27315       !---- Inicializing Space Group ----!
27316       call init_err_symm()
27317
27318       !Constructor eliminated because some components are nowadays allocatable
27319       !There's no risk of undefined fields because in this procedure everything is set.
27320       !
27321       !SpaceGroup=Space_Group_Type(0,"unknown","unknown","unknown","?","?","?","?",.false.,"?","?", &
27322       !                       0,0.0,"?","?", -1, 0.0,  0, 0,  0, Sym_Oper_Type(0, 0.0),"?",         &
27323       !                       wyckoff_type(0,wyck_pos_type(0," ",0," "," ")),0.0)
27324       SpaceGroup%R_Asym_Unit(:,2)=1.0
27325       SpaceGroup%gHall=" "
27326
27327       !---- Loading Tables ----!
27328       call Set_Spgr_Info()
27329       call Set_Wyckoff_Info()
27330
27331       !---- Mode Option ----!
27332       opcion=" "
27333       spgm=adjustl(SpaceGen)
27334       spgm=u_case(spgm)
27335       num=-1
27336
27337       if (present(mode)) then
27338          opcion=adjustl(mode)
27339          call ucase(opcion)
27340
27341          Select case (opcion(1:3))
27342
27343            case("HMS")
27344                do i=1,num_spgr_info
27345                   if (spgm(1:12) == spgr_info(i)%hm) then
27346                      num=i
27347                      exit
27348                   end if
27349                end do
27350
27351            case("ITC")
27352                read(unit=spgm(1:12),fmt=*,iostat=ier) ivet(1)
27353
27354                if( ier == 0) then
27355                   do i=1,num_spgr_info
27356                     if (ivet(1) == spgr_info(i)%n) then
27357                        num=i
27358                      exit
27359                     end if
27360                   end do
27361                else
27362                   do i=1,num_spgr_info
27363                     if (spgm(1:12) == spgr_info(i)%hm) then
27364                       num=i
27365                       exit
27366                     end if
27367                   end do
27368                end if
27369
27370            case("HAL")
27371                do i=1,num_spgr_info
27372                   if (spgm(1:16) == u_case(spgr_info(i)%hall)) then
27373                      num=i
27374                      exit
27375                   end if
27376                end do
27377          End select
27378
27379       else       ! detect automatically the symbol of the group
27380
27381          call getnum(spgm,vet,ivet,iv)
27382          if (iv /= 1) then
27383             !---- Is HM Symbol ? ----!
27384             do i=1,num_spgr_info
27385                if (spgm(1:12) == spgr_info(i)%hm) then
27386                   num=i
27387                   opcion="HMS"
27388                   if(present(force_hall)) then
27389                     opcion="HAL"
27390                     spgm=spgr_info(i)%hall
27391                   end if
27392                   exit
27393                end if
27394             end do
27395              !Special treatment of groups P N M 21 (211), P 21 N M (213),
27396              !P M 21 N (215), B A M B (375), C 4 2 21 (429), C -4 B 2 (457)
27397              ! and F -4 D 2 (463)   => Force HALL in all these cases
27398              if(opcion(1:3) == "HMS" .and.  &
27399              (num==211 .or. num==213 .or. num==215  &
27400              .or. num==375 .or. num==429 .or. num==457 .or. num==463)) then
27401                  opcion(1:3) = "HAL"
27402                  spgm=spgr_info(num)%hall
27403              end if
27404             !---- Is a standard Hall Symbol ? ----!
27405             if (num < 0) then
27406                do i=1,num_spgr_info
27407                   if (spgm(1:16) == u_case(spgr_info(i)%hall)) then
27408                      num=i
27409                      opcion="HAL"
27410                      exit
27411                   end if
27412                end do
27413             end if
27414
27415             !---- Using Generators ----!
27416             if (num <=0) then
27417                 if(present(gen)) then
27418                   opcion="GEN"
27419                 else  !The last option is a non-standard Hall symbol
27420                    opcion="HAL"
27421                 end if
27422             end if
27423          else
27424             if (ivet(1) > 0 .and. ivet(1) < 231) then
27425               do i=1,num_spgr_info
27426                   if (ivet(1) == spgr_info(i)%n) then
27427                      num=i
27428                      spgm=spgr_info(i)%hall
27429                      opcion="HAL"
27430                      exit
27431                   end if
27432                end do
27433             else
27434                err_symm=.true.
27435                ERR_Symm_Mess=" Number of Space Group out of limits"
27436                return
27437             end if
27438          end if
27439       end if  ! present(mode)
27440
27441       select case (opcion(1:3))
27442          case ("FIX")
27443             if (present(gen) .and. present(ngen))  then
27444                ng=ngen
27445                istart=1
27446                num_g=ng-1
27447                do i=1,ngen
27448                   call Read_Xsym(gen(i),istart,ss(:,:,i),ts(:,i))
27449                end do
27450             else
27451                err_symm=.true.
27452                ERR_Symm_Mess=" Generators should be provided if FIX option is Used"
27453                return
27454             end if
27455             call Get_SO_from_FIX(isystm,isymce,ibravl,ng,ss,ts,latsy,co,Spgm,Spacegen(1:1))
27456
27457             SpaceGroup%Spg_Symb     = "unknown "
27458             SpaceGroup%Hall         = "unknown "
27459             SpaceGroup%Laue         = " "
27460             SpaceGroup%Info         = "Fixed symmetry operators (no info)"
27461             SpaceGroup%SPG_lat      = Lat_Ch
27462             SpaceGroup%NumLat       = nlat
27463
27464             if(allocated(SpaceGroup%Latt_trans)) deallocate(SpaceGroup%Latt_trans)
27465             allocate(SpaceGroup%Latt_trans(3,nlat))
27466
27467             SpaceGroup%Latt_trans   = Ltr(:,1:nlat)
27468             SpaceGroup%Num_gen      = max(0,num_g)
27469             SpaceGroup%Centre_coord = co
27470             SpaceGroup%SG_setting   = "Non-Conventional (user-given operators)"
27471             SpaceGroup%CrystalSys   = " "
27472             SpaceGroup%Bravais      = Latt(ibravl)
27473             SpaceGroup%SPG_latsy    = latsy
27474             SpaceGroup%centred      = isymce
27475             SpaceGroup%centre       = Centro(isymce)
27476             SpaceGroup%Numops       = NG
27477
27478          case ("GEN")
27479             if (present(gen) .and. present(ngen))  then
27480                do i=1,ngen
27481                   call Check_Generator(gen(i),ok)
27482                   !write(*,"(a,i3,a,tr2,L)") " => Generator # ",i,"  "//trim(gen(i)), ok
27483                   if(.not. ok) return
27484                end do
27485                ng=ngen
27486                istart=1
27487                num_g=ng
27488                call Get_GenSymb_from_Gener(gen,ng,SpaceGroup%gHall)
27489                do i=1,ngen
27490                   call Read_Xsym(gen(i),istart,ss(:,:,i),ts(:,i))
27491                end do
27492             else
27493                err_symm=.true.
27494                ERR_Symm_Mess=" Generators should be provided in GEN calling Set_SpaceGroup"
27495                return
27496             end if
27497             call Get_SO_from_Gener(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy, &
27498                                    Co,Num_g,Spgm)
27499
27500             SpaceGroup%CrystalSys   = sys_cry(isystm)
27501             SpaceGroup%SG_setting   = "Non-Conventional (user-given operators)"
27502             SpaceGroup%SPG_lat      = Lat_Ch
27503             SpaceGroup%SPG_latsy    = latsy
27504             SpaceGroup%NumLat       = nlat
27505             if(allocated(SpaceGroup%Latt_trans)) deallocate(SpaceGroup%Latt_trans)
27506             allocate(SpaceGroup%Latt_trans(3,nlat))
27507             SpaceGroup%Latt_trans   = Ltr(:,1:nlat)
27508             SpaceGroup%Bravais      = Latt(ibravl)
27509             SpaceGroup%centre       = Centro(isymce)
27510             SpaceGroup%centred      = isymce
27511             SpaceGroup%Centre_coord = co
27512             SpaceGroup%Numops       = NG
27513             SpaceGroup%Num_gen      = max(0,num_g)
27514
27515          case ("HAL")
27516             call Get_SO_from_Hall (Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy, &
27517                                    Co,Num_g,Spgm)
27518
27519             if (num > 0) then
27520                SpaceGroup%NumSpg       = spgr_info(num)%n
27521                SpaceGroup%Spg_Symb     = spgr_info(num)%hm
27522                SpaceGroup%Hall         = spgr_info(num)%hall
27523                call get_laue_str(spgr_info(num)%laue,SpaceGroup%Laue)
27524                call get_PointGroup_str(spgr_info(num)%pg,SpaceGroup%PG)
27525                SpaceGroup%Info         = spgr_info(num)%inf_extra
27526                SpaceGroup%R_Asym_Unit(1,1) = real(spgr_info(num)%asu(1))/24.0
27527                SpaceGroup%R_Asym_Unit(2,1) = real(spgr_info(num)%asu(2))/24.0
27528                SpaceGroup%R_Asym_Unit(3,1) = real(spgr_info(num)%asu(3))/24.0
27529                SpaceGroup%R_Asym_Unit(1,2) = real(spgr_info(num)%asu(4))/24.0
27530                SpaceGroup%R_Asym_Unit(2,2) = real(spgr_info(num)%asu(5))/24.0
27531                SpaceGroup%R_Asym_Unit(3,2) = real(spgr_info(num)%asu(6))/24.0
27532             else
27533                SpaceGroup%Hall         = Spgm
27534             end if
27535             SpaceGroup%CrystalSys   = sys_cry(isystm)
27536             SpaceGroup%SG_setting   = "Generated from Hall symbol"
27537             SpaceGroup%SPG_lat      = Lat_Ch
27538             SpaceGroup%SPG_latsy    = latsy
27539             SpaceGroup%NumLat       = nlat
27540             if(allocated(SpaceGroup%Latt_trans)) deallocate(SpaceGroup%Latt_trans)
27541             allocate(SpaceGroup%Latt_trans(3,nlat))
27542             SpaceGroup%Latt_trans   = Ltr(:,1:nlat)
27543             SpaceGroup%Bravais      = Latt(ibravl)
27544             SpaceGroup%centre       = Centro(isymce)
27545             SpaceGroup%centred      = isymce
27546             SpaceGroup%Centre_coord = co
27547             SpaceGroup%Numops       = NG
27548             SpaceGroup%Num_gen      = max(0,num_g)
27549
27550          case ("HMS")
27551             i=index(SpaceGen,":")
27552             co=0.0
27553             if (i /=0 .and. num > 0) then
27554                spgm=spgr_info(num)%hall
27555                call Get_SO_from_Hall (Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy, &
27556                                       Co,Num_g,Spgm)
27557             else
27558                if (i /= 0) then
27559                   Spgm=SpaceGen(1:i-1)
27560                else
27561                   Spgm=SpaceGen
27562                end if
27563                call Get_SO_from_HMS  (Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy, &
27564                                       Spgm)
27565             end if
27566             if (num > 0) then
27567                SpaceGroup%NumSpg       = spgr_info(num)%n
27568                SpaceGroup%Spg_Symb     = spgr_info(num)%hm
27569                SpaceGroup%Hall         = spgr_info(num)%hall
27570                call get_laue_str(spgr_info(num)%laue,SpaceGroup%Laue)
27571                call get_PointGroup_str(spgr_info(num)%pg,SpaceGroup%PG)
27572                SpaceGroup%Info         = spgr_info(num)%inf_extra
27573                SpaceGroup%R_Asym_Unit(1,1) = real(spgr_info(num)%asu(1))/24.0
27574                SpaceGroup%R_Asym_Unit(2,1) = real(spgr_info(num)%asu(2))/24.0
27575                SpaceGroup%R_Asym_Unit(3,1) = real(spgr_info(num)%asu(3))/24.0
27576                SpaceGroup%R_Asym_Unit(1,2) = real(spgr_info(num)%asu(4))/24.0
27577                SpaceGroup%R_Asym_Unit(2,2) = real(spgr_info(num)%asu(5))/24.0
27578                SpaceGroup%R_Asym_Unit(3,2) = real(spgr_info(num)%asu(6))/24.0
27579             else
27580                SpaceGroup%Spg_Symb     = SpaceGen
27581                SpaceGroup%Num_gen= 0    !unknown
27582             end if
27583             SpaceGroup%CrystalSys   = sys_cry(isystm)
27584             if (i /=0 .and. num > 0) then
27585                SpaceGroup%SG_setting   = "Generated from Hall symbol"
27586                SpaceGroup%Num_gen=max(0,num_g)
27587             else
27588                SpaceGroup%SG_setting   ="IT (Generated from Hermann-Mauguin symbol)"
27589                if(num > 0) then
27590                   Select Case (spgr_info(num)%n)
27591                     case(1:2)
27592                        SpaceGroup%Num_gen= 0    !triclinic
27593                     case(3:15)
27594                        SpaceGroup%Num_gen= 1    !monoclinic
27595                     case(16:74)
27596                        SpaceGroup%Num_gen= 2    !orthorhombic
27597                     case(75:88)
27598                        SpaceGroup%Num_gen= 1    !tetragonal
27599                     case(89:142)
27600                        SpaceGroup%Num_gen= 2    !tetragonal
27601                     case(143:148)
27602                        SpaceGroup%Num_gen= 1    !trigonal
27603                     case(149:167)
27604                        SpaceGroup%Num_gen= 2    !trigonal
27605                     case(168:176)
27606                        SpaceGroup%Num_gen= 1    !hexagonal
27607                     case(177:194)
27608                        SpaceGroup%Num_gen= 2    !hexagonal
27609                     case(195:230)
27610                        SpaceGroup%Num_gen= 3    !cubic
27611                     case default
27612                        SpaceGroup%Num_gen= 0    !unknown
27613                   End Select
27614                end if
27615             end if
27616             SpaceGroup%SPG_lat      = Lat_Ch
27617             SpaceGroup%SPG_latsy    = latsy
27618             SpaceGroup%NumLat       = nlat
27619             if(allocated(SpaceGroup%Latt_trans)) deallocate(SpaceGroup%Latt_trans)
27620             allocate(SpaceGroup%Latt_trans(3,nlat))
27621             SpaceGroup%Latt_trans   = Ltr(:,1:nlat)
27622             SpaceGroup%Bravais      = Latt(ibravl)
27623             SpaceGroup%centre       = Centro(isymce)
27624             SpaceGroup%centred      = isymce
27625             SpaceGroup%Centre_coord = co
27626             SpaceGroup%Numops       = NG
27627
27628          case ("ITC")
27629
27630             call get_generators(spgm,gener)
27631             if (err_symtab) then
27632                err_symm=.true.
27633                ERR_Symm_Mess=" Problems in SpaceGroup: "//trim(spgm)//" => the HM symbol or the number is incorrect "
27634                return
27635             else  !Decode gener in generators to construct the space group
27636                k=0
27637                do i=1,len_trim(gener)
27638                   if (gener(i:i) == ";") then
27639                      k=k+1
27640                      poscol(k)=i
27641                   end if
27642                end do
27643                if (k /= 0) then
27644                   ssymb=" "
27645                   ssymb= adjustl(gener(1:poscol(1)-1))
27646                   call Read_Xsym(ssymb,1,ss(:,:,1),ts(:,1))
27647                   do i=2,k
27648                      ssymb=" "
27649                      ssymb=adjustl(gener(poscol(i-1)+1:poscol(i)-1))
27650                      call Read_Xsym(ssymb,1,ss(:,:,i),ts(:,i))
27651                   end do
27652                   ssymb=" "
27653                   ssymb=gener(poscol(k)+1:)
27654                   call Read_Xsym(ssymb,1,ss(:,:,k+1),ts(:,k+1))
27655                else
27656                   ssymb=gener
27657                   call Read_Xsym(ssymb,1,ss(:,:,k+1),ts(:,k+1))
27658                end if
27659             end if
27660
27661             ng=k+1     !k+1 is the number of generators
27662             num_g=ng
27663             call Get_SO_from_Gener(Isystm,Isymce,Ibravl,Ng,Ss,Ts,Latsy, &
27664                                    Co,Num_g,Spgm)
27665             if (num > 0) then
27666                SpaceGroup%NumSpg       = spgr_info(num)%n
27667                SpaceGroup%Spg_Symb     = spgr_info(num)%hm
27668                SpaceGroup%Hall         = spgr_info(num)%hall
27669                call get_laue_str(spgr_info(num)%laue,SpaceGroup%Laue)
27670                call get_PointGroup_str(spgr_info(num)%pg,SpaceGroup%PG)
27671                SpaceGroup%Info         = spgr_info(num)%inf_extra
27672                SpaceGroup%R_Asym_Unit(1,1) = real(spgr_info(num)%asu(1))/24.0
27673                SpaceGroup%R_Asym_Unit(2,1) = real(spgr_info(num)%asu(2))/24.0
27674                SpaceGroup%R_Asym_Unit(3,1) = real(spgr_info(num)%asu(3))/24.0
27675                SpaceGroup%R_Asym_Unit(1,2) = real(spgr_info(num)%asu(4))/24.0
27676                SpaceGroup%R_Asym_Unit(2,2) = real(spgr_info(num)%asu(5))/24.0
27677                SpaceGroup%R_Asym_Unit(3,2) = real(spgr_info(num)%asu(6))/24.0
27678                SpaceGroup%SG_setting   = "Generated from explicit IT generators"
27679             else
27680                SpaceGroup%Spg_Symb     = SpaceGen
27681                SpaceGroup%Num_gen= 0    !unknown
27682             end if
27683
27684             SpaceGroup%CrystalSys   = sys_cry(isystm)
27685             SpaceGroup%SPG_lat      = Lat_Ch
27686             SpaceGroup%SPG_latsy    = latsy
27687             SpaceGroup%NumLat       = nlat
27688             if(allocated(SpaceGroup%Latt_trans)) deallocate(SpaceGroup%Latt_trans)
27689             allocate(SpaceGroup%Latt_trans(3,nlat))
27690             SpaceGroup%Latt_trans   = Ltr(:,1:nlat)
27691             SpaceGroup%Bravais      = Latt(ibravl)
27692             SpaceGroup%centre       = Centro(isymce)
27693             SpaceGroup%centred      = isymce
27694             SpaceGroup%Centre_coord = co
27695             SpaceGroup%Numops       = NG
27696             SpaceGroup%Num_gen      = max(0,num_g)
27697
27698          case default
27699             err_symm=.true.
27700             ERR_Symm_Mess=" Problems in SpaceGroup"
27701             return
27702       end select
27703
27704       if (err_symm) return
27705       if (Is_Hexa(ng,ss)) SpaceGroup%Hexa=.true.
27706
27707       hexa=SpaceGroup%Hexa  !added 24/05/2007
27708
27709       if (opcion(1:3) /= "FIX") then              !This has been changed of place for allocating
27710           select case (SpaceGroup%centred)        !the allocatable components properly
27711              case (0)
27712                 SpaceGroup%Multip = 2*NG*nlat
27713              case (1)
27714                 SpaceGroup%Multip =   NG*nlat
27715              case (2)
27716                 SpaceGroup%Multip = 2*NG*nlat
27717           end select
27718       else
27719           SpaceGroup%Multip =   NG
27720       end if
27721
27722       !Allocate here the total number of symmetry operators (JRC, Jan2014)
27723
27724       if(allocated(SpaceGroup%Symop)) deallocate(SpaceGroup%Symop)
27725       allocate(SpaceGroup%Symop(SpaceGroup%Multip))
27726       if(allocated(SpaceGroup%SymopSymb)) deallocate(SpaceGroup%SymopSymb)
27727       allocate(SpaceGroup%SymopSymb(SpaceGroup%Multip))
27728
27729       do i=1,SpaceGroup%Numops
27730          SpaceGroup%Symop(i)%Rot(:,:) = ss(:,:,i)
27731          SpaceGroup%Symop(i)%tr(:)    = ts(:,i)
27732       end do
27733
27734       if (opcion(1:3) /= "FIX") then
27735          m=SpaceGroup%Numops
27736          if (SpaceGroup%centred == 0) then
27737             do i=1,SpaceGroup%Numops
27738                m=m+1
27739                vec=-ts(:,i)+2.0*SpaceGroup%Centre_coord(:)
27740                SpaceGroup%Symop(m)%Rot(:,:) = -ss(:,:,i)
27741                SpaceGroup%Symop(m)%tr(:)    =  modulo_lat(vec)
27742             end do
27743          end if
27744          if (SpaceGroup%centred == 2) then
27745             do i=1,SpaceGroup%Numops
27746                m=m+1
27747                SpaceGroup%Symop(m)%Rot(:,:) = -ss(:,:,i)
27748                SpaceGroup%Symop(m)%tr(:)    =  modulo_lat(-ts(:,i))
27749             end do
27750          end if
27751          ngm=m
27752          if (SpaceGroup%NumLat > 1) then
27753
27754             do L=2,SpaceGroup%NumLat  ! min(SpaceGroup%NumLat,4)  restriction removed Jan2014 (JRC)
27755                do i=1,ngm
27756                   m=m+1
27757                   vec=SpaceGroup%Symop(i)%tr(:) + SpaceGroup%Latt_trans(:,L)
27758                   SpaceGroup%Symop(m)%Rot(:,:) = SpaceGroup%Symop(i)%Rot(:,:)
27759                   SpaceGroup%Symop(m)%tr(:)    = modulo_lat(vec)
27760                end do
27761             end do
27762          end if
27763
27764       end if
27765       !write(*,"(a)") " => Generating the symetry operators symbols"
27766       do i=1,SpaceGroup%multip  ! min(SpaceGroup%multip,192) restriction removed Jan2014 (JRC)
27767          call Get_SymSymb(SpaceGroup%Symop(i)%Rot(:,:), &
27768                           SpaceGroup%Symop(i)%tr(:)   , &
27769                           SpaceGroup%SymopSymb(i))
27770       end do
27771       !write(*,"(a)") " => done"
27772
27773       if (num <= 0) then
27774          call Get_Laue_PG(SpaceGroup, SpaceGroup%Laue, SpaceGroup%PG)
27775       end if
27776       !write(*,"(a)") " => Point group done"
27777
27778       if(isymce == 0) then
27779          SpaceGroup%centre = trim(SpaceGroup%centre)//"  Gen(-1):"//SpaceGroup%SymopSymb(NG+1)
27780       end if
27781
27782       if(opcion(1:3)=="GEN") call Get_HallSymb_from_Gener(SpaceGroup)
27783
27784       !write(*,"(a)") " => Wyckoff information"
27785
27786       !---- Wyckoff information ----!
27787       if (len_trim(SpaceGroup%Spg_Symb) /= 0) then
27788          do i=1,273
27789             if (SpaceGroup%Spg_Symb(1:12) /= wyckoff_info(i)%hm) cycle
27790             SpaceGroup%Wyckoff%num_orbit=wyckoff_info(i)%norbit
27791             do j=1,wyckoff_info(i)%norbit
27792
27793                call wyckoff_orbit(SpaceGroup,wyckoff_info(i)%corbit(j), &
27794                                   SpaceGroup%Wyckoff%Orbit(j)%norb,     &
27795                                   SpaceGroup%Wyckoff%Orbit(j)%Str_Orbit)
27796                SpaceGroup%Wyckoff%Orbit(j)%multp=SpaceGroup%Wyckoff%Orbit(j)%norb*spacegroup%numlat
27797             end do
27798             exit
27799          end do
27800          SpaceGroup%Spg_Symb(2:)=l_case(SpaceGroup%Spg_Symb(2:))  !Make lowercase the HM generators of the group
27801       end if
27802       !write(*,"(a)") " => Wyckoff done"
27803
27804       return
27805    End Subroutine Set_SpaceGroup
27806
27807    !!----
27808    !!---- Subroutine Set_SpG_Mult_Table(SpG,tab,complete)
27809    !!----   Type(Space_Group_Type),    intent (in)    :: SpG
27810    !!----   integer, dimension(:,:),   intent (out)   :: tab
27811    !!----   logical, optional,         intent (in)    :: complete
27812    !!----
27813    !!----   Subroutine to construct the multiplication table of the factor group of
27814    !!----   a space group. Two operators are equal if they differ only in a lattice
27815    !!----   translation. The multiplication table is a square matrix with integer
27816    !!----   numbers corresponding to the ordering of operators in the space group
27817    !!----   If "complete" is not present, or if complete=.false., we consider only
27818    !!----   the symmetry operators corresponding to the "primitive" content of the
27819    !!----   unit cell, so a maximun 48x48 matrix is needed to hold the table in this
27820    !!----   case. If complete is present and .true., the full table is constructed.
27821    !!----
27822    !!----
27823    !!----  Update: April 2005
27824    !!----
27825
27826    Subroutine Set_SpG_Mult_Table(SpG,tab,complete)
27827      Type(Space_Group_Type),    intent (in)    :: SpG
27828      integer, dimension(:,:),   intent (out)   :: tab
27829      logical, optional,         intent (in)    :: complete
27830
27831       !---- Local Variables ----!
27832       Type(Sym_Oper_Type) :: Opi,Opj,Opk
27833       integer :: i,j, ng, k
27834       logical :: eqvo
27835       character(len=1) :: lat
27836
27837       tab=0
27838       lat=SpG%SPG_lat
27839       ng=SpG%Numops
27840       if(SpG%Centred /= 1) ng=2*ng
27841       if(present(complete)) then
27842         if(complete) then
27843           lat="P"
27844           ng=SpG%Multip
27845         end if
27846       end if
27847
27848       do i=1,ng
27849         Opi=SpG%SymOp(i)
27850         do j=1,ng
27851           Opj=SpG%SymOp(j)
27852           Opk=Opi*Opj
27853           do k=1,ng
27854             eqvo= Equiv_Symop(Opk,SpG%SymOp(k),lat)
27855             if(eqvo) then
27856               tab(i,j)=k
27857               exit
27858             end if
27859           end do
27860           if(tab(i,j) == 0) then
27861             err_symm=.true.
27862             ERR_Symm_Mess=" Problems constructing the multiplication Table of the space group: "//trim(spg%spg_symb)
27863             return
27864           end if
27865         end do
27866       end do
27867
27868      return
27869    End Subroutine Set_SpG_Mult_Table
27870
27871    !!--++
27872    !!--++ Subroutine Setting_Change_Conv(From_Syst,To_Syst,Spacegroup, Car_Sym, Icar_Sym)
27873    !!--++    character(len=2),    intent(in)     :: From_Syst   !  In -> IT : International Tables
27874    !!--++                                                                ML : Miller & Love
27875    !!--++                                                                KO : Kovalev
27876    !!--++                                                                BC : Bradley & Cracknell
27877    !!--++                                                                ZA : Zack
27878    !!--++    character(len=2),    intent(in)     :: To_Syst     !  In -> (Idem to From_Syst)
27879    !!--++    type (Space_Group),  intent(in out) :: SpaceGroup  !  In ->
27880    !!--++                                                         Out ->
27881    !!--++    character(len=35),    intent(out)   :: car_sym     ! Out ->
27882    !!--++    character(len=35),    intent(out)   :: icar_sym    ! Out ->
27883    !!--++
27884    !!--++    Traslate From From_Syst to To_syst the set of symmetry operators
27885    !!--++
27886    !!--++   Update: February - 2005 (Name changed and overloaded by JRC in Jan2014)
27887    !!
27888    Subroutine Setting_Change_Conv(From_Syst, To_Syst, SpaceGroup, car_sym, icar_sym)
27889       !---- Arguments ----!
27890       character(len=2),          intent(in)     :: From_Syst, To_Syst
27891       type (Space_Group_Type),   intent(in out) :: SpaceGroup
27892       character(len=35),         intent(out)    :: car_sym, icar_sym
27893
27894       !---- Local Variables ----!
27895       character(len=2) :: car1, car2
27896       integer                 :: i,j,num
27897       integer, dimension(4,4) :: s, si, st, sti, w
27898       integer, dimension(3,3) :: r, r_inv, rt, rt_inv
27899       real(kind=cp), dimension(3)      :: t, t_inv, tt, tt_inv
27900
27901       !---- Initializing variables ----!
27902       call init_err_symm()
27903       call Set_System_Equiv()
27904
27905       car1=From_Syst
27906       car2=To_Syst
27907       car_sym=" "
27908       icar_sym=" "
27909       call ucase(car1)
27910       call ucase(car1)
27911
27912       !---- Checking data ----!
27913       if (len_trim (car1) == 0) then
27914          err_symm=.true.
27915          ERR_Symm_Mess=" Blank Option"
27916          return
27917       end if
27918       if (len_trim (car2) == 0) then
27919          err_symm=.true.
27920          ERR_Symm_Mess=" Blank Option"
27921          return
27922       end if
27923       if (SpaceGroup%NumSpg <= 0 .or. SpaceGroup%NumSpg > 230 ) then
27924          err_symm=.true.
27925          ERR_Symm_Mess=" Space Group Not Defined..."
27926          return
27927       end if
27928       SpaceGroup%SG_setting="Changed from "//car1//" to "//car2
27929       num=SpaceGroup%NumSpg
27930       r     = 0
27931       r_inv = 0
27932       rt    = 0
27933       rt_inv= 0
27934       t     = 0.0
27935       t_inv = 0.0
27936       tt    = 0.0
27937       tt_inv= 0.0
27938       do i=1,3
27939          r(i,i)      = 1
27940          r_inv(i,i)  = 1
27941          rt(i,i)     = 1
27942          rt_inv(i,i) = 1
27943       end do
27944       s     = 0
27945       si    = 0
27946       st    = 0
27947       sti   = 0
27948       w     = 0
27949       do i=1,4
27950          s(i,i)   = 1
27951          si(i,i)  = 1
27952          st(i,i)  = 1
27953          sti(i,i) = 1
27954          w(i,i)   = 1
27955       end do
27956
27957       select case (car1)
27958          case ("IT")    !---- International Tables ----!
27959             select case (car2)
27960                case ("IT")
27961                   return
27962                case ("ML")
27963                   car_sym=system_equiv(num)%ml
27964                case ("KO")
27965                   car_sym=system_equiv(num)%ko
27966                case ("BC")
27967                   car_sym=system_equiv(num)%bc
27968                case ("ZA")
27969                   car_sym=system_equiv(num)%za
27970             end select
27971             j=1
27972             call read_Xsym(car_sym,j,r,t)
27973             call inverse_symm(r,t,r_inv,t_inv)
27974             if (err_symm) return
27975
27976          case ("ML")    !---- Miller & Love ----!
27977             select case (car2)
27978                case ("IT")
27979                   car_sym=system_equiv(num)%ml
27980                   j=1
27981                   call read_Xsym(car_sym,j,r_inv,t_inv)
27982                   call inverse_symm(r_inv,t_inv,r,t)
27983                   if (err_symm) return
27984
27985                case ("ML")
27986                   return
27987
27988                case ("KO")
27989                   car_sym=system_equiv(num)%ml
27990                   j=1
27991                   call read_Xsym(car_sym,j,r_inv,t_inv)
27992                   call inverse_symm(r_inv,t_inv,r,t)
27993                   if (err_symm) return
27994                   car_sym=system_equiv(num)%ko
27995                   j=1
27996                   call read_Xsym(car_sym,j,rt,tt)
27997                   call inverse_symm(rt,tt,rt_inv,t_inv)
27998                   if (err_symm) return
27999
28000                case ("BC")
28001                   car_sym=system_equiv(num)%ml
28002                   j=1
28003                   call read_Xsym(car_sym,j,r_inv,t_inv)
28004                   call inverse_symm(r_inv,t_inv,r,t)
28005                   if (err_symm) return
28006                   car_sym=system_equiv(num)%bc
28007                   j=1
28008                   call read_Xsym(car_sym,j,rt,tt)
28009                   call inverse_symm(rt,tt,rt_inv,t_inv)
28010                   if (err_symm) return
28011
28012                case ("ZA")
28013                   car_sym=system_equiv(num)%ml
28014                   j=1
28015                   call read_Xsym(car_sym,j,r_inv,t_inv)
28016                   call inverse_symm(r_inv,t_inv,r,t)
28017                   if (err_symm) return
28018                   car_sym=system_equiv(num)%za
28019                   j=1
28020                   call read_Xsym(car_sym,j,rt,tt)
28021                   call inverse_symm(rt,tt,rt_inv,t_inv)
28022                   if (err_symm) return
28023             end select
28024
28025          case ("KO")    !---- Kovalev ----!
28026             select case (car2)
28027                case ("IT")
28028                   car_sym=system_equiv(num)%ko
28029                   j=1
28030                   call read_Xsym(car_sym,j,r_inv,t_inv)
28031                   call inverse_symm(r_inv,t_inv,r,t)
28032                   if (err_symm) return
28033
28034                case ("ML")
28035                   car_sym=system_equiv(num)%ko
28036                   j=1
28037                   call read_Xsym(car_sym,j,r_inv,t_inv)
28038                   call inverse_symm(r_inv,t_inv,r,t)
28039                   if (err_symm) return
28040                   car_sym=system_equiv(num)%ml
28041                   j=1
28042                   call read_Xsym(car_sym,j,rt,tt)
28043                   call inverse_symm(rt,tt,rt_inv,t_inv)
28044                   if (err_symm) return
28045
28046                case ("KO")
28047                   return
28048
28049                case ("BC")
28050                   car_sym=system_equiv(num)%ko
28051                   j=1
28052                   call read_Xsym(car_sym,j,r_inv,t_inv)
28053                   call inverse_symm(r_inv,t_inv,r,t)
28054                   if (err_symm) return
28055                   car_sym=system_equiv(num)%bc
28056                   j=1
28057                   call read_Xsym(car_sym,j,rt,tt)
28058                   call inverse_symm(rt,tt,rt_inv,t_inv)
28059                   if (err_symm) return
28060
28061                case ("ZA")
28062                   car_sym=system_equiv(num)%ko
28063                   j=1
28064                   call read_Xsym(car_sym,j,r_inv,t_inv)
28065                   call inverse_symm(r_inv,t_inv,r,t)
28066                   if (err_symm) return
28067                   car_sym=system_equiv(num)%za
28068                   j=1
28069                   call read_Xsym(car_sym,j,rt,tt)
28070                   call inverse_symm(rt,tt,rt_inv,t_inv)
28071                   if (err_symm) return
28072             end select
28073
28074          case ("BC")    !---- Bradley & Cracknell ----!
28075             select case (car2)
28076                case ("IT")
28077                   car_sym=system_equiv(num)%bc
28078                   j=1
28079                   call read_Xsym(car_sym,j,r_inv,t_inv)
28080                   call inverse_symm(r_inv,t_inv,r,t)
28081                   if (err_symm) return
28082
28083                case ("ML")
28084                   car_sym=system_equiv(num)%bc
28085                   j=1
28086                   call read_Xsym(car_sym,j,r_inv,t_inv)
28087                   call inverse_symm(r_inv,t_inv,r,t)
28088                   if (err_symm) return
28089                   car_sym=system_equiv(num)%ml
28090                   j=1
28091                   call read_Xsym(car_sym,j,rt,tt)
28092                   call inverse_symm(rt,tt,rt_inv,t_inv)
28093                   if (err_symm) return
28094
28095                case ("KO")
28096                   car_sym=system_equiv(num)%bc
28097                   j=1
28098                   call read_Xsym(car_sym,j,r_inv,t_inv)
28099                   call inverse_symm(r_inv,t_inv,r,t)
28100                   if (err_symm) return
28101                   car_sym=system_equiv(num)%ko
28102                   j=1
28103                   call read_Xsym(car_sym,j,rt,tt)
28104                   call inverse_symm(rt,tt,rt_inv,t_inv)
28105                   if (err_symm) return
28106
28107                case ("BC")
28108                   return
28109
28110                case ("ZA")
28111                   car_sym=system_equiv(num)%bc
28112                   j=1
28113                   call read_Xsym(car_sym,j,r_inv,t_inv)
28114                   call inverse_symm(r_inv,t_inv,r,t)
28115                   if (err_symm) return
28116                   car_sym=system_equiv(num)%za
28117                   j=1
28118                   call read_Xsym(car_sym,j,rt,tt)
28119                   call inverse_symm(rt,tt,rt_inv,t_inv)
28120                   if (err_symm) return
28121             end select
28122
28123          case ("ZA")    !---- Zak ----!
28124             select case (car2)
28125                case ("IT")
28126                   car_sym=system_equiv(num)%za
28127                   j=1
28128                   call read_Xsym(car_sym,j,r_inv,t_inv)
28129                   call inverse_symm(r_inv,t_inv,r,t)
28130                   if (err_symm) return
28131
28132                case ("ML")
28133                   car_sym=system_equiv(num)%za
28134                   j=1
28135                   call read_Xsym(car_sym,j,r_inv,t_inv)
28136                   call inverse_symm(r_inv,t_inv,r,t)
28137                   if (err_symm) return
28138                   car_sym=system_equiv(num)%ml
28139                   j=1
28140                   call read_Xsym(car_sym,j,rt,tt)
28141                   call inverse_symm(rt,tt,rt_inv,t_inv)
28142                   if (err_symm) return
28143
28144                case ("KO")
28145                   car_sym=system_equiv(num)%za
28146                   j=1
28147                   call read_Xsym(car_sym,j,r_inv,t_inv)
28148                   call inverse_symm(r_inv,t_inv,r,t)
28149                   if (err_symm) return
28150                   car_sym=system_equiv(num)%ko
28151                   j=1
28152                   call read_Xsym(car_sym,j,rt,tt)
28153                   call inverse_symm(rt,tt,rt_inv,t_inv)
28154                   if (err_symm) return
28155
28156                case ("BC")
28157                   car_sym=system_equiv(num)%za
28158                   j=1
28159                   call read_Xsym(car_sym,j,r_inv,t_inv)
28160                   call inverse_symm(r_inv,t_inv,r,t)
28161                   if (err_symm) return
28162                   car_sym=system_equiv(num)%bc
28163                   j=1
28164                   call read_Xsym(car_sym,j,rt,tt)
28165                   call inverse_symm(rt,tt,rt_inv,t_inv)
28166                   if (err_symm) return
28167
28168                case ("ZA")
28169                   return
28170             end select
28171
28172       end select
28173
28174       call Get_SymSymb(rt_inv,t_inv,icar_sym)
28175       s(1:3,1:3)  = r
28176       s(1:3,4)    = mod(nint(t*24.0)+48,24)
28177       si(1:3,1:3) = r_inv
28178       si(1:3,4)   = mod(nint(t_inv*24.0)+48,24)
28179
28180       st(1:3,1:3) = rt
28181       st(1:3,4)   = mod(nint(tt*24.0)+48,24)
28182       sti(1:3,1:3)= rt_inv
28183       sti(1:3,4)  = mod(nint(tt_inv*24.0)+48,24)
28184
28185       s=matmul(st,s)
28186       si=matmul(si,sti)
28187
28188       do i=1,SpaceGroup%multip
28189          w(1:3,1:3) = SpaceGroup%Symop(i)%Rot
28190          w(1:3,4)   = mod(nint(SpaceGroup%Symop(i)%Tr*24.0)+48,24)
28191          w=matmul(s,w)
28192          w=matmul(w,si)
28193          SpaceGroup%Symop(i)%Rot = w(1:3,1:3)
28194          SpaceGroup%Symop(i)%Tr  = mod(real(w(1:3,4)/24.0)+10.0_cp,1.0_cp)
28195       end do
28196       do i=1,SpaceGroup%numops
28197          call Get_SymSymb(SpaceGroup%Symop(i)%Rot,  &
28198                           SpaceGroup%Symop(i)%tr,SpaceGroup%SymopSymb(i))
28199       end do
28200
28201       return
28202    End Subroutine Setting_Change_Conv
28203
28204    !!--++
28205    !!--++ Subroutine Setting_Change_NonConv(Mat,Orig,Spg,Spgn,Matkind)
28206    !!--++   real(kind=cp), dimension(3,3),intent(in) :: mat      ! Basis transformation matrix
28207    !!--++   real(kind=cp), dimension(3),  intent(in) :: orig     ! New origing in the old basis
28208    !!--++   type (Space_Group_Type),      intent(in) :: SpG      ! Input space group
28209    !!--++   type (NS_Space_Group_Type),  intent(out) :: SpGn     ! New space group in the new setting.
28210    !!--++   character (len=*), optional,  intent(in) :: matkind  ! Kind of transformation matrix
28211    !!--++
28212    !!--++    Transform the symmetry operators of the space group to a new basis given by
28213    !!--++    the matrix "mat" and vector "orig"
28214    !!--++    If matkind is given and matkind="it"/"IT", the input matrix is given
28215    !!--++    as in International Tables: Mat=P =>  (a,b,c)'=(a,b,c)P
28216    !!--++    Otherwise it is the trasposed matrix Mat=Pt
28217    !!--++
28218    !!--++ Created: January - 2014 (JRC)
28219    !!
28220    Subroutine Setting_Change_NonConv(Mat,Orig,Spg,Spgn,Matkind)
28221       !---- Arguments ----!
28222       real(kind=cp), dimension(3,3),intent(in) :: Mat
28223       real(kind=cp), dimension(3),  intent(in) :: Orig
28224       type (Space_Group_Type),      intent(in) :: SpG
28225       type (NS_Space_Group_Type),  intent(out) :: SpGn
28226       character (len=*), optional,  intent(in) :: Matkind
28227
28228       !--- Local variables ---!
28229       integer                 :: ifail, i, j, k, L, im, nc, m, ngm,n,ngen
28230       real(kind=cp)           :: det
28231       character(len=40)       :: transla
28232       character(len=1)        :: LatSymb
28233       real(kind=cp), dimension (3,3), parameter :: e = reshape ((/1.0,0.0,0.0,  &
28234                                                                   0.0,1.0,0.0,  &
28235                                                                   0.0,0.0,1.0/),(/3,3/))
28236       real(kind=cp), dimension (3,192)    :: newlat = 0.0 !big enough number of centring tranlations
28237       real(kind=cp), dimension (3,3)      :: S, Sinv, rot, rotn  !S is the ITC matrix P.
28238       integer,       dimension (3,3)      :: nulo
28239       real(kind=cp), dimension (  3)      :: tr, trn, v
28240       logical                             :: lattl,change_only_origin
28241       character(len=80)                   :: symbsg
28242       character(len=60),dimension(15)     :: gen
28243       character(len=180)                  :: setting
28244       real(kind=cp),  dimension(3,3,Spg%Multip) :: sm
28245       real(kind=cp),  dimension(3,Spg%Multip)   :: tm
28246
28247       call Init_Err_Symm()
28248       change_only_origin=.false.
28249       nulo=0
28250       call get_setting_info(Mat,orig,setting,matkind)
28251       symbsg=Pack_String(SpG%spg_symb)
28252       if (present(matkind)) then
28253          if (matkind(1:2) == "it" .or. matkind(1:2) == "IT" ) then
28254             S=Mat
28255          else
28256             S=transpose(Mat)
28257          end if
28258       else
28259          S=transpose(Mat)
28260       end if
28261       setting = trim(setting)//" det:"
28262       if(equal_matrix(S,e,3)) change_only_origin=.true.
28263       det=determ_a(Mat)
28264       i=len_trim(setting)
28265       write(unit=setting(i+2:),fmt="(f6.2)") det
28266       !write(unit=*,fmt="(a)") " => Setting Symbol: "//trim(setting)
28267       call matrix_inverse(S,Sinv,ifail)
28268       if (ifail /= 0) then
28269          err_symm=.true.
28270          ERR_Symm_Mess= "Inversion Matrix Failed on: Setting_Change_NonConv"
28271          return
28272       end if
28273
28274       L=0
28275       if (SpG%NumLat > 1) then  !Original lattice is centered
28276          do i=2,SpG%NumLat      !Transform the centring vectors to the new lattice
28277             v=Modulo_Lat(matmul(Sinv,SpG%Latt_trans(:,i)))
28278             if (sum(v) < eps_symm) cycle
28279             L=L+1
28280             newlat(:,L)=v
28281          end do
28282       end if
28283       do i=1,3  !Test the basis vectors of the original setting
28284         rot(:,i)=Modulo_Lat(Sinv(:,i))
28285         if (sum(rot(:,i)) < eps_symm) cycle
28286         L=L+1
28287         newlat(:,L)=rot(:,i)
28288       end do
28289
28290       if (det > 1 ) then  !The new lattice is centred
28291          im=nint(det)-1         !Determine the new lattice translations
28292          ngm=L+im
28293          doi: do i=0,im
28294             v(1) = i
28295             do j=0,im
28296                v(2) = j
28297                do k=0,im
28298                   v(3) = k
28299                   if (nint(sum(v)) == 0) cycle
28300                   tr=Modulo_Lat(matmul(Sinv,v))
28301                   if (sum(tr) < eps_symm) cycle
28302                   lattl =.true.
28303                   do m=1,L
28304                      if (sum(abs(tr-newlat(:,m))) < eps_symm) then
28305                         lattl =.false.
28306                         exit
28307                      end if
28308                   end do
28309                   if (lattl) then ! new lattice translation
28310                      L=L+1
28311                      newlat(:,L) = tr(:)
28312                      if (L == ngm) exit doi
28313                   end if
28314                end do !k
28315             end do !j
28316          end do doi !i
28317       end if
28318
28319       call get_centring_vectors(L,newlat,LatSymb)  !Complete the centring vectors
28320       !Now we have L centring translations
28321       call LatSym(LatSymb,L,newlat)  !provides the value of the global variable inlat: index of the type of lattice
28322       SpGn%SPG_lat      = LatSymb
28323       SpGn%SPG_latsy    = SpG%SPG_latsy(1:1)//LatSymb
28324
28325       !---- Change of symmetry operator under a change of basis and origin
28326       !----  A'= M A,  origin O =>  X'=inv(Mt)(X-O)
28327       !----  Symmetry operator C = (R,T)  -> C' = (R',T')
28328       !----   R' = inv(Mt) R Mt                 ITC:    R'= inv(P) R P
28329       !----   T' = inv(Mt) (T -(E-R)O)                  T'= inv(P) (T-(E-R)O)
28330       sm=0.0
28331       tm=0.0
28332       sm(:,:,1)=SpG%SymOp(1)%Rot
28333       tm(:,1)=SpG%SymOp(1)%tr
28334       n=1
28335       do_i:do i=2,SpG%NumOps
28336          Rot=SpG%SymOp(i)%rot
28337          Rotn=matmul(matmul(Sinv,Rot),S)
28338          !irot=nint(Rotn)
28339          do k=n,1,-1
28340            if(equal_matrix(Rotn,sm(:,:,k),3))  cycle do_i
28341          end do
28342          n=n+1
28343          sm(:,:,N)=Rotn
28344          tr=SpG%SymOp(i)%tr
28345          trn=matmul(Sinv,tr-matmul(e-Rot,orig))
28346          tm(:,n)=Modulo_Lat(trn)
28347       end do do_i
28348
28349       SpGn%Centred=SpG%Centred
28350       SpGn%Centre_coord=SpG%Centre_coord
28351       if (SpG%Centred /= 1) then !the space group is centro-symmetric
28352          nc=SpG%NumOps+1
28353          Rot=SpG%SymOp(nc)%rot
28354          tr=SpG%SymOp(nc)%tr
28355          trn=matmul(Sinv,tr-matmul(e-Rot,orig)) ! matmul(Sinv,tr-2*orig)
28356          trn= Modulo_Lat(trn)
28357          if(sum(abs(trn)) > 3.0*eps_symm) then
28358            SpGn%Centred=0
28359            SpGn%Centre_coord=0.5*trn
28360          end if
28361       end if
28362
28363       !Do another thing we conserve the transformations and generate ourself the new group
28364       !The new multiplicity is
28365       i=1
28366       if(SpGn%Centred /= 1) i=2
28367       SpGn%multip= n * i * nlat  !nlat=L+1
28368
28369       allocate(SpGn%SymOp(SpGn%multip), SpGn%SymOpSymb(SpGn%multip))
28370       SpGn%NumOps=n
28371       do i=1,SpGn%NumOps
28372         SpGn%SymOp(i)%Rot=sm(:,:,i)
28373         SpGn%SymOp(i)%tr=tm(:,i)
28374       end do
28375
28376       allocate(SpGn%Latt_trans(3,nlat))
28377       SpGn%NumLat    = nlat
28378       SpGn%Latt_trans= Ltr(:,1:nlat)
28379       SpGn%CrystalSys   = SpG%CrystalSys
28380       SpGn%SG_setting   = setting
28381       SpGn%Bravais      = Latt(inlat)
28382       Select Case (SpGn%Centred)
28383           Case(0,2)
28384             call Frac_Trans_2Dig(SpGn%Centre_coord,transla)
28385             SpGn%centre="Centric, -1 at "//trim(transla)
28386           Case Default
28387             SpGn%centre="Acentric"
28388       End Select
28389       SpGn%Num_gen      = SpG%Num_gen
28390       SpGn%PG           = SpG%PG
28391       SpGn%Laue         = SpG%laue
28392       SpGn%NumSpg=SpG%NumSpg
28393       m=SpGn%Numops
28394       if (SpGn%centred /= 1) then
28395          do i=1,SpGn%Numops
28396             m=m+1
28397             SpGn%Symop(m)%Rot(:,:) = -SpGn%Symop(i)%Rot(:,:)
28398             SpGn%Symop(m)%tr(:)    =  modulo_lat(-SpGn%Symop(i)%tr(:)+2.0*SpGn%Centre_coord)
28399          end do
28400       end if
28401       ngm=m
28402       if (SpGn%NumLat > 1) then
28403          do L=2,SpGn%NumLat
28404             do i=1,ngm
28405                m=m+1
28406                trn=SpGn%Symop(i)%tr(:) + SpGn%Latt_trans(:,L)
28407                SpGn%Symop(m)%Rot(:,:) = SpGn%Symop(i)%Rot(:,:)
28408                SpGn%Symop(m)%tr(:)    = modulo_lat(trn)
28409             end do
28410          end do
28411       end if
28412       do i=1,SpGn%multip
28413          call Get_SymSymb(SpGn%Symop(i)%Rot(:,:), &
28414                           SpGn%Symop(i)%tr(:)   , &
28415                           SpGn%SymopSymb(i))
28416       end do
28417       !Try to assign a Hall symbol to the space group in the new setting
28418       !If the hall symbol has been found and the symbol exists in the table the H-M symbol is also set.
28419       SpGn%hall="From:"//trim(SpG%hall)
28420       SpGn%spg_symb="From:"//trim(SpG%spg_symb)
28421       if(change_only_origin) then
28422         SpGn%spg_symb=trim(symbsg)
28423       else
28424         if(SpGn%NumSpg == 0) then
28425            SpGn%spg_symb="From:"//trim(symbsg)
28426         end if
28427       end if
28428       !Generate a general symbol, first select generators as a function of SpGn$Numops
28429       n=SpGn%NumOps
28430       Select Case(SpGn%centred)
28431         Case(0)
28432           gen(1)=SpGn%SPG_lat
28433           gen(2)=SpGn%SymopSymb(n+1)
28434           ngen=2
28435         Case(1)
28436           gen(1)=SpGn%SPG_lat
28437           ngen=1
28438         Case(2)
28439           gen(1)="-"//SpGn%SPG_lat
28440           ngen=1
28441       End Select
28442
28443       Select Case(n)
28444         case(1:3)
28445           ngen=ngen+1
28446           gen(ngen)=SpGn%SymopSymb(2)
28447         case(4:)
28448           ngen=ngen+1
28449           gen(ngen)=SpGn%SymopSymb(2)
28450           ngen=ngen+1
28451           gen(ngen)=SpGn%SymopSymb(3)
28452       End Select
28453       !
28454       call Get_GenSymb_from_Gener(gen,ngen,SpGn%ghall)
28455
28456       return
28457    End Subroutine Setting_Change_NonConv
28458
28459    !!----
28460    !!---- Subroutine Similar_Transf_Sg(Mat,Orig,Spg,Spgn,Matkind)
28461    !!----    real(kind=cp), dimension (3,3),   intent( in)    :: Mat     ! Matrix transforming the basis
28462    !!----    real(kind=cp), dimension (  3),   intent( in)    :: orig    ! Coordinates of the new origin
28463    !!----    type (Space_Group_Type) ,         intent( in)    :: SpG     ! Initial space group
28464    !!----    type (Space_Group_Type) ,         intent(out)    :: SpGn    ! Maximum subgroup of SpG
28465    !!----    character (len=*), optional,      intent( in)    :: matkind ! Type of the input matrix
28466    !!----    character (len=*), optional,      intent( in)    :: Fix_lat ! Fixing Lattice type
28467    !!----
28468    !!----    Subroutine to construct a space group "SpGn" that is a maximal subgroup
28469    !!----    of the input space group "SpG" compatible with the transformation
28470    !!----    of the basis corresponding to the matrix "Mat" and the new origin "orig".
28471    !!----    The transformed SpGn will have (if it is the case) conventional centring vectors.
28472    !!----    If matkind is given and matkind="it"/"IT", the input matrix is given
28473    !!----    as in International Tables:
28474    !!--<<
28475    !!----                      (a' b' c') = (a b c) Mat
28476    !!-->>
28477    !!----    If matkind is not given or if it is not equal to "it"/"IT" the input matrix
28478    !!----    is the transpose of the International convention (column matrices for basis vectors)
28479    !!----    The new space group is obtained using the properties of conventional Bravais
28480    !!----    lattices and symmetry operators. Only the symmetry operators of the conventionnal
28481    !!----    form are retained to construct the new space group. If the Hermann-Mauguin symbol
28482    !!----    is not given, that means it correspond to a special setting. The Hall symbol is
28483    !!----    always given.
28484    !!----    The coordinates of the origin is always given with respect to the (a b c) basis.
28485    !!----    If Fix_lat is given a conventional lattice centring, this is fixed irrespective
28486    !!----    of the centring obtained by applying the similarity transformation. For instance
28487    !!----    is Fix_lat="P" and the transformation implies new centring vectors or the input
28488    !!----    group is centred, the generators with fraccional translations are removed from
28489    !!----    the group. If Fix_lat="A" (or whatever) the program will add the corresponding
28490    !!----    generators irrespective that the generator is in the original/transformed group.
28491    !!----
28492    !!---- Update: February - 2005
28493    !!
28494    Subroutine Similar_Transf_SG(Mat,orig,SpG,SpGn,matkind,Fix_lat)
28495       !---- Arguments ----!
28496       real(kind=cp), dimension (3,3),   intent( in)    :: Mat
28497       real(kind=cp), dimension (  3),   intent( in)    :: orig
28498       type (Space_Group_Type) ,         intent( in)    :: SpG
28499       type (Space_Group_Type) ,         intent(out)    :: SpGn
28500       character (len=*), optional,      intent( in)    :: matkind
28501       character (len=*), optional,      intent( in)    :: Fix_lat
28502
28503       !--- Local variables ---!
28504       integer                 :: ifail, i, j, k, det, L, im, nc, m, ngm, ngen, Isystm
28505       real(kind=cp), dimension (3,3), parameter :: e = reshape ((/1.0,0.0,0.0,  &
28506                                                                   0.0,1.0,0.0,  &
28507                                                                   0.0,0.0,1.0/),(/3,3/))
28508       real(kind=cp), dimension (3,192):: newlat = 0.0 !big enough number of centring tranlations
28509       real(kind=cp), dimension (3,3)  :: S, Sinv, rot, rotn
28510       integer,       dimension (3,3)  :: irot
28511       real(kind=cp), dimension (  3)  :: tr, trn, v
28512       real(kind=cp)                   :: rmin,rmax
28513       logical                         :: latt
28514       character(len=40),dimension(60) :: gen
28515       integer,       dimension (60)   :: pt
28516       character(len=40)               :: string
28517       character(len=80)               :: setting, symbsg
28518       character(len=12)               :: csys
28519       character(len=1)                :: lattsymb, crys
28520
28521       err_symm=.false.
28522       call get_setting_info(Mat,orig,setting,matkind)
28523       symbsg=Pack_String(SpG%spg_symb)
28524       csys=SpG%CrystalSys
28525       if (present(matkind)) then
28526          if (matkind(1:2) == "it" .or. matkind(1:2) == "IT" ) then
28527             S=Mat
28528          else
28529             S=transpose(Mat)
28530          end if
28531       else
28532          S=transpose(Mat)
28533       end if
28534
28535       setting = trim(setting)
28536       det=determ_a(Mat)
28537       call matrix_inverse(S,Sinv,ifail)
28538       if (ifail /= 0) then
28539          err_symm=.true.
28540          ERR_Symm_Mess= "Inversion Matrix Failed on: similar_SG"
28541          return
28542       end if
28543
28544       if(present(Fix_lat)) then
28545          lattsymb=Fix_lat
28546       else
28547          L=0
28548          if (SpG%NumLat > 1) then  !Original lattice is centered
28549             do i=2,SpG%NumLat      !Transform the centring vectors to the new lattice
28550                v=Modulo_Lat(matmul(Sinv,SpG%Latt_trans(:,i)))
28551                if (sum(v) < eps_symm) cycle
28552                L=L+1
28553                newlat(:,L)=v
28554             end do
28555          end if
28556
28557          do i=1,3  !Test also the basis vectors of the original setting
28558            rot(:,i)=Modulo_Lat(Sinv(:,i))
28559            if (sum(rot(:,i)) < eps_symm) cycle
28560            L=L+1
28561            newlat(:,L)=rot(:,i)
28562          end do
28563
28564          if (det > 1 ) then  !The new lattice is centred
28565             im=det-1         !Determine the new lattice translations
28566             ngm=L+im
28567             doi: do i=0,im
28568                v(1) = i
28569                do j=0,im
28570                   v(2) = j
28571                   do k=0,im
28572                      v(3) = k
28573                      if (nint(sum(v)) == 0) cycle
28574                      tr=Modulo_Lat(matmul(Sinv,v))
28575                      if (sum(tr) < eps_symm) cycle
28576                      latt =.true.
28577                      do m=1,L
28578                         if (sum(abs(tr-newlat(:,m))) < eps_symm) then
28579                            latt =.false.
28580                            exit
28581                         end if
28582                      end do
28583                      if (latt) then ! new lattice translation
28584                         L=L+1
28585                         newlat(:,L) = tr(:)
28586                         if (L == ngm) exit doi
28587                      end if
28588                   end do !k
28589                end do !j
28590             end do doi !i
28591          end if
28592
28593          call get_centring_vectors(L,newlat,lattsymb)
28594          if(lattsymb == "Z") call Max_Conv_Lattice_Type(L, newlat, lattsymb)
28595          !newlat is not used anymore
28596       end if
28597       !---- Select the generators of the maximum conventional lattice
28598       ngen=0
28599       Select Case(lattsymb)
28600          Case("A")
28601             ngen=1
28602             gen(1)="x,y+1/2,z+1/2"
28603          Case("B")
28604             ngen=1
28605             gen(1)="x+1/2,y,z+1/2"
28606          Case("C")
28607             ngen=1
28608             gen(1)="x+1/2,y+1/2,z"
28609          Case("I")
28610             ngen=1
28611             gen(1)="x+1/2,y+1/2,z+1/2"
28612          Case("F")
28613             ngen=2
28614             gen(1)="x+1/2,y+1/2,z"
28615             gen(2)="x+1/2,y,z+1/2"
28616          Case("R")
28617             ngen=1
28618             gen(1)="x+2/3,y+1/3,z+1/3"
28619       End Select
28620
28621       !---- Up to here all "conventionnal" translational generators have been obtained
28622       !---- Set the minimum and maximum admissible component of translations
28623       select case (csys)
28624          Case("Triclinic")
28625             rmin=0.0
28626             rmax=1.0
28627          Case("Monoclinic")
28628             rmin=0.5
28629             rmax=0.5
28630          Case("Orthorhombic")
28631             rmin=0.5
28632             rmax=0.5
28633             if (lattsymb == "F") then
28634                rmin=0.25
28635                rmax=0.75
28636             end if
28637          Case("Tetragonal")
28638             rmin=0.25
28639             rmax=0.75
28640          Case("Rhombohedral","Hexagonal","Trigonal")
28641             rmin=1.0/6.0
28642             rmax=5.0/6.0
28643          Case("Cubic")
28644             rmin=0.25
28645             rmax=0.75
28646          Case default
28647             rmin=0.5
28648             rmax=0.5
28649       end select
28650
28651       !---- Change of symmetry operator under a change of basis and origin
28652       !----  A'= M A,  origin O =>  X'=inv(Mt)(X-O)
28653       !----  Symmetry operator C = (R,T)  -> C' = (R',T')
28654       !----   R' = inv(Mt) R Mt                 ITC:    R'= inv(P) R P
28655       !----   T' = inv(Mt) (T -(E-R)O)                  T'= inv(P) (T-(E-R)O)
28656       do i=2,SpG%NumOps
28657          Rot=SpG%SymOp(i)%rot
28658          tr=SpG%SymOp(i)%tr
28659          Rotn=matmul(matmul(Sinv,Rot),S)
28660          irot=abs(nint(rotn))
28661          if ( any(irot > 1) ) cycle    !Conserve only the conventional forms  |aij|=1,0
28662          if (.not. Zbelong(Rotn)) cycle
28663          ! Verify is the associated translation is admissible in the crystal system of
28664          ! the parent space group.
28665          trn=matmul(Sinv,tr-matmul(e-Rot,orig))
28666          trn=Modulo_Lat(trn)
28667          if ( any((trn < rmin .and. trn > 0.0) .or. trn > rmax) ) cycle  !internal compiler error in gfortran
28668          call Get_SymSymb(nint(Rotn),trn,string)
28669          ngen=ngen+1
28670          gen(ngen)=string
28671       end do
28672
28673       !----Obtain the maximum expected crystal system after going to the new setting
28674       call Get_Crystal_System(Ngen,Gen, Isystm, Crys)
28675
28676       select case (Isystm)
28677          Case(1)
28678             rmin=0.0
28679             rmax=1.0
28680          Case(2)
28681             rmin=0.5
28682             rmax=0.5
28683          Case(3)
28684             rmin=0.5
28685             rmax=0.5
28686             if (lattsymb == "F") then
28687                rmin=0.25
28688                rmax=0.75
28689             end if
28690          Case(4)
28691             rmin=0.25
28692             rmax=0.75
28693          Case(5,6)
28694             rmin=1.0/6.0
28695             rmax=5.0/6.0
28696          Case(7)
28697             rmin=0.25
28698             rmax=0.75
28699          Case default
28700             rmin=0.0
28701             rmax=1.0
28702       end select
28703
28704       pt(1:ngen) = 1
28705       do i=1,ngen
28706          string=gen(i)
28707
28708          !---- Test if the generator is still compatible with the crystal system
28709          call Read_Xsym(string,1,iRot,tr)
28710          if ( any((tr < rmin .and. tr > 0.0) .or. tr > rmax) ) then
28711             pt(i)=0
28712             cycle
28713          end if
28714          j=index(string,",")
28715          k=index(string,",",back=.true.)
28716          select case (Isystm)
28717             Case(1,2,3)  ! "Triclinic","Monoclinic","Orthorhombic"
28718                if (index(string(1:j),"y") /= 0 .or. index(string(1:j),"z") /= 0) pt(i)=0
28719                if (index(string(j:k),"x") /= 0 .or. index(string(1:j),"z") /= 0) pt(i)=0
28720                if (index(string(k: ),"x") /= 0 .or. index(string(1:j),"y") /= 0) pt(i)=0
28721             Case(4,5,6)  ! "Tetragonal","Rhombohedral","Hexagonal","Trigonal"
28722                if (index(string(1:k),"z") /= 0 ) pt(i)=0
28723                if (index(string(k: ),"x") /= 0 .or. index(string(k: ),"y") /= 0) pt(i)=0
28724          end select
28725       end do
28726
28727       m=0
28728       do i=1,ngen
28729          string=gen(i)
28730          if (pt(i) == 1) then
28731             m=m+1
28732             gen(m)=string
28733          end if
28734       end do
28735       ngen=m
28736       if (SpG%Centred /= 1) then !the space group is centro-symmetric
28737          nc=SpG%NumOps+1
28738          Rot=SpG%SymOp(nc)%rot
28739          tr=SpG%SymOp(nc)%tr
28740          trn=matmul(Sinv,tr-matmul(e-Rot,orig)) ! matmul(Sinv,tr-2*orig)
28741          trn= Modulo_Lat(trn)
28742          if(Lattice_Trans(trn,lattsymb)) trn=(/0.0,0.0,0.0/) !Check Lattice centring
28743
28744          if (.not. any((trn < rmin .and. trn > 0.0) .or. trn > rmax) ) then
28745             ngen=ngen+1
28746             call Get_SymSymb(SpG%SymOp(nc)%rot,trn,gen(ngen))
28747          end if
28748
28749       end if
28750
28751       !---- Check if non conventionnal centring vectors have been generated from
28752       !---- the given generators. In such a case reduce by one unit the number of
28753       !---- generators and restart the generation
28754       dob:do
28755          call set_spacegroup("  ",SpGn,gen,ngen,"GEN")
28756          do i=1,SpGn%multip
28757             call symmetry_symbol(SpGn%SymOp(i),string)
28758             string=adjustl(string)
28759             if (string(1:1) == "t") then
28760                if (lattice_trans(SpGn%SymOp(i)%tr,SpGn%SPG_lat)) cycle
28761                ngen=ngen-1
28762                cycle dob
28763             end if
28764          end do
28765          exit
28766       end do dob
28767
28768       If(present(Fix_Lat)) then
28769          SpGn%spg_symb="From("//trim(symbsg)//") Lat:"//Fix_lat
28770       else
28771          SpGn%spg_symb="From("//trim(symbsg)//")"
28772       end if
28773       call get_HallSymb_from_gener(SpGn)
28774       SpGn%SG_setting=setting
28775
28776       return
28777    End Subroutine Similar_Transf_SG
28778
28779
28780    !!----
28781    !!---- Subroutine Sym_B_Relations(Op/Symb,B_Ind,B_Fac)
28782    !!----    integer, dimension(3,3),     intent (in) :: Op      !  In  -> Rotation Matrix
28783    !!----    character(len=*),            intent (in) :: Symb    !  In  -> Symmetry string
28784    !!----
28785    !!----    integer, dimension(6),       intent(out) :: B_Ind   !  Out -> B Index
28786    !!----    real(kind=cp), dimension(6), intent(out) :: B_Fac   !  Out -> B Factor
28787    !!----
28788    !!----    Symmetry relations among coefficients of the anisotropic temperature
28789    !!----    factor.
28790    !!----
28791    !!----    Order for B is: B11 B22 B33 B12 B13 B23
28792    !!----
28793    !!---- Update: February - 2005
28794    !!
28795
28796    !!--++
28797    !!--++ Subroutine Sym_B_Relations_Op(R,B_Ind,B_Fac)
28798    !!--++    integer,dimension(3,3),      intent (in) :: R
28799    !!--++    integer, dimension(6),       intent(out) :: B_Ind
28800    !!--++    real(kind=cp), dimension(6), intent(out) :: B_Fac
28801    !!--++
28802    !!--++    (OVERLOADED)
28803    !!--++    Symmetry relations among coefficients of the anisotropic temperature
28804    !!--++    factor.
28805    !!--++
28806    !!--++    Order for B is: B11 B22 B33 B12 B13 B23
28807    !!--++
28808    !!--++    B is considered as a 6-D vector and a single 6x6 matrix RB is constructed
28809    !!--++    in such a way as the matrix relation  B'ij = Sum{kh}[Rik Bkh Rjh] = Bij
28810    !!--++    is writen as B'= RB B = B  => (RB-I) B = 0
28811    !!--++
28812    !!--++ Update: February - 2005
28813    !!
28814    Subroutine Sym_B_Relations_OP(R,B_Ind,B_Fac)
28815       !---- Arguments ----!
28816       integer,dimension(3,3),      intent (in) :: R
28817       integer, dimension(6),       intent(out) :: B_Ind
28818       real(kind=cp), dimension(6), intent(out) :: B_Fac
28819
28820       !---- Local variables ----!
28821       integer, dimension(6,6) :: rb
28822       integer                 :: i,j,k,nvar
28823       integer                 :: i1,i2
28824
28825       !---- Init variables ----!
28826       err_symm=.false.
28827       ERR_Symm_Mess=" "
28828
28829        rb(1,1)=r(1,1)*r(1,1)
28830        rb(1,2)=r(2,1)*r(2,1)
28831        rb(1,3)=r(3,1)*r(3,1)
28832        rb(1,4)=2*r(1,1)*r(2,1)
28833        rb(1,5)=2*r(1,1)*r(3,1)
28834        rb(1,6)=2*r(2,1)*r(3,1)
28835
28836        rb(2,1)=r(1,2)*r(1,2)
28837        rb(2,2)=r(2,2)*r(2,2)
28838        rb(2,3)=r(3,2)*r(3,2)
28839        rb(2,4)=2*r(1,2)*r(2,2)
28840        rb(2,5)=2*r(1,2)*r(3,2)
28841        rb(2,6)=2*r(2,2)*r(3,2)
28842
28843        rb(3,1)=r(1,3)*r(1,3)
28844        rb(3,2)=r(2,3)*r(2,3)
28845        rb(3,3)=r(3,3)*r(3,3)
28846        rb(3,4)=2*r(1,3)*r(2,3)
28847        rb(3,5)=2*r(1,3)*r(3,3)
28848        rb(3,6)=2*r(2,3)*r(3,3)
28849
28850        rb(4,1)=r(1,1)*r(1,2)
28851        rb(4,2)=r(2,1)*r(2,2)
28852        rb(4,3)=r(3,1)*r(3,2)
28853        rb(4,4)=r(1,1)*r(2,2)+r(1,2)*r(2,1)
28854        rb(4,5)=r(1,1)*r(3,2)+r(3,1)*r(1,2)
28855        rb(4,6)=r(2,1)*r(3,2)+r(3,1)*r(2,2)
28856
28857        rb(5,1)=r(1,1)*r(1,3)
28858        rb(5,2)=r(2,1)*r(2,3)
28859        rb(5,3)=r(3,1)*r(3,3)
28860        rb(5,4)=r(1,1)*r(2,3)+r(2,1)*r(1,3)
28861        rb(5,5)=r(1,1)*r(3,3)+r(1,3)*r(3,1)
28862        rb(5,6)=r(2,1)*r(3,3)+r(3,1)*r(2,3)
28863
28864        rb(6,1)=r(1,2)*r(1,3)
28865        rb(6,2)=r(2,2)*r(2,3)
28866        rb(6,3)=r(3,2)*r(3,3)
28867        rb(6,4)=r(1,2)*r(2,3)+r(2,2)*r(1,3)
28868        rb(6,5)=r(1,2)*r(3,3)+r(3,2)*r(1,3)
28869        rb(6,6)=r(2,2)*r(3,3)+r(3,2)*r(2,3)
28870
28871      !---- (Rb-1) Array ----!
28872
28873       do i=1,6
28874          rb(i,i)=rb(i,i)-1
28875       end do
28876
28877       !---- Init Output variables ----!
28878       b_ind=-1
28879       b_fac= 0.0
28880       nvar = 0
28881
28882       !---- Free B parameters ----!
28883       do i=1,6
28884          if (all(rb(i,:)==0)) then
28885             b_ind(i)=i
28886             b_fac(i)=1.0
28887             nvar=nvar+1
28888          end if
28889       end do
28890
28891       do j=1,6
28892          if (all(rb(:,j)==0)) then
28893             if (b_ind(j) < 0 ) then
28894                b_ind(j)=j
28895                b_fac(j)=1.0
28896                nvar=nvar+1
28897             end if
28898          end if
28899       end do
28900
28901       !---- Zero B parameters ----!
28902       if (nvar /= 6) then
28903          do i=1,6
28904             j=count(rb(i,:)/=0)
28905             if (j /= 1) cycle
28906             do k=1,6
28907                if (rb(i,k)/=0 .and. b_ind(k) < 0) then
28908                   b_ind(k)=k
28909                   nvar=nvar+1
28910                   exit
28911                end if
28912             end do
28913          end do
28914       end if
28915
28916       !---- Other relations ----!
28917       if (nvar /=6) then
28918          do i=1,6
28919             j=count(rb(i,:)/=0)
28920             if (j /= 2) cycle
28921             do j=1,6
28922                if (rb(i,j)/=0) then
28923                   i1=j
28924                   exit
28925                end if
28926             end do
28927             do k=i1+1,6
28928                if (rb(i,k)/=0) then
28929                   i2=k
28930                   exit
28931                end if
28932             end do
28933
28934             if (b_ind(i1) < 0 .and. b_ind(i2) < 0) then
28935                b_ind(i1)=i1
28936                b_ind(i2)=i1
28937                b_fac(i1)=1.0
28938                b_fac(i2)=-real(rb(i,i1))/real(rb(i,i2))
28939                nvar=nvar+2
28940             else
28941                if (b_ind(i1) < 0) then
28942                   b_fac(i1)=-real(rb(i,i2))/real(rb(i,i1))
28943                   b_ind(i1)=i2
28944                else
28945                   b_fac(i2)=-real(rb(i,i1))/real(rb(i,i2))
28946                   b_ind(i2)=i1
28947                end if
28948                nvar=nvar+1
28949             end if
28950          end do
28951       end if
28952
28953       if (any(b_ind==-1)) then
28954          err_symm=.true.
28955          ERR_Symm_Mess="Symmetry relations in B Factors are wrong! "
28956       end if
28957
28958       return
28959    End Subroutine Sym_B_Relations_OP
28960
28961    !!--++
28962    !!--++ Subroutine Sym_B_Relations_St(Symmcar,B_Ind,B_Fac)
28963    !!--++    character(len=*),            intent (in) :: Symmcar
28964    !!--++    integer, dimension(6),       intent(out) :: B_Ind
28965    !!--++    real(kind=cp), dimension(6), intent(out) :: B_Fac
28966    !!--++
28967    !!--++    (OVERLOADED)
28968    !!--++    Symmetry relations among coefficients of the anisotropic temperature
28969    !!--++    factor.
28970    !!--++
28971    !!--++    Order for B is: B11 B22 B33 B12 B13 B23
28972    !!--++
28973    !!--++ Update: February - 2005
28974    !!
28975    Subroutine Sym_B_Relations_ST(Symmcar,B_Ind,B_Fac)
28976       !---- Arguments ----!
28977       character(len=*),            intent (in) :: Symmcar
28978       integer, dimension(6),       intent(out) :: B_Ind
28979       real(kind=cp), dimension(6), intent(out) :: B_Fac
28980
28981       !---- Local variables ----!
28982       integer, dimension(3,3) :: a
28983       real(kind=cp), dimension(3)      :: t
28984
28985       call read_xsym(symmcar,1,a,t)
28986       call sym_b_relations_op(a,b_ind,b_fac)
28987
28988       return
28989    End Subroutine Sym_B_Relations_ST
28990
28991    !!----
28992    !!---- Subroutine Sym_Prod_St(Syma,Symb,Symab,Modlat)
28993    !!----    character(len=*),         intent (in)  :: syma
28994    !!----    character(len=*),         intent (in)  :: symb
28995    !!----    character(len=len(syma)), intent (out) :: symab
28996    !!----    logical, optional,        intent (in)  :: modlat
28997    !!----
28998    !!----    Obtain the symbol/Op/Matrix+trans of the  symmetry operation corresponding
28999    !!----    to the product of two operators given in the Jone's Faithful(symbol)
29000    !!----    representation or in Symmetry Operator type.
29001    !!--<<
29002    !!----     Op_a =  (Sa,ta) ;  Op_b =  (Sb,tb)
29003    !!----
29004    !!----     Op_ab =  (Sa,ta) (Sb,tb)  = (Sa Sb,  Sa tb + ta)
29005    !!-->>
29006    !!----    If modlat=.true. or it is not present, the traslation
29007    !!----    part of the resulting operator is reduced to have components < 1.0
29008    !!----
29009    !!---- Update: February - 2005
29010    !!
29011    Subroutine Sym_Prod_St(Syma,Symb,Symab,Modlat)
29012       !---- Arguments ----!
29013       character(len=*),         intent (in) :: syma
29014       character(len=*),         intent (in) :: symb
29015       character(len=len(syma)), intent(out) :: symab
29016       logical,optional,         intent (in) :: modlat
29017
29018       !--- Local variables ---!
29019       integer, dimension (3,3)      :: Sa,Sb
29020       real(kind=cp),dimension (3)   :: ta,tb
29021
29022       call Read_Xsym(syma,1,Sa,ta)
29023       call Read_Xsym(symb,1,Sb,tb)
29024
29025       if(present(modlat)) then
29026         if(.not. modlat) then
29027           ta = ta + matmul(real(Sa),tb)
29028         else
29029           ta = modulo_lat(ta + matmul(real(Sa),tb))
29030         end if
29031       else
29032         ta = modulo_lat(ta + matmul(real(Sa),tb))
29033       end if
29034       Sa = matmul(Sa,Sb)
29035       call Get_symsymb(Sa,ta,symab)
29036
29037       return
29038    End Subroutine Sym_Prod_St
29039
29040    !!----
29041    !!---- Subroutine Symmetry_Symbol(Op,Symb), (S,T,Symb), (Symm,Symb)
29042    !!----    type(Sym_Oper_type),         intent (in) :: Op
29043    !!----
29044    !!----    integer, dimension(3,3),     intent (in) :: S
29045    !!----    real(kind=cp), dimension(3), intent (in) :: t
29046    !!----
29047    !!----    character(len=*),            intent (in) :: Symm
29048    !!----
29049    !!----    character(len=*),            intent (out):: symb
29050    !!----
29051    !!----    Obtain the symbol of the symmetry element of the operator Op
29052    !!----
29053    !!---- Update: February - 2005
29054    !!
29055
29056    !!--++
29057    !!--++ Subroutine Symmetry_Symbol_Op(Op,Symb)
29058    !!--++    type(Sym_Oper_type), intent (in)  :: Op
29059    !!--++    character(len=*),    intent (out) :: symb
29060    !!--++
29061    !!--++    (OVERLOADED)
29062    !!--++    Obtain the symbol of the symmetry element of the operator Op
29063    !!--++
29064    !!--++ Update: February - 2005
29065    !!
29066    Subroutine Symmetry_Symbol_OP(Op,symb)
29067       !---- Arguments ----!
29068       type(Sym_Oper_Type),   intent (in)  :: Op
29069       character(len=*),     intent (out)  :: symb
29070
29071       call symmetry_symbol_str(Op%Rot,Op%tr,symb)
29072
29073       return
29074    End Subroutine Symmetry_Symbol_OP
29075
29076    !!--++
29077    !!--++ Subroutine Symmetry_Symbol_Str(S,T,Symb)
29078    !!--++    integer, dimension(3,3),     intent( in) :: s
29079    !!--++    real(kind=cp), dimension(3), intent( in) :: t
29080    !!--++    character (len=*),           intent(out) :: symb
29081    !!--++
29082    !!--++    (OVERLOADED)
29083    !!--++    Obtain the symbol of the symmetry element corresponding to operator (S,T)
29084    !!--++
29085    !!--++ Update: February - 2005
29086    !!
29087    Subroutine Symmetry_Symbol_Str(S,T,Symb)
29088       !---- Arguments ----!
29089       integer,       dimension(3,3),    intent( in) :: s
29090       real(kind=cp), dimension(3),      intent( in) :: t
29091       character (len=*),                intent(out) :: symb
29092
29093       !---- Local variables ----!
29094       character (len=80)      :: carsym
29095       character (len=1)       :: signo
29096       integer                 :: i, n, npos
29097       integer, dimension(3)   :: ix1, ix2, ix3
29098       integer, dimension(3,3) :: w
29099       integer, dimension(3,3), parameter :: identidad = reshape((/1, 0, 0, &
29100                                                                   0, 1, 0, &
29101                                                                   0, 0, 1/),(/3,3/))
29102       real(kind=cp)                    :: rnum
29103       real(kind=cp), dimension(3)      :: t0,t1,t2,t3
29104       real(kind=cp), dimension(3)      :: x1,x2,x3
29105       real(kind=cp), dimension(3)      :: p0,p1,p2,p3
29106       real(kind=cp), dimension(3,3)    :: ww
29107
29108       !---- Initialize ----!
29109       symb=" "
29110       n=axes_rotation(s)
29111       !t0=mod(t+10.0_cp,1.0_cp)  !Attempt to use the given translation
29112       t0=t                       !of the symmetry operator
29113       x1 =0.0
29114       ix1=0
29115       call Init_Err_Symm()
29116
29117       select case (n)
29118          case (1) ! Traslation or identity
29119             if (sum(abs(t)) <= 3.0*eps_symm) then
29120                symb(1:1) ="1"
29121             else
29122                symb(1:3)="t ("
29123                npos=4
29124                call get_string_resolv(t0,x1,ix1,carsym)
29125                symb(npos:)=carsym(1:len_trim(carsym))//")"
29126             end if
29127
29128          case (:-3) ! Rotoinversion
29129             !---- Inversion point ----!
29130             w=s-identidad
29131             call resolv_sist_3x3(w,-t0,t3,x3,ix3)
29132
29133             !---- Axes rotation ----!
29134             w=matmul(s,s)-identidad
29135             t1=matmul(real(s),t0)+t0
29136             call resolv_sist_3x3(w,-t1,t2,x2,ix2)
29137
29138             !---- Sense of rotation ----!
29139             !---- P0, P1 ----!
29140             p0=0.0
29141             p1=1.0
29142             do i=1,3
29143                if (ix2(i) == 0) then
29144                   p0(i)=t2(i)
29145                   p1(i)=t2(i)
29146                else
29147                   p0(i)=t2(i)+x2(i)*p0(ix2(i))
29148                   p1(i)=t2(i)+x2(i)*p1(ix2(i))
29149                end if
29150             end do
29151
29152             !---- P2 ----!
29153             do i=1,3
29154                if (p1(i) > 0.0 ) exit
29155             end do
29156             select case (i)
29157                case (1)
29158                   p2(3)=0.5*p1(3)
29159                   p2(2)=0.7*p1(2)
29160                   p2(1)=-(p2(2)*p1(2) + p2(3)*p1(3))/p1(1)
29161
29162                case (2)
29163                   p2(1)=0.5*p1(1)
29164                   p2(3)=0.7*p1(3)
29165                   p2(2)=-(p2(1)*p1(1) + p2(3)*p1(3))/p1(2)
29166
29167                case (3)
29168                   p2(1)=0.5*p1(1)
29169                   p2(2)=0.7*p1(2)
29170                   p2(3)=-(p2(1)*p1(1) + p2(2)*p1(2))/p1(3)
29171             end select
29172             do i=1,3
29173                if (abs(p2(i) - p0(i)) <= eps_symm) p2(i)=p2(i)*p2(i)+0.5*real(i)
29174             end do
29175
29176             !---- P3 ----!
29177             p3=matmul(real(s),p2)+t0
29178             ww(1,:)=p1-p0
29179             ww(2,:)=p2-p0
29180             ww(3,:)=p3-p0
29181             rnum=determ_a(ww)
29182             if (rnum > 0.0) then
29183                signo="-"
29184             else
29185                signo="+"
29186             end if
29187
29188             !---- Determine the final symbol ----!
29189             write(unit=symb,fmt="(i2)") n
29190             symb=adjustl(symb)
29191             npos=len_trim(symb)
29192             npos=npos+1
29193             symb(npos:npos)=signo
29194             npos=npos+2
29195             call get_string_resolv(t2,x2,ix2,carsym)
29196             symb(npos:)=carsym(1:len_trim(carsym))//";"
29197             npos=len_trim(symb)+2
29198             call get_string_resolv(t3,x3,ix3,carsym)
29199             symb(npos:)=carsym(1:len_trim(carsym))
29200
29201          case (-2)  ! Reflection or glide reflection
29202             t1=matmul(s,t0)+t0
29203             if (t1(1) <= eps_symm .and. t1(2) <= eps_symm .and. &
29204                 t1(3) <= eps_symm) then        ! Pure Reflection
29205
29206                !----Mirror Plane ----!
29207                w=s-identidad
29208                call resolv_sist_3x3(w,-t0,t3,x3,ix3)
29209                symb(1:2)="m "
29210                npos=3
29211                call get_string_resolv(t3,x3,ix3,carsym)
29212                symb(npos:)=carsym(1:len_trim(carsym))
29213             else                          ! Glide Reflection
29214                t3=0.5*t1
29215                w=s-identidad
29216                t1=t0-t3
29217                call resolv_sist_3x3(w,-t1,t2,x2,ix2)
29218
29219                !---- Determine the final symbol ----!
29220                symb(1:2)="g "
29221
29222                !---- a: (1/2, 0, 0) ----!
29223                if ( (abs(t3(1) - 0.5) <= eps_symm) .and. (abs(t3(2)) <= eps_symm) .and. &
29224                     (abs(t3(3)) <= eps_symm) ) then
29225                   symb(1:2)="a "
29226                end if
29227
29228                !---- b: (0, 1/2, 0) ----!
29229                if ( (abs(t3(2) - 0.5) <= eps_symm) .and. (abs(t3(1)) <= eps_symm) .and. &
29230                     (abs(t3(3)) <= eps_symm) ) then
29231                   symb(1:2)="b "
29232                end if
29233
29234                !---- c: (0, 0, 1/2) ----!
29235                if ( (abs(t3(3) - 0.5) <= eps_symm) .and. (abs(t3(2)) <= eps_symm) .and. &
29236                     (abs(t3(1)) <= eps_symm) ) then
29237                   symb(1:2)="c "
29238                end if
29239
29240                !---- n: ( 1/2, 1/2, 0); (0, 1/2, 1/2); (1/2, 0, 1/2) ----!
29241                !---- n: ( 1/2, 1/2, 1/2) ----!
29242                !---- n: (-1/2, 1/2, 1/2); (1/2, -1/2, 1/2); (1/2, 1/2, -1/2) ----!
29243                if ( (abs(t3(1) - 0.5) <= eps_symm) .and. (abs(t3(2) - 0.5) <= eps_symm) .and. &
29244                     (abs(t3(3)) <= eps_symm) ) then
29245                   symb(1:2)="n "
29246                end if
29247                if ( (abs(t3(2) - 0.5) <= eps_symm) .and. (abs(t3(3) - 0.5) <= eps_symm) .and. &
29248                     (abs(t3(1)) <= eps_symm) ) then
29249                   symb(1:2)="n "
29250                end if
29251                if ( (abs(t3(1) - 0.5) <= eps_symm) .and. (abs(t3(3) - 0.5) <= eps_symm) .and. &
29252                     (abs(t3(2)) <= eps_symm) ) then
29253                   symb(1:2)="n "
29254                end if
29255                if ( (abs(t3(1) - 0.5) <= eps_symm) .and. (abs(t3(2) - 0.5) <= eps_symm) .and. &
29256                     (abs(t3(3) - 0.5) <= eps_symm) ) then
29257                   symb(1:2)="n "
29258                end if
29259                if ( (abs(t3(1) + 0.5) <= eps_symm) .and. (abs(t3(2) - 0.5) <= eps_symm) .and. &
29260                     (abs(t3(3) - 0.5) <= eps_symm) ) then
29261                   symb(1:2)="n "
29262                end if
29263                if ( (abs(t3(1) - 0.5) <= eps_symm) .and. (abs(t3(2) + 0.5) <= eps_symm) .and. &
29264                     (abs(t3(3) - 0.5) <= eps_symm) ) then
29265                   symb(1:2)="n "
29266                end if
29267                if ( (abs(t3(1) - 0.5) <= eps_symm) .and. (abs(t3(2) - 0.5) <= eps_symm) .and. &
29268                     (abs(t3(3) + 0.5) <= eps_symm) ) then
29269                   symb(1:2)="n "
29270                end if
29271
29272                !---- d: ( 1/4,+-1/4, 0); (0, 1/4,+-1/4); (+-1/4, 0, 1/4) ----!
29273                !---- d: ( 1/4, 1/4,+-1/4); (+-1/4, 1/4, 1/4); (1/4,+-1/4, 1/4) ----!
29274                !---- d: (-1/4, 1/4,+-1/4); (+-1/4,-1/4, 1/4); (1/4,+-1/4,-1/4) ----!
29275                p3=t3
29276                p3=mod(p3+10.0_cp,1.0_cp)
29277                do i=1,3
29278                   if (p3(i) > 0.5) p3(i)=p3(i) -1.0
29279                end do
29280                if ( (abs(p3(1) - 0.25) <= eps_symm) .and. (abs(abs(p3(2)) - 0.25) <= eps_symm) .and. &
29281                     (abs(p3(3)) <= eps_symm) ) then
29282                   symb(1:2)="d "
29283                end if
29284                if ( (abs(p3(2) - 0.25) <= eps_symm) .and. (abs(abs(p3(3)) - 0.25) <= eps_symm) .and. &
29285                     (abs(p3(1)) <= eps_symm) ) then
29286                   symb(1:2)="d "
29287                end if
29288                if ( (abs(p3(3) - 0.25) <= eps_symm) .and. (abs(abs(p3(1)) - 0.25) <= eps_symm) .and. &
29289                     (abs(p3(2)) <= eps_symm) ) then
29290                   symb(1:2)="d "
29291                end if
29292                if ( (abs(p3(1) - 0.25) <= eps_symm) .and. (abs(abs(p3(3)) - 0.25) <= eps_symm) .and. &
29293                     (abs(p3(2) - 0.25) <= eps_symm) ) then
29294                   symb(1:2)="d "
29295                end if
29296                if ( (abs(p3(2) - 0.25) <= eps_symm) .and. (abs(abs(p3(1)) - 0.25) <= eps_symm) .and. &
29297                     (abs(p3(3) - 0.25) <= eps_symm) ) then
29298                   symb(1:2)="d "
29299                end if
29300                if ( (abs(p3(1) - 0.25) <= eps_symm) .and. (abs(abs(p3(2)) - 0.25) <= eps_symm) .and. &
29301                     (abs(p3(3) - 0.25) <= eps_symm) ) then
29302                   symb(1:2)="d "
29303                end if
29304                if ( (abs(p3(1) + 0.25) <= eps_symm) .and. (abs(abs(p3(3)) - 0.25) <= eps_symm) .and. &
29305                     (abs(p3(2) - 0.25) <= eps_symm) ) then
29306                   symb(1:2)="d "
29307                end if
29308                if ( (abs(p3(2) + 0.25) <= eps_symm) .and. (abs(abs(p3(1)) - 0.25) <= eps_symm) .and. &
29309                     (abs(p3(3) - 0.25) <= eps_symm) ) then
29310                   symb(1:2)="d "
29311                end if
29312                if ( (abs(p3(3) + 0.25) <= eps_symm) .and. (abs(abs(p3(2)) - 0.25) <= eps_symm) .and. &
29313                     (abs(p3(1) - 0.25) <= eps_symm) ) then
29314                   symb(1:2)="d "
29315                end if
29316                npos=3
29317
29318                !---- Glide Part ----!
29319                if ( symb(1:1) == "n" .or. symb(1:1) == "d" .or. &
29320                     symb(1:1) == "g" ) then
29321                   symb(npos:)="("
29322                   npos=npos+1
29323                   x1 =0.0
29324                   ix1=0
29325                   call get_string_resolv(t3,x1,ix1,carsym)
29326                   symb(npos:)=carsym(1:len_trim(carsym))//")"
29327                   npos=len_trim(symb)+2
29328                end if
29329
29330                !---- Location of Glide Plane ----!
29331                call get_string_resolv(t2,x2,ix2,carsym)
29332                symb(npos:)=carsym(1:len_trim(carsym))
29333             end if
29334
29335          case (-1)  ! Inversion
29336             t1=0.5*t0
29337             symb(1:3)="-1 "
29338             npos=4
29339             x1 =0.0
29340             ix1=0
29341             call get_string_resolv(t1,x1,ix1,carsym)
29342             symb(npos:)=carsym(1:len_trim(carsym))
29343
29344          case (2:)  ! Rotation / Screw Rotation
29345             w=identidad
29346             t1=t0
29347             do i=1,n-1
29348                w=matmul(w,s)
29349                t1=t1+matmul(w,t0)
29350             end do
29351             if (abs(t1(1)) <= eps_symm .and. abs(t1(2)) <= eps_symm &
29352                 .and. abs(t1(3)) <= eps_symm) then              ! Pure rotation
29353
29354                !---- Rotations axes ----!
29355                w=s-identidad
29356                call resolv_sist_3x3(w,-t0,t2,x2,ix2)
29357
29358                !---- Sense of rotation ----!
29359                !---- P0, P1 ----!
29360                p0=0.0
29361                p1=1.0
29362                do i=1,3
29363                   if (ix2(i) == 0) then
29364                      p0(i)=t2(i)
29365                      p1(i)=t2(i)
29366                   else
29367                      p0(i)=t2(i)+x2(i)*p0(ix2(i))
29368                      p1(i)=t2(i)+x2(i)*p1(ix2(i))
29369                   end if
29370                end do
29371
29372                !---- P2 ----!
29373                do i=1,3
29374                   if (p1(i) > 0.0 ) exit
29375                end do
29376                select case (i)
29377                   case (1)
29378                      p2(3)=0.5*p1(3)
29379                      p2(2)=0.7*p1(2)
29380                      p2(1)=-(p2(2)*p1(2) + p2(3)*p1(3))/p1(1)
29381
29382                   case (2)
29383                      p2(1)=0.5*p1(1)
29384                      p2(3)=0.7*p1(3)
29385                      p2(2)=-(p2(1)*p1(1) + p2(3)*p1(3))/p1(2)
29386
29387                   case (3)
29388                      p2(1)=0.5*p1(1)
29389                      p2(2)=0.7*p1(2)
29390                      p2(3)=-(p2(1)*p1(1) + p2(2)*p1(2))/p1(3)
29391                end select
29392                do i=1,3
29393                   if (abs(p2(i) - p0(i)) <= eps_symm) p2(i)=p2(i)*p2(i)+0.5*real(i)
29394                end do
29395
29396                !---- P3 ----!
29397                p3=matmul(real(s),p2)+t0
29398                ww(1,:)=p1-p0
29399                ww(2,:)=p2-p0
29400                ww(3,:)=p3-p0
29401
29402                rnum=determ_a(ww)
29403                if (rnum > 0.0) then
29404                   signo="+"
29405                else
29406                   signo="-"
29407                end if
29408
29409                !---- Determine the final symbol ----!
29410                write(unit=symb,fmt="(i2)") n
29411                symb=adjustl(symb)
29412                npos=len_trim(symb)
29413                if ( n /= 2) then
29414                   npos=npos+1
29415                   symb(npos:)=signo
29416                end if
29417                npos=npos+2
29418                call get_string_resolv(t2,x2,ix2,carsym)
29419                symb(npos:)=carsym(1:len_trim(carsym))
29420             else                     ! Screw Rotation
29421                t3=(1.0/real(n))*t1
29422                w=s-identidad
29423                t1=t0-t3
29424                call resolv_sist_3x3(w,-t1,t2,x2,ix2)
29425
29426                !---- Sense of rotation ----!
29427                !---- P0, P1 ----!
29428                p0=0.0
29429                p1=1.0
29430                do i=1,3
29431                   if (ix2(i) == 0) then
29432                      p0(i)=t2(i)
29433                      p1(i)=t2(i)
29434                   else
29435                      p0(i)=t2(i)+x2(i)*p0(ix2(i))
29436                      p1(i)=t2(i)+x2(i)*p1(ix2(i))
29437                   end if
29438                end do
29439
29440                !---- P2 ----!
29441                do i=1,3
29442                   if (p1(i) > 0.0 ) exit
29443                end do
29444                select case (i)
29445                   case (1)
29446                      p2(3)=0.5*p1(3)
29447                      p2(2)=0.7*p1(2)
29448                      p2(1)=-(p2(2)*p1(2) + p2(3)*p1(3))/p1(1)
29449
29450                   case (2)
29451                      p2(1)=0.5*p1(1)
29452                      p2(3)=0.7*p1(3)
29453                      p2(2)=-(p2(1)*p1(1) + p2(3)*p1(3))/p1(2)
29454
29455                   case (3)
29456                      p2(1)=0.5*p1(1)
29457                      p2(2)=0.7*p1(2)
29458                      p2(3)=-(p2(1)*p1(1) + p2(2)*p1(2))/p1(3)
29459                end select
29460                do i=1,3
29461                   if (abs(p2(i) - p0(i)) <= eps_symm) p2(i)=p2(i)*p2(i)+0.5*real(i)
29462                end do
29463
29464                !---- P3 ----!
29465                p3=matmul(real(s),p2)+t0
29466                ww(1,:)=p1-p0
29467                ww(2,:)=p2-p0
29468                ww(3,:)=p3-p0
29469                rnum=determ_a(ww)
29470                if (rnum > 0.0) then
29471                   signo="+"
29472                else
29473                   signo="-"
29474                end if
29475
29476                !---- Determine the final symbol ----!
29477                write(unit=symb,fmt="(i2)") n
29478                symb=adjustl(symb)
29479                npos=len_trim(symb)
29480                if ( n /= 2) then
29481                   npos=npos+1
29482                   symb(npos:npos)=signo
29483                end if
29484                npos=npos+2
29485
29486                !---- Screw Part ----!
29487                symb(npos:)="("
29488                npos=npos+1
29489                x1 =0.0
29490                ix1=0
29491                call get_string_resolv(t3,x1,ix1,carsym)
29492                symb(npos:)=carsym(1:len_trim(carsym))//")"
29493                npos=len_trim(symb)+2
29494                call get_string_resolv(t2,x2,ix2,carsym)
29495                symb(npos:)=carsym(1:len_trim(carsym))
29496             end if
29497
29498       end select
29499
29500       return
29501    End Subroutine Symmetry_Symbol_Str
29502
29503    !!--++
29504    !!--++ Subroutine Symmetry_Symbol_Xyz(Symm,Symb)
29505    !!--++    character(len=*), intent (in)  :: symm
29506    !!--++    character(len=*), intent (out) :: symb
29507    !!--++
29508    !!--++    (OVERLOADED)
29509    !!--++    Obtain the symbol of the  symmetry element corresponding
29510    !!--++    to an operator given in the Jone's Faithful representation
29511    !!--++
29512    !!--++ Update: February - 2005
29513    !!
29514    Subroutine Symmetry_Symbol_Xyz(Symm,Symb)
29515       !---- Arguments ----!
29516       character(len=*), intent (in)  :: symm
29517       character(len=*), intent (out) :: symb
29518
29519       !--- Local variables ---!
29520       integer, dimension (3,3)      :: s
29521       real(kind=cp),    dimension (3)        :: t
29522
29523       call Read_Xsym(symm,1,s,t)
29524       call symmetry_symbol_str(s,t,symb)
29525
29526       return
29527    End Subroutine Symmetry_Symbol_Xyz
29528
29529    !!----
29530    !!---- Subroutine Write_Bin_Spacegroup(SpG,Lun)
29531    !!----    type (Space_Group),  intent(in)  :: SpG   !  In -> SpaceGroup Variable
29532    !!----    integer,             intent(in)  :: Lun   !  In -> Logical unit of the file
29533    !!----
29534    !!----    Writing in file of logical unit "lun" the full structure of Space_Group_Type, SpG
29535    !!----    The file should have been opened with the access="stream" attribute. The procedure
29536    !!----    writes in the given order a series of bytes corresponding to the components of the
29537    !!----    type SpG. For reading back a Space Group structure from a binary file the subroutine
29538    !!----    Read_Bin_Spacegroup has to be used.
29539    !!----
29540    !!---- Update: February - 2013
29541    !!
29542    Subroutine Write_Bin_SpaceGroup(SpG,lun)
29543       !---- Arguments ----!
29544       type (Space_Group_Type),intent(in) :: SpG
29545       integer,                intent(in) :: lun
29546
29547       !---- Local variables ----!
29548       integer                           :: i,j
29549
29550       !---- Writing variables ----!
29551       write(unit=Lun) SpG%NumSpg,        &   ! Number of the Space Group
29552                       SpG%SPG_Symb,      &   ! Hermann-Mauguin Symbol
29553                       SpG%Hall,          &   ! Hall symbol
29554                       SpG%CrystalSys,    &   ! Crystal system
29555                       SpG%Laue,          &   ! Laue Class
29556                       SpG%PG,            &   ! Point group
29557                       SpG%Info,          &   ! Extra information
29558                       SpG%SG_setting,    &   ! Information about the SG setting (IT,KO,ML,ZA,Table,Standard,UnConventional)
29559                       SpG%Hexa,          &   !
29560                       SpG%SPG_lat,       &   ! Lattice type
29561                       SpG%SPG_latsy,     &   ! Lattice type Symbol
29562                       SpG%NumLat,        &   ! Number of lattice points in a cell
29563                       SpG%Latt_trans,    &   ! Lattice translations
29564                       SpG%Bravais,       &   ! String with Bravais symbol + translations
29565                       SpG%Centre,        &   ! Alphanumeric information about the center of symmetry
29566                       SpG%Centred,       &   ! Centric or Acentric [ =0 Centric(-1 no at origin),=1 Acentric,=2 Centric(-1 at origin)]
29567                       SpG%Centre_coord,  &   ! Fractional coordinates of the inversion centre
29568                       SpG%NumOps,        &   ! Number of reduced set of S.O.
29569                       SpG%Multip,        &   ! Multiplicity of the general position
29570                       SpG%Num_gen            ! Minimum number of operators to generate the Group
29571       do i=1,SpG%Multip
29572         write(unit=Lun) SpG%SymOp(i)%Rot,SpG%SymOp(i)%tr ! Symmetry operators
29573         write(unit=Lun) SpG%SymopSymb(i)                 ! Strings form of symmetry operators
29574       end do
29575       write(unit=Lun) SpG%R_Asym_Unit                    ! Asymmetric unit in real space
29576       write(unit=Lun) SpG%Wyckoff%num_orbit              ! Wyckoff Information
29577       do i=1,SpG%Wyckoff%num_orbit
29578         write(unit=Lun) SpG%Wyckoff%orbit(i)%norb
29579         write(unit=Lun) SpG%Wyckoff%orbit(i)%str_Orig
29580         do j=1,SpG%Wyckoff%orbit(i)%norb
29581           write(unit=Lun) SpG%Wyckoff%orbit(i)%str_orbit(j)
29582         end do
29583       end do
29584       return
29585    End Subroutine Write_Bin_SpaceGroup
29586
29587    !!----
29588    !!---- Subroutine Write_Spacegroup(Spacegroup,Iunit,Full)
29589    !!----    type (Space_Group),  intent(in)  :: SpaceGroup !  In -> SpaceGroup Variable
29590    !!----    integer,  optional,  intent(in)  :: iunit      !  In -> Write information on Iunit
29591    !!----    logical,  optional,  intent(in)  :: full       !  In -> Full operator or not
29592    !!----
29593    !!----    Writing in file of logical unit "lun" the characteristics of
29594    !!----    the space group "SpaceG". Part of the information contained
29595    !!----    in  SpaceGroup may be undefined, depending on the tabulated
29596    !!----    nature of the item. If full=.true. is present the whole group
29597    !!----    is output including the symmetry symbol associated to each
29598    !!----    operator.
29599    !!----
29600    !!---- Update: February - 2005
29601    !!
29602    Subroutine Write_SpaceGroup(SpaceGroup,Iunit,Full)
29603       !---- Arguments ----!
29604       type (Space_Group_Type),intent(in) :: SpaceGroup
29605       integer,   optional,    intent(in) :: iunit
29606       logical,   optional,    intent(in) :: full
29607
29608       !---- Local variables ----!
29609       integer,  parameter                      :: max_lines=192
29610       character (len=100), dimension(max_lines):: texto
29611       character (len=40)                       :: aux
29612       integer                                  :: lun
29613       integer                                  :: i, nlines
29614       logical                                  :: print_latt
29615
29616       !---- Initializing variables ----!
29617       lun=6
29618       print_latt=.false.
29619       if (present(iunit)) lun=iunit
29620       if (present(full))  print_latt=.true.
29621
29622       !---- Printing ----!
29623       write(unit=lun,fmt="(/,/,a)")          "        Information on Space Group: "
29624       write(unit=lun,fmt="(a,/ )")           "        --------------------------- "
29625       write(unit=lun,fmt="(a,i3)")          " =>   Number of Space group: ", SpaceGroup%NumSpg
29626       write(unit=lun,fmt="(a,a)")           " =>  Hermann-Mauguin Symbol: ", trim(SpaceGroup%SPG_Symb)
29627       write(unit=lun,fmt="(a,a)")           " =>             Hall Symbol: ", trim(SpaceGroup%Hall)
29628       if(len_trim(SpaceGroup%gHall) > 1) &
29629       write(unit=lun,fmt="(a,a)")           " => Generalized Hall Symbol: ", trim(SpaceGroup%gHall)
29630       if(len_trim(SpaceGroup%info) > 1) &
29631       write(unit=lun,fmt="(a,a)")           " =>    Table Setting Choice: ", trim(SpaceGroup%info)
29632       write(unit=lun,fmt="(a,a)")           " =>            Setting Type: ", trim(SpaceGroup%SG_setting)
29633
29634       write(unit=lun,fmt="(a,a)")           " =>          Crystal System: ", trim(SpaceGroup%CrystalSys)
29635       write(unit=lun,fmt="(a,a)")           " =>              Laue Class: ", trim(SpaceGroup%Laue)
29636       write(unit=lun,fmt="(a,a)")           " =>             Point Group: ", trim(SpaceGroup%Pg)
29637
29638       write(unit=lun,fmt="(a,a)")           " =>         Bravais Lattice: ", trim(SpaceGroup%SPG_Lat)
29639       write(unit=lun,fmt="(a,a)")           " =>          Lattice Symbol: ", trim(SpaceGroup%SPG_Latsy)
29640
29641       write(unit=lun,fmt="(a,i3)")          " =>  Reduced Number of S.O.: ", SpaceGroup%NumOps
29642       write(unit=lun,fmt="(a,i3)")          " =>    General multiplicity: ", SpaceGroup%Multip
29643       write(unit=lun,fmt="(a,a)")           " =>          Centrosymmetry: ", trim(SpaceGroup%Centre)
29644       write(unit=lun,fmt="(a,i3)")          " =>  Generators (exc. -1&L): ", SpaceGroup%num_gen
29645       write(unit=lun,fmt="(a,f6.3,a,f6.3)") " =>         Asymmetric unit: ", SpaceGroup%R_Asym_Unit(1,1), &
29646                                                                  " <= x <= ",SpaceGroup%R_Asym_Unit(1,2)
29647       write(unit=lun,fmt="(a,f6.3,a,f6.3)") "                             ", SpaceGroup%R_Asym_Unit(2,1), &
29648                                                                  " <= y <= ",SpaceGroup%R_Asym_Unit(2,2)
29649       write(unit=lun,fmt="(a,f6.3,a,f6.3)") "                             ", SpaceGroup%R_Asym_Unit(3,1), &
29650                                                                  " <= z <= ",SpaceGroup%R_Asym_Unit(3,2)
29651
29652       if (SpaceGroup%centred == 0) then
29653          call Frac_Trans_1Dig(SpaceGroup%Centre_coord,texto(1))
29654          write(unit=lun,fmt="(a,a)")        " =>               Centre at: ", trim(texto(1))
29655       end if
29656       if (SpaceGroup%SPG_Lat == "Z" .or. print_latt) then
29657          texto(:) (1:100) = " "
29658          if (SpaceGroup%SPG_Lat == "Z") then
29659            write(unit=lun,fmt="(a,i3)")          " => Non-conventional Centring vectors:",SpaceGroup%Numlat
29660          else
29661            write(unit=lun,fmt="(a,i3)")          " => Centring vectors:",SpaceGroup%Numlat-1
29662          end if
29663          nlines=1
29664          do i=2,SpaceGroup%Numlat
29665             call Frac_Trans_1Dig(SpaceGroup%Latt_trans(:,i),aux)
29666             if (mod(i-1,2) == 0) then
29667                write(unit=texto(nlines)(51:100),fmt="(a,i2,a,a)") &
29668                                           " => Latt(",i-1,"): ",trim(aux)
29669                nlines=nlines+1
29670             else
29671                write(unit=texto(nlines)( 1:50),fmt="(a,i2,a,a)")  &
29672                                           " => Latt(",i-1,"): ",trim(aux)
29673             end if
29674          end do
29675          do i=1,nlines
29676             write(unit=lun,fmt="(a)") texto(i)
29677          end do
29678       end if
29679
29680       !---- Symmetry Operators ----!
29681       if (present(full)) then
29682          write(unit=lun,fmt="(/,a,/)")        " => List of all Symmetry Operators and Symmetry Symbols"
29683
29684          do i=1,SpaceGroup%Multip
29685             texto(1)=" "
29686             call Symmetry_Symbol(SpaceGroup%SymopSymb(i),texto(1))
29687             write(unit=lun,fmt="(a,i3,2a,t50,2a)") " => SYMM(",i,"): ",trim(SpaceGroup%SymopSymb(i)), &
29688                                                     "Symbol: ",trim(texto(1))
29689          end do
29690
29691          !---- Wyckoff Information ----!
29692          call Write_Wyckoff(SpaceGroup%Wyckoff, SpaceGroup%SPG_Symb,lun)
29693
29694       else
29695          write(unit=lun,fmt="(/,a)") " => List of S.O. without inversion and lattice centring translations"
29696
29697          texto(:) (1:100) = " "
29698          nlines=1
29699          do i=1,SpaceGroup%NumOps
29700             if (mod(i,2) == 0) then
29701                write(unit=texto(nlines)(51:100),fmt="(a,i3,a,a)") &
29702                                           " => SYMM(",i,"): ",trim(SpaceGroup%SymopSymb(i))
29703                nlines=nlines+1
29704             else
29705                write(unit=texto(nlines)( 1:50),fmt="(a,i3,a,a)")  &
29706                                           " => SYMM(",i,"): ",trim(SpaceGroup%SymopSymb(i))
29707             end if
29708             if(nlines == max_lines) then
29709                texto(nlines)=trim(texto(nlines))//"   <= Maximum number of lines exhausted!"
29710                exit
29711             end if
29712          end do
29713          do i=1,nlines
29714             write(unit=lun,fmt="(a)") trim(texto(i))
29715          end do
29716
29717       end if
29718
29719
29720       return
29721    End Subroutine Write_SpaceGroup
29722
29723    !!----
29724    !!---- Subroutine Write_Sym(Lun,Indx,Sim,Tt,P_Mag,Mag)
29725    !!----    integer,                     intent(in) :: lun       !  In -> Logical unit of the file to write
29726    !!----    integer,dimension(3,3),      intent(in) :: sim       !  In -> Rotational part of the S.O.
29727    !!----    integer,                     intent(in) :: indx      !  In -> Ordinal of the current Symm.Operator
29728    !!----    real(kind=cp), dimension(3), intent(in) :: tt        !  In -> Translation part of the S.O.
29729    !!----    real(kind=cp),               intent(in) :: p_mag     !  In -> Magnetic phase of the magnetic S.O.
29730    !!----    logical,                     intent(in) :: mag       !  In -> .true. if it is a magnetic S.O.
29731    !!----
29732    !!----    Writing the reduced set of symmetry operators
29733    !!----    Logical hexa must be defined (valid for conventional bases)
29734    !!----
29735    !!---- Update: February - 2005
29736    !!
29737    Subroutine Write_Sym(Lun,Indx,Sim,Tt,P_Mag,Mag)
29738       !---- Arguments ----!
29739       integer,                     intent(in) :: lun,indx
29740       integer, dimension(3,3),     intent(in) :: sim
29741       real(kind=cp), dimension(3), intent(in) :: tt
29742       real(kind=cp),               intent(in) :: p_mag
29743       logical,                     intent(in) :: mag
29744
29745       !---- Local variables ----!
29746       character (len=35)             :: symcod
29747       character (len=40)             :: Seitz_symb
29748       integer                        :: j,ihex,i1,i2,isl
29749
29750       if (.not. hexa) then
29751          i1=1
29752          i2=24
29753       else
29754          i1=25
29755          i2=36
29756       end if
29757       call SearchOp(sim,i1,i2,Isl)
29758       call Get_SymSymb(sim,tt,Symcod)
29759
29760       if (hexa) then
29761          j=abs(isl)-24
29762          if(Isl < 0) j=j+12
29763          call  Get_Seitz(j,tt,Seitz_symb)
29764          write(unit=lun,fmt="(i4,4(a,a))") indx," :: ",trim(IntSymD6h(j))," :: ", &
29765                                      trim(Kov_D6h(j))," :: ",trim(SymCod)," :: ",trim(Seitz_symb)
29766
29767          if (mag) then
29768             j=abs(isl)-24
29769             ihex=2
29770             if (j < 0) then
29771                j=j+24
29772                ihex=1
29773             end if
29774             if (isl < 0) j=j+24/ihex
29775             write(unit=lun,fmt="(a,i2,a,a19,a,f12.4)") "      (",indx,"): ",  &
29776                                                  MAGmat(J+(ihex-1)*48)," MPhas: ",P_MAG
29777          end if
29778
29779       else              ! No hexa
29780          j=abs(isl)
29781          if (isl < 0) j=j+24
29782          call  Get_Seitz(j,tt,Seitz_symb)
29783          write(unit=lun,fmt="(i4,4(a,a))") indx," :: ",trim(IntSymOh(j))," :: ", &
29784                                      trim(Kov_Oh(j))," :: ",trim(SymCod)," :: ",trim(Seitz_symb)
29785          if (mag) then
29786             j=abs(isl)
29787             if (isl < 0) j=j+24
29788             write(unit=lun,fmt="(a,i2,a,a13,a,f12.4)") "      (",indx,"): ",   &
29789                                                  MAGmat(J)," MPhas: ",P_MAG
29790          end if
29791       end if            ! End if(Hexa)
29792
29793       return
29794    End Subroutine Write_Sym
29795
29796    !!----
29797    !!---- Subroutine Write_SymTrans_Code(N,Tr,Code)
29798    !!----    integer,                    intent(in)  :: N
29799    !!----    real(kind=cp),dimension(3), intent(in)  :: Tr
29800    !!----    character (len=*),          intent(out) :: Code
29801    !!----
29802    !!----    Write the code string for reference the symmetry operator and the
29803    !!----    Traslation applied.
29804    !!--<<        _2.555     : N_Op = 2, Tr=( 0.0, 0.0, 0.0)
29805    !!----        _3.456     : N_Op = 3, Tr=(-1.0, 0.0, 1.0)
29806    !!-->>
29807    !!----
29808    !!---- Update: April - 2005
29809    !!
29810    Subroutine Write_SymTrans_Code(N,Tr,Code)
29811       !---- Arguments ----!
29812       integer,                    intent(in)  :: N
29813       real(kind=cp),dimension(3), intent(in)  :: Tr
29814       character (len=*),          intent(out) :: Code
29815
29816       !---- Local Variables ----!
29817       character(len=3)      :: car
29818       integer, dimension(3) :: i
29819
29820       Code=" "
29821       if (N <=0) return
29822       car="   "
29823       !---- Number of the Symmetry Operator ----!
29824       write(unit=car,fmt="(i3)") n
29825       car=adjustl(car)
29826       Code="_"//trim(car)
29827       car="   "
29828       !---- Traslation Part ----!
29829       i=5+nint(tr)
29830       if (any(i /= 5)) then
29831          write(unit=car(1:1),fmt="(i1)") i(1)
29832          write(unit=car(2:2),fmt="(i1)") i(2)
29833          write(unit=car(3:3),fmt="(i1)") i(3)
29834          code=trim(code)//"."//trim(car)
29835       else
29836          if(len_trim(code)==2 .and. code(2:2) == "1") Code=" "
29837       end if
29838
29839
29840       return
29841    End Subroutine Write_SymTrans_Code
29842
29843    !!----
29844    !!---- Subroutine Write_Wyckoff(Wyckoff,Spg_Name,Lun, Sorting)
29845    !!----    type(wyckoff_type), intent(in) :: Wyckoff     !  In -> Wyckoff Type variable
29846    !!----    character(len=*),   intent(in) :: Spg_Name    !  In -> SpaceGroup Name
29847    !!----    integer,optional,   intent(in) :: Lun         !  In -> Unit to write the information
29848    !!----    logical, optional,  intent(in) :: Sorting     !  In -> .true. for sorting list
29849    !!----
29850    !!----    Print/Write the Wyckoff positions in Lun unit
29851    !!----
29852    !!---- Update: February - 2005
29853    !!
29854    Subroutine Write_Wyckoff(Wyckoff,Spg, Lun, Sorting)
29855       !---- Arguments ----!
29856       type(wyckoff_type), intent(in) :: wyckoff
29857       character(len=*),   intent(in) :: Spg
29858       integer, optional,  intent(in) :: Lun
29859       logical, optional,  intent(in) :: Sorting
29860
29861       !---- Local variables ----!
29862       character(len=3)      :: carm
29863       character(len=12)     :: site
29864       integer               :: i,j,iunit
29865       integer,dimension(26) :: list,order
29866       character(len=*), dimension(26),parameter :: alphabet = (/  &
29867       "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"/)
29868
29869       if (wyckoff%num_orbit == 0) return
29870       iunit=6
29871       if (present(lun)) iunit=lun
29872
29873       !---- Sorting the final Wyckoff List ----!
29874       do i=1, wyckoff%num_orbit
29875          list(i)=wyckoff%orbit(i)%norb
29876          order(i)=i
29877       end do
29878
29879       if (present(sorting)) then
29880          if (sorting) call sort(list,wyckoff%num_orbit,order)
29881       end if
29882
29883       !---- Info ----!
29884       write(unit=iunit,fmt="(/,a)") " => Special Wyckoff Positions for "//trim(spg)
29885       write(unit=iunit,fmt="(a)") " "
29886       write(unit=iunit,fmt="(a)") "    Multp     Site        Representative Coordinates (centring translations excluded)"
29887       do i=wyckoff%num_orbit,1,-1
29888          write(unit=carm,fmt="(i3)") wyckoff%orbit(order(i))%multp
29889          site=alphabet(i)
29890          do j=1,wyckoff%orbit(order(i))%norb,3
29891             write(unit=iunit,fmt="(a,a,t15,a,t30,a,t50,a,t70,a)") "    ",&
29892                   carm,site,wyckoff%orbit(order(i))%str_orbit(j:j+2)
29893             carm=" "
29894             site=" "
29895          end do
29896          write(unit=iunit,fmt="(a)") " "
29897       end do
29898
29899       return
29900     End Subroutine Write_Wyckoff
29901
29902    !!----
29903    !!---- Subroutine Wyckoff_Orbit(Spacegroup,Wyckoffstr,N_Orbit,Orbitstr)
29904    !!----    type (Space_Group_Type),       intent( in) :: SpaceGroup !  In -> SpaceGroup Variable
29905    !!----    character(len=*),              intent( in) :: WyckoffStr !  In -> Representative of the Orbit
29906    !!----    integer,                       intent(out) :: N_Orbit    ! Out -> Number of Components in the Orbit
29907    !!----    character(len=*),dimension(:), intent(out) :: OrbitStr   ! Out -> Wyckoff Positions Strings
29908    !!----
29909    !!----    Calculation of the Wyckoff positions from the representative element
29910    !!----
29911    !!---- Update: February - 2005
29912    !!
29913    Subroutine Wyckoff_Orbit(SGrp,Wyckoff_Car, N, Wyckoff_Orb)
29914       !---- Arguments ----!
29915       type (Space_Group_Type),        intent( in) :: SGrp           !  In -> Space Group Information
29916       character(len=*),               intent( in) :: Wyckoff_Car    !  In -> Representative of the Orbit to calculate
29917       integer,                        intent(out) :: N              ! Out -> Number of components in the orbit
29918       character(len=*),dimension(:),  intent(out) :: Wyckoff_Orb    ! Out -> Wyckoff positions for this Orbit
29919
29920       !---- Local Variables ----!
29921       logical                         :: delete
29922       character(len=40)               :: symb,symb2
29923       integer                         :: i,j,k,num
29924       integer,dimension(3,3)          :: w
29925       real(kind=cp),   dimension(3,3) :: w1
29926       real(kind=cp), dimension(3)     :: t,t1,t2
29927
29928       Wyckoff_Orb=" "
29929       n=0
29930       if (len_trim(wyckoff_car) <= 0) return
29931
29932       n=1
29933       wyckoff_orb(n)=adjustl(wyckoff_car)
29934       call Read_Xsym(wyckoff_car,1,w,t)
29935       err_symm=.false.
29936
29937       num=sgrp%multip/sgrp%numlat
29938
29939       do i=2,num
29940          w1=real(sgrp%symop(i)%rot)
29941          t1=sgrp%symop(i)%tr
29942          t1=applyso(sgrp%symop(i),t)
29943          t1=mod(t1+10.0_cp,1.0_cp)
29944          w1=matmul(w1,real(w))
29945          call Get_SymSymb(w1,t1,symb)
29946          delete=.false.
29947          do j=1,n
29948             if (symb == wyckoff_orb(j)) then
29949                delete=.true.
29950                exit
29951             end if
29952          end do
29953          if (delete) cycle
29954
29955          !---- Lattice Contribution ----!
29956          do j=2,sgrp%numlat
29957             t2=t1+sgrp%latt_trans(:,j)
29958             t2=mod(t2+10.0_cp,1.0_cp)
29959             call Get_SymSymb(w1,t2,symb2)
29960             delete=.false.
29961             do k=1,n
29962                if (symb2 == wyckoff_orb(k)) then
29963                   delete=.true.
29964                   exit
29965                end if
29966             end do
29967             if (delete) exit
29968          end do
29969          if (delete) cycle
29970
29971          n=n+1
29972          wyckoff_orb(n)=adjustl(symb)
29973       end do
29974
29975       return
29976    End Subroutine Wyckoff_Orbit
29977
29978    Subroutine Copy_NS_SpG_To_SpG(SpGN,SpG)
29979       !---- Arguments ----!
29980       type(NS_Space_Group_type), intent(in)    :: SpGN
29981       type(Space_Group_type),    intent(out)   :: SpG
29982
29983       !---- Local Variables ----!
29984       logical              :: change
29985       integer              :: i,j,k
29986       real, dimension(3,3) :: w
29987
29988       !> Init
29989       call init_err_symm()
29990       change=.true.
29991
29992       !> Check if the copy is possible
29993       loop_1: do k=1,SpG%Multip
29994          w=SpGn%Symop(k)%Rot
29995          w=abs(w)*100.0
29996          do i=1,3
29997             do j=1,3
29998                if (w(i,j) > 0.5 .and. w(i,j) < 99.5) then
29999                   change=.false.
30000                   exit loop_1
30001                end if
30002             end do
30003          end do
30004       end do loop_1
30005
30006       if (.not. change) then
30007          err_symm=.true.
30008          ERR_Symm_Mess="No copy was possible for SpgN to Spg "
30009          return
30010       end if
30011
30012       SpG%NumSpg      = SpGn%NumSpg
30013       SpG%SPG_Symb    = SpGn%SPG_Symb
30014       SpG%Hall        = SpGn%Hall
30015       SpG%gHall       = SpGn%gHall
30016       SpG%CrystalSys  = SpGn%CrystalSys
30017       SpG%Laue        = SpGn%Laue
30018       SpG%PG          = SpGn%PG
30019       SpG%Info        = SpGn%Info
30020       SpG%SG_setting  = SpGn%SG_setting
30021       SpG%SPG_lat     = SpGn%SPG_lat
30022       SpG%SPG_latsy   = SpGn%SPG_latsy
30023       SpG%NumLat      = SpGn%NumLat
30024       if(allocated(SpG%Latt_Trans)) deallocate(SpG%Latt_Trans)
30025       allocate(SpG%Latt_Trans(3,SpG%NumLat))
30026       SpG%Latt_Trans  = SpGn%Latt_Trans
30027       SpG%Bravais     = SpGn%Bravais
30028       SpG%Centre      = SpGn%Centre
30029       SpG%Centred     = SpGn%Centred
30030       SpG%Centre_coord= SpGn%Centre_coord
30031       SpG%NumOps      = SpGn%NumOps
30032       SpG%Multip      = SpGn%Multip
30033       SpG%Num_gen     = SpGn%Num_gen
30034       if(allocated(SpG%SymopSymb)) deallocate(SpG%SymopSymb)
30035       allocate(SpG%SymopSymb(SpG%Multip))
30036       SpG%SymopSymb=SpGn%SymopSymb
30037       if(allocated(SpG%Symop)) deallocate(SpG%Symop)
30038       allocate(SpG%Symop(SpG%Multip))
30039       do i=1,SpG%Multip
30040         SpG%Symop(i)%Rot(:,:) = nint(SpGn%Symop(i)%Rot(:,:))
30041         SpG%Symop(i)%tr(:) =  SpGn%Symop(i)%tr(:)
30042       end do
30043
30044       return
30045    End Subroutine Copy_NS_SpG_To_SpG
30046
30047 End Module CFML_Crystallographic_Symmetry
30048!!-------------------------------------------------------
30049!!---- Crystallographic Fortran Modules Library (CrysFML)
30050!!-------------------------------------------------------
30051!!---- The CrysFML project is distributed under LGPL. In agreement with the
30052!!---- Intergovernmental Convention of the ILL, this software cannot be used
30053!!---- in military applications.
30054!!----
30055!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
30056!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
30057!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
30058!!----
30059!!---- Authors: Juan Rodriguez-Carvajal (ILL)
30060!!----          Javier Gonzalez-Platas  (ULL)
30061!!----
30062!!---- Contributors: Laurent Chapon     (ILL)
30063!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
30064!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
30065!!----               Tierry Roisnel     (CDIFX,Rennes France)
30066!!----               Eric Pellegrini    (ILL)
30067!!----
30068!!---- This library is free software; you can redistribute it and/or
30069!!---- modify it under the terms of the GNU Lesser General Public
30070!!---- License as published by the Free Software Foundation; either
30071!!---- version 3.0 of the License, or (at your option) any later version.
30072!!----
30073!!---- This library is distributed in the hope that it will be useful,
30074!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
30075!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30076!!---- Lesser General Public License for more details.
30077!!----
30078!!---- You should have received a copy of the GNU Lesser General Public
30079!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
30080!!----
30081!!----
30082!!---- MODULE: CFML_Crystal_Metrics
30083!!----   INFO: Module to define crystallographic types and to provide
30084!!----         automatic crystallographic operations.
30085!!----
30086!!---- HISTORY
30087!!----    Update: 05/03/2011
30088!!----
30089!!--.. INFORMATION
30090!!--..
30091!!--..    List Of Matrix Relationships For Crystallographic Applications
30092!!--..
30093!!--..    Small "t" is for transpose, inv(F) is the inverse of matrix F
30094!!--..
30095!!--..    Basis vectors as symbolic matrices
30096!!--..       At = (a,b,c)  At'=(a',b',c') ;  At* = (a*,b*,c*)  At*'=(a*',b*',c*')
30097!!--..
30098!!--..    Direct and reciprocal metric tensors: G, G*=inv(G)
30099!!--..    X  column vector in     direct space, referred to basis A
30100!!--..    X* column vector in reciprocal space, referred to basis A*
30101!!--..
30102!!--..       A'  = M  A           X'  = inv(Mt) X
30103!!--..       A*  = G* A           X*  =   G     X
30104!!--..       A*' = inv(Mt) A*     X*' =   M     X*
30105!!--..
30106!!--..       G' = M G Mt          G*' = inv(Mt) G* inv(M)
30107!!--..
30108!!--..   Symmetry operator defined in bases: A, A', A*, A*'
30109!!--..       C = (R,T), C'= (R',T'), C*= (R*,T*), C*'= (R*',T*')
30110!!--..
30111!!--..       R'  = inv(Mt) R Mt  ; T' = inv(Mt) T
30112!!--..       R*' =  M  R* inv(M) ; T*' = M T*
30113!!--..       R*  = G R G*  = inv(Rt)
30114!!--..
30115!!--..   If a change of origin is performed the positions are changed
30116!!--..   Ot=(o1,o2,o3) origin of the new basis A' w.r.t. old basis A
30117!!--..
30118!!--..       X' = inv(Mt) (X-O)
30119!!--..
30120!!--..   Changing just the origin   Xn  = C  X  = R  X  + T
30121!!--..                              Xn' = C' X' = R' X' + T'
30122!!--..          R=R'                X'  = X -O
30123!!--..                              Xn' = Xn-O
30124!!--..                  Xn-O = R' (X-O) + T' = R X + T - O
30125!!--..                   R X - R O + T' = R X + T - O
30126!!--..                               T' = T - (O - R O) = T - (E-R)O
30127!!--..
30128!!--..   Changing the basis (A,o) -> (A',o')
30129!!--..                  Xn  = C  X  = R  X  + T
30130!!--..                  Xn' = C' X' = R' X' + T'
30131!!--..                  X'= inv(Mt) (X-O), Xn' = inv(Mt) (Xn-O)
30132!!--..
30133!!--..            inv(Mt) (Xn-O) = R' inv(Mt) (X-O) + T'
30134!!--..            inv(Mt) (R  X  + T -O) = R' inv(Mt) (X-O) + T'
30135!!--..            inv(Mt) R X + inv(Mt)(T-O) = R' inv(Mt) X - R' inv(Mt) O + T'
30136!!--..            inv(Mt) R = R' inv(Mt)  => R' = inv(Mt) R Mt
30137!!--..            inv(Mt) (T-O)  = - R' inv(Mt) O + T'
30138!!--..            T' = R' inv(Mt) O + inv(Mt) (T-O)
30139!!--..            T' = inv(Mt) R Mt inv(Mt) O + inv(Mt) (T-O)
30140!!--..            T' = inv(Mt) R  O + inv(Mt) (T-O)
30141!!--..            T' = inv(Mt) R  O + inv(Mt) T - inv(Mt) O
30142!!--..            T' = inv(Mt)( R  O + T -  O) = inv(Mt) (T -(E-R)O)
30143!!--..
30144!!--..
30145!!--..                       R' = inv(Mt) R Mt
30146!!--..
30147!!--..                       T' = inv(Mt) (T -(E-R)O)
30148!!--..
30149!!--..
30150!!--..   A symmetry operator does not change the modulus of vectors and
30151!!--..   the angles between vectors (dot product is invariant):
30152!!--..
30153!!--..      X' = R X ,  Y' = R Y  =>  Xt' = Xt Rt,  Yt' = Yt Rt
30154!!--..
30155!!--..      Xt' G Y' = Xt Rt G R Y = Xt G Y  =>  G = Rt G R
30156!!--..
30157!!--..
30158!!--..   Second rank tensor Q and Q* defined in bases A and A*.
30159!!--..
30160!!--..      Q' = M Q Mt      Q* = G* Q G*     Q*'= inv(Mt) Q* inv(M)
30161!!--..
30162!!--..   A symmetry operator R is equivalent to a transformation
30163!!--..   M = inv(Rt) acting on basis vectors => G' = inv(Rt) G inv(R) = G
30164!!--..   The anisotropic temperature factors Beta is defined in reciprocal
30165!!--..   space: is a tensor like Q*, the transformation of beta under
30166!!--..   a symmetry operator is then :
30167!!--..
30168!!--..           Beta' = Inv(Mt) Beta inv(M) = R Beta Rt
30169!!--..
30170!!----
30171!!---- DEPENDENCIES
30172!!--++    Use CFML_GlobalDeps,    only: Cp, Eps, Pi
30173!!--++    Use CFML_Math_General, only: Cosd, Sind, Acosd, Co_Prime, swap, Sort, atand, &
30174!!--++                                 Co_Linear
30175!!--++    Use CFML_Math_3D,      only : Matrix_Inverse, determ_A, determ_V, Cross_Product
30176!!----
30177!!---- VARIABLES
30178!!----    CRYSTAL_CELL_TYPE
30179!!----    TWOFOLD_AXES_TYPE
30180!!----    ZONE_AXIS_TYPE
30181!!----    ERR_CRYS
30182!!----    ERR_CRYS_MESS
30183!!--++    IDENTITY                       [Private]
30184!!--++    TPI2                           [Private]
30185!!----
30186!!---- PROCEDURES
30187!!----    Functions:
30188!!----       CART_U_VECTOR
30189!!----       CART_VECTOR
30190!!----       CELL_VOLUME_SIGMA
30191!!----       CONVERT_B_BETAS
30192!!----       CONVERT_B_U
30193!!----       CONVERT_BETAS_B
30194!!----       CONVERT_BETAS_U
30195!!----       CONVERT_U_B
30196!!----       CONVERT_U_BETAS
30197!!----       GET_BETAS_FROM_BISO
30198!!--++       METRICS                     [Private]
30199!!----       ROT_MATRIX
30200!!----       U_EQUIV
30201!!----
30202!!----    Subroutines:
30203!!----       CHANGE_SETTING_CELL
30204!!----       GET_BASIS_FROM_UVW
30205!!----       GET_CONVENTIONAL_CELL
30206!!----       GET_CRYST_FAMILY
30207!!--++       GET_CRYST_ORTHOG_MATRIX     [Private]
30208!!----       GET_DERIV_ORTH_CELL
30209!!----       GET_PRIMITIVE_CELL
30210!!----       GET_TRANSFM_MATRIX
30211!!----       GET_TWOFOLD_AXES
30212!!----       INIT_ERR_CRYS
30213!!----       NIGGLI_CELL                 [Overloaded]
30214!!--++       NIGGLI_CELL_ABC             [Private]
30215!!--++       NIGGLI_CELL_NIGGLIMAT       [Private]
30216!!--++       NIGGLI_CELL_PARAMS          [Private]
30217!!--++       NIGGLI_CELL_TYPE            [Private]
30218!!--++       NIGGLI_CELL_VECT            [Private]
30219!!----       READ_BIN_CRYSTAL_CELL
30220!!--++       RECIP                       [Private]
30221!!----       SET_CRYSTAL_CELL
30222!!----       VOLUME_SIGMA_FROM_CELL
30223!!----       WRITE_BIN_CRYSTAL_CELL
30224!!----       WRITE_CRYSTAL_CELL
30225!!----
30226!!
30227 Module CFML_Crystal_Metrics
30228
30229    !---- Use files ----!
30230    Use CFML_GlobalDeps,   only : Cp, Eps, Pi, TO_RAD
30231    Use CFML_Math_General, only : Cosd, Sind, Acosd, Co_Prime, swap, Sort, atand, Co_Linear
30232    Use CFML_Math_3D,      only : Matrix_Inverse, determ_A, determ_V, Cross_Product
30233
30234    implicit none
30235
30236    private
30237
30238    !---- List of public variables ----!
30239
30240    !---- List of public functions ----!
30241    public :: Cart_u_vector, Cart_vector, Convert_B_Betas, Convert_B_U, &
30242              Convert_Betas_B, Convert_Betas_U, Convert_U_B,            &
30243              Convert_U_Betas, Rot_matrix, U_Equiv, Cell_Volume_Sigma,  &
30244              Get_Betas_From_Biso
30245
30246    !---- List of public overloaded procedures: functions ----!
30247
30248    !---- List of public subroutines ----!
30249    public :: Init_Err_Crys, Change_Setting_Cell,Set_Crystal_Cell,           &
30250              Get_Cryst_Family, Write_Crystal_Cell, Get_Deriv_Orth_Cell,     &
30251              Get_Primitive_Cell, Get_TwoFold_Axes, Get_Conventional_Cell,   &
30252              Get_Transfm_Matrix, Get_basis_from_uvw, Volume_Sigma_from_Cell,&
30253              Read_Bin_Crystal_Cell,Write_Bin_Crystal_Cell
30254
30255
30256    !---- List of public overloaded procedures: subroutines ----!
30257
30258    public  :: Niggli_Cell
30259
30260    !---- List of private functions ----!
30261    private :: metrics
30262
30263    !---- List of private Subroutines ----!
30264    private :: Recip, Get_Cryst_Orthog_Matrix, Niggli_Cell_Vect, Niggli_Cell_Params, &
30265               Niggli_Cell_type, Niggli_Cell_abc,  Niggli_Cell_nigglimat
30266
30267    !---- Definitions ----!
30268
30269    !!----
30270    !!----  TYPE :: CRYSTAL_CELL_TYPE
30271    !!--..
30272    !!----  Type, public :: Crystal_Cell_Type
30273    !!----     real(kind=cp),dimension(3)   :: cell, ang          ! Direct cell parameters
30274    !!----     integer,      dimension(3)   :: lcell, lang        ! Code number for refinement in optimization procedures
30275    !!----     real(kind=cp),dimension(3)   :: cell_std, ang_std  ! Standar deviations cell parameters
30276    !!----     real(kind=cp),dimension(3)   :: rcell,rang         ! Reciprocal cell parameters
30277    !!----     real(kind=cp),dimension(3,3) :: GD,GR              ! Direct and reciprocal Metric Tensors
30278    !!----     real(kind=cp),dimension(3,3) :: Cr_Orth_cel        ! P-Matrix transforming Orthonormal
30279    !!----                                                        ! basis to direct Crytal cell (as I.T.)
30280    !!----                                                        ! (or crystallographic components to
30281    !!----                                                        !  Cartesian components: XC = Cr_Orth_cel X -> XC,X: column vectors)
30282    !!----     real(kind=cp),dimension(3,3) :: Orth_Cr_cel        ! Inv(Cr_Orth_cel) -> Cartesian to cryst. components
30283    !!----     real(kind=cp),dimension(3,3) :: BL_M               ! Busing-Levy B-matrix (transforms hkl to  a
30284    !!----                                                          Cartesian system with x//a*, y in (a*,b*) and z//c
30285    !!----     real(kind=cp),dimension(3,3) :: BL_Minv            ! Inverse of the Busing-Levy B-matrix
30286    !!----     real(kind=cp)                :: CellVol            ! Direct and Reciprocal
30287    !!----     real(kind=cp)                :: RCellVol           ! Cell volumes
30288    !!----     Character (len=1)            :: CartType           ! Cartesian Frame type: if CartType='A'
30289    !!----                                                        ! the Cartesian Frame has x // a.
30290    !!----  End Type Crystal_Cell_Type
30291    !!----
30292    !!---- Updated: November - 2013 (adding lcell and lang components)
30293    !!
30294    Type, public :: Crystal_Cell_Type
30295       real(kind=cp),dimension(3)   :: cell, ang
30296       integer,      dimension(3)   :: lcell, lang
30297       real(kind=cp),dimension(3)   :: cell_std, ang_std
30298       real(kind=cp),dimension(3)   :: rcell, rang
30299       real(kind=cp),dimension(3,3) :: GD,GR
30300       real(kind=cp),dimension(3,3) :: Cr_Orth_cel
30301       real(kind=cp),dimension(3,3) :: Orth_Cr_cel
30302       real(kind=cp),dimension(3,3) :: BL_M
30303       real(kind=cp),dimension(3,3) :: BL_Minv
30304       real(kind=cp)                :: CellVol
30305       real(kind=cp)                :: RCellVol
30306       character (len=1)            :: CartType
30307    End Type Crystal_Cell_Type
30308
30309    !!----
30310    !!----  TYPE :: TWOFOLD_AXES_TYPE
30311    !!--..
30312    !!----  Type, public :: Twofold_Axes_Type
30313    !!----     integer                       :: ntwo        ! Number of two-fold axes
30314    !!----     real(kind=cp)                 :: tol         ! Angular tolerance (ca 3 degrees)
30315    !!----     real(kind=cp),dimension(3,12) :: caxes       ! Cartesian components of two-fold axes
30316    !!----     integer,dimension(3,12)       :: dtwofold    ! Direct indices of two-fold axes
30317    !!----     integer,dimension(3,12)       :: rtwofold    ! Reciprocal indices of two-fold axes
30318    !!----     integer,dimension(12)         :: dot         ! Scalar product of reciprocal and direct indices
30319    !!----     real(kind=cp),dimension(12)   :: cross       ! Angle between direct and reciprocal axes ( < tol)
30320    !!----     real(kind=cp),dimension(12)   :: maxes       ! Modulus of the zone axes (two-fold axes) vectors
30321    !!----     real(kind=cp),dimension(3)    :: a,b,c       ! Cartesian components of direct cell parameters
30322    !!----  End Type Twofold_Axes_Type
30323    !!----
30324    !!----  All components are initialised to zero in the type declaration
30325    !!----
30326    !!---- Update: October - 2008
30327    !!
30328    Type, public :: Twofold_Axes_Type
30329       integer                        :: ntwo=0
30330       real(kind=cp)                  :: tol=3.0
30331       real(kind=cp) ,dimension(3,12) :: caxes=0.0
30332       integer,dimension(3,12)        :: dtwofold=0
30333       integer,dimension(3,12)        :: rtwofold=0
30334       integer,dimension(12)          :: dot=0
30335       real(kind=cp), dimension(12)   :: cross=0.0
30336       real(kind=cp), dimension(12)   :: maxes=0.0
30337       real(kind=cp), dimension(3)    :: a=0.0,b=0.0,c=0.0
30338    End Type Twofold_Axes_Type
30339
30340    !!----
30341    !!----  TYPE :: ZONE_AXIS_TYPE
30342    !!--..
30343    !!----  Type, public :: Zone_Axis_Type
30344    !!----    Integer               :: nlayer   ! number of the reciprocal layer considered normally nlayer=0
30345    !!----    Integer, dimension(3) :: uvw      ! Indices of the zone axis
30346    !!----    Integer, dimension(3) :: rx       ! Indices (reciprocal vector) of the basis vector 1
30347    !!----    Integer, dimension(3) :: ry       ! Indices (reciprocal vector) of the basis vector 2
30348    !!----  End Type Zone_Axis_Type
30349    !!----
30350    !!----
30351    !!----  This type comes from ResVis. It is useful to have it as a genereal type for
30352    !!----  many kinds of applications. Used in the subroutine Get_Basis_From_UVW.
30353    !!----
30354    !!---- Updated: February - 2012
30355    !!
30356
30357    Type, public :: Zone_Axis_Type
30358      Integer               :: nlayer
30359      Integer, dimension(3) :: uvw
30360      Integer, dimension(3) :: rx
30361      Integer, dimension(3) :: ry
30362    End Type Zone_Axis_Type
30363
30364
30365
30366    !!----
30367    !!---- ERR_CRYS
30368    !!----    logical, public :: Err_Crys
30369    !!----
30370    !!----    Logical Variable indicating an error in CFML_Crystal_Metrics module
30371    !!----
30372    !!---- Update: February - 2005
30373    !!
30374    logical, public          :: ERR_Crys
30375
30376    !!----
30377    !!---- ERR_CRYS_MESS
30378    !!----    character(len=150), public :: ERR_Crys_Mess
30379    !!----
30380    !!----    String containing information about the last error
30381    !!----
30382    !!---- Update: February - 2005
30383    !!
30384    character(len=150), public :: ERR_Crys_Mess
30385
30386    !!--++
30387    !!--++ IDENTITY
30388    !!--++    real(kind=cp), dimension(3,3), parameter :: identity=reshape ((/1.0,0.0,0.0,
30389    !!--++                                                                    0.0,1.0,0.0,
30390    !!--++                                                                    0.0,0.0,1.0/),(/3,3/))
30391    !!--++
30392    !!--++    (PRIVATE)
30393    !!--++    Identity matrix
30394    !!--++
30395    !!--++ Update: October - 2008
30396    !!
30397    real(kind=cp),dimension(3,3), parameter  :: identity=reshape ((/1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0/),(/3,3/))
30398
30399    !!--++
30400    !!--++ TPI2
30401    !!--++    real(kind=cp), parameter :: tpi2=2.0*pi*pi
30402    !!--++
30403    !!--++    (PRIVATE)
30404    !!--++    Two times PI squared
30405    !!--++
30406    !!--++ Update: February - 2005
30407    !!
30408    real(kind=cp), parameter, private :: tpi2=2.0*pi*pi
30409
30410    !---- Interfaces - Overloaded ----!
30411
30412    !!--.. Three non coplanar vectors {a,b,c} generates a lattice using integer linear combinations
30413    !!--.. There are an infinite number of primitive unit cells generating the same lattice L.
30414    !!--.. N={a,b,c} is a Buerger cell if and only if |a|+|b|+|c| is a minimal value for all primitive
30415    !!--.. cells of L.
30416    !!--.. N is a Niggli cell of L if  (i) it is as Buerger cell of L and
30417    !!--..                            (ii) |90-alpha| + |90-beta| + |90-gamma| -> maximum
30418    !!--..                  / a.a  b.b  c.c \       /  s11  s22  s33 \
30419    !!--..   Niggli matrix  |               |   =   |                |
30420    !!--..                  \ b.c  a.c  a.b /       \  s23  s13  s12 /
30421    !!--..
30422
30423    Interface  Niggli_Cell                   ! The first(s) argument(s) is(are)
30424      Module Procedure Niggli_Cell_abc       ! List of cell parameters passed as a 6D vector
30425      Module Procedure Niggli_Cell_nigglimat ! Niggli matrix passed as a 2x3 matrix (ultimately applying the algorithm)
30426      Module Procedure Niggli_Cell_Params    ! List of cell parameters a,b,c,alpha,beta,gamma
30427      Module Procedure Niggli_Cell_type      ! The object Cell is passed as argument
30428      Module Procedure Niggli_Cell_Vect      ! Input three vectors in Cartesian components
30429    End Interface  Niggli_Cell
30430
30431 Contains
30432
30433    !-------------------!
30434    !---- Functions ----!
30435    !-------------------!
30436
30437    !!----
30438    !!---- Function Cart_U_Vector(Code,V,Celda) Result(Vc)
30439    !!----    character (len=*),             intent(in) :: code    !  In -> D: Direct, R: Reciprocal
30440    !!----    real(kind=cp), dimension(3),   intent(in) :: v       !  In -> Vector
30441    !!----    Type (Crystal_Cell_Type),      intent(in) :: Celda   !  In -> Cell Variable
30442    !!----    real(kind=cp),dimension(3)                :: vc      ! Out ->
30443    !!----
30444    !!----    Convert a vector in crystal space to unitary cartesian components
30445    !!----
30446    !!---- Update: February - 2005
30447    !!
30448    Function Cart_U_Vector(Code,V,Celda) Result(Vc)
30449       !---- Arguments ----!
30450       character (len=*),           intent(in) :: code
30451       real(kind=cp), dimension(3), intent(in) :: v
30452       type (Crystal_Cell_Type),    intent(in) :: Celda
30453       real(kind=cp), dimension(3)             :: vc
30454
30455       !---- Local Variables ----!
30456       real(kind=cp) :: vmod
30457
30458       vc=cart_vector(code,v,celda)
30459       vmod=sqrt(dot_product(vc,vc))
30460       if (vmod > 0.0) then
30461          vc=vc/vmod
30462       end if
30463
30464       return
30465    End Function Cart_U_Vector
30466
30467    !!----
30468    !!---- Function Cart_Vector(Code,V,Celda) Result(Vc)
30469    !!----    character (len=*),             intent(in) :: code     !  In -> D: Direct, R: Reciprocal
30470    !!----    real(kind=cp), dimension(3),   intent(in) :: v        !  In -> Vector
30471    !!----    Type (Crystal_Cell_Type),      intent(in) :: Celda    !  In -> Cell variable
30472    !!----    real(kind=cp) dimension(3)                :: vc       ! Out ->
30473    !!----
30474    !!----    Convert a vector in crystal space to cartesian components
30475    !!----    The value of code has been extended to use also the Busing-Levy
30476    !!----    Cartesian system as reference also for direct and reciprocal space.
30477    !!----    Codes:
30478    !!----    The Cartesian frame is that defined by the setting of the "Celda" object
30479    !!----         D: The components are given with respect to basis (a,b,c)
30480    !!----         R: The components are given with respect to basis (a*,b*,c*)
30481    !!----        BL: The components are given with respect to basis (a*,b*,c*) but
30482    !!----            the Cartesian frame is that defined by Busing and Levy
30483    !!----       BLD: The components are given with respect to basis (a,b,c) but
30484    !!----            the Cartesian frame is that defined by Busing and Levy
30485    !!----
30486    !!----
30487    !!---- Updated: June - 2012
30488    !!
30489    Function Cart_Vector(Code,V,Celda) Result(Vc)
30490       !---- Arguments ----!
30491       character (len=*),           intent(in) :: code
30492       real(kind=cp), dimension(3), intent(in) :: v
30493       type (Crystal_Cell_Type),    intent(in) :: Celda
30494       real(kind=cp), dimension(3)             :: vc
30495
30496       select case (trim(code))
30497          case("d","D")
30498             vc = matmul(celda%Cr_Orth_cel,v)  !Direct conversion to Cartesian frame
30499
30500          case ("r","R")
30501             vc = matmul(celda%GR,v)            !Converts to direct space
30502             vc = matmul(celda%Cr_Orth_cel,vc)  !Converts to Cartesian frame
30503
30504          case ("bl","BL")
30505             vc = matmul(celda%BL_M,vc) !Direct conversion to BL Cartesian frame
30506
30507          case ("bld","BLD")
30508             vc = matmul(celda%GD,v)   !Converts to reciprocal space
30509             vc = matmul(celda%BL_M,vc)!Converts to BL Cartesian frame
30510
30511       end select
30512
30513       return
30514    End Function Cart_Vector
30515
30516    !!----
30517    !!---- Function Cell_Volume_Sigma(Cell) result(sigma)
30518    !!----   type(Crystal_Cell_Type), intent(in) :: Cell   !  In  ->  Cell variable
30519    !!----   real(kind=cp)                       :: sigma  !  Out ->  Sigma of volume
30520    !!----
30521    !!----    Calculates the standard deviation of the unit cell volume
30522    !!----    from the standard deviations of cell parameters. The input
30523    !!----    variable is of type Crytal_Cell_Type, if the standard deviations of
30524    !!----    of both cell axes and cell angles are zero the result is sigma=0.0,
30525    !!----    otherwise the calculation is performed
30526    !!----    It is assumed that there is no correlation (covariance terms) between
30527    !!----    the standard deviations of the different cell parameters.
30528    !!----
30529    !!---- Updated: January - 2013 (JRC)
30530    !!
30531    Function Cell_Volume_Sigma(Cell) result(sigma)
30532       !---- Arguments ----!
30533       type(Crystal_Cell_Type), intent(in) :: Cell
30534       real(kind=cp)                       :: sigma
30535
30536       !--- Local variables ---!
30537       integer                     :: i
30538       real(kind=cp)               :: q,ca,cb,cc,vc,sa,sb,sc
30539       real(kind=cp), dimension(3) :: var_ang
30540
30541       !> Check
30542       sigma=0.0
30543       if(sum(abs(Cell%cell_std)) < eps .and. sum(abs(Cell%ang_std)) < eps ) return
30544
30545       vc=0.0
30546       do i=1,3
30547          q=Cell%cell_std(i)/Cell%cell(i)
30548          vc=vc+q*q
30549       end do
30550       if (sum(abs(Cell%ang_std)) > eps) then
30551          ca=cosd(Cell%ang(1)) ;  sa=sind(Cell%ang(1))
30552          cb=cosd(Cell%ang(2)) ;  sb=sind(Cell%ang(2))
30553          cc=cosd(Cell%ang(3)) ;  sc=sind(Cell%ang(3))
30554          q=1.0-ca*ca-cb*cb-cc*cc+2.0*ca*cb*cc
30555          var_ang = (Cell%ang_std * TO_RAD)**2/q
30556          vc=vc+ (ca-cb*cc)*(ca-cb*cc)*sa*sa * var_ang(1)
30557          vc=vc+ (cb-ca*cc)*(cb-ca*cc)*sb*sb * var_ang(2)
30558          vc=vc+ (cc-ca*cb)*(cc-ca*cb)*sc*sc * var_ang(3)
30559       end if
30560
30561       sigma=Cell%Cellvol*sqrt(vc)
30562
30563       return
30564    End Function Cell_Volume_Sigma
30565
30566    !!--..
30567    !!--.. Betas are defined by the following expression of the temperature factor:
30568    !!--.. Taniso= exp( -(beta11 h^2 + beta22 k^2 + beta33 l^2 + 2 (beta12 h k + beta13 h l + beta23 k l)) )
30569    !!--.. Taniso= exp( -(bet(1) h^2 + bet(2) k^2 + bet(3) l^2 + 2 (bet(4) h k + bet(5) h l + bet(6) k l)) )
30570    !!--..
30571    !!--.. Us are defined by the following expression of the temperature factor:
30572    !!--.. Taniso= exp( -2pi^2 (h^2 (a*)^2 U11+ k^2 (b*)^2 U22+ l^2 (c*)^2 U33+
30573    !!--..                2 (h k (a*) (b*) U12+ h l (a*) (c*) U13+  k l (b*) (c*) U23)) )
30574    !!--..
30575
30576    !!----
30577    !!---- Function Convert_B_Betas(B,Cell) Result(Beta)
30578    !!----    real(kind=cp),dimension(6), intent(in)  :: B
30579    !!----    type (Crystal_cell_Type),   intent(in)  :: Cell
30580    !!----    real(kind=cp),dimension(6)              :: Beta
30581    !!----
30582    !!----    Convert Thermal factors from B to Betas
30583    !!----
30584    !!---- Update: February - 2003
30585    !!
30586    Function Convert_B_Betas(B,Cell) Result(Beta)
30587       !---- Arguments ----!
30588       real(kind=cp),dimension(6), intent(in)  :: B
30589       type (Crystal_cell_Type),   intent(in)  :: Cell
30590       real(kind=cp),dimension(6)              :: Beta
30591
30592       beta(1)=0.25*b(1)*cell%gr(1,1)                ! beta11
30593       beta(2)=0.25*b(2)*cell%gr(2,2)                ! beta22
30594       beta(3)=0.25*b(3)*cell%gr(3,3)                ! beta33
30595       beta(4)=0.25*b(4)*cell%rcell(1)*cell%rcell(2) ! beta12
30596       beta(5)=0.25*b(5)*cell%rcell(1)*cell%rcell(3) ! beta13
30597       beta(6)=0.25*b(6)*cell%rcell(2)*cell%rcell(3) ! beta23
30598
30599       return
30600    End Function Convert_B_Betas
30601
30602    !!----
30603    !!---- Function Convert_B_U(B) Result(U)
30604    !!----    real(kind=cp),dimension(6), intent(in)  :: B
30605    !!----    real(kind=cp),dimension(6)              :: U
30606    !!----
30607    !!----    Convert Thermal factors from B to U
30608    !!----
30609    !!---- Update: February - 2003
30610    !!
30611    Function Convert_B_U(B) Result(U)
30612       !---- Arguments ----!
30613       real(kind=cp),dimension(6),  intent(in)  :: B
30614       real(kind=cp),dimension(6)               :: U
30615
30616       u=b/(4.0*tpi2)
30617
30618       return
30619    End Function Convert_B_U
30620
30621    !!----
30622    !!---- Function Convert_Betas_B(Beta,Cell) Result(B)
30623    !!----    real(kind=cp),dimension(6), intent(in)  :: Beta
30624    !!----    type (Crystal_cell_Type),   intent(in)  :: Cell
30625    !!----    real(kind=cp),dimension(6)              :: B
30626    !!----
30627    !!----    Convert Thermal factors from Betas to B
30628    !!----
30629    !!---- Update: February - 2003
30630    !!
30631    Function Convert_Betas_B(Beta,Cell) Result(B)
30632       !---- Arguments ----!
30633       real(kind=cp),dimension(6), intent(in)  :: Beta
30634       type (Crystal_cell_Type),   intent(in)  :: Cell
30635       real(kind=cp),dimension(6)              :: B
30636
30637       b(1)=4.0*beta(1)/cell%gr(1,1)                  ! B11
30638       b(2)=4.0*beta(2)/cell%gr(2,2)                  ! B22
30639       b(3)=4.0*beta(3)/cell%gr(3,3)                  ! B33
30640       b(4)=4.0*beta(4)/(cell%rcell(1)*cell%rcell(2)) ! B12
30641       b(5)=4.0*beta(5)/(cell%rcell(1)*cell%rcell(3)) ! B13
30642       b(6)=4.0*beta(6)/(cell%rcell(2)*cell%rcell(3)) ! B23
30643
30644       return
30645    End Function Convert_Betas_B
30646
30647    !!----
30648    !!---- Function Convert_Betas_U(Beta,Cell) Result(U)
30649    !!----    real(kind=cp),dimension(6), intent(in)  :: Beta
30650    !!----    type (Crystal_cell_Type),   intent(in)  :: Cell
30651    !!----    real(kind=cp),dimension(6)              :: U
30652    !!----
30653    !!----    Convert Thermal factors from Betas to U
30654    !!----
30655    !!---- Update: February - 2003
30656    !!
30657    Function Convert_Betas_U(Beta,Cell) Result(U)
30658       !---- Arguments ----!
30659       real(kind=cp),dimension(6),intent(in)  :: Beta
30660       type (Crystal_cell_Type),  intent(in)  :: Cell
30661       real(kind=cp),dimension(6)             :: U
30662
30663       u(1)=beta(1)/(tpi2*cell%gr(1,1))                ! U11
30664       u(2)=beta(2)/(tpi2*cell%gr(2,2))                ! U22
30665       u(3)=beta(3)/(tpi2*cell%gr(3,3))                ! U33
30666       u(4)=beta(4)/(tpi2*cell%rcell(1)*cell%rcell(2)) ! U12
30667       u(5)=beta(5)/(tpi2*cell%rcell(1)*cell%rcell(3)) ! U13
30668       u(6)=beta(6)/(tpi2*cell%rcell(2)*cell%rcell(3)) ! U23
30669
30670       return
30671    End Function Convert_Betas_U
30672
30673    !!----
30674    !!---- Function Convert_U_B(U) Result(B)
30675    !!----    real(kind=cp),dimension(6), intent(in)  :: U
30676    !!----    real(kind=cp),dimension(6)              :: B
30677    !!----
30678    !!----    Convert Thermal factors from U to B
30679    !!----
30680    !!---- Update: February - 2003
30681    !!
30682    Function Convert_U_B(U) Result(B)
30683       !---- Arguments ----!
30684       real(kind=cp),dimension(6),        intent(in)  :: U
30685       real(kind=cp),dimension(6)                     :: B
30686
30687       b=4.0*tpi2*u
30688
30689       return
30690    End Function Convert_U_B
30691
30692    !!----
30693    !!---- Function Convert_U_Betas(U,Cell) Result(Beta)
30694    !!----    real(kind=cp),dimension(6), intent(in)  :: U
30695    !!----    type (Crystal_cell_Type),   intent(in)  :: Cell
30696    !!----    real(kind=cp),dimension(6)              :: Beta
30697    !!----
30698    !!----    Convert Thermal factors from U to Betas
30699    !!----
30700    !!---- Update: February - 2003
30701    !!
30702    Function Convert_U_Betas(U,Cell) Result(Beta)
30703       !---- Arguments ----!
30704       real(kind=cp),dimension(6),intent(in)  :: U
30705       type (Crystal_cell_Type),  intent(in)  :: Cell
30706       real(kind=cp),dimension(6)             :: Beta
30707
30708       beta(1)=tpi2*u(1)*cell%gr(1,1)                ! beta11
30709       beta(2)=tpi2*u(2)*cell%gr(2,2)                ! beta22
30710       beta(3)=tpi2*u(3)*cell%gr(3,3)                ! beta33
30711       beta(4)=tpi2*u(4)*cell%rcell(1)*cell%rcell(2) ! beta12
30712       beta(5)=tpi2*u(5)*cell%rcell(1)*cell%rcell(3) ! beta13
30713       beta(6)=tpi2*u(6)*cell%rcell(2)*cell%rcell(3) ! beta23
30714
30715       return
30716    End Function Convert_U_Betas
30717
30718    !!----
30719    !!---- Function Get_Betas_from_Biso(Biso,Cell) Result(Betas)
30720    !!----    real(kind=cp),             intent(in)  :: Biso
30721    !!----    type (Crystal_cell_Type),  intent(in)  :: Cell
30722    !!----    real(kind=cp),dimension(6)             :: Betas
30723    !!----
30724    !!----    Get Betas from Biso
30725    !!----
30726    !!---- Update: April - 2013
30727    !!
30728    Function Get_Betas_from_Biso(Biso,Cell) Result(Betas)
30729       !--- Argument ----!
30730       real(kind=cp),             intent(in)  :: Biso
30731       type (Crystal_cell_Type),  intent(in)  :: Cell
30732       real(kind=cp),dimension(6)             :: Betas
30733
30734       !---- Local variables ----!
30735       real(kind=cp), dimension (3,3) :: L,LT,U,bet
30736       integer                        :: i
30737
30738       betas=0.0
30739
30740       l=Cell%Orth_Cr_cel
30741       lt=Transpose(l)
30742       u = 0.0
30743       do i=1,3
30744          u(i,i) = 0.25*biso
30745       end do
30746       bet= matmul (l,lt)
30747       bet= matmul (bet,u)
30748       do i=1,3
30749          betas(i) = bet(i,i)
30750       end do
30751
30752       betas(4) = bet(1,2)
30753       betas(5) = bet(1,3)
30754       betas(6) = bet(2,3)
30755
30756       return
30757    End Function Get_Betas_from_Biso
30758
30759    !!--++
30760    !!--++ Function Metrics(A,B) Result(G)
30761    !!--++    real(kind=cp), dimension(3)  , intent(in ) :: a   !  In -> Cell Parameters
30762    !!--++    real(kind=cp), dimension(3)  , intent(in ) :: b   !  In -> Ang Parameters
30763    !!--++    real(kind=cp), dimension(3,3)              :: g   ! Out -> Metrics array
30764    !!--++
30765    !!--++    (PRIVATE)
30766    !!--++    Constructs the metric tensor
30767    !!--++
30768    !!--++ Update: February - 2005
30769    !!
30770    Function Metrics(A,B) Result(G)
30771       !---- Arguments ----!
30772       real(kind=cp), dimension(3)  , intent(in ) :: a
30773       real(kind=cp), dimension(3)  , intent(in ) :: b
30774       real(kind=cp), dimension(3,3)              :: g
30775
30776       !---- Local Variables ----!
30777       integer :: i
30778
30779       G(1,2)= a(1)*a(2)*cosd(b(3))
30780       G(1,3)= a(1)*a(3)*cosd(b(2))
30781       G(2,3)= a(2)*a(3)*cosd(b(1))
30782
30783       do i=1,3
30784          G(i,i)= a(i)*a(i)
30785       end do
30786
30787       G(2,1)=G(1,2)
30788       G(3,1)=G(1,3)
30789       G(3,2)=G(2,3)
30790
30791       return
30792    End Function Metrics
30793
30794    !!----
30795    !!---- Function Rot_Matrix(U, Phi, Celda)
30796    !!----    real(kind=cp), dimension(3),        intent(in) :: U
30797    !!----    real(kind=cp),                      intent(in) :: Phi
30798    !!----    type (Crystal_Cell_Type), optional, intent(in) :: Celda
30799    !!----    real(kind=cp), dimension(3,3)                  :: Rm
30800    !!----
30801    !!----    Returns the matrix (Gibbs matrix) of the active rotation of "phi" degrees
30802    !!----    along the "U" direction: R v = v', the vector v is tranformed to vector v'
30803    !!----    keeping the reference frame unchanged.
30804    !!----
30805    !!----    If one wants to calculate the components of the vector "v" in a rotated
30806    !!----    reference frame it suffices to invoke the function using "-phi".
30807    !!----    If "Celda" is present, "U" is in "Celda" coordinates,
30808    !!----    if not "U" is in cartesian coordinates.
30809    !!----
30810    !!----
30811    !!---- Update: February - 2005
30812    !!
30813    Function Rot_Matrix(U,Phi,Celda) Result(Rm)
30814       !---- Argument ----!
30815       real(kind=cp), dimension(3), intent(in)        :: U
30816       real(kind=cp), intent(in)                      :: phi
30817       type (Crystal_Cell_Type), optional, intent(in) :: Celda
30818       real(kind=cp), dimension(3,3)                  :: RM
30819
30820       !---- Local variables ----!
30821       real(kind=cp)               :: c, s, umc, umod
30822       real(kind=cp), dimension(3) :: UU
30823
30824
30825       if (present(celda)) then
30826          uu= matmul(celda%cr_orth_cel,u)
30827       else
30828          uu=u
30829       end if
30830
30831       umod=sqrt(dot_product(uu,uu))
30832
30833       if (umod < tiny(1.0)) then
30834          uu=(/0.0,0.0,1.0/)
30835       else
30836          uu= uu/umod
30837       end if
30838
30839       c= cosd(phi)
30840       s= sind(phi)
30841       umc = 1.0-c
30842       rm(1,1)= c+ umc*uu(1)**2
30843       rm(1,2)= umc*uu(1)*uu(2)- s*uu(3)
30844       rm(1,3)= umc*uu(1)*uu(3)+ s*uu(2)
30845
30846       rm(2,1)= umc*uu(2)*uu(1)+ s*uu(3)
30847       rm(2,2)= c+ umc*uu(2)**2
30848       rm(2,3)= umc*uu(2)*uu(3)- s*uu(1)
30849
30850       rm(3,1)= umc*uu(3)*uu(1)- s*uu(2)
30851       rm(3,2)= umc*uu(3)*uu(2)+ s*uu(1)
30852       rm(3,3)= c+ umc*uu(3)**2
30853
30854       return
30855    End Function Rot_Matrix
30856
30857    !!----
30858    !!---- Function U_Equiv(Cell, Th_U) Result(Uequi)
30859    !!----    type(Crystal_Cell_Type),    intent(in)     :: Cell    !  In -> Cell variable
30860    !!----    real(kind=cp), dimension(6),intent(in)     :: Th_U    !  In -> U parameters
30861    !!----
30862    !!----    Subroutine to obtain the U equiv from U11 U22 U33 U12 U13 U23
30863    !!----
30864    !!---- Update: February - 2005
30865    !!
30866    Function U_Equiv(Cell, Th_U) Result(Uequi)
30867       !---- Arguments ----!
30868       type (Crystal_cell_Type),    intent(in)  :: Cell
30869       real(kind=cp), dimension(6), intent(in)  :: Th_U
30870       real(kind=cp)                            :: Uequi
30871
30872       !---- Local variables ----!
30873       real(kind=cp)    :: a, b, c, as, bs, cs, cosa, cosb, cosg
30874       real(kind=cp)    :: u11, u22, u33, u23, u13, u12
30875
30876       a  =cell%cell(1)
30877       b  =cell%cell(2)
30878       c  =cell%cell(3)
30879       as =cell%rcell(1)
30880       bs =cell%rcell(2)
30881       cs =cell%rcell(3)
30882       cosa=cosd(cell%ang(1))
30883       cosb=cosd(cell%ang(2))
30884       cosg=cosd(cell%ang(3))
30885
30886       u11=Th_u(1)
30887       u22=Th_u(2)
30888       u33=Th_u(3)
30889       u12=Th_u(4)
30890       u13=Th_u(5)
30891       u23=Th_u(6)
30892       uequi= (1.0/3.0) * (u11 * a * a * as * as + &
30893                           u22 * b * b * bs * bs + &
30894                           u33 * c * c * cs * cs + &
30895                           2.0*u12 * a * b * as * bs * cosg + &
30896                           2.0*u13 * a * c * as * cs * cosb + &
30897                           2.0*u23 * b * c * bs * cs * cosa )
30898
30899       return
30900    End Function U_Equiv
30901
30902    !---------------------!
30903    !---- Subroutines ----!
30904    !---------------------!
30905
30906    !!----
30907    !!---- Subroutine Change_Setting_Cell(Cell,Mat,Celln,Matkind)
30908    !!----    type (Crystal_Cell_Type),      intent( in)    :: Cell
30909    !!----    real(kind=cp), dimension (3,3),intent( in)    :: Mat
30910    !!----    type (Crystal_Cell_Type),      intent(out)    :: Celln
30911    !!----    character (len=*), optional,   intent (in)    :: matkind
30912    !!----
30913    !!---- Calculates a new cell giving the transformation matrix.
30914    !!---- The input matrix can be given as the S-matrix in International
30915    !!---- Tables or its transposed (default) that corresponds to the matrix
30916    !!---- relating formal column matrices containing the basis vectors.
30917    !!----
30918    !!---- Update: February - 2005
30919    !!
30920    Subroutine Change_Setting_Cell(Cell,Mat,Celln,Matkind)
30921       !---- Arguments ----!
30922       type (Crystal_Cell_Type),      intent( in)    :: Cell
30923       real(kind=cp), dimension (3,3),intent( in)    :: Mat
30924       type (Crystal_Cell_Type),      intent(out)    :: Celln
30925       character(len=*),  optional,   intent (in)    :: Matkind
30926
30927       !--- Local variables ---!
30928       integer                       :: i
30929       real(kind=cp), dimension(3)   :: cellv,angl
30930       real(kind=cp), dimension(3,3) :: S,Gn,ST
30931
30932       if (present(matkind)) then
30933          if (matkind(1:2) == "it" .or. matkind(1:2) == "IT" ) then
30934             S=Mat
30935            ST=transpose(Mat)
30936          else
30937             S=transpose(Mat)
30938            ST=Mat
30939          end if
30940       else
30941          S=transpose(Mat)
30942         ST=Mat
30943       end if
30944
30945       !---- Get the new metric tensor
30946       !---- GDN= Mat GD MatT  or GDN= ST GD S
30947       gn=matmul(ST,matmul(Cell%GD,S))
30948
30949       !---- Calculate new cell parameters from the new metric tensor
30950       do i=1,3
30951          Cellv(i)=sqrt(gn(i,i))
30952       end do
30953       angl(1)=acosd(Gn(2,3)/(cellv(2)*cellv(3)))
30954       angl(2)=acosd(Gn(1,3)/(cellv(1)*cellv(3)))
30955       angl(3)=acosd(Gn(1,2)/(cellv(1)*cellv(2)))
30956
30957       !---- Construct the new cell
30958       call Set_Crystal_Cell(cellv,angl,Celln)
30959
30960       return
30961    End Subroutine Change_Setting_Cell
30962
30963    !!----
30964    !!---- Subroutine Get_basis_from_uvw(dmin,u,cell,ZoneB,ok,mode)
30965    !!----    real(kind=cp)             intent(in) :: dmin  !minimum d-spacing (smax=1/dmin)
30966    !!----    integer, dimension(3),    intent(in) :: u     !Zone axis indices
30967    !!----    type (Crystal_Cell_Type), intent(in) :: cell
30968    !!----    type (Zone_Axis_Type),    intent(out):: ZoneB !Object containing u and basis vector in the plane
30969    !!----    logical,                  intent(out):: ok
30970    !!----    character(len=*),optional,intent(in) :: mode
30971    !!----
30972    !!----  Subroutine to construct ZA of type Zone_Axis. This subroutine picks up two reciprocal
30973    !!----  lattice vectors satisfying the equation
30974    !!----                            hu+kv+lw=0
30975    !!----  The two reciprocal lattice vectors have no coprime factors and
30976    !!----  constitute the basis of a reciprocal lattice plane. They are
30977    !!----  obtained as the shortest two reciprocal lattice vectors satisfying
30978    !!----  the above equation. If mode is provided and mode="R", we interpret
30979    !!----  that the input zone axis is a reciprocal lattice vector and what we
30980    !!----  obtain is the basis of a direct plane in terms of lattice vectors.
30981    !!----  If mode="R", dmin corresponds n(uvw)max
30982    !!----  This subroutine has been imported from resvis_proc.f90.
30983    !!----
30984    !!----  Created: February 2006 (Imported from old programs for electron diffraction, Thesis JRC)
30985    !!----  Updated: February 2012 (JRC)
30986    !!----
30987    Subroutine Get_basis_from_uvw(dmin,u,cell,ZoneB,ok,mode)
30988       !--- Arguments ---!
30989       real(kind=cp),            intent(in) :: dmin
30990       integer, dimension(3),    intent(in) :: u
30991       type (Crystal_Cell_Type), intent(in) :: cell
30992       type (Zone_Axis_Type),    intent(out):: ZoneB
30993       logical,                  intent(out):: ok
30994       character(len=*),optional,intent(in) :: mode
30995
30996       !--- Local Variables ---!
30997       integer                :: n,ik,il,um,iv,i1,i2,i,coun01,coun02,coun1,coun2
30998       integer,dimension(1)   :: i0
30999       integer                :: kmin,kmax,lmin,lmax
31000       integer,dimension(3)   :: au,h,mu
31001       real, dimension(2)     :: rm
31002       real, dimension(3,3)   :: mat
31003       integer,dimension(3,2) :: bas
31004       real                   :: rv,s2max
31005
31006       ZoneB%nlayer=0
31007       ZoneB%uvw=u
31008       ok=.false.
31009
31010       au=abs(u)
31011       um=3*maxval(au)
31012       i0=maxloc(au)
31013
31014       i=i0(1)
31015       iv=u(i)
31016       mu=u
31017       if (iv < 0) then
31018         mu=-u
31019         iv=-iv
31020       end if
31021
31022       Select Case (i)
31023         Case(1)
31024           i1=2; i2=3
31025         Case(2)
31026           i1=1; i2=3
31027         Case(3)
31028           i1=1; i2=2
31029       End Select
31030
31031       rm(1)=100000.0; rm(2)=rm(1)
31032       bas(:,1) = (/ 71,121, 113/)
31033       bas(:,2) = (/117, 91,-111/)
31034
31035       if(present(mode)) then
31036         s2max=dmin*dmin   !here dmin is really n_max
31037         kmax=nint(dmin/Cell%cell(i1)+1.0)
31038         lmax=nint(dmin/Cell%cell(i2)+1.0)
31039         kmax=min(um,kmax)
31040         lmax=min(um,lmax)
31041         mat=cell%gd
31042       else
31043         s2max=1.0/(dmin*dmin)
31044         kmax=nint(Cell%cell(i1)/dmin+1.0)
31045         lmax=nint(Cell%cell(i2)/dmin+1.0)
31046         kmax=min(um,kmax)
31047         lmax=min(um,lmax)
31048         mat=cell%gr
31049       end if
31050
31051       kmin=-kmax; lmin=-lmax
31052       coun1=0; coun2=0
31053       do ik=kmax,kmin,-1
31054          do il=lmax,lmin,-1
31055             if (ik == 0 .and. il == 0) cycle
31056             n=-ik*mu(i1)-il*mu(i2)
31057             if (mod(n,iv) == 0) then               !n is multiple of iv
31058                h(i)= n/iv ; h(i1)=ik ; h(i2) = il  !h is solution of hu+kv+lw=0
31059                rv=dot_product(real(h),matmul(mat,real(h)))
31060                if (rv > s2max  .or. rv < 1.0e-20) cycle
31061                if (rv < rm(1)) then
31062                   if (.not. co_linear(bas(:,1),h,3) ) then
31063                      bas(:,2)=bas(:,1)
31064                      rm(2) = rm(1)
31065                      if (coun1 >=1) coun2=coun2+1
31066                   end if
31067                   bas(:,1)=h
31068                   rm(1) = rv
31069                   coun1=coun1+1
31070                else if (rv < rm(2) .and. .not. co_linear(bas(:,1),h,3) ) then
31071                   bas(:,2)=h
31072                   rm(2) = rv
31073                   coun2=coun2+1
31074                end if
31075             end if
31076          end do
31077       end do
31078       ZoneB%rx=bas(:,1)
31079       ZoneB%ry=bas(:,2)
31080       if (coun1 >= 1 .and. coun2 >=1) ok=.true.
31081       coun01=0; coun02=0; coun1=0; coun2=0
31082       do i=1,3
31083          if (ZoneB%rx(i) < 0) coun1=coun1+1
31084          if (ZoneB%ry(i) < 0) coun2=coun2+1
31085          if (ZoneB%rx(i) == 0) coun01=coun01+1
31086          if (ZoneB%ry(i) == 0) coun02=coun02+1
31087       end do
31088       if (coun1 >= 2 .or. (coun1 == 1 .and. coun01 == 2)) ZoneB%rx=-ZoneB%rx
31089       if (coun2 >= 2 .or. (coun2 == 1 .and. coun02 == 2)) ZoneB%ry=-ZoneB%ry
31090
31091       return
31092    End Subroutine Get_Basis_From_Uvw
31093
31094    !!----
31095    !!---- Subroutine Get_Conventional_Cell(Twofold,Cell,Tr,Message,Ok,told)
31096    !!----   Type(Twofold_Axes_Type), intent(in)  :: twofold
31097    !!----   Type(Crystal_Cell_Type), intent(out) :: Cell
31098    !!----   integer, dimension(3,3), intent(out) :: tr
31099    !!----   character(len=*),        intent(out) :: message
31100    !!----   logical,                 intent(out) :: ok
31101    !!----   real(kind=cp), optional, intent(in)  :: told
31102    !!----
31103    !!----  This subroutine provides the "conventional" (or quasi! being still tested )
31104    !!----  from the supplied object "twofold" that has been obtained from a previous
31105    !!----  call to Get_TwoFold_Axes. The conventional unit cell can be deduced from
31106    !!----  the distribution of two-fold axes in the lattice. The cell produced in this
31107    !!----  procedure applies some rules for obtaining the conventional cell, for instance
31108    !!----  in monoclinic lattices (a single two-fold axis) the two-fold axis is along
31109    !!----  b and the final cell is right handed with a <= c and beta >= 90. It may be
31110    !!----  A,C or I centred. The convertion to the C-centred setting in the A and I
31111    !!----  centring, is not attempted. The angular tolerance for accepting a two-fold
31112    !!----  axis, or higher order axes, as such has been previously set into twofold%tol
31113    !!----  component. The output Tr-matrix is the transpose of the IT convention.
31114    !!----  It corresponds to the transformation between formal column matrices containing
31115    !!----  the basis vectors.
31116    !!----  The tolerance for comparing distances in angstroms told is optional.
31117    !!----- By default the used tolerance is 0.2 angstroms.
31118    !!----
31119    !!---- Update: November - 2008
31120    !!----
31121    Subroutine Get_Conventional_Cell(Twofold,Cell,Tr,Message,Ok,told)
31122       !---- Arguments ----!
31123       Type(Twofold_Axes_Type), intent(in)  :: Twofold
31124       Type(Crystal_Cell_Type), intent(out) :: Cell
31125       integer, dimension(3,3), intent(out) :: tr
31126       character(len=*),        intent(out) :: message
31127       logical,                 intent(out) :: ok
31128       real(kind=cp), optional, intent(in)  :: told
31129
31130       !---- Local variables ----!
31131       integer, dimension(1)          :: ix
31132       integer, dimension(2)          :: ab
31133       integer, dimension(3)          :: rw,h1,h2
31134       integer, dimension(66)         :: inp
31135       integer, dimension(3,48)       :: row
31136       real(kind=cp), dimension(3)    :: u,v1,v2,v3,a,b,c,vec,vi,vj,vk
31137       real(kind=cp), dimension(48)   :: mv
31138       real(kind=cp), dimension(66)   :: ang
31139       integer                        :: iu,iv,iw,nax,i,j,k,m,namina,naminb,naminc,ia
31140       real(kind=cp)                  :: dot,ep,domina,dominb,dominc,aij,aik,ajk
31141       real(kind=cp)                  :: delt,tola
31142       logical                        :: hexap, hexac
31143
31144       a=twofold%a; b=twofold%b; c=twofold%c
31145       delt=twofold%tol
31146       ep=cosd(90.0-delt)
31147       domina=9.0e+30; dominc=domina
31148       tr=reshape((/1,0,0,0,1,0,0,0,1/),(/3,3/))
31149       ab=0; mv=0.0; ang=0.0; row=0; inp=0
31150       ok=.true.
31151       tola=0.2
31152       if(present(told)) tola=told
31153
31154       Select Case(twofold%ntwo)
31155          Case (1)    !Monoclinic
31156             v2=twofold%caxes(:,1)
31157             u = v2/twofold%maxes(1)
31158             tr(2,:)=twofold%dtwofold(:,1)
31159             nax=0
31160             do iu=-3,3
31161                do iv=-3,3
31162                   do_iw: do iw=0,3
31163                      rw=(/iu,iv,iw/)
31164                      ! if(iu == 0 .and. iv == 0 .and. iw == 0) cycle
31165                      if (.not. Co_prime(rw,3)) cycle
31166                      vec=real(iu)*a+real(iv)*b+real(iw)*c
31167                      dot=sqrt(dot_product(vec,vec))
31168                      vec=vec/dot
31169                      if (abs(dot_product(u,vec)) < ep) then
31170                         do m=1,nax
31171                            if(co_linear(rw,row(:,m),3)) cycle do_iw
31172                         end do
31173                         nax=nax+1
31174                         row(:,nax) = rw
31175                         mv(nax) = dot
31176                         if (dot < domina) then
31177                            domina=dot
31178                            namina=nax
31179                            tr(1,:)=rw
31180                            v1=real(iu)*a+real(iv)*b+real(iw)*c
31181                         end if
31182                      end if
31183                   end do do_iw
31184                end do
31185             end do
31186
31187             do i=1,nax
31188                if (i == namina) cycle
31189                if (mv(i) < dominc) then
31190                   dominc=mv(i)
31191                   naminc=i
31192                end if
31193             end do
31194             tr(3,:)=row(:,naminc)
31195             v3=row(1,naminc)*a+row(2,naminc)*b+row(3,naminc)*c
31196
31197             !Length of the three basis vectors should be stored in mv(1),mv(2),mv(3)
31198             mv(1)=sqrt(dot_product(v1,v1))
31199             mv(2)=sqrt(dot_product(v2,v2))
31200             mv(3)=sqrt(dot_product(v3,v3))
31201
31202             !The two shortest vectors perpendicular to the primary twofold axis have been found
31203             !and the transformation matrix has been constructed
31204             namina=determ_A(tr)
31205             if (namina < 0) then   !right handed system
31206                tr(2,:)=-tr(2,:)
31207                v2=-v2
31208                namina=-namina
31209             end if
31210
31211             !Test if beta is lower than 90 in such a case invert c and b
31212             dominb=dot_product(v1/mv(1),v3/mv(3))
31213             if (dominb > 0.0) then  !angle beta < 90
31214                tr(2,:)=-tr(2,:)
31215                v2=-v2
31216                tr(3,:)=-tr(3,:)
31217                v3=-v3
31218             end if
31219
31220             Select Case (namina)
31221                Case(1)
31222                   message="Monoclinic, primitive cell"
31223                Case(2)
31224                   rw=matmul((/0,1,1/),tr)
31225                   if (.not. co_prime(rw,3)) then
31226                      message="Monoclinic, A-centred cell"
31227                   else
31228                      rw=matmul((/1,1,1/),tr)
31229                      if (.not. co_prime(rw,3)) then
31230                         message="Monoclinic, I-centred cell"
31231                      else
31232                         rw=matmul((/1,1,0/),tr)
31233                         if(.not. co_prime(rw,3)) message="Monoclinic, C-centred cell"
31234                      end if
31235                   end if
31236
31237                Case(3:)
31238                   message="Error in monoclinic cell"
31239                   ok=.false.
31240             End Select
31241
31242          Case (3)    !Orthorhombic/Trigonal
31243             u(1:3)=twofold%maxes(1:3)
31244             ix=minloc(u)
31245             namina=ix(1)
31246             ix=maxloc(u)
31247             naminc=ix(1)
31248             if (naminc == namina) then
31249                namina=1; naminb=2; naminc=3
31250             else
31251                do i=1,3
31252                   if(i == namina) cycle
31253                   if(i == naminc) cycle
31254                   naminb=i
31255                   exit
31256                end do
31257             end if
31258             tr(1,:) = twofold%dtwofold(:,namina)
31259             tr(2,:) = twofold%dtwofold(:,naminb)
31260             tr(3,:) = twofold%dtwofold(:,naminc)
31261             v1 = twofold%caxes(:,namina)
31262             v2 = twofold%caxes(:,naminb)
31263             v3 = twofold%caxes(:,naminc)
31264             mv(1)=twofold%maxes(namina)
31265             mv(2)=twofold%maxes(naminb)
31266             mv(3)=twofold%maxes(naminc)
31267
31268             !Check the system by verifying that the two-fold axes form 90 (orthorhombic)
31269             !or 120 degrees (Trigonal)
31270             domina=dot_product(v2/mv(2),v3/mv(3))
31271             dominb=dot_product(v1/mv(1),v3/mv(3))
31272             dominc=dot_product(v1/mv(1),v2/mv(2))
31273
31274             if (abs(domina) < ep .and. abs(dominb) < ep .and. abs(dominc) < ep) then !orthorhombic
31275                namina=determ_A(tr)
31276                if (namina < 0) then
31277                   tr(3,:)=-tr(3,:)
31278                   v3=-v3
31279                   namina=-namina
31280                end if
31281                Select Case (namina)
31282                   Case(1)
31283                      message="Orthorhombic, Primitive cell"
31284
31285                   Case(2)
31286                      rw=matmul((/0,1,1/),tr)
31287                      if (.not. co_prime(rw,3)) then
31288                         message="Orthorhombic, A-centred cell"
31289                      else
31290                         rw=matmul((/1,1,1/),tr)
31291                         if (.not. co_prime(rw,3)) then
31292                            message="Orthorhombic, I-centred cell"
31293                         else
31294                            rw=matmul((/1,1,0/),tr)
31295                            if (.not. co_prime(rw,3)) then
31296                               message="Orthorhombic, C-centred cell"
31297                            else
31298                               rw=matmul((/1,0,1/),tr)
31299                               if (.not. co_prime(rw,3)) message="Orthorhombic, B-centred cell"
31300                            end if
31301                         end if
31302                      end if
31303
31304                   Case(3:)
31305                      message="Orthorhombic, F-centred cell"
31306                End Select
31307
31308             else !Rhombohedral/Trigonal
31309
31310                !In the Trigonal system the two-fold axes are in the plane perpendicular to
31311                !the three-fold axis, and valid a,b, vectors can be chosen among any two two-fold
31312                !axes forming an angle of 120 degrees
31313                !verify that 1 and 2 form 120
31314                ang(1)=acosd(domina)    !2-3
31315                ang(2)=acosd(dominb)    !1-3
31316                ang(3)=acosd(dominc)    !1-2
31317                dot=1.0
31318                iu=1
31319                j=0
31320                do i=1,3
31321                   if (abs(ang(i)-120.0) < delt) then
31322                      j=i
31323                      exit
31324                   end if
31325                end do
31326
31327                if ( j == 0) then
31328                   do i=1,3
31329                      if (abs(ang(i)-60.0) < delt) then
31330                         j=i
31331                         dot=-1.0
31332                         iu=-1
31333                         exit
31334                      end if
31335                   end do
31336                End if
31337
31338                if ( j == 0) then
31339                   message="Trigonal/Rhombohedral test failed! Supply only one two-fold axis"
31340                   ok=.false.
31341                   return
31342                else
31343                   Select Case (j)
31344                      case(1)
31345                         vi=v2
31346                         vj=dot*v3
31347                         h1=tr(2,:); h2=iu*tr(3,:)
31348                         tr(3,:)=tr(1,:)
31349                         tr(1,:)=h1
31350                         tr(2,:)=h2
31351
31352                      case(2)
31353                         vi=v1
31354                         vj=dot*v3
31355                         h2=iu*tr(3,:)
31356                         tr(3,:)=tr(2,:)
31357                         tr(2,:)=h2
31358
31359                      case(3)
31360                         vi=v1
31361                         vj=dot*v2
31362                         tr(2,:)=iu*tr(2,:)
31363
31364                   End Select
31365
31366                   v1 = vi
31367                   v2 = vj
31368                   mv(1)=sqrt(dot_product(v1,v1))
31369                   mv(2)=sqrt(dot_product(v2,v2))
31370                   vi=v1/mv(1)
31371                   vj=v2/mv(2)
31372                   ok=.false.
31373
31374                   do_iu: do iu=-3,3
31375                      do iv=-3,3
31376                         do iw=0,3
31377                            rw=(/iu,iv,iw/)
31378                            if (.not. Co_prime(rw,3)) cycle
31379                            vec=real(iu)*a+real(iv)*b+real(iw)*c
31380                            dot=sqrt(dot_product(vec,vec))
31381                            vec=vec/dot
31382                            if (abs(dot_product(vi,vec)) < ep  .and. abs(dot_product(vj,vec)) < ep) then
31383                               tr(3,:)=rw
31384                               ok=.true.
31385                               exit do_iu
31386                            end if
31387                         end do
31388                      end do
31389                   end do do_iu
31390
31391                   If (ok) then
31392                      namina=determ_A(tr)
31393                      if (namina < 0) then
31394                         tr(3,:)=-tr(3,:)
31395                         namina=-namina
31396                      end if
31397                      v3 = tr(3,1)*a+tr(3,2)*b+tr(3,3)*c
31398                      mv(3)=sqrt(dot_product(v3,v3))
31399                      Select Case (namina)
31400                         case(1)
31401                            message="Primitive hexagonal cell"
31402                         case(3)
31403                            rw=matmul((/2,1,1/),tr)
31404                            if (.not. co_prime(rw,3)) then
31405                               message="Rhombohedral, obverse setting cell"
31406                            else
31407                               message="Rhombohedral, reverse setting cell"
31408                            end if
31409                      End Select
31410
31411                   Else
31412                      message="Trigonal/Rhombohedral test failed! Supply only one two-fold axis"
31413                      ok=.false.
31414                      return
31415                   End if
31416                End if !j==0
31417             End if  !orthorhombic test
31418
31419          Case (5)    !Tetragonal
31420             m=0
31421             inp=0
31422             mv(1:5)=twofold%maxes(1:5)
31423             do i=1,twofold%ntwo-1
31424                vi=twofold%caxes(:,i)/twofold%maxes(i)
31425                do j=i+1,twofold%ntwo
31426                   vj=twofold%caxes(:,j)/twofold%maxes(j)
31427                   m=m+1
31428                   ang(m)=acosd(dot_product(vi,vj))
31429                   if (abs(ang(m)-45.0) < delt .or. abs(ang(m)-135.0) < delt) then
31430                      inp(i)=1
31431                      inp(j)=1
31432                      if (mv(i) > mv(j)) then
31433                         ia=j
31434                      else
31435                         ia=i
31436                      end if
31437                      if (ab(1) == 0) then
31438                         ab(1) = ia
31439                      else
31440                         ab(2) = ia
31441                      end if
31442                   end if
31443                end do
31444             end do
31445
31446             !Determination of the c-axis (that making 90 degree with all the others)
31447             ix=minloc(inp)
31448             naminc=ix(1)
31449
31450             !The two axes forming a,b are those of indices ab(1) and ab(2)
31451             namina=ab(1)
31452             naminb=ab(2)
31453             if (namina == 0 .or. naminb == 0) then
31454                ok=.false.
31455                message="Basis vectors a-b not found!"
31456                return
31457             end if
31458
31459             tr(1,:) = twofold%dtwofold(:,namina)
31460             tr(2,:) = twofold%dtwofold(:,naminb)
31461             tr(3,:) = twofold%dtwofold(:,naminc)
31462             v1 = twofold%caxes(:,namina)
31463             v2 = twofold%caxes(:,naminb)
31464             v3 = twofold%caxes(:,naminc)
31465             mv(1)=twofold%maxes(namina)
31466             mv(2)=twofold%maxes(naminb)
31467             mv(3)=twofold%maxes(naminc)
31468             namina=determ_A(tr)
31469             if (namina < 0) then
31470                tr(3,:)=-tr(3,:)
31471                v3=-v3
31472                namina=-namina
31473             end if
31474
31475             Select Case (namina)
31476                Case(1)
31477                   message="Tetragonal, Primitive cell"
31478                Case(2)
31479                   message="Tetragonal, I-centred cell"
31480                Case(3:)
31481                   message="Error in tetragonal cell"
31482                   ok=.false.
31483                   return
31484             End Select
31485
31486          Case (7)    !Hexagonal
31487
31488             m=0
31489             inp=0
31490             mv(1:7)=twofold%maxes(1:7)
31491             hexap=.false.;  hexac=.false.
31492
31493             !Search tha a-b plane
31494             do_ii:do i=1,twofold%ntwo-1
31495                vi=twofold%caxes(:,i)/twofold%maxes(i)
31496                do j=i+1,twofold%ntwo
31497                   vj=twofold%caxes(:,j)/twofold%maxes(j)
31498                   aij=acosd(dot_product(vi,vj))
31499                   if (abs(aij-120.0) < delt) then
31500                      if (abs(mv(i)-mv(j)) < tola .and. .not. hexap ) then
31501                         rw(1)=i; rw(2)=j
31502                         u(1)=mv(i); u(2)=mv(j)
31503                         hexap=.true.
31504                         exit do_ii
31505                      end if
31506                   end if
31507                end do
31508             end do do_ii
31509
31510             if (hexap) then ! Search the c-axis, it should be also a two-fold axis!
31511                             ! because Op(6).Op(6).Op(6)=Op(2)
31512                v1 = twofold%caxes(:,rw(1))
31513                v2 = twofold%caxes(:,rw(2))
31514                vj=v1/u(1)
31515                vk=v2/u(2)
31516                do i=1,twofold%ntwo
31517                   vi=twofold%caxes(:,i)/twofold%maxes(i)
31518                   aij=acosd(dot_product(vi,vj))
31519                   aik=acosd(dot_product(vi,vk))
31520                   if (abs(aij-90.0) < delt .and. abs(aik-90.0) < delt ) then
31521                      rw(3)=i
31522                      u(3)= mv(i)
31523                      hexac=.true.
31524                      exit
31525                   end if
31526                end do
31527             else
31528                ok=.false.
31529                return
31530             end if
31531
31532             if (hexac) then
31533                do i=1,3
31534                   tr(i,:) = twofold%dtwofold(:,rw(i))
31535                   mv(i)=u(i)
31536                end do
31537                v3 = twofold%caxes(:,rw(3))
31538                namina=determ_A(tr)
31539                if (namina < 0) then
31540                   tr(3,:)=-tr(3,:)
31541                   v3=-v3
31542                   namina=-namina
31543                end if
31544
31545                Select Case (namina)
31546                   Case(1)
31547                      message="Hexagonal, Primitive cell"
31548                   Case(2:)
31549                      message="Hexagonal, centred cell? possible mistake"
31550                End Select
31551
31552             else
31553                ok=.false.
31554                message="The c-axis of a hexagonal cell was not found!"
31555                return
31556             end if
31557
31558          Case (9)   !Cubic
31559             m=0
31560             inp=0
31561             mv(1:9)=twofold%maxes(1:9)
31562             do_i:do i=1,twofold%ntwo-2
31563                vi=twofold%caxes(:,i)/twofold%maxes(i)
31564                do j=i+1,twofold%ntwo-1
31565                   vj=twofold%caxes(:,j)/twofold%maxes(j)
31566                   do k=j+1,twofold%ntwo
31567                      vk=twofold%caxes(:,k)/twofold%maxes(k)
31568                      aij=acosd(dot_product(vi,vj))
31569                      aik=acosd(dot_product(vi,vk))
31570                      ajk=acosd(dot_product(vj,vk))
31571                      if (abs(aij-90.0) < delt .and. abs(aik-90.0) < delt .and. abs(ajk-90.0) < delt ) then
31572                         if (abs(mv(i)-mv(j)) < tola .and. abs(mv(i)-mv(k)) < tola .and. abs(mv(j)-mv(k)) < tola ) then
31573                            rw(1)=i; rw(2)=j; rw(3)=k
31574                            u(1)=mv(i); u(2)=mv(j); u(3)=mv(k)
31575                            exit do_i
31576                         end if
31577                      end if
31578                   end do
31579                end do
31580             end do do_i
31581
31582             do i=1,3
31583                tr(i,:) = twofold%dtwofold(:,rw(i))
31584                mv(i)=u(i)
31585             end do
31586             v1 = twofold%caxes(:,rw(1))
31587             v2 = twofold%caxes(:,rw(2))
31588             v3 = twofold%caxes(:,rw(3))
31589             namina=determ_A(tr)
31590             if (namina < 0) then
31591                tr(3,:)=-tr(3,:)
31592                v3=-v3
31593                namina=-namina
31594             end if
31595
31596             Select Case (namina)
31597                Case(0)
31598                  write(unit=message,fmt="(a)") "Pseudo-cubic but tolerance too small ... "
31599                  ok=.false.
31600                  return
31601                Case(1)
31602                   message="Cubic, Primitive cell"
31603                Case(2)
31604                   rw=matmul((/0,1,1/),tr)
31605                   if (.not. co_prime(rw,3)) then
31606                      message="Cubic, A-centred cell"
31607                   else
31608                      rw=matmul((/1,1,1/),tr)
31609                      if (.not. co_prime(rw,3)) then
31610                         message="Cubic, I-centred cell"
31611                      else
31612                         rw=matmul((/1,1,0/),tr)
31613                         if (.not. co_prime(rw,3)) then
31614                            message="Cubic, C-centred cell"
31615                         else
31616                            rw=matmul((/1,0,1/),tr)
31617                            if (.not. co_prime(rw,3)) message="Cubic, B-centred cell"
31618                         end if
31619                      end if
31620                   end if
31621
31622                Case(3:)
31623                  message="Cubic, F-centred cell"
31624             End Select
31625
31626          case default
31627             write(unit=message,fmt="(a,i3)") "Wrong number of two-fold axes! ",twofold%ntwo
31628             ok=.false.
31629             return
31630
31631      End Select
31632
31633      !Calculation of the new cell
31634      ang(1)=acosd(dot_product(v2/mv(2),v3/mv(3)))
31635      ang(2)=acosd(dot_product(v1/mv(1),v3/mv(3)))
31636      ang(3)=acosd(dot_product(v1/mv(1),v2/mv(2)))
31637      Call Set_Crystal_Cell(mv(1:3),ang(1:3),Cell)
31638      ok=.true.
31639
31640      return
31641    End Subroutine Get_Conventional_Cell
31642
31643    !!----
31644    !!---- Subroutine Get_Cryst_Family(Cell,Car_Family,Car_Symbol,Car_System)
31645    !!----    type(Crystal_Cell_type),         intent(in ) :: Cell
31646    !!----    character(len=*),                intent(out) :: Car_Family
31647    !!----    character(len=*),                intent(out) :: Car_Symbol
31648    !!----    character(len=*),                intent(out) :: Car_System
31649    !!----
31650    !!---- Obtain the Crystal Family, Symbol and System from cell parameters
31651    !!----
31652    !!---- Update: May - 2005
31653    !!----
31654    Subroutine Get_Cryst_Family(Cell,Car_Family,Car_Symbol,Car_System)
31655       !---- Arguments ----!
31656       type(Crystal_Cell_type),   intent(in ) :: Cell
31657       character(len=*),          intent(out) :: Car_Family
31658       character(len=*),          intent(out) :: Car_Symbol
31659       character(len=*),          intent(out) :: Car_System
31660
31661       !---- Local variables ----!
31662       integer, dimension(3) :: icodp, icoda
31663       integer               :: n1,n2
31664
31665       Car_Family=" "
31666       Car_Symbol=" "
31667       Car_System=" "
31668
31669       icodp=0
31670       icoda=0
31671
31672       !---- Cell Parameters ----!
31673
31674       !---- a ----!
31675       icodp(1)=1
31676
31677       !---- b ----!
31678       if (abs(cell%cell(2)-cell%cell(1)) <= 0.0001) then
31679          icodp(2)=icodp(1)
31680       else
31681          icodp(2)=2
31682       end if
31683
31684       !---- c ----!
31685       if (abs(cell%cell(3)-cell%cell(1)) <= 0.0001) then
31686          icodp(3)=icodp(1)
31687       else
31688          icodp(3)=3
31689       end if
31690
31691       !---- Angles Parameters ----!
31692
31693       !---- alpha ----!
31694       icoda(1)=1
31695
31696       !---- beta ----!
31697       if (abs(cell%ang(2)-cell%ang(1)) <= 0.0001) then
31698          icoda(2)=icoda(1)
31699       else
31700          icoda(2)=2
31701       end if
31702
31703       !---- gamma ----!
31704       if (abs(cell%ang(3)-cell%ang(1)) <= 0.0001) then
31705          icoda(3)=icoda(1)
31706       else
31707          icoda(3)=3
31708       end if
31709
31710
31711       n1=count(icoda==icoda(1))
31712       n2=count(icodp==icodp(1))
31713       select case (n1)
31714          case (1) ! all are differents
31715             if (n2 ==1) then
31716                Car_Family="Triclinic"
31717                Car_Symbol ="a"
31718                Car_System ="Triclinic"
31719             else
31720                Err_Crys=.true.
31721                ERR_Crys_Mess=" Error obtaining Crystal Familiy"
31722             end if
31723
31724          case (2) ! two angles are equal
31725             if (icoda(1) == icoda(2)) then
31726                if (abs(cell%ang(3)-120.0) <= 0.0001) then
31727                   if (icodp(1)==icodp(2)) then
31728                      !---- Hexagonal ----!
31729                      Car_Family="Hexagonal"
31730                      Car_Symbol ="h"
31731                      Car_System ="Hexagonal"
31732                   else
31733                      Err_Crys=.true.
31734                      ERR_Crys_Mess=" Error obtaining Crystal Familiy"
31735                   end if
31736                else
31737                   !---- Monoclinic ----!
31738                   Car_Family="Monoclinic"
31739                   Car_Symbol ="m"
31740                   Car_System ="Monoclinic"
31741                end if
31742
31743             else
31744                !---- Monoclic b-unique setting ----!
31745                if (abs(cell%ang(1)-90.0) <= 0.0001) then
31746                   Car_Family="Monoclinic"
31747                   Car_Symbol ="m"
31748                   Car_System ="Monoclinic"
31749                else
31750                   Err_Crys=.true.
31751                   ERR_Crys_Mess=" Error obtaining Crystal Familiy"
31752                end if
31753             end if
31754
31755          case (3) ! all are the same angle
31756             if (abs(cell%ang(1) - 90.000) <= 0.0001) then
31757                select case (n2)
31758                   case (1)
31759                      !---- Orthorhombic ----!
31760                      Car_Family="Orthorhombic"
31761                      Car_Symbol ="o"
31762                      Car_System ="Orthorhombic"
31763
31764                   case (2)
31765                      !---- Tetragonal ----!
31766                      if (icodp(1)==icodp(2)) then
31767                         Car_Family="Tetragonal"
31768                         Car_Symbol ="t"
31769                         Car_System ="Tetragonal"
31770                      else
31771                         err_crys=.true.
31772                         ERR_Crys_Mess=" Error obtaining Crystal Familiy"
31773                      end if
31774
31775                   case (3)
31776                      !---- Cubic ----!
31777                      Car_Family="Cubic"
31778                      Car_Symbol ="c"
31779                      Car_System ="Cubic"
31780                end select
31781
31782             else
31783                if (n2 == 3) then
31784                   !---- Hexagonal with rhombohedral axes ----!
31785                   Car_Family="Hexagonal"
31786                   Car_Symbol ="h"
31787                   Car_System ="Trigonal"
31788                else
31789                   Err_Crys=.true.
31790                   ERR_Crys_Mess=" Error obtaining Crystal Familiy"
31791                end if
31792             end if
31793
31794       end select ! n
31795
31796       return
31797    End Subroutine Get_Cryst_Family
31798
31799    !!--++
31800    !!--++ Subroutine Get_Cryst_Orthog_Matrix(Cellv,Ang, Crystort,Cartype)
31801    !!--++    real(kind=cp), dimension(3  ), intent (in ) :: cellv           !  In ->  a,b,c parameters
31802    !!--++    real(kind=cp), dimension(3  ), intent (in ) :: ang             !  In ->  angles parameters of cell
31803    !!--++    real(kind=cp), dimension(3,3), intent (out) :: CrystOrt        ! Out ->  Conversion matrix (a) = (e) CrystOrt
31804    !!--++    character (len=1), optional,   intent (in)  :: CarType         !  In ->  Type of Cartesian axes
31805    !!--++
31806    !!--++    (PRIVATE)
31807    !!--++    Obtains the matrix giving the crystallographic basis in
31808    !!--++    direct space in terms of a Cartesian basis. The output matrix
31809    !!--++    can be directly used for transforming crystallographic components
31810    !!--++    to Cartesian components of the components of a vector considered
31811    !!--++    as a column vector:   XC = CrystOrt X.
31812    !!--++
31813    !!--++    If CartType is not present, or if it is not equal to 'A',
31814    !!--++    the cartesian system is defined as:
31815    !!--++          z // c; y is in the bc-plane; x is y ^ z
31816    !!--++    a = (a sinbeta singamma*, -a sinbeta cosgamma*, a cosbeta )
31817    !!--++    b = (         0         ,     b sinalpha      , b cosalpha)
31818    !!--++    c = (         0         ,         0           , c         )
31819    !!--++
31820    !!--++    If CartType = 'A', the Cartesian system is defined as:
31821    !!--++         x // a; y is in the ab-plane; z is x ^ z
31822    !!--++    a = (       a   ,         0           ,       0             )
31823    !!--++    b = ( b cosgamma,    b singamma       ,       0             )
31824    !!--++    c = (  c cosbeta, -c sinbeta cosalpha*, c sinbeta sinalpha* )
31825    !!--++
31826    !!--++    The output matrix is the tranposed of the above one(s) so that the
31827    !!--++    matrix can directly be used for transforming "components" given
31828    !!--++    in a crystallographic basis to "components" in cartesian basis
31829    !!--++    when the components are used as "column" vectors.
31830    !!--++
31831    !!--++      [a] = C [e] , In [a],[e] basis vectors are in column form
31832    !!--++      (a) = (e) CT, In (a),(e) basis vectors are in row form
31833    !!--++      CrystOrt = CT  => (a) = (e) CystOrt, in ITC: (a) = (e) P
31834    !!--++
31835    !!--++    Remember that  C.CT = GD (direct cell metrics)
31836    !!--++
31837    !!--++
31838    !!--++      Xc = CrystOrt X (Xc Cartesian components, X crystallographic components)
31839    !!--++
31840    !!--++ Update: February - 2005
31841    !!
31842    Subroutine Get_Cryst_Orthog_Matrix(Cellv,Ang, Crystort,CarType)
31843       !---- Arguments ----!
31844       real(kind=cp), dimension(3  ), intent (in ) :: cellv,ang
31845       real(kind=cp), dimension(3,3), intent (out) :: CrystOrt
31846       character (len=1), optional,   intent (in ) :: CarType
31847
31848       !---- Local Variables ----!
31849       real(kind=cp) :: cosgas, singas
31850
31851       if (present(CarType)) then
31852          if (CarType == "A" .or. CarType == "a" ) then  ! x//a
31853             !  Transponse of the following matrix:
31854             !    a = (       a   ,         0           ,       0             )
31855             !    b = ( b cosgamma,    b singamma       ,       0             )
31856             !    c = (  c cosbeta, -c sinbeta cosalpha*, c sinbeta sinalpha* )
31857             cosgas =(cosd(ang(3))*cosd(ang(2))-cosd(ang(1)))/(sind(ang(3))*sind(ang(2)))
31858             singas = sqrt(1.0-cosgas**2)
31859             CrystOrt(1,1) = cellv(1)
31860             CrystOrt(1,2) = cellv(2)*cosd(ang(3))
31861             CrystOrt(1,3) = cellv(3)*cosd(ang(2))
31862             CrystOrt(2,1) = 0.0
31863             CrystOrt(2,2) = cellv(2)*sind(ang(3))
31864             CrystOrt(2,3) =-cellv(3)*sind(ang(2))*cosgas
31865             CrystOrt(3,1) = 0.0
31866             CrystOrt(3,2) = 0.0
31867             CrystOrt(3,3) = cellv(3)*sind(ang(2))*singas
31868             return
31869          end if
31870       end if
31871
31872       !
31873       !  By default, the cartesian frame is such as z//c
31874       !  Transponse of the following matrix:
31875       !    a = (a sinbeta singamma*, -a sinbeta cosgamma*, a cosbeta )
31876       !    b = (         0         ,     b sinalpha      , b cosalpha)
31877       !    c = (         0         ,         0           , c         )
31878       cosgas =(cosd(ang(1))*cosd(ang(2))-cosd(ang(3)))/(sind(ang(1))*sind(ang(2)))
31879       singas = sqrt(1.0-cosgas**2)
31880       CrystOrt(1,1) = cellv(1)*sind(ang(2))*singas
31881       CrystOrt(1,2) = 0.0
31882       CrystOrt(1,3) = 0.0
31883       CrystOrt(2,1) =-cellv(1)*sind(ang(2))*cosgas
31884       CrystOrt(2,2) = cellv(2)*sind(ang(1))
31885       CrystOrt(2,3) = 0.0
31886       CrystOrt(3,1) = cellv(1)*cosd(ang(2))
31887       CrystOrt(3,2) = cellv(2)*cosd(ang(1))
31888       CrystOrt(3,3) = cellv(3)
31889
31890       return
31891    End Subroutine Get_Cryst_Orthog_Matrix
31892
31893    !!----
31894    !!---- Subroutine Get_Deriv_Orth_Cell(Cellp,De_Orthcell,Cartype)
31895    !!----    type(Crystal_Cell_type),         intent(in ) :: cellp
31896    !!----    real(kind=cp), dimension(3,3,6), intent(out) :: de_Orthcell
31897    !!----    character (len=1), optional,     intent(in ) :: CarType
31898    !!----
31899    !!----    Subroutine to get derivative matrix of the transformation matrix
31900    !!----    to orthogonal frame. Useful for calculations of standard deviations
31901    !!----    of distances and angles. The specialised subroutine calculating
31902    !!----    sigmas of distances "distance_and_sigma" is in Atom_mod.
31903    !!----    The output matrices "de_Orthcell" are the derivatives of, with
31904    !!----    respect to a(1),b(2),c(3),alpha(4),beta(5) and gamma(6) of the
31905    !!----    matrix   "Cellp%Cr_Orth_cel".
31906    !!----
31907    !!---- Update: February - 2005
31908    !!
31909    Subroutine Get_Deriv_Orth_Cell(Cellp,De_Orthcell,Cartype)
31910       !---- Arguments ----!
31911       type(Crystal_Cell_type),         intent(in ) :: cellp
31912       real(kind=cp), dimension(3,3,6), intent(out) :: de_Orthcell
31913       character (len=1), optional,     intent(in ) :: CarType
31914
31915       !---- Local Variables ----!
31916       real(kind=cp) ::  ca,cb,cg,sa,sb,sg,f,g, fa,fb,fc,ga,gb,gc
31917
31918       de_Orthcell=0.0
31919       ca=cosd(cellp%ang(1))
31920       cb=cosd(cellp%ang(2))
31921       cg=cosd(cellp%ang(3))
31922       sa=sind(cellp%ang(1))
31923       sb=sind(cellp%ang(2))
31924       sg=sind(cellp%ang(3))
31925
31926       if (present(CarType)) then
31927          if (CarType == "A" .or. CarType == "a" ) then  ! x//a
31928
31929             f=(ca-cb*cg)/sg    !-cosgas*sinbeta
31930             g=SQRT(sb*sb-f*f)  ! singas*sinbeta
31931             fa=-sa/sg          ! df/dalpha
31932             fb=sb*cg/sg        ! df/dbeta
31933             fc=cb/sg**2        ! df/dgamma
31934             ga=-f*fa/g         ! dg/dalpha
31935             gb=(sb*cb-f*fb)/g  ! dg/dbeta
31936             gc=f/g*fc          ! dg/dgamma
31937
31938             ! M: Transponse of the following matrix:
31939             !    a = (       a   ,         0           ,       0             )
31940             !    b = ( b cosgamma,    b singamma       ,       0             )
31941             !    c = (  c cosbeta, -c sinbeta cosalpha*, c sinbeta sinalpha* )
31942
31943             !
31944             !        (   a         b*cg        c*cb )
31945             !    M = (   0         b*sg        c*f  )
31946             !        (   0          0          c*g  )
31947             !
31948             !           (   1      0      0 )
31949             !  dM_da =  (   0      0      0 )
31950             !           (   0      0      0 )
31951             de_Orthcell(1,1,1) = 1.0
31952
31953             !           (   0      cg     0 )
31954             !  dM_db =  (   0      sg     0 )
31955             !           (   0      0      0 )
31956             de_Orthcell(1,2,2) = cg
31957             de_Orthcell(2,2,2) = sg
31958
31959             !
31960             !            (   0          0          cb )
31961             !  dM_dc =   (   0          0          f  )
31962             !            (   0          0          g  )
31963             de_Orthcell(1,3,3) = cb
31964             de_Orthcell(2,3,3) = f
31965             de_Orthcell(3,3,3) = g
31966
31967             !
31968             !             (   0          0           0   )
31969             ! dM_dalpha=  (   0          0          c*fa )
31970             !             (   0          0          c*ga )
31971             !
31972             de_Orthcell(2,3,4) = cellp%cell(3)*fa
31973             de_Orthcell(3,3,4) = cellp%cell(3)*ga
31974
31975             !
31976             !             (   0          0         -c*sb )
31977             ! dM_dbeta =  (   0          0          c*fb )
31978             !             (   0          0          c*gb )
31979             !
31980             de_Orthcell(1,3,5) = -cellp%cell(3)*sb
31981             de_Orthcell(2,3,5) =  cellp%cell(3)*fb
31982             de_Orthcell(3,3,5) =  cellp%cell(3)*gb
31983
31984             !
31985             !              (   0        -b*sg         0   )
31986             ! dM_dgamma =  (   0         b*cg        c*fc )
31987             !              (   0          0          c*gc )
31988             !
31989             de_Orthcell(1,2,6) = -cellp%cell(2)*sg
31990             de_Orthcell(2,2,6) =  cellp%cell(2)*cg
31991             de_Orthcell(2,3,6) =  cellp%cell(3)*fc
31992             de_Orthcell(3,3,6) =  cellp%cell(3)*gc
31993
31994             return
31995          end if
31996       end if
31997
31998       !
31999       !  By default, the cartesian frame is such as z//c
32000       !  Transponse of the following matrix:
32001       !    a = (a sinbeta singamma*, -a sinbeta cosgamma*, a cosbeta )
32002       !    b = (         0         ,     b sinalpha      , b cosalpha)
32003       !    c = (         0         ,         0           , c         )
32004
32005       !         ( a sinbeta singamma*          0             0 )
32006       !    M =  (-a sinbeta cosgamma*      b sinalpha        0 )
32007       !         ( a cosbeta                b cosalpha        c )
32008
32009       f=(cg-ca*cb)/sa    !-sinbeta . cosgamma*
32010       g=SQRT(sb*sb-f*f)  ! sinbeta . singamma*
32011       fa= cb/sa**2       ! df/dalpha
32012       fb=sb*ca/sa        ! df/dbeta
32013       fc=-sb/sa          ! df/dgamma
32014       ga=-f*fa/g         ! dg/dalpha
32015       gb=(sb*cb-f*fb)/g  ! dg/dbeta
32016       gc=f/g*fc          ! dg/dgamma
32017
32018       !         ( a*g        0         0 )
32019       !    M =  ( a*f      b*sa        0 )
32020       !         ( a*cb     b*ca        c )
32021
32022       !
32023       !           (   g       0      0 )
32024       !  dM_da =  (   f       0      0 )
32025       !           (   cb      0      0 )
32026       de_Orthcell(1,1,1) = g
32027       de_Orthcell(1,2,1) = f
32028       de_Orthcell(1,3,1) = cb
32029
32030       !           (   0      0      0 )
32031       !  dM_db =  (   0      sa     0 )
32032       !           (   0      ca     0 )
32033       de_Orthcell(1,2,2) = sa
32034       de_Orthcell(3,2,2) = ca
32035
32036       !
32037       !            (   0      0      0  )
32038       !  dM_dc =   (   0      0      0  )
32039       !            (   0      0      1  )
32040       de_Orthcell(3,3,3) = 1
32041
32042       !
32043       !             ( a*ga         0          0 )
32044       ! dM_dalpha=  ( a*fa       -b*ca        0 )
32045       !             (   0         b*sa        0 )
32046       !
32047       de_Orthcell(1,1,4) = cellp%cell(1)*ga
32048       de_Orthcell(2,1,4) = cellp%cell(1)*fa
32049       de_Orthcell(2,2,4) =-cellp%cell(2)*ca
32050       de_Orthcell(3,2,4) = cellp%cell(2)*sa
32051
32052       !
32053       !             (  a*gb        0         0 )
32054       ! dM_dbeta =  (  a*fb        0         0 )
32055       !             ( -a*sb        0         0 )
32056       !
32057       de_Orthcell(1,1,5) = cellp%cell(1)*gb
32058       de_Orthcell(2,1,5) = cellp%cell(1)*fb
32059       de_Orthcell(3,1,5) =-cellp%cell(1)*sb
32060
32061       !
32062       !              (  a*gc     0      0   )
32063       ! dM_dgamma =  (  a*fc     0      0   )
32064       !              (   0       0      0   )
32065       !
32066       de_Orthcell(1,1,6) = cellp%cell(1)*gc
32067       de_Orthcell(2,1,6) = cellp%cell(1)*fc
32068
32069       return
32070    End Subroutine Get_Deriv_Orth_Cell
32071
32072    !!----
32073    !!---- Subroutine Get_Primitive_Cell(Lat_Type,Centred_Cell,Primitive_Cell,Transfm)
32074    !!----    character(len=*),               intent(in)  :: lat_type
32075    !!----    type(Crystal_Cell_Type),        intent(in)  :: centred_cell
32076    !!----    type(Crystal_Cell_Type),        intent(out) :: primitive_cell
32077    !!----    real(kind=cp), dimension(3,3),  intent(out) :: transfm
32078    !!----
32079    !!----    Subroutine for getting the primitive cell from a centred cell
32080    !!----    On input Lat_type is the lattice type: P,A,B,C,I,R or F
32081    !!----    Centred_cell is the Crystal_Cell_Type of the input lattice
32082    !!----    The subroutine calculates the transformation matric "transfm"
32083    !!----    and provides the complete description of the primitive cell
32084    !!----    in the object, of type Crystal_Cell_Type, primitive_cell.
32085    !!----
32086    !!---- Update: April - 2008
32087    !!
32088    Subroutine Get_Primitive_Cell(Lat_Type,Centred_Cell,Primitive_Cell,Transfm)
32089       !---- Arguments ----!
32090       character(len=*),              intent(in)  :: lat_type
32091       type(Crystal_Cell_Type),       intent(in)  :: centred_cell
32092       type(Crystal_Cell_Type),       intent(out) :: primitive_cell
32093       real(kind=cp), dimension(3,3), intent(out) :: transfm
32094
32095       !---- Local variables ----!
32096       integer                       :: i
32097       real(kind=cp), dimension(3)   :: celp,celang
32098       real(kind=cp), dimension(3,3) :: cart,metric
32099       character(len=1)              :: lat
32100
32101       lat=adjustl(lat_type)
32102       Select Case(lat)
32103          case("a","A")
32104             transfm= reshape((/1.0,0.0,0.0,  0.0,0.5,0.5,  0.0,-0.5,0.5/),(/3,3/))
32105          case("b","B")
32106             transfm= reshape((/0.5,0.0,0.5,  0.0,1.0,0.0, -0.5, 0.0,0.5/),(/3,3/))
32107          case("c","C")
32108             transfm= reshape((/0.5,0.5,0.0, -0.5,0.5,0.0,  0.0, 0.0,1.0/),(/3,3/))
32109          case("i","I")
32110             transfm= reshape((/1.0,0.0,0.0,  0.0,1.0,0.0,  0.5, 0.5,0.5/),(/3,3/))
32111          case("r","R")
32112             transfm= reshape((/2.0/3.0, 1.0/3.0, 1.0/3.0,  &
32113                               -1.0/3.0, 1.0/3.0, 1.0/3.0,  &
32114                               -1.0/3.0,-2.0/3.0, 1.0/3.0/),(/3,3/))
32115          case("f","F")
32116             transfm= reshape((/0.5,0.0,0.5,  0.5,0.5,0.0,  0.0, 0.5,0.5/),(/3,3/))
32117          case default  !assumed primitive
32118             primitive_cell=centred_cell
32119             transfm= reshape((/1.0,0.0,0.0,  0.0,1.0,0.0,  0.0,0.0,1.0/),(/3,3/))
32120             return
32121       End Select
32122       transfm=transpose(transfm)
32123       cart=matmul(transfm,transpose(Centred_Cell%Cr_Orth_cel))
32124       metric=matmul(cart,transpose(cart))
32125
32126       !---- Calculate new cell parameters from the new metric tensor
32127       do i=1,3
32128          Celp(i)=sqrt(metric(i,i))
32129       end do
32130
32131       celang(1)=acosd(metric(2,3)/(celp(2)*celp(3)))
32132       celang(2)=acosd(metric(1,3)/(celp(1)*celp(3)))
32133       celang(3)=acosd(metric(1,2)/(celp(1)*celp(2)))
32134       call Set_Crystal_Cell(celp,celang,primitive_cell)
32135
32136       return
32137    End Subroutine Get_Primitive_Cell
32138
32139    !!----
32140    !!---- Subroutine Get_Transfm_Matrix(cella,cellb,trm,ok,tol)
32141    !!----    type(Crystal_Cell_Type),     intent(in) :: cella,cellb
32142    !!----    real(kind=cp),dimension(3,3),intent(out):: trm
32143    !!----    Logical,                     intent(out):: ok
32144    !!----    real(kind=cp),optional,      intent(in) :: tol
32145    !!----
32146    !!----    Subroutine for getting the transformation matrix between two
32147    !!----    primitive unit cells (the range of indices is fixed to -2 to 2)
32148    !!----
32149    !!---- Update: January - 2011
32150    !!
32151    Subroutine Get_Transfm_Matrix(cella,cellb,trm,ok,tol)
32152       !---- Arguments ----!
32153       type(Crystal_Cell_Type),     intent(in) :: cella,cellb
32154       real(kind=cp),dimension(3,3),intent(out):: trm
32155       Logical,                     intent(out):: ok
32156       real(kind=cp),optional,      intent(in) :: tol
32157
32158       !---- Local variables ----!
32159       type(Crystal_Cell_Type) :: Cellt
32160       integer,dimension(3,3)  :: Nu
32161       integer                 :: j,i1,i2,i3,i4,i5,i6,i7,i8,i9
32162       real(kind=cp)           :: tolt
32163
32164       tolt=0.3
32165       if(present(tol)) tolt=tol
32166       ok=.false.
32167       dox: do i1=-2,2                     !         |i1  i4  i7|
32168          do i2=-2,2                       !    Nu = |i2  i5  i8|
32169             do i3=-2,2                    !         |i3  i6  i9|
32170                do i4=-2,2
32171                   do i5=-2,2
32172                      do i6=-2,2
32173                         do i7=-2,2
32174                            do i8=-2,2
32175                               do i9=-2,2
32176                                  j=i1*i5*i9+i4*i8*i3+i2*i6*i7-i3*i5*i7-i8*i6*i1-i2*i4*i9     !determinant (much faster than calling determ_A)
32177                                  if ( j /= 1) cycle
32178                                  Nu=reshape((/i1,i2,i3,i4,i5,i6,i7,i8,i9/),(/3,3/))
32179                                  Trm=real(Nu)
32180                                  call Change_Setting_Cell(Cella,Trm,Cellt)
32181                                  if (Sum(abs(Cellt%cell(:)-Cellb%cell(:)))+Sum(abs(Cellt%ang(:)-Cellb%ang(:))) < tolt  ) then
32182                                     ok=.true.
32183                                     exit dox
32184                                  end if
32185                               end do    !i9
32186                            end do     !i8
32187                         end do      !i7
32188                      end do       !i6
32189                   end do        !i5
32190                end do         !i4
32191             end do          !i3
32192          end do           !i2
32193       end do  dox       !i1
32194
32195       return
32196    End Subroutine Get_Transfm_Matrix
32197
32198    !!----
32199    !!---- Subroutine Get_TwoFold_Axes(Celln,Tol,Twofold)
32200    !!----    type(Crystal_Cell_Type), intent (in) :: Celln
32201    !!----    real(kind=cp),           intent (in) :: tol !angular tolerance in degrees
32202    !!----    Type(Twofold_Axes_Type), intent(out) :: twofold
32203    !!----
32204    !!----    Subroutine for getting the possible two-fold axes (within an
32205    !!----    angular tolerance tol) existing in the lattice generated by the
32206    !!----    unit cell "Celln". Strictly independent two-fold axes are stored
32207    !!----    in the variable "twofold" that is of type Twofold_Axes_Type
32208    !!----    The output order of the two-fold axes is ascending in their
32209    !!----    modulus. Shorter vectors appears before longer ones.
32210    !!----    The conditions for a reciprocal or direct row to be a two-fold
32211    !!----    axis are discussed by Y. Le Page in J.Appl.Cryst. 15, 255 (1982).
32212    !!----
32213    !!----
32214    !!---- Update: November - 2008
32215    !!
32216    Subroutine Get_TwoFold_Axes(Celln,Tol,Twofold)
32217       !---- Arguments ----!
32218       type(Crystal_Cell_Type), intent (in) :: Celln
32219       real(kind=cp),           intent (in) :: Tol !angular tolerance in degrees
32220       Type(twofold_axes_type), intent(out) :: Twofold
32221
32222       !---- Local variables ----!
32223       integer                        :: i,j,n,m, ih,ik,il,iu,iv,iw,imax,ntwo
32224       real(kind=cp), dimension(3)    :: dv, rv, a, b, c, as, bs, cs, cross
32225       real(kind=cp), dimension(  12) :: maxes,crossa
32226       integer, dimension(  12)       :: dota,ind
32227       real(kind=cp), dimension(3,12) :: caxes
32228       integer, dimension(3,12)       :: dtw,rtw
32229       integer, dimension(3)          :: v,h
32230       real(kind=cp)                  :: dot,crossm
32231
32232       maxes=0.0; crossa=0.0; dota=0; caxes=0.0; dtw=0; rtw=0
32233       a=Celln%Cr_Orth_cel(:,1)
32234       b=Celln%Cr_Orth_cel(:,2)
32235       c=Celln%Cr_Orth_cel(:,3)
32236       twofold%a=a
32237       twofold%b=b
32238       twofold%c=c
32239       as=cross_product(b,c)/Celln%CellVol !Reciprocal lattice vectors in
32240       bs=cross_product(c,a)/Celln%CellVol !Cartesian components
32241       cs=cross_product(a,b)/Celln%CellVol
32242       ntwo=0
32243       imax=2   !Is inough if the input cell is the Buerger or Niggli cell
32244
32245       do_iu: do iu=imax, 0,-1
32246          do iv=imax,-imax,-1
32247             do iw=imax,-imax,-1
32248                v=(/iu,iv,iw/)
32249                if (.not. Co_Prime(v,2)) cycle
32250                do ih=imax,0,-1
32251                   do ik=imax,-imax,-1
32252                      do_il:do il=imax,-imax,-1
32253                         h=(/ih,ik,il/)
32254                         if (.not. Co_Prime(h,2)) cycle
32255                         n=abs(ih*iu+ik*iv+il*iw)
32256                         if ( n == 2 .or. n == 1) then
32257                            dv=real(iu)*a+real(iv)*b+real(iw)*c
32258                            rv=real(ih)*as+real(ik)*bs+real(il)*cs
32259                            cross=cross_product(dv,rv)
32260                            dot=sqrt(dot_product(cross,cross))
32261                            crossm=atand(dot/real(n))
32262                            if (abs(crossm) <= tol) then
32263                               do m=1,ntwo
32264                                  if (determ_V((/17,41,71/),v,dtw(:,m) ) == 0) cycle do_il
32265                               end do
32266                               ntwo=ntwo+1
32267                               dtw(:,ntwo)= v
32268                               dv=v(1)*a+v(2)*b+v(3)*c
32269                               caxes(:,ntwo)=dv
32270                               maxes(ntwo)=sqrt(dot_product(dv,dv))
32271                               rtw(:,ntwo)= h
32272                               dota(ntwo)=n
32273                               crossa(ntwo)=crossm
32274                            end if
32275                            if (ntwo == 12) exit do_iu
32276                         end if
32277                      end do do_il
32278                   end do
32279                end do
32280             end do
32281          end do
32282       end do do_iu
32283       call sort(maxes,ntwo,ind)
32284       do i=1,ntwo
32285          j=ind(i)
32286          twofold%dtwofold(:,i)= dtw(:,j)
32287          twofold%caxes(:,i)= caxes(:,j)
32288          twofold%maxes(i)= maxes(j)
32289          twofold%rtwofold(:,i)= rtw(:,j)
32290          twofold%dot(i)= dota(j)
32291          twofold%cross(i)= crossa(j)
32292       End do
32293       twofold%ntwo=ntwo
32294       twofold%tol=tol
32295
32296       return
32297    End Subroutine Get_TwoFold_Axes
32298
32299    !!----
32300    !!---- SUBROUTINE INIT_ERR_CRYS()
32301    !!----
32302    !!----    Initialize Flags of Errors in this module
32303    !!----
32304    !!---- Update: February - 2005
32305    !!
32306    Subroutine Init_Err_Crys()
32307
32308       Err_Crys=.false.
32309       ERR_Crys_Mess=" "
32310
32311       return
32312    End Subroutine Init_Err_Crys
32313
32314    !!----
32315    !!---- Subroutine Niggli_Cell(XXX,Niggli_Point,Celln,Trans)
32316    !!----   XXX is one of:
32317    !!----   real(kind=cp),dimension(6),              intent(in out) :: Ad             ! Cell Parameters
32318    !!----   or
32319    !!----   real(kind=cp),dimension(2,3),            intent(in out) :: N_Mat          ! Niggli Matrix
32320    !!----   or
32321    !!----   real(kind=cp)                            intent(in out) :: A, B, C, Alfa, Beta, Gamma
32322    !!----   or
32323    !!----   type(Crystal_Cell_Type),                 intent(in out ):: cell
32324    !!----   or
32325    !!----   real(kind=cp),dimension(3),              intent(in)     :: A,B,C         ! 3 vectors
32326    !!----   real(kind=cp),dimension(5), optional,    intent(out)    :: Niggli_Point
32327    !!----   type(Crystal_Cell_Type),optional,        intent(out)    :: Celln
32328    !!----   real(kind=cp), dimension(3,3), optional, intent(out)    :: Trans
32329    !!----
32330    !!----    Calculates the Niggli cell
32331    !!----
32332    !!---- Update: October - 2008
32333    !!
32334
32335    !!--++
32336    !!--++ Subroutine Niggli_Cell_ABC(Ad,Niggli_Point,Celln,Trans)
32337    !!--++    real(kind=cp),dimension(6),              intent(in out) :: Ad
32338    !!--++    real(kind=cp),dimension(5), optional,    intent(out)    :: Niggli_Point
32339    !!--++    type(Crystal_Cell_Type),optional,        intent(out)    :: celln
32340    !!--++    real(kind=cp), dimension(3,3), optional, intent(out)    :: trans
32341    !!--++
32342    !!--++    (OVERLOADED)
32343    !!--++    Calculates the Niggli cell when the input is the list of cell parameters
32344    !!--++    provided as a 6D vector. Calls the subroutine Niggli_Cell_Nigglimat for
32345    !!--++    the effective calculations
32346    !!--++
32347    !!--++ Update: October - 2008
32348    !!
32349    Subroutine Niggli_Cell_ABC(Ad,Niggli_Point,Celln,Trans)    !Scalar algorithm
32350       !---- Arguments ----!
32351       real(kind=cp),dimension(6),              intent(in out) :: ad
32352       real(kind=cp),dimension(5), optional,    intent(out)    :: Niggli_Point
32353       type(Crystal_Cell_Type),optional,        intent(out)    :: celln
32354       real(kind=cp), dimension(3,3), optional, intent(out)    :: trans
32355
32356       !---- Local variables ----!
32357       real(kind=cp), dimension(2,3)    :: n_mat
32358       type(Crystal_Cell_Type)          :: celda
32359
32360       n_mat(1,1)=ad(1)*ad(1)
32361       n_mat(1,2)=ad(2)*ad(2)
32362       n_mat(1,3)=ad(3)*ad(3)
32363       n_mat(2,1)=ad(2)*ad(3)*cosd(ad(4))
32364       n_mat(2,2)=ad(1)*ad(3)*cosd(ad(5))
32365       n_mat(2,3)=ad(1)*ad(2)*cosd(ad(6))
32366
32367       if (present(Niggli_Point)) then
32368          if (present(trans)) then
32369             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda,trans)
32370          else
32371             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda)
32372          end if
32373       else if(present(trans)) then
32374          call Niggli_Cell_nigglimat(n_mat,celln=celda,trans=trans)
32375       else
32376          call Niggli_Cell_nigglimat(n_mat,celln=celda)
32377       end if
32378
32379       if (Err_Crys) return
32380       if (present(celln)) celln=celda
32381
32382       !Reconstruct the new cell (Niggli Cell)
32383       ad(1) = sqrt(n_mat(1,1))
32384       ad(2) = sqrt(n_mat(1,2))
32385       ad(3) = sqrt(n_mat(1,3))
32386       ad(4) = acosd(n_mat(2,1)/(ad(2)*ad(3)))
32387       ad(5) = acosd(n_mat(2,2)/(ad(1)*ad(3)))
32388       ad(6) = acosd(n_mat(2,3)/(ad(1)*ad(2)))
32389
32390       return
32391    End Subroutine Niggli_Cell_abc
32392
32393    !!--++
32394    !!--++ Subroutine Niggli_Cell_Nigglimat(N_Mat,Niggli_Point,Celln,Trans)    !Scalar algorithm
32395    !!--++    real(kind=cp),dimension(2,3),              intent(in out) :: n_mat
32396    !!--++    real(kind=cp),dimension(5),      optional, intent(out)    :: Niggli_Point
32397    !!--++    type(Crystal_Cell_Type), optional,         intent(out)    :: celln
32398    !!--++    real(kind=cp), dimension(3,3),   optional, intent(out)    :: trans
32399    !!--++
32400    !!--++    (OVERLOADED)
32401    !!--++    Calculates the Niggli cell when the input is the Niggli Matrix (part of the metrics)
32402    !!--++    of a primitive cell. Applies the scalar algorithm of
32403    !!--++    I. Krivy and B. Gruber, Acta Cryst A32, 297 (1976)
32404    !!--++    If Trans is present, Celln should also be present.
32405    !!--++
32406    !!--++ Update: January - 2011
32407    !!
32408    Subroutine Niggli_Cell_Nigglimat(N_Mat,Niggli_Point,Celln,Trans)    !Scalar algorithm
32409       !---- Arguments ----!
32410       real(kind=cp),dimension(2,3),              intent(in out) :: n_mat
32411       real(kind=cp),dimension(5),      optional, intent(out)    :: Niggli_Point
32412       type(Crystal_Cell_Type),         optional, intent(out)    :: celln
32413       real(kind=cp), dimension(3,3),   optional, intent(out)    :: trans
32414
32415       !--- Local variables ---!
32416       type(Crystal_Cell_Type)       :: Cellp
32417       real(kind=cp)                 :: A,B,C,u,v,w,eps
32418       real(kind=cp), dimension(3,3) :: trm
32419       real(kind=cp), dimension(3)   :: cel,ang
32420       integer                       :: iu,iv,iw, ncount ! ncount is the counter no more that Numiter=100
32421                                                         ! iterations are permitted. In case of exhausting
32422                                                         ! the iteration Err_Crys=.true. but the current
32423                                                         ! cell is output anyway
32424       real(kind=cp),parameter        :: epr=0.0001      !Relative epsilon
32425       integer, parameter             :: numiter=100
32426       logical                        :: ok
32427
32428       ! N is a Niggli cell of L if  (i) it is as Buerger cell of L and
32429       !                            (ii) |90-alpha| + |90-beta| + |90-gamma| -> maximum
32430       !                  / a.a  b.b  c.c \       /  s11  s22  s33 \
32431       !   Niggli matrix  |               |   =   |                |
32432       !                  \ b.c  a.c  a.b /       \  s23  s13  s12 /
32433       !
32434       ! I. Krivy and B. Gruber, Acta Cryst A32, 297 (1976)
32435       ! Krivy-Gruber algorithms safely implemented (suggestion of Ralf Grosse-Kunsleve)
32436       ! R.W. Grosse-Kunstleve, N. K. Sauter and P. D. Adams, Acta Cryst A60, 1-6 (2004)
32437       ! Epsilon: e
32438       !    x < y -> x < y-e;    x > y -> y < x-e
32439       !   x <= y -> .not. y < x-e;   x >= y -> .not. x < y-e
32440       !   x == y -> .not. (x < y-e .or. y < x-e)
32441       !
32442       A=n_mat(1,1)
32443       B=n_mat(1,2)
32444       C=n_mat(1,3)
32445       u=2.0*n_mat(2,1)
32446       v=2.0*n_mat(2,2)
32447       w=2.0*n_mat(2,3)
32448       eps=epr*(A*B*C)**(1.0/6.0)
32449       ncount=0
32450       ok=.true.
32451       if (present(trans)) then
32452          !Construct the input cell Cellp from its Niggli parameters
32453          cel(1) = sqrt(A)
32454          cel(2) = sqrt(B)
32455          cel(3) = sqrt(C)
32456          ang(1) = acosd(u/(cel(2)*cel(3)*2.0))
32457          ang(2) = acosd(v/(cel(1)*cel(3)*2.0))
32458          ang(3) = acosd(w/(cel(1)*cel(2)*2.0))
32459          call Set_Crystal_Cell(cel,ang, Cellp)
32460       end if
32461
32462       do
32463          ncount=ncount+1
32464          if (ncount > numiter) then
32465             ok=.false.
32466             exit
32467          end if
32468
32469          !---- if(A > B .or. ( A == B  .and. abs(u) > abs(v)) ) then  ! A1
32470          if (B < A-eps .or. ( .not.( A < B-eps .or. B < A-eps)  .and. abs(v) < abs(u)-eps ) ) then  ! A1
32471             call swap(A,B)
32472             call swap(u,v)
32473          end if
32474
32475          !---- if(B > C .or. ( B == C .and. abs(v) > abs(w)) ) then  ! A2
32476          if (C < B-eps .or. ( .not.( C < B-eps .or. B < C-eps) .and. abs(w) < abs(v)-eps) ) then  ! A2
32477             call swap(B,C)
32478             call swap(v,w)
32479             cycle
32480          end if
32481
32482          !---- if (u*v*w > 0.0) then                                 ! A3
32483          iu=1; iv=1; iw=1
32484          if ( u < -eps) iu=-1
32485          if ( v < -eps) iv=-1
32486          if ( w < -eps) iw=-1
32487          if (abs(u) < eps) iu=0
32488          if (abs(v) < eps) iv=0
32489          if (abs(w) < eps) iw=0
32490          if (iu*iv*iw > 0) then                                      ! A3
32491             u=abs(u)
32492             v=abs(v)
32493             w=abs(w)
32494          else                                                        ! A4
32495             u=-abs(u)
32496             v=-abs(v)
32497             w=-abs(w)
32498          end if
32499
32500          !---- if( abs(u) > B .or. ( u == B .and. 2.0*v < w) .or. ( u == -B .and. w < 0.0)) then  ! A5
32501          if ( B < abs(u)-eps  .or. ( .not.(u < B-eps .or. B < u-eps) .and. 2.0*v < w-eps) .or. &
32502             ( .not.(u < -B-eps .or. -B < u-eps) .and. w < -eps)) then  ! A5
32503             iu=1; if( u < -eps) iu=-1
32504             C = B+C - u * iu
32505             v =  v  - w * iu
32506             u = u - 2.0*B*iu
32507             cycle
32508          end if
32509
32510          !---- if( abs(v) > A .or. ( v == A .and. 2.0*u < w) .or. ( v == -A .and. w < 0.0)) then  ! A6
32511          if ( A < abs(v)-eps .or. (.not. (v < A-eps .or. A < v-eps) .and. 2.0*u < w-eps) .or. &
32512             ( .not.( v < -A-eps .or. -A < v-eps) .and. w < -eps)) then  ! A6
32513             iv=1; if( v < -eps) iv=-1
32514             C = A+C - v * iv
32515             u =  u  - w * iv
32516             v = v - 2.0*A*iv
32517             cycle
32518          end if
32519
32520          !---- if( abs(w) > A .or. ( w == A .and. 2.0*u < v) .or. ( w == -A .and. v < 0.0)) then  ! A7
32521          if ( A < abs(w)-eps .or. ( .not. (w < A-eps .or. A < w-eps) .and. 2.0*u < v-eps) .or. &
32522             ( .not. (w < -A-eps .or. -A < w-eps) .and. v < -eps)) then  ! A7
32523             iw=1; if( w < -eps) iw=-1
32524             B = A+B - w * iw
32525             u =  u  - v * iw
32526             w = w - 2.0*A*iw
32527             cycle
32528          end if
32529
32530          !---- if(u+v+w+A+B < 0.0 .or. (u+v+w+A+B == 0.0 .and. 2.0*(A+v)+w > 0.0 )) then  ! A8
32531          if (u+v+w+A+B < -eps .or. ( abs(u+v+w+A+B) < eps .and. 2.0*(A+v)+w > eps )) then  ! A8
32532             C=A+B+C+u+v+w
32533             u=2.0*B+u+w
32534             v=2.0*A+v+w
32535             cycle
32536          end if
32537          exit
32538       end do
32539
32540       !---- Reconstruct the new Niggli matrix
32541       n_mat(1,1)=A; n_mat(1,2)=B; n_mat(1,3)=C
32542       n_mat(2,1)=0.5*u; n_mat(2,2)=0.5*v; n_mat(2,3)=0.5*w
32543
32544       if (.not. ok) Then
32545          Err_Crys=.true.
32546          ERR_Crys_Mess=" The limit of iterations in Niggli_Cell_NiggliMat has been reached!"
32547          return
32548       end if
32549
32550       if (present(Niggli_point)) then
32551          Niggli_point(1)= A/C
32552          Niggli_point(2)= B/C
32553          Niggli_point(3)= u/C
32554          Niggli_point(4)= v/C
32555          Niggli_point(5)= w/C
32556       end if
32557
32558       if (present(celln)) then
32559          !Reconstruct the new cell (Niggli Cell)
32560          cel(1) = sqrt(A)
32561          cel(2) = sqrt(B)
32562          cel(3) = sqrt(C)
32563          ang(1) = acosd(u/(cel(2)*cel(3)*2.0))
32564          ang(2) = acosd(v/(cel(1)*cel(3)*2.0))
32565          ang(3) = acosd(w/(cel(1)*cel(2)*2.0))
32566          call Set_Crystal_Cell(cel,ang, Celln)
32567          if (present(trans)) then
32568            Call Get_Transfm_Matrix(cellp,celln,trm,ok)
32569            if(ok) then
32570              trans=trm
32571            else
32572              trans=identity
32573            end if
32574          end if
32575       end if
32576
32577       return
32578    End Subroutine Niggli_Cell_nigglimat
32579
32580    !!--++
32581    !!--++ Subroutine Niggli_Cell_Params(A,B,C,Al,Be,Ga,Niggli_Point,Celln,Trans)
32582    !!--++    real(kind=cp),                           intent (in out)  :: a,b,c,al,be,ga
32583    !!--++    real(kind=cp),dimension(5), optional,    intent(out)      :: Niggli_Point
32584    !!--++    type(Crystal_Cell_Type),optional,        intent(out)      :: celln
32585    !!--++    real(kind=cp), dimension(3,3), optional, intent(out)      :: trans
32586    !!--++
32587    !!--++    (OVERLOAD)
32588    !!--++     Calculates the Niggli cell when the input is the list of cell parameters
32589    !!--++     provided as six scalars.
32590    !!--++     Calls the subroutine Niggli_Cell_Nigglimat for the effective calculations
32591    !!--++
32592    !!--++ Update: October - 2008
32593    !!
32594    Subroutine Niggli_Cell_Params(A,B,C,Al,Be,Ga,Niggli_Point,Celln,Trans)
32595       !---- Arguments ----!
32596       real(kind=cp),                           intent (in out)  :: a,b,c,al,be,ga
32597       real(kind=cp),dimension(5), optional,    intent(out)      :: Niggli_Point
32598       type(Crystal_Cell_Type), optional,       intent(out)      :: celln
32599       real(kind=cp), dimension(3,3), optional, intent(out)      :: trans
32600
32601       !--- Local variables ---!
32602       type(Crystal_Cell_Type)          :: celda
32603       real(kind=cp), dimension(2,3)    :: n_mat
32604
32605
32606       call Init_Err_Crys()
32607       if ( al+be < ga+1.0  .or. al+ga < be+1.0 .or. be+ga < al+1.0) then
32608          Err_Crys=.true.
32609          ERR_Crys_Mess=" The provided angles cannot set a unit cell!"
32610          return
32611       end if
32612
32613       call Set_Crystal_Cell((/a,b,c/),(/al,be,ga/), Celda)
32614       if (Err_Crys) return
32615
32616       n_mat(1,1)=Celda%GD(1,1); n_mat(1,2)=Celda%GD(2,2); n_mat(1,3)=Celda%GD(3,3)
32617       n_mat(2,1)=Celda%GD(2,3); n_mat(2,2)=Celda%GD(1,3); n_mat(2,3)=Celda%GD(1,2)
32618
32619       if (present(Niggli_Point)) then
32620          if (present(trans)) then
32621             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda,trans)
32622          else
32623             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda)
32624          end if
32625       else if(present(trans)) then
32626          call Niggli_Cell_nigglimat(n_mat,celln=celda,trans=trans)
32627       else
32628          call Niggli_Cell_nigglimat(n_mat,celln=celda)
32629       end if
32630       if (Err_Crys) return
32631
32632       if (present(celln)) then
32633          celln=celda
32634       else
32635           a=celda%cell(1); b=celda%cell(2); c=celda%cell(3)
32636          al=celda%ang(1); be=celda%ang(2); ga=celda%ang(3)
32637       end if
32638
32639       return
32640    End Subroutine Niggli_Cell_Params
32641
32642    !!--++
32643    !!--++ Subroutine Niggli_Cell_Type(Cell,Niggli_Point,Celln,Trans)
32644    !!--++    type(Crystal_Cell_Type),                 intent(in out ) :: cell
32645    !!--++    real(kind=cp),dimension(5),    optional, intent(out)     :: Niggli_Point
32646    !!--++    type(Crystal_Cell_Type),       optional, intent(out)     :: celln
32647    !!--++    real(kind=cp), dimension(3,3), optional, intent(out)     :: trans
32648    !!--++
32649    !!--++
32650    !!--++    (OVERLOADED)
32651    !!--++    Calculates the Niggli cell when the input is an object of type Crystal_Cell_Type
32652    !!--++    Calls the subroutine Niggli_Cell_Nigglimat for the effective calculations
32653    !!--++
32654    !!--++ Update: October - 2008
32655    !!
32656    Subroutine Niggli_Cell_Type(Cell,Niggli_Point,Celln,Trans)
32657       !---- Arguments ----!
32658       type(Crystal_Cell_Type),                 intent(in out ) :: cell
32659       real(kind=cp),dimension(5),    optional, intent(out)     :: Niggli_Point
32660       type(Crystal_Cell_Type),       optional, intent(out)     :: celln
32661       real(kind=cp), dimension(3,3), optional, intent(out)     :: trans
32662
32663       !--- Local variables ---!
32664       type(Crystal_Cell_Type)         :: celda
32665       real(kind=cp), dimension(2,3)   :: n_mat
32666
32667       call Init_Err_Crys()
32668       celda=cell
32669       n_mat(1,1)=Celda%GD(1,1); n_mat(1,2)=Celda%GD(2,2); n_mat(1,3)=Celda%GD(3,3)
32670       n_mat(2,1)=Celda%GD(2,3); n_mat(2,2)=Celda%GD(1,3); n_mat(2,3)=Celda%GD(1,2)
32671
32672       if (present(Niggli_Point)) then
32673          if (present(trans)) then
32674             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda,trans)
32675          else
32676             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda)
32677          end if
32678       else if(present(trans)) then
32679          call Niggli_Cell_nigglimat(n_mat,celln=celda,trans=trans)
32680       else
32681          call Niggli_Cell_nigglimat(n_mat,celln=celda)
32682       end if
32683       if (Err_Crys) return
32684
32685       if (present(celln)) then
32686          celln=celda
32687       else
32688          cell=celda
32689       end if
32690
32691       return
32692    End Subroutine Niggli_Cell_Type
32693
32694    !!--++
32695    !!--++ Subroutine Niggli_Cell_Vect(A,B,C,Niggli_Point,Celln,Trans)
32696    !!--++    real(kind=cp),dimension(3),                intent(in)     :: a,b,c
32697    !!--++    real(kind=cp),dimension(5),      optional, intent(out)    :: Niggli_Point
32698    !!--++    type(Crystal_Cell_Type),         optional, intent(out)    :: celln
32699    !!--++    real(kind=cp), dimension(3,3),   optional, intent(out)    :: trans
32700    !!--++
32701    !!--++    (OVERLOADED)
32702    !!--++    Calculates the Niggli cell when the input is given as three vectors
32703    !!--++    in Cartesian components. A test of linear indenpendency is performed.
32704    !!--++    Calls the subroutine Niggli_Cell_Nigglimat for the effective calculations
32705    !!--++
32706    !!--++ Update: October - 2008
32707    !!
32708    Subroutine Niggli_Cell_Vect(A,B,C,Niggli_Point,Celln,Trans)
32709       !---- Arguments ----!
32710       real(kind=cp),dimension(3),                intent(in)     :: a,b,c
32711       real(kind=cp),dimension(5),      optional, intent(out)    :: Niggli_Point
32712       type(Crystal_Cell_Type),         optional, intent(out)    :: celln
32713       real(kind=cp), dimension(3,3),   optional, intent(out)    :: trans
32714
32715       !--- Local variables ---!
32716       type(Crystal_Cell_Type)       :: celda
32717       real(kind=cp), dimension(2,3) :: n_mat
32718       real(kind=cp)                 :: det
32719
32720       det=determ_V(a,b,c)
32721       if (abs(det) < 0.0001) then
32722          Err_Crys=.true.
32723          ERR_Crys_Mess=" The three input vectors are nor linearly independent!"
32724          return
32725       end if
32726       n_mat(1,1)=dot_product(a,a); n_mat(1,2)=dot_product(b,b); n_mat(1,3)=dot_product(c,c)
32727       n_mat(2,1)=dot_product(b,c); n_mat(2,2)=dot_product(a,c); n_mat(2,3)=dot_product(a,b)
32728
32729       if (present(Niggli_Point)) then
32730          if (present(trans)) then
32731             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda,trans)
32732          else
32733             call Niggli_Cell_nigglimat(n_mat,Niggli_Point,celda)
32734          end if
32735       else if(present(trans)) then
32736          call Niggli_Cell_nigglimat(n_mat,celln=celda,trans=trans)
32737       else
32738          call Niggli_Cell_nigglimat(n_mat,celln=celda)
32739       end if
32740       if (Err_Crys) return
32741       if (present(celln)) celln=celda
32742
32743       return
32744    End Subroutine Niggli_Cell_Vect
32745
32746    !!----
32747    !!---- Subroutine Read_Bin_Crystal_Cell(Celda,Lun,ok)
32748    !!----    Type (Crystal_Cell_Type),  intent(out) :: Celda   ! Out -> Cell variable
32749    !!----    Integer,                   intent(in)  :: lun     !  In -> Unit to write
32750    !!----    logical,                   intent(out) :: ok
32751    !!----
32752    !!----    Reads the cell characteristics in a binary file associated to the
32753    !!----    logical unit lun. The file is supposed to be opened with form="unformatted",
32754    !!----    access="stream" or equivalent
32755    !!----
32756    !!----    Updated: February - 2013
32757    !!
32758    Subroutine Read_Bin_Crystal_Cell(Celda,Lun,ok)
32759       !---- Arguments ----!
32760       Type (Crystal_Cell_Type),  intent(out) :: Celda
32761       Integer,                   intent(in)  :: Lun
32762       logical,                   intent(out) :: ok
32763       integer :: ier
32764       ok=.true.
32765       read(unit=lun,iostat=ier)             &
32766                       Celda%cell,           &
32767                       Celda%ang,            &
32768                       Celda%cell_std,       &
32769                       Celda%ang_std,        &
32770                       Celda%rcell,          &
32771                       Celda%rang,           &
32772                       Celda%GD,Celda%GR,    &
32773                       Celda%Cr_Orth_cel,    &
32774                       Celda%Orth_Cr_cel,    &
32775                       Celda%BL_M,           &
32776                       Celda%BL_Minv,        &
32777                       Celda%CellVol,        &
32778                       Celda%RCellVol,       &
32779                       Celda%CartType
32780       if( ier /= 0) ok=.false.
32781       return
32782    End Subroutine Read_Bin_Crystal_Cell
32783
32784
32785    !!--++
32786    !!--++ Subroutine Recip(A,Ang,Ar,Angr,Vol,Volr)
32787    !!--++    real(kind=cp), dimension(3), intent(in ) :: a        !  In -> a,b,c
32788    !!--++    real(kind=cp), dimension(3), intent(in ) :: ang      !  In -> alpha,beta,gamma
32789    !!--++    real(kind=cp), dimension(3), intent(out) :: ar       !  In -> a*,b*,c*
32790    !!--++    real(kind=cp), dimension(3), intent(out) :: angr     !  In -> alpha*,beta*,gamma*
32791    !!--++    real(kind=cp),               intent(out) :: vol      ! Out -> Vol
32792    !!--++    real(kind=cp),               intent(out) :: volr     ! Out -> Vol*
32793    !!--++
32794    !!--++    (PRIVATE)
32795    !!--++    Calculates the reciprocal lattice vectors and cell volume
32796    !!--++
32797    !!--++ Update: February - 2005
32798    !!
32799    Subroutine Recip(A,Ang,Ar,Angr,Vol,Volr)
32800       !---- Arguments ----!
32801       real(kind=cp), dimension(3), intent(in ) :: a,ang
32802       real(kind=cp), dimension(3), intent(out) :: ar,angr
32803       real(kind=cp),               intent(out) :: vol,volr
32804
32805       !---- Local Variables ----!
32806       integer        :: i
32807       real(kind=cp)  :: s,p,cose
32808
32809       p=1.0
32810       s=1.0
32811       do i=1,3
32812          cose=cosd(ang(i))
32813          p=p*cose
32814          s=s-cose*cose
32815       end do
32816       vol=sqrt(abs(s+2.0*p))
32817
32818       do i=1,3
32819          vol=vol*a(i)
32820       end do
32821       volr=1.0/vol
32822
32823       ar(1)=a(2)*a(3)*sind(ang(1))/vol
32824       ar(2)=a(3)*a(1)*sind(ang(2))/vol
32825       ar(3)=a(1)*a(2)*sind(ang(3))/vol
32826       angr(1)=(cosd(ang(2))*cosd(ang(3))-cosd(ang(1)))/(sind(ang(2))*sind(ang(3)))
32827       angr(2)=(cosd(ang(1))*cosd(ang(3))-cosd(ang(2)))/(sind(ang(1))*sind(ang(3)))
32828       angr(3)=(cosd(ang(2))*cosd(ang(1))-cosd(ang(3)))/(sind(ang(2))*sind(ang(1)))
32829       do i=1,3
32830          angr(i)=acosd(angr(i))
32831       end do
32832
32833       return
32834    End Subroutine Recip
32835
32836    !!----
32837    !!---- Subroutine Set_Crystal_Cell(Cellv,Angl,Celda,Cartype,Scell,Sangl)
32838    !!----    real(kind=cp), dimension (3),        intent(in ) :: cellv   !  In -> a,b,c
32839    !!----    real(kind=cp), dimension (3),        intent(in ) :: angl    !  In -> angles of cell parameters
32840    !!----    Type (Crystal_Cell_Type),            intent(out) :: Celda   !  Out-> Celda components
32841    !!----    character (len=1),          optional,intent(in ) :: CarType !  In -> Type of Cartesian Frame
32842    !!----    real(kind=cp), dimension(3),optional,intent(in ) :: scell,sangl
32843    !!----
32844    !!----    Constructs the object "Celda" of type Crystal_Cell. Control for error
32845    !!----    is present
32846    !!----
32847    !!---- Update: February - 2005
32848    !!
32849    Subroutine Set_Crystal_Cell(Cellv,Angl,Celda,Cartype,Scell,Sangl)
32850       !---- Arguments ----!
32851       real(kind=cp), dimension (3),        intent(in ) :: cellv, angl
32852       Type (Crystal_Cell_Type),            intent(out) :: Celda
32853       character (len=1),          optional,intent(in ) :: CarType
32854       real(kind=cp), dimension(3),optional,intent(in ) :: scell,sangl
32855
32856       !---- Local Variables ----!
32857       integer :: ifail
32858
32859       call Init_Err_Crys()
32860
32861       if (present(scell) .and. present(sangl)) then
32862          Celda%cell_std=scell
32863          Celda%ang_std=sangl
32864       else
32865          Celda%cell_std=0.0
32866          Celda%ang_std=0.0
32867          Celda%lcell=0    !These codes are attributed in refinement programs
32868          Celda%lang=0     !In order to preserve the values given by these programs the
32869       end if              !procedure should be invoked with standard deviations
32870
32871       Celda%cell=cellv
32872       Celda%ang=angl
32873       where(Celda%ang < eps) Celda%ang =90.0
32874       call recip(cellv,angl,Celda%rcell,Celda%rang,Celda%CellVol,Celda%RCellVol)
32875       if (present(CarType)) then
32876          call Get_Cryst_Orthog_matrix(cellv,angl,Celda%Cr_Orth_cel,CarType)
32877          Celda%CartType=CarType
32878       else
32879          call Get_Cryst_Orthog_matrix(cellv,angl,Celda%Cr_Orth_cel)
32880          Celda%CartType="C"
32881       end if
32882       call matrix_inverse(Celda%Cr_Orth_cel,Celda%Orth_Cr_cel,ifail)
32883
32884       if (ifail /= 0) then
32885          err_crys=.true.
32886          ERR_Crys_Mess=" Bad cell parameters "
32887          return
32888       end if
32889
32890       Celda%GD=Metrics(cellv,angl)
32891       Celda%GR=Metrics(Celda%rcell,Celda%rang)
32892
32893       ! Busing-Levy matrix component
32894       !(it corresponds to the transpose of Orth_Cr_cel when Celda%CartType="C")
32895       If (Celda%CartType == "C") then
32896          Celda%bl_m=Transpose(Celda%Orth_Cr_cel)
32897          Celda%bl_minv=Transpose(Celda%Cr_Orth_cel)
32898       else
32899          Celda%bl_m(1,1)=celda%rcell(1)
32900          Celda%bl_m(1,2)=celda%rcell(2)*cosd(celda%rang(3))
32901          Celda%bl_m(1,3)=celda%rcell(3)*cosd(celda%rang(2))
32902          Celda%bl_m(2,2)=celda%rcell(2)*sind(celda%rang(3))
32903          Celda%bl_m(2,3)=-(celda%rcell(3)*sind(celda%rang(2))*cosd(celda%ang(1)))
32904          Celda%bl_m(3,3)=1.0/celda%cell(3)
32905          Celda%bl_m(2,1)=0.0
32906          Celda%bl_m(3,1)=0.0
32907          Celda%bl_m(3,2)=0.0
32908          call matrix_inverse(Celda%bl_m,Celda%bl_minv,ifail)
32909
32910          if (ifail /= 0) then
32911             err_crys=.true.
32912             ERR_Crys_Mess=" Bad cell parameters "
32913             return
32914          end if
32915       end if
32916
32917       return
32918    End Subroutine Set_Crystal_Cell
32919
32920    !!----
32921    !!---- Subroutine Volume_Sigma_from_Cell(cell,ang,sigc,siga,volume,sigv)
32922    !!----    real(kind=cp), dimension(3),  intent(in) :: Cell   !  In  ->  a,b,c parameters
32923    !!----    real(kind=cp), dimension(3),  intent(in) :: Ang    !  In  -> alpha, beta, gamma
32924    !!----    real(kind=cp), dimension(3),  intent(in) :: SigC   !  In  -> sigmas for a ,b and c
32925    !!----    real(kind=cp), dimension(3),  intent(in) :: SigA   !  In  -> sigmas for angles
32926    !!----    real(kind=cp),                intent(out):: Volume ! Out  -> Volume from cell parameters
32927    !!----    real(kind=cp),                intent(out):: SigV   ! Out  -> Sigma for Volume
32928    !!----
32929    !!----    Calculates the volume and their standard deviation from unit cell
32930    !!----    parameters. If the standard deviations of cell parameters are zero
32931    !!----    the result is sigma=0.0, otherwise the calculation is performed.
32932    !!----    It is assumed that there is no correlation (covariance terms) between
32933    !!----    the standard deviations of the different cell parameters.
32934    !!----
32935    !!---- Updated: January - 2013 (JGP)
32936    !!
32937    Subroutine Volume_Sigma_from_Cell(cell,ang,sigc,siga,volume,sigv)
32938       !---- Arguments ----!
32939       real(kind=cp), dimension(3),  intent(in) :: Cell   !  In  ->  a,b,c parameters
32940       real(kind=cp), dimension(3),  intent(in) :: Ang    !  In  -> alpha, beta, gamma
32941       real(kind=cp), dimension(3),  intent(in) :: SigC   !  In  -> sigmas for a ,b and c
32942       real(kind=cp), dimension(3),  intent(in) :: SigA   !  In  -> sigmas for angles
32943       real(kind=cp),                intent(out):: Volume ! Out  -> Volume from cell parameters
32944       real(kind=cp),                intent(out):: SigV   ! Out  -> Sigma for Volume
32945
32946       !---- Local Variables ----!
32947       real(kind=cp) :: a,b,c,ca,cb,cg,sa,sb,sg
32948       real(kind=cp) :: t, dvda, dvdb, dvdc, dvdalpha, dvdbeta, dvdgamma
32949
32950       !> Init
32951       volume=0.0
32952       sigv=0.0
32953
32954       a=cell(1)
32955       b=cell(2)
32956       c=cell(3)
32957       ca=cosd(ang(1))
32958       cb=cosd(ang(2))
32959       cg=cosd(ang(3))
32960       sa=sind(ang(1))
32961       sb=sind(ang(2))
32962       sg=sind(ang(3))
32963
32964       t=sqrt(1.0 - ca**2 - cb**2 - cg**2 + 2.0*ca*cb*cg)
32965
32966       volume=a*b*c*t
32967
32968       if(sum(abs(sigc)) < eps .and. sum(abs(siga)) < eps ) return
32969
32970       dvda=b*c*t
32971       dvdb=a*c*t
32972       dvdc=a*b*t
32973
32974       dvdalpha=(a*b*c)*( (sa/t)*(ca-cb*cg) )
32975       dvdbeta= (a*b*c)*( (sb/t)*(cb-ca*cg) )
32976       dvdgamma=(a*b*c)*( (sg/t)*(cg-ca*cb) )
32977
32978       sigv= (dvda*sigc(1))**2 + (dvdb*sigc(2))**2 + (dvdc*sigc(3))**2 +  &
32979             (dvdalpha*siga(1)*to_rad)**2 + (dvdbeta*siga(2)*to_rad)**2 + &
32980             (dvdgamma*siga(3)*to_rad)**2
32981
32982       sigv=sqrt(sigv)
32983
32984       return
32985    End Subroutine Volume_Sigma_from_Cell
32986
32987    !!----
32988    !!---- Subroutine Write_Crystal_Cell(Celda,Lun)
32989    !!----    Type (Crystal_Cell_Type),  intent(in)  :: Celda   !  In -> Cell variable
32990    !!----    Integer,                   intent(in)  :: lun     !  In -> Unit to write
32991    !!----
32992    !!----    Writes the cell characteristics in a binary file associated to the
32993    !!----    logical unit lun. The file is supposed to be opened with form="unformatted",
32994    !!----    access="stream" or equivalent
32995    !!----
32996    !!---- Update: February - 2013
32997    !!
32998    Subroutine Write_Bin_Crystal_Cell(Celda,Lun)
32999       !---- Arguments ----!
33000       Type (Crystal_Cell_Type),  intent(in) :: Celda
33001       Integer,                   intent(in) :: Lun
33002       write(unit=lun) Celda%cell,           &
33003                       Celda%ang,            &
33004                       Celda%cell_std,       &
33005                       Celda%ang_std,        &
33006                       Celda%rcell,          &
33007                       Celda%rang,           &
33008                       Celda%GD,Celda%GR,    &
33009                       Celda%Cr_Orth_cel,    &
33010                       Celda%Orth_Cr_cel,    &
33011                       Celda%BL_M,           &
33012                       Celda%BL_Minv,        &
33013                       Celda%CellVol,        &
33014                       Celda%RCellVol,       &
33015                       Celda%CartType
33016       return
33017    End Subroutine Write_Bin_Crystal_Cell
33018
33019    !!----
33020    !!---- Subroutine Write_Crystal_Cell(Celda,Lun)
33021    !!----    Type (Crystal_Cell_Type),  intent(in)  :: Celda   !  In -> Cell variable
33022    !!----    Integer,optional           intent(in)  :: lun     !  In -> Unit to write
33023    !!----
33024    !!----    Writes the cell characteristics in a file associated to the
33025    !!----    logical unit lun
33026    !!----
33027    !!---- Update: January - 2011
33028    !!
33029    Subroutine Write_Crystal_Cell(Celda,Lun)
33030       !---- Arguments ----!
33031       Type (Crystal_Cell_Type),  intent(in) :: Celda
33032       Integer,optional,          intent(in) :: Lun
33033
33034       !---- Local variables ----!
33035       integer            :: iunit
33036       integer            :: i,j
33037
33038       iunit=6
33039       if (present(lun)) iunit=lun
33040
33041       Write(unit=iunit,fmt="(/,a)")    "        Metric information:"
33042       Write(unit=iunit,fmt="(a,/)")    "        -------------------"
33043       Write(unit=iunit,fmt="(a,/)")    " => Direct cell parameters:"
33044       Write(unit=iunit,fmt="(3(a,f12.4))")"         a = ", Celda%cell(1),"      b = ", Celda%cell(2), "      c = ", Celda%cell(3)
33045       Write(unit=iunit,fmt="(3(a,f12.3))")"     alpha = ", Celda%ang(1) ,"   beta = ", Celda%ang(2) , "  gamma = ", Celda%ang(3)
33046       Write(unit=iunit,fmt="(a,f12.4)")   "                        Direct Cell Volume = ",Celda%CellVol
33047       Write(unit=iunit,fmt="(/,a,/)")     " => Reciprocal cell parameters:"
33048       Write(unit=iunit,fmt="(3(a,f12.6))")"         a*= ", Celda%rcell(1),"      b*= ",Celda%rcell(2),"      c*= ", Celda%rcell(3)
33049       Write(unit=iunit,fmt="(3(a,f12.3))")"     alpha*= ", Celda%rang(1) ,"   beta*= ",Celda%rang(2) ,"  gamma*= ", Celda%rang(3)
33050       Write(unit=iunit,fmt="(a,f12.8)")   "                    Reciprocal Cell Volume = ",Celda%RCellVol
33051       Write(unit=iunit,fmt="(/,a,/)")     " => Direct and Reciprocal Metric Tensors:"
33052       Write(unit=iunit,fmt="(a)")         "                   GD                                       GR"
33053
33054       do i=1,3
33055          Write(unit=iunit,fmt="(3f12.4,a,3f12.6)") (Celda%GD(i,j),j=1,3),"      ", (Celda%GR(i,j),j=1,3)
33056       end do
33057
33058       if (Celda%CartType == "A") then
33059          Write(unit=iunit,fmt="(/,a,/)") " =>  Cartesian frame: x // a; y is in the ab-plane; z is x ^ y   "
33060       else
33061          Write(unit=iunit,fmt="(/,a,/)") " =>  Cartesian frame: z // c; y is in the bc-plane; x is y ^ z   "
33062       end if
33063
33064       Write(unit=iunit,fmt="(a)")       "     Crystal_to_Orthonormal_Matrix              Orthonormal_to_Crystal Matrix"
33065       Write(unit=iunit,fmt="(a)")       "              Cr_Orth_cel                               Orth_Cr_cel  "
33066       do i=1,3
33067          Write(unit=iunit,fmt="(3f12.4,a,3f12.6)") (Celda%Cr_Orth_cel(i,j),j=1,3),"      ", (Celda%Orth_Cr_cel(i,j),j=1,3)
33068       end do
33069
33070       Write(unit=iunit,fmt="(/,a)")     "     Busing-Levy B-matrix: Hc=B.H            Inverse of the Busing-Levy B-matrix"
33071       Write(unit=iunit,fmt="(a)")       "                BL_M                                      BL_Minv  "
33072       do i=1,3
33073          Write(unit=iunit,fmt="(3f12.6,a,3f12.4)") (Celda%BL_M(i,j),j=1,3),"      ", (Celda%BL_Minv(i,j),j=1,3)
33074       end do
33075
33076       return
33077    End Subroutine Write_Crystal_Cell
33078
33079 End Module CFML_Crystal_Metrics
33080!!-------------------------------------------------------
33081!!---- Crystallographic Fortran Modules Library (CrysFML)
33082!!-------------------------------------------------------
33083!!---- The CrysFML project is distributed under LGPL. In agreement with the
33084!!---- Intergovernmental Convention of the ILL, this software cannot be used
33085!!---- in military applications.
33086!!----
33087!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
33088!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
33089!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
33090!!----
33091!!---- Authors: Juan Rodriguez-Carvajal (ILL)
33092!!----          Javier Gonzalez-Platas  (ULL)
33093!!----
33094!!---- Contributors: Laurent Chapon     (ILL)
33095!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
33096!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
33097!!----               Tierry Roisnel     (CDIFX,Rennes France)
33098!!----               Eric Pellegrini    (ILL)
33099!!----
33100!!---- This library is free software; you can redistribute it and/or
33101!!---- modify it under the terms of the GNU Lesser General Public
33102!!---- License as published by the Free Software Foundation; either
33103!!---- version 3.0 of the License, or (at your option) any later version.
33104!!----
33105!!---- This library is distributed in the hope that it will be useful,
33106!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
33107!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
33108!!---- Lesser General Public License for more details.
33109!!----
33110!!---- You should have received a copy of the GNU Lesser General Public
33111!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
33112!!----
33113!!----
33114!!---- MODULE: CFML_Reflections_Utilities
33115!!----   INFO: Series of procedures handling operation with
33116!!----         Bragg reflections
33117!!----
33118!!---- HISTORY
33119!!----    Update: 06/03/2011
33120!!----
33121!!---- DEPENDENCIES
33122!!----
33123!!--++    Use CFML_GlobalDeps,                only: sp, cp, pi
33124!!--++    Use CFML_Math_General,              only: sort
33125!!--++    Use CFML_String_Utilities,          only: l_case,Get_LogUnit
33126!!--++    Use CFML_Crystallographic_Symmetry, only: Sym_Oper_Type, Space_Group_Type
33127!!--++    Use CFML_Crystal_Metrics,           only: Crystal_Cell_Type
33128!!----
33129!!---- VARIABLES
33130!!--++    EPS_REF                  [Private]
33131!!----    ERR_REFL
33132!!----    ERR_REFL_MESS
33133!!--++    HKL_REF_COND_INI         [Private]
33134!!----    HKL_REF_COND
33135!!----    REFLECT_TYPE
33136!!----    REFLECTION_TYPE
33137!!----    REFLECTION_LIST_TYPE
33138!!----
33139!!---- PUBLIC PROCEDURES
33140!!----    Functions:
33141!!----       ASU_HKL
33142!!--++       ASU_HKL_CUBIC         [Private]
33143!!--++       ASU_HKL_HEXAGONAL     [Private]
33144!!--++       ASU_HKL_MONOCLINIC    [Private]
33145!!--++       ASU_HKL_ORTHORHOMBIC  [Private]
33146!!--++       ASU_HKL_TETRAGONAL    [Private]
33147!!--++       ASU_HKL_TRICLINIC     [Private]
33148!!--++       ASU_HKL_TRIGONAL      [Private]
33149!!----       GET_HEQUIV_ASU
33150!!----       GET_MAXNUMREF
33151!!----       HKL_ABSENT
33152!!--++       HKL_ABSENTI           [Overloaded]
33153!!--++       HKL_ABSENTR           [Overloaded]
33154!!----       HKL_EQUAL
33155!!--++       HKL_EQUALI            [Overloaded]
33156!!--++       HKL_EQUALR            [Overloaded]
33157!!----       HKL_EQUIV
33158!!--++       HKL_EQUIVI            [Overloaded]
33159!!--++       HKL_EQUIVR            [Overloaded]
33160!!----       HKL_LAT_ABSENT
33161!!----       HKL_MULT
33162!!--++       HKL_MULTI             [Overloaded]
33163!!--++       HKL_MULTR             [Overloaded]
33164!!----       HKL_R
33165!!--++       HR_I                  [Overloaded]
33166!!--++       HR_R                  [Overloaded]
33167!!----       HKL_S
33168!!--++       HS_I                  [Overloaded]
33169!!--++       HS_R                  [Overloaded]
33170!!----       UNIT_CART_HKL
33171!!--++       UNIT_CART_HKLI        [Overloaded]
33172!!--++       UNIT_CART_HKLR        [Overloaded]
33173!!----
33174!!----    Subroutines:
33175!!--++       GLIDE_PLANES_CONDITIONS  [Private]
33176!!----       HKL_EQUIV_LIST
33177!!--++       HKL_EQUIV_LISTI       [Overloaded]
33178!!--++       HKL_EQUIV_LISTR       [Overloaded]
33179!!----       HKL_GEN
33180!!----       HKL_GEN_SXTAL
33181!!--++       HKL_GEN_SXTAL_REFLECTION    [Overloaded]
33182!!--++       HKL_GEN_SXTAL_LIST          [Overloaded]
33183!!----       HKL_RP
33184!!--++       HKL_RPI               [Overloaded]
33185!!--++       HKL_RPR               [Overloaded]
33186!!----       HKL_UNI
33187!!--++       HKL_UNI_REFLECT       [Overloaded]
33188!!--++       HKL_UNI_REFLECTION    [Overloaded]
33189!!--++       HKL_UNI_REFLLIST      [Overloaded]
33190!!----       INIT_ERR_REFL
33191!!----       INIT_REFLIST
33192!!--++       INIT_REF_COND         [Private]
33193!!--++       INTEGRAL_CONDITIONS   [Private]
33194!!--++       SCREW_AXIS_CONDITIONS [Private]
33195!!----       SEARCH_EXTINCTIONS
33196!!--++       SEARCH_EXTINCTIONS_IUNIT [Overloaded]
33197!!--++       SEARCH_EXTINCTIONS_FILE [Overloaded]
33198!!----       WRITE_ASU
33199!!----       WRITE_REFLIST_INFO
33200!!----
33201!!----
33202!!
33203 Module CFML_Reflections_Utilities
33204
33205    !---- Use Modules ----!
33206    Use CFML_GlobalDeps,                only: sp, cp, pi
33207    Use CFML_Math_General,              only: sort
33208    Use CFML_String_Utilities,          only: l_case,Get_LogUnit
33209    Use CFML_Crystallographic_Symmetry, only: Sym_Oper_Type, Space_Group_Type, Lattice_Centring_Type, &
33210                                              Allocate_Lattice_Centring
33211    Use CFML_Crystal_Metrics,           only: Crystal_Cell_Type
33212
33213    !---- Variables ----!
33214    implicit none
33215
33216    private
33217
33218    !---- List of public variables ----!
33219
33220    !---- List of public functions ----!
33221    public :: Asu_Hkl,Get_MaxNumRef, Hkl_Absent, Hkl_Equal, Hkl_Equiv, Hkl_Mult,   &
33222              Get_Hequiv_Asu,Hkl_R, Hkl_S, Unit_Cart_Hkl, Hkl_Lat_Absent
33223
33224    !---- List of public overloaded procedures: functions ----!
33225
33226    !---- List of public subroutines ----!
33227    public :: Hkl_Equiv_List, Hkl_Gen, Hkl_Rp, Hkl_Uni, Init_Err_Refl, Init_RefList, &
33228              Search_Extinctions, Write_Asu, Write_RefList_Info, Hkl_Gen_Sxtal
33229
33230    !---- List of public overloaded procedures: subroutines ----!
33231
33232    !---- List of private functions ----!
33233    private :: Asu_Hkl_Cubic, Asu_Hkl_Hexagonal, Asu_Hkl_Monoclinic, Asu_Hkl_Orthorhombic,   &
33234               Asu_Hkl_Tetragonal, Asu_Hkl_Triclinic, Asu_Hkl_Trigonal, Hkl_AbsentI, hkl_equalI, &
33235               hkl_equivi, Hkl_MultI, HR_I, HS_I, Unit_Cart_HklI, Hkl_AbsentR, Hkl_EqualR, hkl_Equivr, &
33236               Hkl_MultR, HR_R, HS_R, Unit_Cart_HklR
33237
33238    !---- List of private subroutines ----!
33239    private :: Hkl_Equiv_Listi, Hkl_Equiv_Listr, Hkl_RpI, Hkl_RpR, Hkl_Uni_reflect, &
33240               Hkl_Uni_reflection, Glide_Planes_Conditions, Integral_Conditions, Screw_Axis_Conditions,&
33241               Init_Ref_Cond, Hkl_uni_refllist, Hkl_Gen_Sxtal_list,Hkl_Gen_Sxtal_reflection, &
33242               Search_Extinctions_Iunit, Search_Extinctions_File
33243
33244    !---- Definitions ----!
33245
33246    !---- Local Variables ----!
33247
33248    !!--++
33249    !!--++ eps_ref
33250    !!--++    real(kind=cp), parameter, private :: eps_ref
33251    !!--++
33252    !!--++    (PRIVATE)
33253    !!--++    Epsilon for comparisons within this module. Increased w.r.t. previous versions.
33254    !!--++
33255    !!--++ Update: December - 2010
33256    !!
33257    real(kind=cp), parameter, private :: eps_ref  = 0.0002_cp
33258
33259    !!----
33260    !!---- ERR_REFL
33261    !!----    logical, public :: err_refl
33262    !!----
33263    !!----    Logical Variable indicating an error in CFML_Reflections_Utilities module
33264    !!----
33265    !!---- Update: February - 2005
33266    !!
33267    logical, public :: ERR_Refl
33268
33269    !!----
33270    !!---- ERR_REFL_MESS
33271    !!----    character(len=150), public :: ERR_Refl_Mess
33272    !!----
33273    !!----    String containing information about the last error
33274    !!----
33275    !!---- Update: February - 2005
33276    !!
33277    character(len=150), public :: ERR_Refl_Mess
33278
33279    !!--++
33280    !!--++ HKL_REF_COND_INI
33281    !!--++    logical, public :: hkl_ref_cond_ini
33282    !!--++
33283    !!--++    Logical Variable indicating if the reflection conditions
33284    !!--++    array has been initialized
33285    !!--++
33286    !!--++ Update: August - 2005
33287    !!
33288    logical, private:: hkl_ref_cond_ini=.false.
33289
33290    !!----
33291    !!---- HKL_REF_CONDITIONS
33292    !!----    character(len=*), dimension(58), public :: Hkl_Ref_Conditions
33293    !!----
33294    !!----    Reflection conditions for Lattices, glide planes, screw axes
33295    !!--..
33296    !!--..
33297    !!--.. International tables vol. A, Fourth, revised edition (1996) p27-28-29
33298    !!--..
33299    !!--.. Table 2.1.3.1: integral reflection conditions for centred cells (lattices)
33300    !!--..
33301    !!--..        reflection condition          Centring type of cell               Centring symbol
33302    !!--..
33303    !!--..         none                         primitive                           P
33304    !!--..                                                                          R (rhomboedral axes)
33305    !!--..         h+k   = 2n                   C-face centred                      C
33306    !!--..         k+l   = 2n                   A-face centred                      A
33307    !!--..         h+l   = 2n                   B-face centred                      B
33308    !!--..         h+k+l = 2n                   Body centred                        I
33309    !!--..
33310    !!--..         h+k   = 2n
33311    !!--..     and k+l   = 2n
33312    !!--..     and h+l   = 2n                   All-face centred                    F
33313    !!--..    or h,k,l all odd
33314    !!--..    or h,k,l all even
33315    !!--..
33316    !!--..        -h+k+l = 3n                   Rhombohedrally centred,             R
33317    !!--..                                      obverse setting
33318    !!--..
33319    !!--..         h-k+l = 3n                   Rhombohedrally centred,             R
33320    !!--..                                      reverse setting
33321    !!--..
33322    !!--.. Glide Planes and Screw Axes: Table 2.13.2
33323    !!--..
33324    !!--..         0 k l:    k=2n    b/2             monoclinic, orthorhombic, tetragonal and cubic
33325    !!--..         0 k l:    l=2n    c/2             monoclinic, orthorhombic, tetragonal and cubic
33326    !!--..         0 k l:  k+l=2n    b/2 +  c/2      monoclinic, orthorhombic, tetragonal and cubic
33327    !!--..         0 k l:  k+l=4n    b/4 +- c/4      orthorhombic and cubic
33328    !!--..
33329    !!--..         h 0 l:    h=2n    a/2             monoclinic, orthorhombic, tetragonal and cubic
33330    !!--..         h 0 l:    l=2n    c/2             monoclinic, orthorhombic, tetragonal and cubic
33331    !!--..         h 0 l:  l+h=2n    c/2 +  a/2      monoclinic, orthorhombic, tetragonal and cubic
33332    !!--..         h 0 l:  l+h=4n    c/4 +- a/4      orthorhombic and cubic
33333    !!--..
33334    !!--..         h k 0:    h=2n    a/2             monoclinic, orthorhombic, tetragonal and cubic
33335    !!--..         h k 0:    k=2n    b/2             monoclinic, orthorhombic, tetragonal and cubic
33336    !!--..         h k 0:  h+k=2n    a/2 +  b/2      monoclinic, orthorhombic, tetragonal and cubic
33337    !!--..         h k 0:  h+k=4n    a/4 +- b/4      monoclinic, orthorhombic, tetragonal and cubic
33338    !!--..
33339    !!--..         h  -h   0 l:  l=2n    c/2      hexagonal   (c)
33340    !!--..         0   k  -k l:  l=2n    c/2      hexagonal   (c)
33341    !!--..        -h   0   h l:  l=2n    c/2      hexagonal   (c)
33342    !!--..         h   h -2h l:  l=2n    c/2      hexagonal   (c)
33343    !!--..       -2h   h   h l:  l=2n    c/2      hexagonal   (c)
33344    !!--..         h -2h   h l:  l=2n    c/2      hexagonal   (c)
33345    !!--..
33346    !!--..         h    h    l:   l=2n    c/2    (1-10)   rhomboedral
33347    !!--..         h    k    k:   h=2n    c/2    (01-1)   rhomboedral
33348    !!--..         h    k    h:   k=2n    c/2    (-101)   rhomboedral
33349    !!--..
33350    !!--..         h    h    l:    l=2n    c/2                  (1-10)   (c,n) tetragonal and cubic
33351    !!--..         h    h    l: 2h+l=4n    a/4 +- b/4 +- c/4    (1-10)   (d)   tetragonal and cubic
33352    !!--..         h   -h    l:    l=2n    c/2                  (110)    (c,n) tetragonal and cubic
33353    !!--..         h   -h    l: 2h+l=4n    a/4 +- b/4 +- c/4    (110)    (d)   tetragonal and cubic
33354    !!--..
33355    !!--..         h    k    k:    h=2n    a/2                  (01-1)   (a,n) cubic
33356    !!--..         h    k    k: 2k+h=4n  +-a/4 + b/4 +- c/4     (01-1)   (d)   cubic
33357    !!--..         h    k   -k:    h=2n    a/2                  (011)    (a,n) cubic
33358    !!--..         h    k   -k: 2k+h=4n  +-a/4 + b/4 +- c/4     (011)    (d)   cubic
33359    !!--..
33360    !!--..         h    k    h:    k=2n    b/2                  (-101)   (b,n) cubic
33361    !!--..         h    k    h: 2h+k=4n  +-a/4 +-b/4 +- c/4     (-101)   (d)   cubic
33362    !!--..        -h    k    h:    k=2n    b/2                  (101)    (b,n) cubic
33363    !!--..        -h    k    h: 2h+k=4n  +-a/4 + b/4 +- c/4     (011)    (d)   cubic
33364    !!--..
33365    !!--..
33366    !!--.. Screw Axes:      33 extinctions
33367    !!--..
33368    !!--..            axe//x  [100]        axe//y [010]        axe//z [001]
33369    !!--..
33370    !!--..   21     h 0 0:  h=2n           0 k 0:  k=2n        0 0 l:   l=2n         mono, ortho, tetra, cubic
33371    !!--..   42     h 0 0:  h=2n           0 k 0:  k=2n        0 0 l:   l=2n         cubic
33372    !!--..
33373    !!--..   41     h 0 0:  h=4n           0 k 0:  k=4n        0 0 l:   l=4n         cubic
33374    !!--..   43     h 0 0:  h=4n           0 k 0:  k=4n        0 0 l:   l=4n         cubic
33375    !!--..
33376    !!--..   63                                              0 0 0 l:   l=2n         hexa
33377    !!--..   31                                              0 0 0 l:   l=3n         hexa
33378    !!--..   32                                              0 0 0 l:   l=3n         hexa
33379    !!--..   62                                              0 0 0 l:   l=3n         hexa
33380    !!--..   64                                              0 0 0 l:   l=3n         hexa
33381    !!--..
33382    !!--..   61                                              0 0 0 l:   l=6n         hexa
33383    !!--..   65                                              0 0 0 l:   l=6n         hexa
33384    !!--..
33385    !!----
33386    !!---- Update: May - 2005
33387    !!
33388    character(len=80), dimension(58),  public :: Hkl_Ref_Conditions
33389
33390    !!----
33391    !!---- TYPE :: REFLECT_TYPE
33392    !!--..
33393    !!---- Type, public :: Reflect_Type
33394    !!----    integer,dimension(3) :: H    ! H
33395    !!----    integer              :: Mult ! mutiplicity
33396    !!----    real(kind=cp)        :: S    ! Sin(Theta)/lambda
33397    !!---- End Type Reflect_Type
33398    !!----
33399    !!---- Update: February - 2005
33400    !!
33401    Type, public :: Reflect_Type
33402       integer,dimension(3) :: H     ! H
33403       integer              :: Mult  ! mutiplicity
33404       real(kind=cp)        :: S     ! Sin(Theta)/lambda=1/2d
33405    End Type Reflect_Type
33406
33407    !!----
33408    !!---- TYPE :: REFLECTION_TYPE
33409    !!--..
33410    !!---- Type, public :: Reflection_Type
33411    !!----    integer,dimension(3) :: H    ! H
33412    !!----    integer              :: Mult ! mutiplicity
33413    !!----    real(kind=cp)        :: Fo   ! Observed Structure Factor
33414    !!----    real(kind=cp)        :: Fc   ! Calculated Structure Factor
33415    !!----    real(kind=cp)        :: SFo  ! Sigma of  Fo
33416    !!----    real(kind=cp)        :: S    ! Sin(Theta)/lambda
33417    !!----    real(kind=cp)        :: W    ! Weight
33418    !!----    real(kind=cp)        :: Phase! Phase in degrees
33419    !!----    real(kind=cp)        :: A    ! real part of the Structure Factor
33420    !!----    real(kind=cp)        :: B    ! Imaginary part of the Structure Factor
33421    !!----    real(kind=cp)        :: AA   ! Free
33422    !!----    real(kind=cp)        :: BB   ! Free
33423    !!---- End Type Reflection_Type
33424    !!----
33425    !!---- Update: February - 2005
33426    !!
33427    Type, public :: Reflection_Type
33428       integer,dimension(3) :: H     ! H
33429       integer              :: Mult  ! mutiplicity
33430       real(kind=cp)        :: Fo    ! Observed Structure Factor
33431       real(kind=cp)        :: Fc    ! Calculated Structure Factor
33432       real(kind=cp)        :: SFo   ! Sigma of  Fo
33433       real(kind=cp)        :: S     ! Sin(Theta)/lambda
33434       real(kind=cp)        :: W     ! Weight
33435       real(kind=cp)        :: Phase ! Phase in degrees
33436       real(kind=cp)        :: A     ! real part of the Structure Factor
33437       real(kind=cp)        :: B     ! Imaginary part of the Structure Factor
33438       real(kind=cp)        :: AA    ! Free
33439       real(kind=cp)        :: BB    ! Free
33440    End Type Reflection_Type
33441
33442    !!----
33443    !!---- TYPE :: REFLECTION_LIST_TYPE
33444    !!--..
33445    !!---- Type, public :: Reflection_List_Type
33446    !!----    integer                                        :: NRef ! Number of Reflections
33447    !!----    type(reflection_type),allocatable,dimension(:) :: Ref  ! Reflection List
33448    !!---- End Type Reflection_List_Type
33449    !!----
33450    !!---- Update: February - 2005
33451    !!
33452    Type, public :: Reflection_List_Type
33453       integer                                         :: NRef  ! Number of Reflections
33454       type(reflection_type),allocatable, dimension(:) :: Ref ! Reflection List
33455    End Type Reflection_List_Type
33456
33457    !---- Interfaces Definitions for Overload ----!
33458
33459    Interface Hkl_Absent
33460       Module Procedure hkl_AbsentI
33461       Module Procedure hkl_AbsentR
33462    End Interface Hkl_Absent
33463
33464    Interface Hkl_Equal
33465       Module Procedure Hkl_EqualI
33466       Module Procedure Hkl_EqualR
33467    End Interface Hkl_Equal
33468
33469    Interface Hkl_Equiv
33470       Module Procedure Hkl_EquivI
33471       Module Procedure Hkl_EquivR
33472    End Interface Hkl_Equiv
33473
33474    Interface Hkl_Mult
33475       Module Procedure Hkl_MultI
33476       Module Procedure Hkl_MultR
33477    End Interface Hkl_Mult
33478
33479    Interface Hkl_R
33480       Module Procedure HR_I
33481       Module Procedure HR_R
33482    End Interface Hkl_R
33483
33484    Interface Hkl_S
33485       Module Procedure HS_I
33486       Module Procedure HS_R
33487    End Interface Hkl_S
33488
33489    Interface Hkl_Equiv_List
33490       Module Procedure Hkl_Equiv_ListI
33491       Module Procedure Hkl_Equiv_ListR
33492    End Interface Hkl_Equiv_List
33493
33494    Interface Hkl_Rp
33495       Module Procedure Hkl_RpI
33496       Module Procedure Hkl_RpR
33497    End Interface Hkl_Rp
33498
33499    Interface HKL_GEN_SXTAL
33500       Module Procedure HKL_GEN_SXTAL_reflection
33501       Module Procedure HKL_GEN_SXTAL_list
33502    End Interface HKL_GEN_SXTAL
33503
33504    Interface Hkl_Uni
33505       Module Procedure Hkl_Uni_reflect
33506       Module Procedure Hkl_Uni_reflection
33507       Module Procedure Hkl_Uni_ReflList
33508    End Interface Hkl_Uni
33509
33510    Interface Search_Extinctions
33511       Module Procedure Search_Extinctions_Iunit
33512       Module Procedure Search_Extinctions_File
33513    End Interface Search_Extinctions
33514
33515    Interface Unit_Cart_Hkl
33516       Module Procedure Unit_Cart_HklI
33517       Module Procedure Unit_Cart_HklR
33518    End Interface Unit_Cart_Hkl
33519
33520 Contains
33521
33522    !---- Functions ----!
33523
33524    !!----
33525    !!---- Function Asu_Hkl(H, Spacegroup) Result(K)
33526    !!----    integer, dimension (3),  intent(in) :: h
33527    !!----    type (Space_Group_Type), intent(in) :: Spacegroup
33528    !!----    integer, dimension(3)               :: k
33529    !!----
33530    !!----    Obtain an equivalent reflection in asymmetric unit using
33531    !!----    simple transformation rules for each crystal system.
33532    !!----    When these rules are not satisfied the output is the
33533    !!----    (0,0,0) reflection. For obtaining a reflection within
33534    !!----    the asymmetric unit given an input reflection the best
33535    !!----    is to use the function: Get_Hequiv_Asu
33536    !!----
33537    !!--<<
33538    !!----    We assumed that F(hkl)=F(-h -k -l).
33539    !!-->>
33540    !!----    If and error occurs, the function returns also (0,0,0).
33541    !!----
33542    !!---- Update: February - 2005
33543    !!
33544    Function Asu_Hkl(H,Spacegroup) Result(K)
33545       !---- Arguments ----!
33546       integer, dimension (3),  intent(in) :: h
33547       type (Space_Group_Type), intent(in) :: SpaceGroup
33548       integer, dimension(3)               :: k
33549
33550       !---- Local  variables ----!
33551       character(len=2)  :: inf
33552
33553       k=0
33554       if (SpaceGroup%NumSpg > 0 .and. SpaceGroup%NumSpg <= 231) then
33555          select case (SpaceGroup%NumSpg)
33556             case (1:2)
33557                k=asu_hkl_triclinic(h)
33558
33559             case (3:15)
33560                inf(1:2)=adjustl(Spacegroup%info(1:2))
33561                if(inf(1:1) == "-") inf(1:1)=inf(2:2)
33562                select case (inf(1:1))
33563                   case ("b")
33564                      k=asu_hkl_monoclinic(h,"b")
33565                   case ("c")
33566                      k=asu_hkl_monoclinic(h,"c")
33567                   case ("a")
33568                      k=asu_hkl_monoclinic(h,"a")
33569                   case default
33570                      k=asu_hkl_monoclinic(h,"b")
33571                end select
33572
33573             case (16:74)
33574                k=asu_hkl_orthorhombic(h)
33575
33576             case (75:88)
33577                k=asu_hkl_tetragonal(h,"4/m  ")
33578
33579             case (89:142)
33580                k=asu_hkl_tetragonal(h,"4/mmm")
33581
33582             case (143:148)
33583                k=asu_hkl_trigonal(h,"-3  ")
33584
33585             case (149,151,153,157,159,162,163)
33586                k=asu_hkl_trigonal(h,"-31m")
33587
33588             case (150,152,154,155,156,158,160,161,164,165,166,167)
33589                k=asu_hkl_trigonal(h,"-3m")
33590
33591             case (168:176)
33592                k=asu_hkl_hexagonal(h,"6/m  ")
33593
33594             case (177:194)
33595                k=asu_hkl_hexagonal(h,"6/mmm")
33596
33597             case (195:206)
33598                k=asu_hkl_cubic(h,"m-3 ")
33599
33600             case (207:230)
33601                k=asu_hkl_cubic(h,"m-3m")
33602
33603          end select
33604
33605       else
33606
33607          !---- General ----!
33608          select case(SpaceGroup%Laue)
33609             case("-1   ")
33610                k=asu_hkl_triclinic(h)
33611             case("2/m  ")
33612                k=asu_hkl_monoclinic(h,"b")
33613             case("mmm  ")
33614                k=asu_hkl_orthorhombic(h)
33615             case("4/m  ")
33616                k=asu_hkl_tetragonal(h,"4/m  ")
33617             case("4/mmm")
33618                k=asu_hkl_tetragonal(h,"4/mmm")
33619             case("-3   ")
33620                k=asu_hkl_trigonal(h,"-3  ")
33621             case("-3m  ")
33622                k=asu_hkl_trigonal(h,"-3m")
33623             case("6/m  ")
33624                k=asu_hkl_hexagonal(h,"6/m  ")
33625             case("6/mmm")
33626                k=asu_hkl_hexagonal(h,"6/mmm")
33627             case("m-3  ")
33628                k=asu_hkl_cubic(h,"m-3 ")
33629             case("m-3m ")
33630                k=asu_hkl_cubic(h,"m-3m")
33631             case default
33632               return
33633          end select
33634
33635       end if
33636
33637       return
33638    End Function Asu_Hkl
33639
33640    !!--++
33641    !!--++ Function Asu_Hkl_Cubic(H,Mode) Result(K)
33642    !!--++    integer, dimension (3),  intent(in) :: h
33643    !!--++    character(len=*),        intent(in) :: Mode
33644    !!--++    integer, dimension(3)               :: k
33645    !!--++
33646    !!--++    (PRIVATE)
33647    !!--++    Obtain a reflection in asymmetric unit for Cubic
33648    !!--++
33649    !!--++ Update: February - 2005
33650    !!
33651    Function Asu_Hkl_Cubic(H,Mode) Result(K)
33652       !---- Argument ----!
33653       integer, dimension(3), intent(in) :: h
33654       character(len=*),      intent(in) :: Mode
33655       integer, dimension(3)             :: k
33656
33657       !---- Local Variable ----!
33658       character(len=4)      :: mod_laue
33659       integer, dimension(3) :: hh
33660
33661       k=0
33662       mod_laue=l_case(adjustl(Mode))
33663       if (len_trim(mod_laue) == 0) then
33664          return
33665       end if
33666
33667       select case(mod_laue)
33668          case("m-3  ")
33669             !---- Laue: m-3 ----!
33670             !---- hkl: h>l, k>l, l>=0 ; hkk: k>=0 h>=k ----!
33671             select case (h(1))
33672                case (:-1)
33673                   hh=-h
33674                case (0)
33675                   select case (h(2))
33676                      case (:-1)
33677                         hh=-h
33678                      case (0)
33679                         if (h(3) >= 0) then
33680                            hh=h
33681                         else
33682                            hh=-h
33683                         end if
33684                      case (1:)
33685                         hh=h
33686                   end select
33687                case (1:)
33688                   hh=h
33689             end select
33690             if (hh(3) >=0 .and. hh(1) >= hh(3) .and. hh(2) == hh(3)) k=hh
33691             if (hh(3) >=0 .and. hh(1) >  hh(3) .and. hh(2) >  hh(3)) k=hh
33692
33693          case("m-3m ")
33694             !---- Laue: m-3m ----!
33695             !---- hkl: h >=0, k >=0, l >=0, h >=k, k >=l ----!
33696             select case (h(1))
33697                case (:-1)
33698                   hh=-h
33699                case (0)
33700                   select case (h(2))
33701                      case (:-1)
33702                         hh=-h
33703                      case (0)
33704                         if (h(3) >= 0) then
33705                            hh=h
33706                         else
33707                            hh=-h
33708                         end if
33709                      case (1:)
33710                         hh=h
33711                   end select
33712                case (1:)
33713                   hh=h
33714             end select
33715             if (hh(3) >= 0 .and. hh(2) >= hh(3) .and. hh(1) >= hh(2)) k=hh
33716
33717          case default
33718             return
33719       end select
33720
33721       return
33722    End Function Asu_Hkl_Cubic
33723
33724    !!--++
33725    !!--++ Function Asu_Hkl_Hexagonal(H,Mode) Result(K)
33726    !!--++    integer, dimension (3),  intent(in) :: h
33727    !!--++    character(len=*),        intent(in) :: Mode
33728    !!--++    integer, dimension(3)               :: k
33729    !!--++
33730    !!--++    (PRIVATE)
33731    !!--++    Obtain a reflection in asymmetric unit for Hexagonal
33732    !!--++
33733    !!--++ Update: February - 2005
33734    !!
33735    Function Asu_Hkl_Hexagonal(H,Mode) Result(K)
33736       !---- Argument ----!
33737       integer, dimension(3), intent(in) :: h
33738       character(len=*),      intent(in) :: Mode
33739       integer, dimension(3)             :: k
33740
33741       !---- Local Variable ----!
33742       character(len=5)      :: mod_laue
33743       integer, dimension(3) :: hh
33744
33745       k=0
33746       mod_laue=l_case(adjustl(Mode))
33747       if (len_trim(mod_laue) == 0) then
33748          return
33749       end if
33750
33751       select case(mod_laue)
33752          case("6/m  ")
33753             !---- Laue: 6/m ----!
33754             !---- hkl: h>0,k>0,l>=0;  0kl k>=0,l>=0 ----!
33755             select case (h(1))
33756                case (:-1)
33757                   hh=-h
33758                case (0)
33759                   select case (h(2))
33760                      case (:-1)
33761                         hh=-h
33762                      case (0)
33763                         if (h(3) >= 0) then
33764                            hh=h
33765                         else
33766                            hh=-h
33767                         end if
33768                      case (1:)
33769                         hh=h
33770                   end select
33771                case (1:)
33772                   hh=h
33773             end select
33774             if (hh(1) > 0 .and. hh(2) > 0 .and. hh(3) >= 0) k=hh
33775             if (hh(1) == 0 .and. hh(2) >= 0 .and. hh(3) >= 0) k=hh
33776
33777          case("6/mmm")
33778             !---- Laue: 6/mmm ----!
33779             !---- hkl: h >=0, k >=0, l >=0, h >=k ----!
33780             select case (h(1))
33781                case (:-1)
33782                   hh=-h
33783                case (0)
33784                   select case (h(2))
33785                      case (:-1)
33786                         hh=-h
33787                      case (0)
33788                         if (h(3) >= 0) then
33789                            hh=h
33790                         else
33791                            hh=-h
33792                         end if
33793                      case (1:)
33794                         hh=h
33795                   end select
33796                case (1:)
33797                   hh=h
33798             end select
33799             if (hh(2) >=0 .and. hh(1) >= hh(2) .and. hh(3) >= 0) k=hh
33800
33801          case default
33802             return
33803       end select
33804
33805       return
33806    End Function Asu_Hkl_Hexagonal
33807
33808    !!--++
33809    !!--++ Function Asu_Hkl_Monoclinic(H,Axis) Result(K)
33810    !!--++    integer, dimension (3),     intent(in) :: h
33811    !!--++    character(len=*), optional, intent(in) :: axis
33812    !!--++    integer, dimension(3)                  :: k
33813    !!--++
33814    !!--++    (PRIVATE)
33815    !!--++    Obtain a reflection in asymmetric unit for Monoclinic
33816    !!--++    Unique axis b: hkl: k >=0, l >=0    hk0: h >=0
33817    !!--++    Unique axis c: hkl: k >=0, l >=0    h0l: h >=0
33818    !!--++    Unique axis a: hkl: h >=0, l >=0    0kl: l >=0
33819    !!--++
33820    !!--++ Update: February - 2005
33821    !!
33822    Function Asu_Hkl_Monoclinic(H,Mode) Result(K)
33823       !---- Argument ----!
33824       integer, dimension(3),      intent(in) :: h
33825       character(len=*), optional, intent(in) :: mode
33826       integer, dimension(3)                  :: k
33827
33828       !---- Local Variable ----!
33829       character(len=1)     :: ax
33830       integer,dimension(3) :: hh
33831
33832       k=0
33833       if (present(mode)) then
33834          ax=l_case(adjustl(mode))
33835          if (ax ==" ") ax="b"
33836       else
33837          ax="b"
33838       end if
33839
33840       select case (ax)
33841          !---- Laue: 2/m     Unique Axis: b ----!
33842          !---- hkl: k >=0, l >=0    hk0: h >=0
33843          case ("b")
33844             select case (h(3))
33845                case (:-1)
33846                   hh=-h
33847                case (0)
33848                   select case (h(2))
33849                      case (:-1)
33850                         hh=-h
33851                      case (0)
33852                         if (h(1) >=0) then
33853                            hh=h
33854                         else
33855                            hh=-h
33856                         end if
33857                      case (1:)
33858                         hh=h
33859                   end select
33860                case (1:)
33861                   hh=h
33862             end select
33863
33864             if (hh(3) == 0) then
33865                if (hh(1) >=0 ) k=hh
33866             else
33867                if (hh(2) >=0 .and. hh(3) >=0) k=hh
33868             end if
33869
33870          !---- Laue: 2/m     Unique Axis: c ----!
33871          !---- hkl: k >=0, l >=0    h0l: h >=0
33872          case ("c")
33873             select case (h(3))
33874                case (:-1)
33875                   hh=-h
33876                case (0)
33877                   select case (h(2))
33878                      case (:-1)
33879                         hh=-h
33880                      case (0)
33881                         if (h(1) >= 0) then
33882                            hh=h
33883                         else
33884                            hh=-h
33885                         end if
33886                      case (1:)
33887                         hh=h
33888                   end select
33889                case (1:)
33890                   hh=h
33891             end select
33892
33893             if (hh(2) == 0) then
33894                if (hh(1) >= 0) k=hh
33895             else
33896                if (hh(2) >=0 .and. hh(3) >=0) k=hh
33897             end if
33898
33899          !---- Laue: 2/m     Unique Axis: c ----!
33900          !---- hkl: h >=0, l >=0    0kl: l >=0
33901          case ("a")
33902             select case (h(1))
33903                case (:-1)
33904                   hh=-h
33905                case (0)
33906                   select case (h(3))
33907                      case (:-1)
33908                         hh=-h
33909                      case (0)
33910                         if (h(2) >= 0) then
33911                            hh=h
33912                         else
33913                            hh=-h
33914                         end if
33915                      case (1:)
33916                         hh=h
33917                   end select
33918                case (1:)
33919                   hh=h
33920             end select
33921
33922             if (hh(1) == 0) then
33923                if (hh(2) >= 0) k=hh
33924             else
33925                if (hh(1) >=0 .and. hh(3) >=0) k=hh
33926             end if
33927
33928       end select
33929
33930       return
33931    End Function Asu_Hkl_Monoclinic
33932
33933    !!--++
33934    !!--++ Function Asu_Hkl_Orthorhombic(H) Result(K)
33935    !!--++    integer, dimension (3),  intent(in) :: h
33936    !!--++    integer, dimension(3)               :: k
33937    !!--++
33938    !!--++    (PRIVATE)
33939    !!--++    Obtain a reflection in asymmetric unit for Orthorhombic
33940    !!--++    hkl: h >=0, k >=0, l >=0
33941    !!--++
33942    !!--++ Update: February - 2005
33943    !!
33944    Function Asu_Hkl_Orthorhombic(H) Result(K)
33945       !---- Argument ----!
33946       integer, dimension(3), intent(in) :: h
33947       integer, dimension(3)             :: k
33948
33949       !---- Local Variable ----!
33950       integer, dimension(3) :: hh
33951
33952       k=0
33953       !---- Laue: mmm ----!
33954       !---- hkl: h >=0, k >=0, l >=0 ----!
33955       select case (h(1))
33956          case (:-1)
33957             hh=-h
33958          case (0)
33959             select case (h(2))
33960                case (:-1)
33961                   hh=-h
33962                case (0)
33963                   if (h(3) >= 0) then
33964                      hh=h
33965                   else
33966                      hh=-h
33967                   end if
33968                case (1:)
33969                   hh=h
33970             end select
33971          case (1:)
33972             hh=h
33973       end select
33974
33975       if (hh(1) >= 0 .and. hh(2) >= 0 .and. hh(3) >= 0) k=hh
33976
33977       return
33978    End Function Asu_Hkl_Orthorhombic
33979
33980    !!--++
33981    !!--++ Function Asu_Hkl_Tetragonal(H,Mode) Result(K)
33982    !!--++    integer, dimension (3),  intent(in) :: h
33983    !!--++    character(len=*),        intent(in) :: Mode
33984    !!--++    integer, dimension(3)               :: k
33985    !!--++
33986    !!--++    (PRIVATE)
33987    !!--++    Obtain a reflection in asymmetric unit for Tetragonal
33988    !!--++
33989    !!--++ Update: February - 2005
33990    !!
33991    Function Asu_Hkl_Tetragonal(H,Mode) Result(K)
33992       !---- Argument ----!
33993       integer, dimension(3), intent(in) :: h
33994       character(len=*),      intent(in) :: Mode
33995       integer, dimension(3)             :: k
33996
33997       !---- Local Variable ----!
33998       character(len=5)     :: mod_laue
33999       integer,dimension(3) :: hh
34000
34001       k=0
34002       mod_laue=l_case(adjustl(Mode))
34003       if (len_trim(mod_laue) == 0) then
34004          return
34005       end if
34006
34007       select case(mod_laue)
34008          case("4/m  ")
34009             !---- Laue: 4/m ----!
34010             !---- hkl: h >=0, l >=0, k >=0 if h = 0 ----!
34011             select case (h(1))
34012                case (:-1)
34013                   hh=-h
34014                case (0)
34015                   select case (h(2))
34016                      case (:-1)
34017                         hh=-h
34018                      case (0)
34019                         if (h(3) >= 0) then
34020                            hh=h
34021                         else
34022                            hh=-h
34023                         end if
34024                      case (1:)
34025                         hh=h
34026                   end select
34027                case (1:)
34028                   hh=h
34029             end select
34030             if (hh(1) == 0 .and. hh(2) >= 0 .and. hh(3) >=0) k=hh
34031             if (hh(1)  > 0 .and. hh(2) >  0 .and. hh(3) >=0) k=hh
34032
34033          case("4/mmm")
34034             !---- Laue: 4/mmm ----!
34035             !---- hkl: h >=0, l >=0, h >=k   (k >=0) ----!
34036             select case (h(1))
34037                case (:-1)
34038                   hh=-h
34039                case (0)
34040                   select case (h(2))
34041                      case (:-1)
34042                         hh=-h
34043                      case (0)
34044                         if (h(3) >= 0) then
34045                            hh=h
34046                         else
34047                            hh=-h
34048                         end if
34049                      case (1:)
34050                         hh=h
34051                   end select
34052                case (1:)
34053                   hh=h
34054             end select
34055             if (hh(1) >=0 .and. hh(2) >=0 .and. hh(3) >=0 .and. hh(1) >= hh(2)) k=hh
34056
34057          case default
34058             return
34059       end select
34060
34061       return
34062    End Function Asu_Hkl_Tetragonal
34063
34064    !!--++
34065    !!--++ Function Asu_Hkl_Triclinic(H) Result(K)
34066    !!--++    integer, dimension (3),  intent(in) :: h
34067    !!--++    integer, dimension(3)               :: k
34068    !!--++
34069    !!--++    (PRIVATE)
34070    !!--++    Obtain a reflection in asymmetric unit for Triclinic
34071    !!--++    hkl: l >=0    hk0: h >=0    0k0: k >=0
34072    !!--++
34073    !!--++ Update: February - 2005
34074    !!
34075    Function Asu_Hkl_Triclinic(H) Result(K)
34076       !---- Argument ----!
34077       integer, dimension(3), intent(in) :: h
34078       integer, dimension(3)             :: k
34079
34080       k=0
34081       !---- Laue: -1 ----!
34082       !---- hkl: l >=0    hk0: h >=0    0k0: k >=0
34083       select case (h(3))
34084          case (:-1)
34085             k=-h
34086          case (0)
34087             select case (h(1))
34088                case (:-1)
34089                   k=-h
34090                case (0)
34091                   if (h(2) < 0) then
34092                      k=-h
34093                   else
34094                      k=h
34095                   end if
34096                case (1:)
34097                   k=h
34098             end select
34099          case (1:)
34100             k=h
34101       end select
34102
34103       return
34104    End Function Asu_Hkl_Triclinic
34105
34106    !!--++
34107    !!--++ Function Asu_Hkl_Trigonal(H,Mode) Result(K)
34108    !!--++    integer, dimension (3),  intent(in) :: h
34109    !!--++    character(len=*),        intent(in) :: Mode
34110    !!--++    integer, dimension(3)               :: k
34111    !!--++
34112    !!--++    (PRIVATE)
34113    !!--++    Obtain a reflection in asymmetric unit for Trigonal
34114    !!--++
34115    !!--++ Update: February - 2005
34116    !!
34117    Function Asu_Hkl_Trigonal(H,Mode) Result(K)
34118       !---- Argument ----!
34119       integer, dimension(3), intent(in) :: h
34120       character(len=*),      intent(in) :: Mode
34121       integer, dimension(3)             :: k
34122
34123       !---- Local Variable ----!
34124       character(len=4)      :: mod_laue
34125       integer, dimension(3) :: hh
34126
34127       k=0
34128       mod_laue=l_case(adjustl(Mode))
34129       if (len_trim(mod_laue) == 0) then
34130          return
34131       end if
34132
34133       select case(mod_laue)
34134          case("-3  ")
34135             !---- Laue: -3 ----!
34136             !---- hkl: h+k>0, l>0 ; hk0:h>0, k>=0
34137             select case (h(1))
34138                case (:-1)
34139                   hh=-h
34140                case (0)
34141                   select case (h(2))
34142                      case (:-1)
34143                         hh=-h
34144                      case (0)
34145                         if (h(3) >= 0) then
34146                            hh=h
34147                         else
34148                            hh=-h
34149                         end if
34150                      case (1:)
34151                         hh=h
34152
34153                   end select
34154                case (1:)
34155                   hh=h
34156             end select
34157             if (hh(1) == 0 .and. hh(2) == 0 .and. hh(3) > 0) k=hh
34158             if (hh(1)+hh(2) > 0 .and. hh(3) > 0 ) k=hh
34159             if (hh(1) > 0  .and. hh(2) >= 0  .and. hh(3) == 0) k=hh
34160
34161          case("-3m ")
34162             !---- Laue: -3m ----!
34163             !---- hkl: h>=0, h>=k ; hhl: h>=0,l>=0 ----!
34164             select case (h(1))
34165                case (:-1)
34166                   hh=-h
34167                case (0)
34168                   select case (h(2))
34169                      case (:-1)
34170                         hh=-h
34171                      case (0)
34172                         if (h(3) >= 0) then
34173                            hh=h
34174                         else
34175                            hh=-h
34176                         end if
34177                      case (1:)
34178                         hh=h
34179                   end select
34180                case (1:)
34181                   hh=h
34182             end select
34183             if (hh(1) >= hh(2) .and.  hh(2) >= 0 ) k=hh
34184             if (hh(1) >= 0 .and. hh(2) > 0 .and. hh(3) > 0 ) k=hh
34185             if (hh(1) >= 0 .and. hh(2) == hh(1) .and. hh(3) >=0) k=hh
34186
34187          case("-31m")
34188             !---- Laue: -31m ----!
34189             !---- hkl: h>=0,h>=k>0 ; h0l: h>=0,l>=0 ----!
34190             select case (h(1))
34191                case (:-1)
34192                   hh=-h
34193                case (0)
34194                   select case (h(2))
34195                      case (:-1)
34196                         hh=-h
34197                      case (0)
34198                         if (h(3) >= 0) then
34199                            hh=h
34200                         else
34201                            hh=-h
34202                         end if
34203                      case (1:)
34204                           hh=h
34205                   end select
34206                case (1:)
34207                   hh=h
34208             end select
34209             if (hh(1) >= hh(2) .and. hh(1) >=0 .and. hh(2) > 0) k=hh
34210             if (hh(1) >= 0 .and. hh(2) ==0 .and. hh(3) >= 0) k=hh
34211
34212          case default
34213             return
34214       end select
34215
34216       return
34217    End Function Asu_Hkl_Trigonal
34218
34219    !!----
34220    !!---- Function  Get_Hequiv_Asu(h,SpaceGroup) result(k)
34221    !!----    integer, dimension (3),  intent(in) :: h
34222    !!----    type (Space_Group_Type), intent(in) :: SpaceGroup
34223    !!----    integer, dimension(3)               :: k
34224    !!----
34225    !!----    Provides a reflection equivalent to the input one but
34226    !!----    within the asymmetric unit
34227    !!----
34228    !!---- Update: December - 2005
34229    !!
34230    Function Get_Hequiv_Asu(H,Spacegroup) Result(k)
34231       !---- Arguments ----!
34232       integer, dimension (3),  intent(in) :: h
34233       type (Space_Group_Type), intent(in) :: SpaceGroup
34234       integer, dimension(3)               :: k
34235
34236       !---- Local Variables ----!
34237       integer                             :: i
34238       integer, dimension(3)               :: kk,nul
34239
34240       k=h
34241       nul=(/0,0,0/)
34242       do i=1,SpaceGroup%NumOps
34243         k=matmul(h,SpaceGroup%SymOp(i)%Rot)
34244         kk=asu_hkl(k,SpaceGroup)
34245         if (hkl_equal(kk,nul)) cycle
34246         k=kk
34247         exit
34248       end do
34249       return
34250    End Function Get_Hequiv_Asu
34251
34252    !!----
34253    !!---- Function  Get_MaxNumRef(SinTLMax, VolCell, SinTLMin, Mult) result(numref)
34254    !!----    real(kind=cp),           intent(in) :: SinTLMax !Maximum sinTheta/Lambda
34255    !!----    real(kind=cp),           intent(in) :: VolCell  !Direct Cell Volume
34256    !!----    real(kind=cp), optional, intent(in) :: SinTLMin !Minimum sinTheta/Lambda
34257    !!----    Integer,       optional, intent(in) :: Mult     !General Multiplicity
34258    !!----    Integer                             :: numref
34259    !!----
34260    !!----    Provides un upper limit of the expected maximum number of
34261    !!----    reflections up to SinTLMax for a volume VolCell of the
34262    !!----    primitive cell. If the optional argument SinTLMin is given,
34263    !!----    the result is the number of reflections in the interval (SinTLMin,SinTLMax).
34264    !!----    If Mult is provided the result is divided by half this multiplicity
34265    !!----    so we obtain an estimation of the expected mumber of unique reflections.
34266    !!----
34267    !!---- Update: February - 2005
34268    !!
34269    Function Get_MaxNumRef(SinTLMax, VolCell, SinTLMin, Mult) Result(numref)
34270       !---- Arguments ----!
34271       real(kind=cp),           intent(in) :: SinTLMax
34272       real(kind=cp),           intent(in) :: VolCell
34273       real(kind=cp), optional, intent(in) :: SinTLMin
34274       integer,       optional, intent(in) :: Mult
34275       integer                             :: numref
34276
34277       !---- Local Variables ----!
34278       real(kind=cp)                      :: r3
34279
34280       r3=8.0*SinTLMax*SinTLMax*SinTLMax*1.05
34281
34282       if (present(SinTLMin)) r3= r3-8.0*SinTLMin*SinTLMin*SinTLMin
34283
34284       numref=4.0*pi*r3*VolCell/3.0
34285       !The factor 2 is given because, for high symmetry, sometimes the obtained number is
34286       !not enough for allocating the real number of reflections
34287       if (present(Mult)) numref=2*numref/max(1,Mult)
34288
34289       return
34290    End Function Get_MaxNumRef
34291
34292    !!----
34293    !!---- Function  Hkl_Absen(H, Spacegroup)
34294    !!----    integer/real(kind=cp), dimension(3), intent(in) :: h
34295    !!----    type (Space_Group_Type),             intent(in) :: SpaceGroup
34296    !!----
34297    !!----    Returns the value ".true." if the reflection is absent.
34298    !!----
34299    !!---- Update: February - 2005
34300    !!
34301
34302    !!--++
34303    !!--++ Logical Function  Hkl_AbsentI(H, Spacegroup)
34304    !!--++    integer, dimension(3),   intent(in) :: h
34305    !!--++    Type (Space_Group_Type), intent(in) :: SpaceGroup
34306    !!--++
34307    !!--++    (OVERLOADED)
34308    !!--++    Calculate if the reflection is an absence
34309    !!--++
34310    !!--++  Update: February - 2005
34311    !!
34312    Function Hkl_AbsentI(H,Spacegroup) Result(Info)
34313       !---- Arguments ----!
34314       integer, dimension(3),   intent (in) :: h
34315       Type (Space_Group_Type), intent (in) :: SpaceGroup
34316       logical                              :: info
34317
34318       !---- Local Variables ----!
34319       integer, dimension(3)              :: k
34320       integer                            :: i
34321       real(kind=cp)                      :: r1,r2
34322
34323       info=.false.
34324
34325       do i=1,SpaceGroup%multip
34326          k = hkl_r(h,SpaceGroup%SymOp(i))
34327          if (hkl_equal(h,k)) then
34328             r1=dot_product(SpaceGroup%SymOp(i)%Tr,real(h))
34329             r2=nint(r1)
34330             if (abs(r1-r2) > eps_ref) then
34331                info=.true.
34332                exit
34333             end if
34334          end if
34335       end do
34336
34337       return
34338    End Function Hkl_AbsentI
34339
34340    !!--++
34341    !!--++ Logical Function Hkl_AbsentR(H, Spacegroup)
34342    !!--++    real(kind=cp), dimension(3), intent(in) :: h
34343    !!--++    Type (Space_Group_Type),     intent(in) :: SpaceGroup
34344    !!--++
34345    !!--++    (OVERLOADED)
34346    !!--++    Calculate if the reflection is an absence
34347    !!--++
34348    !!--++ Update: February - 2005
34349    !!
34350    Function Hkl_AbsentR(H,Spacegroup) Result(Info)
34351       !---- Arguments ----!
34352       real(kind=cp), dimension(3), intent (in) :: h
34353       Type (Space_Group_Type),     intent (in) :: SpaceGroup
34354       logical                                  :: info
34355
34356       !---- Local Variables ----!
34357       integer                      :: i
34358       real(kind=cp), dimension(3)  :: k
34359       real(kind=cp)                :: r1,r2
34360
34361       info=.false.
34362       do i=1,SpaceGroup%multip
34363          k = hkl_r(h,SpaceGroup%SymOp(i))
34364          if (hkl_equal(h,k)) then
34365             r1=dot_product(SpaceGroup%SymOp(i)%Tr,h)
34366             r2=nint(r1)
34367             if (abs(r1-r2) > eps_ref) then
34368                info=.true.
34369                exit
34370             end if
34371          end if
34372       end do
34373
34374       return
34375    End Function Hkl_AbsentR
34376
34377    !!----
34378    !!---- Logical Function  Hkl_Equal(H,K)
34379    !!----    integer/real(kind=cp), dimension(3), intent(in) :: h
34380    !!----    integer/real(kind=cp), dimension(3), intent(in) :: k
34381    !!----
34382    !!----    Calculate if two reflections are equal
34383    !!----
34384    !!---- Update: February - 2005
34385    !!
34386
34387    !!--++
34388    !!--++ Logical Function  Hkl_EqualI(H,K)
34389    !!--++    integer, dimension(3), intent(in) :: h
34390    !!--++    integer, dimension(3), intent(in) :: k
34391    !!--++
34392    !!--++    (OVERLOADED)
34393    !!--++    True if 2 reflections are equal
34394    !!--++
34395    !!--++  Update: February - 2005
34396    !!
34397    Function Hkl_EqualI(H,K) Result (Info)
34398       !---- Arguments ----!
34399       integer, dimension(3), intent(in) :: h,k
34400       logical                           :: info
34401
34402       info=.false.
34403       if (h(1)==k(1) .and. h(2)==k(2) .and. h(3)==k(3)) info=.true.
34404
34405       return
34406    End Function Hkl_EqualI
34407
34408    !!--++
34409    !!--++ Logical Function  Hkl_EqualR(H,K)
34410    !!--++    real(kind=cp), dimension(3), intent(in) :: h
34411    !!--++    real(kind=cp), dimension(3), intent(in) :: k
34412    !!--++
34413    !!--++    (OVERLOADED)
34414    !!--++    True if 2 reflections are equal
34415    !!--++
34416    !!--++ Update: February - 2005
34417    !!
34418    Function Hkl_EqualR(H,K) Result (Info)
34419       !---- Arguments ----!
34420       real(kind=cp), dimension(3), intent(in) :: h,k
34421       logical                                 :: info
34422
34423       info=.false.
34424       if (abs(h(1)-k(1)) <= eps_ref .and. abs(h(2)-k(2)) <= eps_ref .and. &
34425           abs(h(3)-k(3)) <= eps_ref) info=.true.
34426
34427       return
34428    End Function Hkl_EqualR
34429
34430    !!----
34431    !!---- Logical Function  Hkl_Equiv(H,K,Spacegroup,Friedel)
34432    !!----    integer/real(kind=cp), dimension(3), intent(in) :: h
34433    !!----    integer/real(kind=cp), dimension(3), intent(in) :: k
34434    !!----    type (Space_Group_Type),             intent(in) :: SpaceGroup
34435    !!----    Logical, optional ,                  intent(in) :: Friedel
34436    !!----
34437    !!----    Calculate if two reflections are equivalent
34438    !!----
34439    !!---- Update: February - 2005
34440    !!
34441
34442    !!--++
34443    !!--++ Logical Function  Hkl_EquivI(H,K, Spacegroup,Friedel)
34444    !!--++    integer, dimension(3),   intent(in) :: h
34445    !!--++    integer, dimension(3),   intent(in) :: k
34446    !!--++    Type (Space_Group_Type), intent(in) :: SpaceGroup
34447    !!--++    logical, optional,       intent(in) :: Friedel
34448    !!--++
34449    !!--++    (OVERLOADED)
34450    !!--++    Calculate if the reflections are equivalent
34451    !!--++
34452    !!--++ Update: February - 2005
34453    !!
34454    Function Hkl_EquivI(H,K,Spacegroup,Friedel) Result (Info)
34455       !---- Arguments ----!
34456       integer, dimension(3),    intent(in)  :: h,k
34457       Type (Space_Group_Type),  intent (in) :: SpaceGroup
34458       logical, optional,        intent(in)  :: Friedel
34459       logical                               :: info
34460
34461       !---- Local Variables ----!
34462       integer                           :: i, nops
34463       integer, dimension(3)             :: hh
34464
34465       info=.false.
34466       nops= SpaceGroup%numops*max(SpaceGroup%centred,1)
34467       do i=1,nops
34468          hh = hkl_r(h,SpaceGroup%SymOp(i))
34469          if (hkl_equal(k,hh)) then
34470             info=.true.
34471             exit
34472          end if
34473          if (present(Friedel)) then
34474             if (Friedel) then
34475                if (hkl_equal(k,-hh)) then
34476                   info=.true.
34477                   exit
34478                end if
34479             end if
34480          end if
34481       end do
34482
34483       return
34484    End Function Hkl_EquivI
34485
34486    !!--++
34487    !!--++ Logical Function  Hkl_EquivR(H,K, Spacegroup,Friedel)
34488    !!--++    real(kind=cp), dimension(3),      intent(in) :: h
34489    !!--++    real(kind=cp), dimension(3),      intent(in) :: k
34490    !!--++    Type (Space_Group_Type),          intent(in) :: SpaceGroup
34491    !!--++    logical, optional,                intent(in) :: Friedel
34492    !!--++
34493    !!--++    (OVERLOADED)
34494    !!--++    Calculate if the reflections are equivalent
34495    !!--++
34496    !!--++ Update: February - 2005
34497    !!
34498    Function Hkl_EquivR(H,K,Spacegroup,Friedel) Result (Info)
34499       !---- Arguments ----!
34500       real(kind=cp), dimension(3), intent(in) :: h,k
34501       Type (Space_Group_Type),     intent(in) :: SpaceGroup
34502       logical, optional,           intent(in) :: Friedel
34503       logical                                 :: info
34504
34505       !---- Local Variables ----!
34506       integer                            :: i, nops
34507       real(kind=cp), dimension(3)        :: hh
34508
34509       info=.false.
34510       nops= SpaceGroup%numops*max(SpaceGroup%centred,1)
34511       do i=1, nops
34512          hh = hkl_r(h,SpaceGroup%SymOp(i))
34513          if (hkl_equal(k,hh)) then
34514             info=.true.
34515             exit
34516          end if
34517          if (present(Friedel)) then
34518             if (Friedel) then
34519                if (hkl_equal(k,-hh)) then
34520                   info=.true.
34521                   exit
34522                end if
34523             end if
34524          end if
34525       end do
34526
34527       return
34528    End Function Hkl_EquivR
34529
34530    !!--++
34531    !!--++ Logical Function  Hkl_AbsentI(H, Spacegroup)
34532    !!--++    integer, dimension(3),   intent(in) :: h
34533    !!--++    Type (Space_Group_Type), intent(in) :: SpaceGroup
34534    !!--++
34535    !!--++    (OVERLOADED)
34536    !!--++    Calculate if the reflection is a lattice absence
34537    !!--++
34538    !!--++  Update: February - 2005
34539    !!
34540    Function Hkl_Lat_Absent(H,Latt) Result(Info)
34541       !---- Arguments ----!
34542       integer, dimension(3),        intent (in) :: h
34543       Type (Lattice_Centring_Type), intent (in) :: Latt
34544       logical                                   :: info
34545
34546       !---- Local Variables ----!
34547       integer               :: k,i
34548       logical               :: tinv
34549       real(kind=cp)         :: r1,r2
34550
34551       info=.false.
34552       if(.not. Latt%set) return
34553       tinv=.false.
34554       if(ubound(Latt%Ltr,1) == 4) tinv=.true.
34555       do i=1,Latt%n_lat
34556          r1=dot_product(Latt%Ltr(1:3,i),real(h))
34557          r2=nint(r1)
34558          k=nint(2.0*r1)
34559          if(tinv) then  !Time inversion is considered
34560             if(Latt%Ltr(4,i) > 0.0) then  !No time inversion, lattice centring
34561               if(mod(k,2) /= 0) info=.true.
34562               exit
34563             else !now time inversion is associated with the translation (Anti-translation)
34564               if (abs(r1-r2) < eps_ref) info=.true.
34565               exit
34566             end if
34567          else  !No time inversion is considered only normal lattice centring vectors
34568             if(mod(k,2) /= 0) info=.true.
34569             exit
34570          end if
34571       end do
34572       return
34573    End Function Hkl_Lat_Absent
34574
34575    !!----
34576    !!---- Function  Hkl_Mult(H, Spacegroup, Friedel)
34577    !!----    integer/real(kind=cp), dimension(3), intent(in) :: h
34578    !!----    type (Space_Group_Type),             intent(in) :: SpaceGroup
34579    !!----    Logical,                             intent(in) :: Friedel
34580    !!----
34581    !!----    Calculate the multiplicity of the reflection
34582    !!----
34583    !!---- Update: February - 2005
34584    !!
34585
34586    !!--++
34587    !!--++ Function  Hkl_MultI(H, Spacegroup,Friedel)
34588    !!--++    integer, dimension(3),   intent(in) :: h
34589    !!--++    Type (Space_Group_Type), intent(in) :: SpaceGroup
34590    !!--++    Logical,                 intent(in) :: Friedel
34591    !!--++
34592    !!--++    (OVERLOADED)
34593    !!--++    Calculate the multiplicity of the reflection
34594    !!--++
34595    !!--++ Update: February - 2005
34596    !!
34597    Function Hkl_MultI(H,Spacegroup,Friedel) Result(N)
34598       !---- Arguments ----!
34599       integer, dimension(3),   intent (in) :: h
34600       Type (Space_Group_Type), intent (in) :: SpaceGroup
34601       Logical,                 intent (in) :: Friedel
34602       integer                              :: N
34603
34604       !---- Local Variables ----!
34605       logical                                :: esta
34606       integer, dimension(3)                  :: k
34607       integer                                :: i,j,ng
34608       integer, dimension(3,SpaceGroup%numops):: klist
34609
34610       ng=SpaceGroup%numops
34611       n=1
34612
34613       !if NG = 0 (strange case), skip it, fix by Petr
34614       if (ng > 1) then
34615           klist(:,1)=h(:)
34616
34617           do i=2,ng
34618              k = hkl_r(h,SpaceGroup%SymOp(i))
34619              esta=.false.
34620              do j=1,n
34621                 if (hkl_equal(k,klist(:,j)) .or. hkl_equal(-k,klist(:,j))) then
34622                    esta=.true.
34623                    exit
34624                 end if
34625              end do
34626              if (esta) cycle
34627              n=n+1
34628              klist(:,n) = k
34629           end do
34630       end if
34631       if (Friedel .or. SpaceGroup%centred == 2) then
34632           n=n*2
34633       end if
34634
34635       return
34636    End Function Hkl_MultI
34637
34638    !!--++
34639    !!--++ Function  Hkl_MultR(H, Spacegroup,Friedel)
34640    !!--++    real(kind=cp), dimension(3),      intent(in) :: h
34641    !!--++    Type (Space_Group_Type),          intent(in) :: SpaceGroup
34642    !!--++    Logical,                          intent(in) :: Friedel
34643    !!--++
34644    !!--++    (OVERLOADED)
34645    !!--++    Calculate the multiplicity of the reflection
34646    !!--++
34647    !!--++ Update: February - 2005
34648    !!
34649    Function Hkl_MultR(H,Spacegroup,Friedel) Result(N)
34650       !---- Arguments ----!
34651       real(kind=cp), dimension(3), intent (in) :: h
34652       Type (Space_Group_Type),     intent (in) :: SpaceGroup
34653       Logical,                     intent (in) :: Friedel
34654       integer                                  :: n
34655
34656       !---- Local Variables ----!
34657       logical :: esta
34658       real(kind=cp), dimension(3)   :: k
34659       integer                       :: i,j,ng
34660       real(kind=cp), dimension(3,SpaceGroup%numops):: klist
34661
34662       ng=SpaceGroup%numops
34663       n=1
34664       klist(:,1)=h(:)
34665       do i=2,ng
34666          k = hkl_r(h,SpaceGroup%SymOp(i))
34667          esta=.false.
34668          do j=1,n
34669             if (hkl_equal(k,klist(:,j)) .or. hkl_equal(-k,klist(:,j))) then
34670                esta=.true.
34671                exit
34672             end if
34673          end do
34674          if (esta) cycle
34675          n=n+1
34676          klist(:,n) = k
34677       end do
34678       if (Friedel .or. SpaceGroup%centred == 2) n=n*2
34679
34680       return
34681    End Function Hkl_MultR
34682
34683    !!----
34684    !!---- Function  Hkl_R(H,Op)
34685    !!----    integer/real(kind=cp), dimension(3), intent(in) :: h
34686    !!----    type (Sym_Oper_Type),                intent(in) :: Op
34687    !!----
34688    !!----    Calculate the equivalent reflection
34689    !!----
34690    !!---- Update: February - 2005
34691    !!
34692
34693    !!--++
34694    !!--++ Function  Hr_I(H,Op)
34695    !!--++    integer, dimension(3), intent(in) :: h
34696    !!--++    type (Sym_Oper_Type),  intent(in) :: Op
34697    !!--++
34698    !!--++    (OVERLOADED)
34699    !!--++    Calculate the equivalent reflection
34700    !!--++
34701    !!--++ Update: February - 2005
34702    !!
34703    Function HR_I(H,Op) Result(K)
34704       !---- Arguments ----!
34705       integer, dimension(3), intent(in) :: h
34706       Type(Sym_Oper_Type),   intent(in) :: Op
34707       integer, dimension(3)             :: k
34708
34709       k = matmul(h,Op%Rot)
34710
34711    End Function HR_I
34712
34713    !!--++
34714    !!--++ Function  Hr_R(H,Op)
34715    !!--++    real(kind=cp),    dimension(3), intent(in) :: h
34716    !!--++    type (Sym_Oper_Type),           intent(in) :: Op
34717    !!--++
34718    !!--++    (OVERLOADED)
34719    !!--++    Calculate the equivalent reflection
34720    !!--++
34721    !!--++ Update: February - 2005
34722    !!
34723    Function HR_R(H,Op) Result(K)
34724       !---- Arguments ----!
34725       real(kind=cp), dimension(3),  intent(in) :: h
34726       Type(Sym_Oper_Type),          intent(in) :: Op
34727       real(kind=cp), dimension(3)              :: k
34728
34729       k = matmul(h,Op%Rot)
34730
34731       return
34732    End Function HR_R
34733
34734    !!----
34735    !!---- Function  Hkl_S(H, Crystalcell)
34736    !!----    integer/real(kind=cp), dimension(3), intent(in) :: h
34737    !!----    type (Crystal_Cell_Type),            intent(in) :: CrystalCell
34738    !!--<<
34739    !!----    Calculates: sin_theta/lamda = 1/(2d)
34740    !!-->>
34741    !!----
34742    !!----  Update: February - 2005
34743    !!
34744
34745    !!--++
34746    !!--++ FUNCTION  HS_I(h, CrystalCell)
34747    !!--++    integer, dimension(3),    intent(in) :: h
34748    !!--++    Type (Crystal_Cell_Type), intent(in) :: CrystalCell
34749    !!--++
34750    !!--++    (OVERLOADED)
34751    !!--++    Calculate sin_theta/lamda = 1/ (2d)
34752    !!--++
34753    !!--++ Update: February - 2005
34754    !!
34755    Function HS_I(H,Crystalcell) Result(S)
34756       !---- Arguments ----!
34757       integer, dimension(3),    intent(in)  :: h
34758       type (Crystal_Cell_Type), intent (in) :: CrystalCell
34759       real(kind=cp)                         :: s
34760
34761       s= 0.5*sqrt( h(1)*h(1)*CrystalCell%GR(1,1) + h(2)*h(2)*CrystalCell%GR(2,2) + &
34762                    h(3)*h(3)*CrystalCell%GR(3,3) + 2.0*h(1)*h(2)*CrystalCell%GR(1,2) + &
34763                2.0*h(1)*h(3)*CrystalCell%GR(1,3) + 2.0*h(2)*h(3)*CrystalCell%GR(2,3) )
34764
34765       return
34766    End Function HS_I
34767
34768    !!--++
34769    !!--++ Function  HS_R(H, Crystalcell)
34770    !!--++    real(kind=cp), dimension(3),       intent(in) :: h
34771    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell
34772    !!--++
34773    !!--++    (OVERLOADED)
34774    !!--++    Calculate sin_theta/lamda = 1/ (2d)
34775    !!--++
34776    !!--++ Update: February - 2005
34777    !!
34778    Function HS_R(H,Crystalcell) Result(S)
34779       !---- Arguments ----!
34780       real(kind=cp), dimension(3),intent(in)  :: h
34781       type (Crystal_Cell_Type),   intent (in) :: CrystalCell
34782       real(kind=cp)                           :: s
34783
34784       s= 0.5*sqrt( h(1)*h(1)*CrystalCell%GR(1,1) + h(2)*h(2)*CrystalCell%GR(2,2) + &
34785                    h(3)*h(3)*CrystalCell%GR(3,3) + 2.0*h(1)*h(2)*CrystalCell%GR(1,2) + &
34786                2.0*h(1)*h(3)*CrystalCell%GR(1,3) + 2.0*h(2)*h(3)*CrystalCell%GR(2,3) )
34787
34788       return
34789
34790    End Function HS_R
34791
34792    !!----
34793    !!----  Function  Unit_Cart_Hkl(H, Crystalcell) Result (U)
34794    !!----     integer/real(kind=cp), dimension(3), intent(in) :: h
34795    !!----     type (Crystal_Cell_Type),            intent(in) :: CrystalCell
34796    !!----
34797    !!----     Calculate a unitary vector in the cartesian crystal frame
34798    !!----     along a reciprocal vector hkl (reciprocal lattice)
34799    !!----
34800    !!---- Update: February - 2005
34801    !!
34802
34803    !!--++
34804    !!--++ Function Unit_Cart_Hkli(H, Crystalcell) Result (U)
34805    !!--++    integer, dimension(3),    intent(in) :: h
34806    !!--++    Type (Crystal_Cell_Type), intent(in) :: CrystalCell
34807    !!--++    real(kind=cp),dimension(3)           :: u
34808    !!--++
34809    !!--++    (OVERLOADED)
34810    !!--++    Calculate a unitary vector in the cartesian crystal
34811    !!--++    frame along a reciprocal vector hkl (reciprocal lattice)
34812    !!--++
34813    !!--++ Update: February - 2005
34814    !!
34815    Function Unit_Cart_HklI(H, Crystalcell) Result (U)
34816       !---- Arguments ----!
34817       integer, dimension(3),    intent(in)  :: h
34818       type (Crystal_Cell_Type), intent (in) :: CrystalCell
34819       real(kind=cp), dimension(3)           :: u
34820
34821       !---- Local Variables ----!
34822       real(kind=cp), dimension(3)           :: v
34823
34824       v=matmul(CrystalCell%GR,real(h))     ![L-2]
34825       u=matmul(CrystalCell%Cr_Orth_cel,v)  ![L-1]
34826       u=u/sqrt(u(1)*u(1)+u(2)*u(2)+u(3)*u(3))
34827
34828       return
34829    End Function Unit_Cart_HklI
34830
34831
34832    !!--++
34833    !!--++ Function Unit_Cart_HklR(H, Crystalcell) Result (U)
34834    !!--++    real(kind=cp), dimension(3),       intent(in) :: h
34835    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell
34836    !!--++    real(kind=cp),dimension(3)                    :: u
34837    !!--++
34838    !!--++    (OVERLOADED)
34839    !!--++    Calculate a unitary vector in the cartesian crystal
34840    !!--++    frame along a reciprocal vector hkl (reciprocal lattice)
34841    !!--++
34842    !!--++ Update: February - 2005
34843    !!
34844    Function Unit_Cart_HklR(H, Crystalcell) Result (U)
34845       !---- Arguments ----!
34846       real(kind=cp), dimension(3),intent(in)  :: h
34847       type (Crystal_Cell_Type),   intent (in) :: CrystalCell
34848       real(kind=cp), dimension(3)             :: u
34849
34850       !---- Local Variables ----!
34851       real(kind=cp), dimension(3)             :: v
34852
34853       v=matmul(CrystalCell%GR,h)
34854       u=matmul(CrystalCell%Cr_Orth_cel,v)
34855       u=u/sqrt(u(1)*u(1)+u(2)*u(2)+u(3)*u(3))
34856
34857       return
34858    End Function Unit_Cart_HklR
34859
34860    !---- Subroutines ----!
34861
34862    !!--++
34863    !!--++ Subroutine Glide_Planes_Conditions(Spacegroup, iunit)
34864    !!--++    type (Space_Group_Type), intent(in) :: Spacegroup
34865    !!--++    integer,optional,        intent(in) :: iunit
34866    !!--++
34867    !!--++    Reflections Conditions according with I.T. Table 2.2.13.2
34868    !!--++    space.
34869    !!--++
34870    !!--++ Update: May - 2005
34871    !!
34872    Subroutine Glide_Planes_Conditions(Spacegroup,Iunit)
34873       !---- Arguments ----!
34874       type (Space_Group_Type), intent(in)     :: spacegroup
34875       integer, optional,       intent(in)     :: iunit
34876
34877       !---- Local variables ----!
34878       integer               :: h, k,l, m
34879       integer               :: n, n_ext
34880       integer, dimension(3) :: hh
34881       integer               :: num_exti
34882       logical               :: zonal_condition
34883
34884       zonal_condition   = .false.
34885
34886       if (present(iunit) ) then
34887          write(unit=iunit,fmt=*) " "
34888          write(unit=iunit,fmt=*) " >>> Zonal reflections conditions for glide planes:"
34889          write(unit=iunit,fmt=*) "---------------------------------------------------"
34890          write(unit=iunit,fmt=*) " "
34891       end if
34892
34893       !GLIDE PLANES and screw axes: table 2.13.2
34894       !-------------
34895       !
34896       !        0 k l:    k=2n    b/2             monoclinic, orthorhombic, tetragonal and cubic
34897       !        0 k l:    l=2n    c/2             monoclinic, orthorhombic, tetragonal and cubic
34898       !        0 k l:  k+l=2n    b/2 +  c/2      monoclinic, orthorhombic, tetragonal and cubic
34899       !        0 k l:  k+l=4n    b/4 +- c/4      orthorhombic and cubic
34900       !
34901       !
34902       !        h 0 l:    h=2n    a/2             monoclinic, orthorhombic, tetragonal and cubic
34903       !        h 0 l:    l=2n    c/2             monoclinic, orthorhombic, tetragonal and cubic
34904       !        h 0 l:  l+h=2n    c/2 +  a/2      monoclinic, orthorhombic, tetragonal and cubic
34905       !        h 0 l:  l+h=4n    c/4 +- a/4      orthorhombic and cubic
34906       !
34907       !        h k 0:    h=2n    a/2             monoclinic, orthorhombic, tetragonal and cubic
34908       !        h k 0:    k=2n    b/2             monoclinic, orthorhombic, tetragonal and cubic
34909       !        h k 0:  h+k=2n    a/2 +  b/2      monoclinic, orthorhombic, tetragonal and cubic
34910       !        h k 0:  h+k=4n    a/4 +- b/4      monoclinic, orthorhombic, tetragonal and cubic
34911
34912       if (SpaceGroup%CrystalSys(1:10) == "Monoclinic"   .or. SpaceGroup%CrystalSys(1:10) == "Tetragonal" .or.     &
34913           SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic") then
34914
34915          !---- glide plane b/2:
34916          ! Hkl_Ref_Conditions(7)  =   "(0 k l)      k=2n : 0yz glide plane with b/2 translation"
34917          num_exti = 7
34918          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
34919          n_ext = 0   ! nombre de reflecions obeissant a la regle
34920          do k=-6, 6
34921             do l=-6, 6
34922                hh(1)=0
34923                hh(2)=k
34924                hh(3)=l
34925                m =  k
34926                if (m /= int(m/2)*2) then
34927                   n=n+1
34928                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
34929                end if
34930             end do   ! l loop
34931          end do    ! k loop
34932          if (n==n_ext) then
34933             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
34934             zonal_condition = .true.
34935          end if
34936
34937          !---- glide plane c/2:
34938          ! Hkl_Ref_Conditions(8)  =   "(0 k l)      l=2n : 0yz glide plane with c/2 translation"
34939          num_exti = 8
34940          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
34941          n_ext = 0   ! nombre de reflecions obeissant a la regle
34942          do k=-6, 6
34943             do l=-6, 6
34944                hh(1)=0
34945                hh(2)=k
34946                hh(3)=l
34947                m =  l
34948                if (m /= int(m/2)*2) then
34949                   n=n+1
34950                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
34951                end if
34952             end do   ! l loop
34953          end do    ! k loop
34954          if (n==n_ext) then
34955             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
34956             zonal_condition = .true.
34957          end if
34958
34959          !---- glide plane b/2 + c/2:
34960          !Hkl_Ref_Conditions(9)  =   "(0 k l)    k+l=2n : 0yz glide plane with b/2 + c/2 translation"
34961          num_exti = 9
34962          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
34963          n_ext = 0   ! nombre de reflecions obeissant a la regle
34964          do k=-6, 6
34965             do l=-6, 6
34966                hh(1)=0
34967                hh(2)=k
34968                hh(3)=l
34969                m =  k+l
34970                if (m /= int(m/2)*2) then
34971                   n=n+1
34972                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
34973                end if
34974             end do   ! l loop
34975          end do    ! k loop
34976          if (n==n_ext) then
34977             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
34978             zonal_condition = .true.
34979          end if
34980       end if    ! fin de la condition "if monoclinic, tetragonal, ortho, cubic
34981
34982
34983       if (SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic") then
34984          !---- glide plane b/4 + c/4:
34985          ! Hkl_Ref_Conditions(10)  =   "(0 k l)    k+l=4n : 0yz glide plane with b/4 +- c/4 translation"
34986          num_exti = 10
34987          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
34988          n_ext = 0   ! nombre de reflecions obeissant a la regle
34989          do k=-6, 6, 1
34990             do l=-6, 6, 1
34991                hh(1)=0
34992                hh(2)=k
34993                hh(3)=l
34994                m =  k+l
34995                if (m /= int(m/4)*4) then
34996                   n=n+1
34997                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
34998                end if
34999             end do   ! l loop
35000          end do    ! k loop
35001          if (n==n_ext) then
35002             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35003             zonal_condition = .true.
35004          end if
35005       end if ! fin de la condition "if ortho, cubic
35006
35007       if (SpaceGroup%CrystalSys(1:10) == "Monoclinic"   .or. SpaceGroup%CrystalSys(1:10) == "Tetragonal" .or.     &
35008          SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic") then
35009
35010          !---- glide plane a/2:
35011          !  Hkl_Ref_Conditions(11)  =   "(h 0 l)      h=2n : x0z glide plane with a/2 translation"
35012          num_exti = 11
35013          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35014          n_ext = 0   ! nombre de reflecions obeissant a la regle
35015          do h=-6, 6
35016             do l=-6, 6
35017                hh(1)=h
35018                hh(2)=0
35019                hh(3)=l
35020                m =  h
35021                if (m /= int(m/2)*2) then
35022                   n=n+1
35023                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35024                end if
35025             end do   ! l loop
35026          end do     ! h loop
35027          if (n==n_ext) then
35028             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35029             zonal_condition = .true.
35030          end if
35031
35032          !---- glide plane c/2:
35033          ! Hkl_Ref_Conditions(12) =   "(h 0 l)      l=2n : x0z glide plane with c/2 translation"
35034          num_exti = 12
35035          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35036          n_ext = 0   ! nombre de reflecions obeissant a la regle
35037          do h=-6, 6
35038             do l=-6, 6
35039                hh(1)=h
35040                hh(2)=0
35041                hh(3)=l
35042                m =  l
35043                if (m /= int(m/2)*2) then
35044                   n=n+1
35045                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35046                end if
35047             end do   ! l loop
35048          end do     ! h loop
35049          if (n==n_ext) then
35050             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35051             zonal_condition = .true.
35052          end if
35053
35054          !---- glide plane c/2 + a/2:
35055          ! Hkl_Ref_Conditions(13) =   "(h 0 l)    l+h=2n : x0z glide plane with a/2 + c/2 translations"
35056          num_exti = 13
35057          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35058          n_ext = 0   ! nombre de reflecions obeissant a la regle
35059          do h=-6, 6
35060             do l=-6, 6
35061                hh(1)=h
35062                hh(2)=0
35063                hh(3)=l
35064                m =  h+l
35065                if (m /= int(m/2)*2) then
35066                   n=n+1
35067                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35068                end if
35069             end do   ! l loop
35070          end do     ! h loop
35071          if (n==n_ext) then
35072             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35073             zonal_condition = .true.
35074          end if
35075       end if  ! fin de la condition "if monoclinic, tetragonal, ortho, cubic
35076
35077       if (SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic") then
35078
35079          !---- glide plane c/4 + a/4:
35080          ! Hkl_Ref_Conditions(14) =   "(h 0 l)    l+h=4n : x0z glide plane with a/4 +- c/4 translations"
35081          num_exti = 14
35082          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35083          n_ext = 0   ! nombre de reflecions obeissant a la regle
35084          do h=-6, 6
35085             do l=-6, 6
35086                hh(1)=h
35087                hh(2)=0
35088                hh(3)=l
35089                m =  h+l
35090                if (m /= int(m/4)*4) then
35091                   n=n+1
35092                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35093                end if
35094             end do   ! l loop
35095          end do     ! h loop
35096          if (n==n_ext) then
35097             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35098             zonal_condition = .true.
35099          end if
35100       end if ! fin de la condition "if ortho, cubic
35101
35102       if (SpaceGroup%CrystalSys(1:10) == "Monoclinic"   .or. SpaceGroup%CrystalSys(1:10) == "Tetragonal" .or.     &
35103          SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic") then
35104
35105          !---- glide plane a/2:
35106          ! Hkl_Ref_Conditions(15) =   "(h k 0)      h=2n : xy0 glide plane with a/2 translation"
35107          num_exti = 15
35108          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35109          n_ext = 0   ! nombre de reflecions obeissant a la regle
35110          do h=-6, 6
35111             do k=-6, 6
35112                hh(1)=h
35113                hh(2)=k
35114                hh(3)=0
35115                m =  h
35116                if (m /= int(m/2)*2) then
35117                   n=n+1
35118                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35119                end if
35120             end do    ! k loop
35121          end do     ! h loop
35122          if (n==n_ext) then
35123             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35124             zonal_condition = .true.
35125          end if
35126
35127          !---- glide plane b/2:
35128          !Hkl_Ref_Conditions(16) =   "(h k 0)      k=2n : xy0 glide plane with b/2 translation"
35129          num_exti = 16
35130          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35131          n_ext = 0   ! nombre de reflecions obeissant a la regle
35132          do h=-6, 6
35133             do k=-6, 6
35134                hh(1)=h
35135                hh(2)=k
35136                hh(3)=0
35137                m =  k
35138                if (m /= int(m/2)*2) then
35139                   n=n+1
35140                  if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35141                end if
35142             end do    ! k loop
35143          end do     ! h loop
35144          if (n==n_ext) then
35145             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35146             zonal_condition = .true.
35147          end if
35148
35149          !---- glide plane a/2 + b/2:
35150          ! Hkl_Ref_Conditions(17) =   "(h k 0)    h+k=2n : xy0 glide plane with a/2 + b/2 translations"
35151          num_exti = 17
35152          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35153          n_ext = 0   ! nombre de reflecions obeissant a la regle
35154          do h=-6, 6
35155             do k=-6, 6
35156                hh(1)=h
35157                hh(2)=k
35158                hh(3)=0
35159                m =  h+k
35160                if (m /= int(m/2)*2) then
35161                   n=n+1
35162                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35163                end if
35164             end do    ! k loop
35165          end do     ! h loop
35166          if (n==n_ext) then
35167             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35168             zonal_condition = .true.
35169          end if
35170       end if  ! fin de la condition "if monoclinic, tetragonal, ortho, cubic
35171
35172       if (SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic") then
35173          !---- glide plane a/4 + b/4:
35174          ! Hkl_Ref_Conditions(18) =   "(h k 0)    h+k=4n : xy0 glide plane with a/4 +- b/4 translations"
35175          num_exti = 18
35176          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
35177          n_ext = 0   ! nombre de reflecions obeissant a la regle
35178          do h=-6, 6, 1
35179             do k=-6, 6, 1
35180                hh(1)=h
35181                hh(2)=k
35182                hh(3)=0
35183                m =  h+k
35184                if (m /= int(m/4)*4) then
35185                   n=n+1
35186                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
35187                end if
35188             end do    ! k loop
35189          end do     ! h loop
35190          if (n==n_ext) then
35191             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35192             zonal_condition = .true.
35193          end if
35194       end if  ! fin de la condition "if ortho, cubic
35195
35196       if (SpaceGroup%SPG_Latsy(1:1) == "h") then
35197          !---- glide plane with c/2 translation: hexagonal
35198          !  Hkl_Ref_Conditions(19) =   "(  h  -h   0 l) l=2n : (11-20) glide plane with c/2 translation (c)"
35199          num_exti = 19
35200          n = 0
35201          n_ext = 0
35202          do h=-6, +6, 1
35203             do l=-6, +6, 1
35204                hh(1)=h
35205                hh(2)=-h
35206                hh(3)=l
35207                m=l
35208                if (m /=int(m/2)*2) then
35209                   n=n+1
35210                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35211                end if
35212             end do  ! l loop
35213          end do   ! h loop
35214          if (n==n_ext) then
35215             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35216             zonal_condition = .true.
35217          end if
35218
35219          !---- glide plane with c/2 translation: hexagonal
35220          !  Hkl_Ref_Conditions(20) =   "(  0   k  -k l) l=2n : (-2110) glide plane with c/2 translation (c)"
35221          num_exti = 20
35222          n = 0
35223          n_ext = 0
35224          do k=-6, +6, 1
35225             do l=-6, +6, 1
35226                hh(1)=0
35227                hh(2)=k
35228                hh(3)=l
35229                m=l
35230                if (m /=int(m/2)*2) then
35231                   n=n+1
35232                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35233                end if
35234             end do  ! l loop
35235          end do   ! h loop
35236          if (n==n_ext) then
35237             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35238             zonal_condition = .true.
35239          end if
35240
35241          !---- glide plane with c/2 translation: hexagonal
35242          !Hkl_Ref_Conditions(21) =   "( -h   0   h l) l=2n : (1-210) glide plane with c/2 translation (c)"
35243          num_exti = 21
35244          n = 0
35245          n_ext = 0
35246          do h=-6, 6
35247             do l=-6, 6
35248                hh(1)=-h
35249                hh(2)=0
35250                hh(3)=l
35251                m=l
35252                if (m /=int(m/2)*2) then
35253                   n=n+1
35254                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35255                end if
35256             end do  ! l loop
35257          end do   ! h loop
35258          if (n==n_ext) then
35259             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35260             zonal_condition = .true.
35261          end if
35262
35263          !---- glide plane with c/2 translation: hexagonal
35264          ! Hkl_Ref_Conditions(22) =   "(  h   h -2h l) l=2n : (1-100) glide plane with c/2 translation (c)"
35265          num_exti = 22
35266          n = 0
35267          n_ext = 0
35268          do h=-6, +6, 1
35269             do l=-6, +6, 1
35270                hh(1)=h
35271                hh(2)=h
35272                hh(3)=l
35273                m=l
35274                if (m /=int(m/2)*2) then
35275                   n=n+1
35276                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35277                end if
35278             end do  ! l loop
35279          end do   ! h loop
35280          if (n==n_ext) then
35281             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35282             zonal_condition = .true.
35283          end if
35284
35285          !---- glide plane with c/2 translation: hexagonal
35286          !  Hkl_Ref_Conditions(23) =   "(-2h   h   h l) l=2n : (01-10) glide plane with c/2 translation (c)"
35287          num_exti = 23
35288          n = 0
35289          n_ext = 0
35290          do h=-6, +6, 1
35291             do l=-6, +6, 1
35292                hh(1)=-2*h
35293                hh(2)=h
35294                hh(3)=l
35295                m=l
35296                if (m /=int(m/2)*2) then
35297                   n=n+1
35298                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35299                end if
35300             end do  ! l loop
35301          end do   ! h loop
35302          if (n==n_ext) then
35303             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35304             zonal_condition = .true.
35305          end if
35306
35307          !---- glide plane with c/2 translation: hexagonal
35308          !  Hkl_Ref_Conditions(24) =   "(  h -2h   h l) l=2n : (-1010) glide plane with c/2 translation (c)"
35309          num_exti = 24
35310          n = 0
35311          n_ext = 0
35312          do h=-6, +6, 1
35313             do l=-6, +6, 1
35314                hh(1)=h
35315                hh(2)=-2*h
35316                hh(3)=l
35317                m=l
35318                if (m /=int(m/2)*2) then
35319                   n=n+1
35320                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35321                end if
35322             end do  ! l loop
35323          end do   ! h loop
35324          if (n==n_ext) then
35325             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35326             zonal_condition = .true.
35327          end if
35328       end if ! fin de la condition if hexagonal
35329
35330       !25: glide plane with c/2 translation: rhomboedral
35331       !  Hkl_Ref_Conditions(25) =  "(  h  h  l) l=2n : (1-10) glide plane with c/2 translation (c,n)"
35332       num_exti = 25
35333       n = 0
35334       n_ext = 0
35335       do h=-6, +6, 1
35336          do l=-6, +6, 1
35337             hh(1)=h
35338             hh(2)=h
35339             hh(3)=l
35340             m=l
35341             if (m /=int(m/2)*2) then
35342                n=n+1
35343                if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35344             end if
35345          end do  ! l loop
35346       end do   ! h loop
35347       if (n==n_ext) then
35348          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35349          zonal_condition = .true.
35350       end if
35351
35352       !---- glide plane with c/2 translation: rhomboedral
35353       !  Hkl_Ref_Conditions(26) =  "(  h  k  k) h=2n : (01-1) glide plane with a/2 translation (a,n)"
35354       num_exti = 26
35355       n = 0
35356       n_ext = 0
35357       do h=-6, +6, 1
35358          do k=-6, +6, 1
35359             hh(1)=h
35360             hh(2)=k
35361             hh(3)=k
35362             m=h
35363             if (m /=int(m/2)*2) then
35364                n=n+1
35365                if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35366             end if
35367          end do  ! l loop
35368       end do   ! h loop
35369       if (n==n_ext) then
35370          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35371          zonal_condition = .true.
35372       end if
35373
35374       !27: glide plane with c/2 translation: rhomboedral
35375       !  Hkl_Ref_Conditions(27) =  "(  h  k  h) k=2n : (-101) glide plane with b/2 translation (b,n)"
35376       num_exti = 27
35377       n = 0
35378       n_ext = 0
35379       do h=-6, +6, 1
35380          do k=-6, +6, 1
35381             hh(1)=h
35382             hh(2)=k
35383             hh(3)=h
35384             m=k
35385             if (m /=int(m/2)*2) then
35386                n=n+1
35387                if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35388             end if
35389          end do  ! l loop
35390       end do   ! h loop
35391       if (n==n_ext) then
35392          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35393          zonal_condition = .true.
35394       end if
35395
35396       if (SpaceGroup%CrystalSys(1:10) == "Tetragonal" .or. SpaceGroup%CrystalSys(1:5) == "Cubic") then
35397          !---- glide plane with c/2 translation: tetragonal + cubic
35398          !  Hkl_Ref_Conditions(28) =  "(  h  h  l)    l=2n : (1-10) glide plane with c/2 translation (c,n)"
35399          num_exti = 28
35400          n = 0
35401          n_ext = 0
35402          do h=-6, +6, 1
35403             do l=-6, +6, 1
35404                hh(1)=h
35405                hh(2)=h
35406                hh(3)=l
35407                m=l
35408                if (m /=int(m/2)*2) then
35409                   n=n+1
35410                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35411                end if
35412             end do  ! l loop
35413          end do   ! h loop
35414          if (n==n_ext) then
35415             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35416             zonal_condition = .true.
35417          end if
35418
35419          !---- glide plane with a/4 +- b/4 +- c/4 translation: tetragonal + cubic
35420          !  Hkl_Ref_Conditions(29) =  "(  h  h  l) 2h+l=4n : (1-10) glide plane with a/4 +- b/4 +- c/4 translation (d)"
35421          num_exti = 29
35422          n = 0
35423          n_ext = 0
35424          do h=-6, +6, 1
35425             do l=-6, +6, 1
35426                hh(1)=h
35427                hh(2)=h
35428                hh(3)=l
35429                m=2*h+l
35430                if (m /=int(m/4)*4) then
35431                   n=n+1
35432                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35433                end if
35434             end do  ! l loop
35435          end do   ! h loop
35436          if (n==n_ext) then
35437             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35438             zonal_condition = .true.
35439          end if
35440
35441          !30: glide plane with c/2 translation: tetragonal + cubic
35442          !  Hkl_Ref_Conditions(30) =  "(  h -h  l)    l=2n : (110)  glide plane with c/2 translation (c,n)"
35443          num_exti = 30
35444          n = 0
35445          n_ext = 0
35446          do h=-6, +6, 1
35447             do l=-6, +6, 1
35448                hh(1)=h
35449                hh(2)=-h
35450                hh(3)=l
35451                m=l
35452                if (m /=int(m/2)*2) then
35453                   n=n+1
35454                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35455                end if
35456             end do  ! l loop
35457          end do   ! h loop
35458          if (n==n_ext) then
35459             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35460             zonal_condition = .true.
35461          end if
35462
35463          ! 31: glide plane with a/4 +- b/4 +- c/4 translation: tetragonal + cubic
35464          !  Hkl_Ref_Conditions(31) = "(  h -h  l) 2h+l=4n : (110)  glide plane with a/4 +- b/4 +- c/4 translation (d)"
35465          num_exti = 31
35466          n = 0
35467          n_ext = 0
35468          do h=-6, +6, 1
35469             do l=-6, +6, 1
35470                hh(1)=h
35471                hh(2)=-h
35472                hh(3)=l
35473                m=2*h+l
35474                if (m /=int(m/4)*4) then
35475                   n=n+1
35476                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35477                end if
35478             end do  ! l loop
35479          end do   ! h loop
35480          if (n==n_ext) then
35481             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35482             zonal_condition = .true.
35483          end if
35484       end if   ! fin de la condition "if tetragonal .or. cubic
35485
35486       if (SpaceGroup%CrystalSys(1:5) == "Cubic") then
35487          !---- glide plane with a/2 translation: tetragonal + cubic
35488          !  Hkl_Ref_Conditions(32) = "(  h  k  k)    h=2n : (01-1) glide plane with a/2 translation (a,n)"
35489          num_exti = 32
35490          n = 0
35491          n_ext = 0
35492          do h=-6, +6, 1
35493             do k=-6, +6, 1
35494                hh(1)=h
35495                hh(2)=k
35496                hh(3)=k
35497                m=h
35498                if (m /=int(m/2)*2) then
35499                   n=n+1
35500                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35501                end if
35502             end do  ! l loop
35503          end do   ! h loop
35504          if (n==n_ext) then
35505             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35506             zonal_condition = .true.
35507          end if
35508
35509          !---- glide plane with +-a/4 +- b/4 +- c/4 translation: tetragonal + cubic
35510          !  Hkl_Ref_Conditions(33) = "(  h  k  k) 2k+h=4n : (01-1) glide plane with +-a/4 + b/4 +- c/4 translation (d)"
35511          num_exti = 33
35512          n = 0
35513          n_ext = 0
35514          do h=-6, +6, 1
35515             do k=-6, +6, 1
35516                hh(1)=h
35517                hh(2)=k
35518                hh(3)=k
35519                m=2*k+h
35520                if (m /=int(m/4)*4) then
35521                   n=n+1
35522                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35523                end if
35524             end do  ! l loop
35525          end do   ! h loop
35526          if (n==n_ext) then
35527             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35528             zonal_condition = .true.
35529          end if
35530
35531          !34: glide plane with a/2 translation: tetragonal + cubic
35532          !  Hkl_Ref_Conditions(34) =  "(  h  k -k)    h=2n : (011)  glide plane with a/2 translation (a,n)"
35533          num_exti = 34
35534          n = 0
35535          n_ext = 0
35536          do h=-6, +6, 1
35537             do k=-6, +6, 1
35538                hh(1)=h
35539                hh(2)=k
35540                hh(3)=-k
35541                m=h
35542                if (m /=int(m/2)*2) then
35543                   n=n+1
35544                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35545                end if
35546             end do  ! l loop
35547          end do   ! h loop
35548          if (n==n_ext) then
35549             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35550             zonal_condition = .true.
35551          end if
35552
35553          ! 35: glide plane with a/4 +- b/4 +- c/4 translation: tetragonal + cubic
35554          !  Hkl_Ref_Conditions(351) = "(  h  k -k) 2k+h=4n : (011)  glide plane with +-a/4 + b/4 +- c/4 translation (d)"
35555          num_exti = 35
35556          n = 0
35557          n_ext = 0
35558          do h=-6, +6, 1
35559             do k=-6, +6, 1
35560                hh(1)=h
35561                hh(2)=k
35562                hh(3)=-k
35563                m=2*k+h
35564                if (m /=int(m/4)*4) then
35565                   n=n+1
35566                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35567                end if
35568             end do  ! l loop
35569          end do   ! h loop
35570          if (n==n_ext) then
35571             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35572             zonal_condition = .true.
35573          end if
35574
35575          !36: glide plane with b/2 translation: tetragonal + cubic
35576          !  Hkl_Ref_Conditions(36) = "(  h  k  h)    k=2n : (-101) glide plane with b/2 translation (b,n)"
35577          num_exti = 36
35578          n = 0
35579          n_ext = 0
35580          do h=-6, +6, 1
35581             do k=-6, +6, 1
35582                hh(1)=h
35583                hh(2)=k
35584                hh(3)=h
35585                m=k
35586                if (m /=int(m/2)*2) then
35587                   n=n+1
35588                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35589                end if
35590             end do  ! l loop
35591          end do   ! h loop
35592          if (n==n_ext) then
35593             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35594             zonal_condition = .true.
35595          end if
35596
35597          !37: glide plane with +-a/4 +- b/4 +- c/4 translation: tetragonal + cubic
35598          !  Hkl_Ref_Conditions(33) = "(  h  k  h) 2h+k=4n : (-101) glide plane with +-a/4 + b/4 +- c/4 translation (d)"
35599          num_exti = 37
35600          n = 0
35601          n_ext = 0
35602          do h=-6, +6, 1
35603             do k=-6, +6, 1
35604                hh(1)=h
35605                hh(2)=k
35606                hh(3)=h
35607                m=2*h+k
35608                if (m /=int(m/4)*4) then
35609                   n=n+1
35610                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35611                end if
35612             end do  ! l loop
35613          end do   ! h loop
35614          if (n==n_ext) then
35615             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35616             zonal_condition = .true.
35617          end if
35618
35619          !38: glide plane with b/2 translation: tetragonal + cubic
35620          !  Hkl_Ref_Conditions(38) = "( -h  k  h)    k=2n : (101)  glide plane with b/2 translation (b,n)"
35621          num_exti = 38
35622          n = 0
35623          n_ext = 0
35624          do h=-6, +6, 1
35625             do k=-6, +6, 1
35626                hh(1)=-h
35627                hh(2)=k
35628                hh(3)=h
35629                m=k
35630                if (m /=int(m/2)*2) then
35631                   n=n+1
35632                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35633                end if
35634             end do  ! l loop
35635          end do   ! h loop
35636          if (n==n_ext) then
35637             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35638             zonal_condition = .true.
35639          end if
35640
35641          ! 39: glide plane with a/4 +- b/4 +- c/4 translation: tetragonal + cubic
35642          !  Hkl_Ref_Conditions(39) = "( -h  k  h) 2h+k=4n : (101)  glide plane with +-a/4 + b/4 +- c/4 translation (d)"
35643          num_exti = 39
35644          n = 0
35645          n_ext = 0
35646          do h=-6, +6, 1
35647             do k=-6, +6, 1
35648                hh(1)=-h
35649                hh(2)=k
35650                hh(3)=h
35651                m=2*h+k
35652                if (m /=int(m/4)*4) then
35653                   n=n+1
35654                   if (hkl_absent(hh, spacegroup)) n_ext=n_ext+1
35655                end if
35656             end do  ! l loop
35657          end do   ! h loop
35658          if (n==n_ext) then
35659             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
35660             zonal_condition = .true.
35661          end if
35662       end if  ! fin de la condition "if cubic
35663
35664       if (.not. zonal_condition)   then
35665          if (present(iunit)) write(unit=iunit,fmt=*) "     =====>>> no zonal reflection condition"
35666       end if
35667
35668       return
35669    End Subroutine Glide_Planes_Conditions
35670
35671    !!----
35672    !!---- Subroutine Hkl_Equiv_List(H,Spacegroup,Friedel,Mul,Hlist)
35673    !!----    integer/real(kind=cp), dimension(3),                    intent(in) :: h
35674    !!----    type (Space_Group_Type),                                intent(in) :: SpaceGroup
35675    !!----    logical,                                                intent(in) :: Friedel
35676    !!----    integer,                                                intent(out):: mul
35677    !!----    integer/real(kind=cp),dimension(3,SpaceGroup%numops*2), intent(out):: hlist
35678    !!----
35679    !!----    Calculate the multiplicity of the reflection and the list of all
35680    !!----    equivalent reflections. Friedel law assumed if Friedel=.true.
35681    !!----
35682    !!---- Update: February - 2005
35683    !!
35684
35685    !!--++
35686    !!--++ Subroutine Hkl_Equiv_ListI(H,Spacegroup,Friedel,Mul,Hlist)
35687    !!--++    integer, dimension(3),                    intent(in) :: h
35688    !!--++    type (Space_Group_Type),                  intent(in) :: SpaceGroup
35689    !!--++    logical,                                  intent(in) :: Friedel
35690    !!--++    integer,                                  intent(out):: mul
35691    !!--++    integer,dimension(3,SpaceGroup%numops*2), intent(out):: hlist
35692    !!--++
35693    !!--++    (OVERLOADED)
35694    !!--++    Calculate the multiplicity of the reflection and the list of all
35695    !!--++    equivalent reflections. Friedel law assumed if Friedel=.true.
35696    !!--++
35697    !!--++ Update: February - 2005
35698    !!
35699    Subroutine Hkl_Equiv_Listi(H,Spacegroup,Friedel,Mul,Hlist)
35700       !---- Arguments ----!
35701       integer, dimension(3),                     intent (in) :: h
35702       Type (Space_Group_Type),                   intent (in) :: SpaceGroup
35703       Logical,                                   intent (in) :: Friedel
35704       integer,                                   intent(out) :: mul
35705       integer, dimension(3,SpaceGroup%numops*2), intent(out) :: hlist
35706
35707       !---- Local Variables ----!
35708       logical              :: esta
35709       integer, dimension(3):: k
35710       integer              :: i,j,ng
35711
35712       hlist = 0
35713       ng=SpaceGroup%numops
35714       mul=1
35715       hlist(:,1)=h(:)
35716       do i=2,ng
35717          k = hkl_r(h,SpaceGroup%SymOp(i))
35718          esta=.false.
35719          do j=1,mul
35720             if (hkl_equal(k,hlist(:,j)) .or. (hkl_equal(-k,hlist(:,j)) .and. Friedel)) then
35721                esta=.true.
35722                exit
35723             end if
35724          end do
35725          if (esta) cycle
35726          mul=mul+1
35727          hlist(:,mul) = k
35728       end do
35729
35730       if (Friedel .or. SpaceGroup%centred == 2) then
35731          j=mul
35732          mul=mul*2
35733          do i=j+1,mul
35734             hlist(:,i)=-hlist(:,i-j)
35735          end do
35736       end if
35737
35738       return
35739    End Subroutine Hkl_Equiv_Listi
35740
35741    !!--++
35742    !!--++ Subroutine Hkl_Equiv_ListR(H,Spacegroup,Friedel,Mul,Hlist)
35743    !!--++    real(kind=cp),    dimension(3),                    intent(in) :: h
35744    !!--++    type (Space_Group_Type),                           intent(in) :: SpaceGroup
35745    !!--++    Logical,                                           intent(in) :: Friedel
35746    !!--++    integer,                                           intent(out):: mul     !multiplicity
35747    !!--++    real(kind=cp),   dimension(3,SpaceGroup%numops*2), intent(out):: hlist
35748    !!--++
35749    !!--++    (OVERLOADED)
35750    !!--++    Calculate the multiplicity of the reflection and the list of all
35751    !!--++    equivalent reflections. Friedel law assumed if Friedel=.true.
35752    !!--++
35753    !!--++ Update: February - 2005
35754    !!
35755    Subroutine Hkl_Equiv_ListR(H,Spacegroup,Friedel,Mul,Hlist)
35756       !---- Arguments ----!
35757       real(kind=cp), dimension(3),                     intent (in) :: h
35758       Type (Space_Group_Type),                         intent (in) :: SpaceGroup
35759       Logical,                                         intent (in) :: Friedel
35760       integer,                                         intent(out) :: mul
35761       real(kind=cp), dimension(3,SpaceGroup%numops*2), intent (out) :: hlist
35762
35763       !---- Local Variables ----!
35764       logical                    :: esta
35765       real(kind=cp), dimension(3):: k
35766       integer                    :: i,j,ng
35767
35768       hlist = 0.0
35769       ng=SpaceGroup%numops
35770       mul=1
35771       hlist(:,1)=h(:)
35772       do i=2,ng
35773          k = hkl_r(h,SpaceGroup%SymOp(i))
35774          esta=.false.
35775          do j=1,mul
35776             if (hkl_equal(k,hlist(:,j)) .or. (hkl_equal(-k,hlist(:,j)) .and. Friedel)) then
35777                esta=.true.
35778                exit
35779             end if
35780          end do
35781          if (esta) cycle
35782          mul=mul+1
35783          hlist(:,mul) = k
35784       end do
35785       if (Friedel .or. SpaceGroup%centred == 2) then
35786          j=mul
35787          mul=mul*2
35788          do i=j+1,mul
35789             hlist(:,i)=-hlist(:,i-j)
35790          end do
35791       end if
35792
35793       return
35794    End Subroutine Hkl_Equiv_Listr
35795
35796    !!----
35797    !!---- Subroutine  Hkl_Gen(Crystalcell,Spacegroup,Friedel,Value1,Value2,Num_Ref,Reflex)
35798    !!----    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell     !Unit cell object
35799    !!----    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup      !Space Group object
35800    !!----    Logical,                           intent(in) :: Friedel         !If true, Friedel law applied
35801    !!----    real(kind=cp),                     intent(in) :: value1,value2   !Range in SinTheta/Lambda
35802    !!----    Integer            ,               intent(out):: Num_Ref         !Number of generated reflections
35803    !!----    Type (Reflect_Type), dimension(:), intent(out):: Reflex          !List of generated hkl,mult, s
35804    !!----
35805    !!----    Calculate unique reflections between two values of
35806    !!----    sin_theta/lambda.  The output is not ordered.
35807    !!----
35808    !!---- Update: February - 2005
35809    !!
35810    Subroutine Hkl_Gen(Crystalcell,Spacegroup,Friedel,Value1,Value2,Num_Ref,Reflex)
35811       !---- Arguments ----!
35812       type (Crystal_Cell_Type),          intent(in)     :: crystalcell
35813       type (Space_Group_Type) ,          intent(in)     :: spacegroup
35814       Logical,                           intent(in)     :: Friedel
35815       real(kind=cp),                     intent(in)     :: value1,value2
35816       integer,                           intent(out)    :: num_ref
35817       type (Reflect_Type), dimension(:), intent(out)    :: reflex
35818
35819       !---- Local variables ----!
35820       real(kind=cp)         :: vmin,vmax,sval
35821       integer               :: h,k,l,hmin,kmin,lmin,hmax,kmax,lmax, maxref
35822       integer, dimension(3) :: hh,kk,nulo
35823       character(len=2)      :: inf
35824
35825       nulo=0
35826       maxref=size(reflex)
35827       vmin=min(value1,value2)
35828       vmax=max(value1,value2)
35829       hmax=nint(CrystalCell%cell(1)*2.0*vmax+1.0)
35830       kmax=nint(CrystalCell%cell(2)*2.0*vmax+1.0)
35831       lmax=nint(CrystalCell%cell(3)*2.0*vmax+1.0)
35832       lmin= 0  ! l positive or zero except for -3 1 m (see below)
35833
35834       !---- Select approximate region to generate reflections depending
35835       !---- on the space group. This allows a faster generation.
35836       select Case(SpaceGroup%NumSpg)
35837          case (1:2)                 ! -1    -> hkl: l >=0; hk0: h >=0; 0k0: k >=0
35838             hmin=-hmax
35839             kmin=-kmax
35840
35841          case (3:15)                ! 2/m
35842             inf(1:2)=adjustl(Spacegroup%info(1:2))
35843             if(inf(1:1) == "-") inf(1:1)=inf(2:2)
35844             select case (inf(1:1))
35845                case ("b")     !       -> hkl: k >=0, l >=0; hk0: h >=0
35846                   hmin=-hmax
35847                   kmin=0
35848                case ("c")     !       -> hkl: k >=0, l >=0; h0l: h >=0
35849                   hmin=-hmax
35850                   kmin=0
35851                case ("a")     !       -> hkl: h >=0, l >=0; 0kl: l >=0  Provisional (to be tested)
35852                   kmin=-kmax
35853                   hmin=0
35854                case default
35855                   hmin=-hmax
35856                   kmin=0
35857             end select
35858
35859          case (16:74)         ! mmm   -> hkl: h >=0, k >=0, l >=0
35860             hmin=0
35861             kmin=0
35862
35863          case (75:88)         ! 4/m   -> hkl: h >=0, l >=0, k >=0 if h = 0
35864                               !                             k > 0 if h > 0
35865             hmin=0
35866             kmin=0
35867
35868          case (89:142)        ! 4/mmm -> hkl: h >=0, k>=0, l>=0, h >=k
35869             hmin=0
35870             kmin=0
35871
35872          case (143:148)       ! -3    -> hkl: h+k>0, l>0 ;  hk0: h>0, k>=0
35873             hmin=0
35874             kmin=-kmax
35875
35876          case (149,151,153,157,159,162,163) ! -3 1 m  -> hkl: h>=0,h>=k>0 ; h0l: h>=0,l>=0
35877             hmin=0
35878             kmin=0
35879             lmin=-lmax
35880
35881          case (150,152,154,155,156,158,160,161,164,165,166,167)
35882                              ! -3 m   -> hkl: h>=0 h>=k ; hhl: h>=0,l>=0
35883             hmin=0
35884             kmin=0
35885
35886          case (168:176)    ! 6/m   -> hkl: h>0,k>0,l>=0;  0kl k>=0,l>=0
35887             hmin=0
35888             kmin=0
35889
35890          case (177:194)    ! 6/mmm -> hkl: h >=0, k >=0, l >=0, h >=k
35891             hmin=0
35892             kmin=0
35893
35894          case (195:206)    ! m-3   -> hkl: h > l, k > l, l >=0 ; hkk: k>=0 h>=k
35895             hmin=0
35896             kmin=0
35897
35898          case (207:230)    ! m-3m  -> hkl: h >=0, k >=0, l >=0, h >=k, k >=l
35899             hmin=0
35900             kmin=0
35901
35902          case default      ! Assumed -1
35903             hmin=-hmax
35904             kmin=-kmax
35905       end Select
35906
35907       num_ref=0
35908       ext_do: do h=hmin,hmax
35909          do k=kmin,kmax
35910             do l=lmin,lmax
35911
35912                hh(1)=h
35913                hh(2)=k
35914                hh(3)=l
35915
35916                if (hkl_equal(hh,nulo)) cycle
35917                sval=hkl_s(hh,crystalcell)
35918                if (sval > vmax .or. sval < vmin) cycle
35919                if (hkl_absent(hh,Spacegroup)) cycle
35920
35921                kk=asu_hkl(hh,Spacegroup)
35922                if (hkl_equal(kk,nulo)) cycle
35923                if (hkl_equal(kk,-hh)) cycle
35924
35925                num_ref=num_ref+1
35926                if(num_ref > maxref) then
35927                   num_ref=maxref
35928                   exit ext_do
35929                end if
35930                reflex(num_ref)%h    = kk
35931                reflex(num_ref)%mult = hkl_mult(kk,SpaceGroup,friedel)
35932                reflex(num_ref)%S    = sval
35933             end do
35934          end do
35935       end do ext_do
35936
35937       return
35938    End Subroutine Hkl_Gen
35939
35940    !!----
35941    !!---- Subroutine  Hkl_Gen_Sxtal (Crystalcell,Spacegroup,stlmin,stlmax,Num_Ref,Reflex,ord,hlim)
35942    !!----    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell     !Unit cell object
35943    !!----    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup      !Space Group object
35944    !!----    real(kind=cp),                     intent(in) :: stlmin,stlmax   !Minimum and Maximum SinTheta/Lambda
35945    !!----    Integer            ,               intent(out):: Num_Ref         !Number of generated reflections
35946    !!----    Type (Reflect_Type), dimension(:), intent(out):: Reflex          !List of generated hkl,mult, s
35947    !!----    or
35948    !!----    Type (Reflection_List_Type),       intent(out):: Reflex          !List of generated hkl,mult, s
35949    !!----    Integer, dimension(3),   optional, intent(in) :: ord             !Order for loop of hkl-indices
35950    !!----    Integer, dimension(3,2), optional, intent(in) :: hlim            !hkl-limits
35951    !!----
35952    !!----    Calculate all allowed reflections between a minimum and a maximum value of sin_theta/lambda.
35953    !!----    If the limits of indices are provided in hlim, only the reflections verifying the prescription
35954    !!----    are finally kept. hlim(:,1) and hlim(:,2) contain the minimum and maximum values respectively.
35955    !!----    The output is not ordered but the user can obtain the reflections generated
35956    !!----    in a particular way by providing the integer vector "ord", containing a permutation
35957    !!----    of the three numbers 1,2,3. By default the loop generating the hkl-indices uses
35958    !!----    the vector ord=(/3,2,1/), this means that the inner loop (more rapidly changing index)
35959    !!----    is the l-index, then the k-index and finally the h-index.
35960    !!----
35961    !!---- Update: May - 2006
35962    !!
35963
35964    !!--++
35965    !!--++ Subroutine  Hkl_Gen_Sxtal_Reflection(Crystalcell,Spacegroup,stlmin,stlmax,Num_Ref,Reflex,ord,hlim)
35966    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell     !Unit cell object
35967    !!--++    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup      !Space Group object
35968    !!--++    real(kind=cp),                     intent(in) :: stlmin,stlmax   !Minimum and Maximum SinTheta/Lambda
35969    !!--++    Integer            ,               intent(out):: Num_Ref         !Number of generated reflections
35970    !!--++    Type (Reflect_Type), dimension(:), intent(out):: Reflex          !List of generated hkl,mult, s
35971    !!--++    Integer, dimension(3),   optional, intent(in) :: ord             !Order for loop of hkl-indices
35972    !!--++    Integer, dimension(3,2), optional, intent(in) :: hlim            !hkl-limits
35973    !!--++
35974    !!--++    (OVERLOADED)
35975    !!--++    Calculate all allowed reflections between a minimum and a maximum value of sin_theta/lambda.
35976    !!--++    If the limits of indices are provided in hlim, only the reflections verifying the prescription
35977    !!--++    are finally kept. hlim(:,1) and hlim(:,2) contain the minimum and maximum values respectively.
35978    !!--++    The reflections are stored in the array Reflex, with components of type: Reflect_Type
35979    !!--++    The output is not ordered but the user can obtain the reflections generated
35980    !!--++    in a particular way by providing the integer vector "ord", containing a permutation
35981    !!--++    of the three numbers 1,2,3. By default the loop generating the hkl-indices uses
35982    !!--++    the vector ord=(/3,2,1/), this means that the inner loop (more rapidly changing index)
35983    !!--++    is the l-index, then the k-index and finally the h-index.
35984    !!--++
35985    !!--++ Update: May - 2006
35986    !!
35987    Subroutine Hkl_Gen_Sxtal_Reflection(Crystalcell,Spacegroup,stlmin,stlmax,Num_Ref,Reflex,ord,hlim)
35988       !---- Arguments ----!
35989       type (Crystal_Cell_Type),          intent(in)  :: crystalcell
35990       type (Space_Group_Type) ,          intent(in)  :: spacegroup
35991       real(kind=cp),                     intent(in)  :: stlmin,stlmax
35992       integer,                           intent(out) :: num_ref
35993       type (Reflect_Type), dimension(:), intent(out) :: reflex
35994       Integer, dimension(3),   optional, intent(in)  :: ord
35995       Integer, dimension(3,2), optional, intent(in)  :: hlim
35996       !---- Local variables ----!
35997       real(kind=cp)         :: sval
35998       integer               :: h,k,l,hmax,kmax,lmax, maxref
35999       integer, dimension(3) :: hh,nulo,od,imin,imax
36000
36001       nulo=0
36002       maxref=size(reflex)
36003       hmax=nint(CrystalCell%cell(1)*2.0*stlmax+1.0)
36004       kmax=nint(CrystalCell%cell(2)*2.0*stlmax+1.0)
36005       lmax=nint(CrystalCell%cell(3)*2.0*stlmax+1.0)
36006       if(present(hlim)) then
36007         imin=hlim(:,1)
36008         imax=hlim(:,2)
36009       else
36010         imin=(/-hmax,-kmax,-lmax/)
36011         imax=(/ hmax, kmax, lmax/)
36012       end if
36013       od=(/3,2,1/)
36014       if(present(ord)) od=ord
36015
36016       num_ref=0
36017       ext_do: do h=imin(od(3)),imax(od(3))
36018          do k=imin(od(2)),imax(od(2))
36019             do l=imin(od(1)),imax(od(1))
36020                hh(od(3))=h
36021                hh(od(2))=k
36022                hh(od(1))=l
36023                if (hkl_equal(hh,nulo)) cycle
36024                sval=hkl_s(hh,crystalcell)
36025                if (sval > stlmax .or. sval < stlmin) cycle
36026                if (hkl_absent(hh,Spacegroup)) cycle
36027                num_ref=num_ref+1
36028                if(num_ref > maxref) then
36029                   num_ref=maxref
36030                   exit ext_do
36031                end if
36032                reflex(num_ref)%h    = hh
36033                reflex(num_ref)%mult = hkl_mult(hh,SpaceGroup,.false.)
36034                reflex(num_ref)%S    = sval
36035            end do
36036          end do
36037       end do ext_do
36038
36039       return
36040    End Subroutine Hkl_Gen_Sxtal_Reflection
36041
36042    !!--++
36043    !!--++ Subroutine  Hkl_Gen_Sxtal_list(Crystalcell,Spacegroup,stlmin,stlmax,Num_Ref,Reflex,ord,hlim)
36044    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell     !Unit cell object
36045    !!--++    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup      !Space Group object
36046    !!--++    real(kind=cp),                     intent(in) :: stlmin,stlmax   !Minimum and Maximum SinTheta/Lambda
36047    !!--++    Integer            ,               intent(out):: Num_Ref         !Number of generated reflections
36048    !!--++    Type(Reflection_List_Type),        intent(out):: reflex          !Generated set of reflections
36049    !!--++    Integer, dimension(3),   optional, intent(in) :: ord             !Order for loop of hkl-indices
36050    !!--++    Integer, dimension(3,2), optional, intent(in) :: hlim            !hkl-limits
36051    !!--++
36052    !!--++    (OVERLOADED)
36053    !!--++    Calculate all allowed reflections between a minimum and a maximum value of sin_theta/lambda.
36054    !!--++    If the limits of indices are provided in hlim, only the reflections verifying the prescription
36055    !!--++    are finally kept. hlim(:,1) and hlim(:,2) contain the minimum and maximum values respectively.
36056    !!--++    The reflections are stored in the scalar object Reflex of type: Reflection_List_Type
36057    !!--++    The output is not ordered but the user can obtain the reflections generated
36058    !!--++    in a particular way by providing the integer vector "ord", containing a permutation
36059    !!--++    of the three numbers 1,2,3. By default the loop generating the hkl-indices uses
36060    !!--++    the vector ord=(/3,2,1/), this means that the inner loop (more rapidly changing index)
36061    !!--++    is the l-index, then the k-index and finally the h-index.
36062    !!--++
36063    !!--++ Update: May - 2006
36064    !!
36065    Subroutine Hkl_Gen_Sxtal_List(Crystalcell,Spacegroup,stlmin,stlmax,Num_Ref,Reflex,ord,hlim)
36066       !---- Arguments ----!
36067       type (Crystal_Cell_Type),          intent(in)  :: crystalcell
36068       type (Space_Group_Type) ,          intent(in)  :: spacegroup
36069       real(kind=cp),                     intent(in)  :: stlmin,stlmax
36070       integer,                           intent(out) :: num_ref
36071       Type(Reflection_List_Type),        intent(out) :: reflex   !Ordered set of reflections
36072       Integer, dimension(3),   optional, intent(in)  :: ord
36073       Integer, dimension(3,2), optional, intent(in)  :: hlim
36074
36075       !---- Local variables ----!
36076       real(kind=cp)         :: sval
36077       integer               :: h,k,l,hmax,kmax,lmax, maxref,i
36078       integer, dimension(3) :: hh,nulo,od,imin,imax
36079       Type(Reflection_Type), dimension(:), allocatable :: tmp_reflex
36080
36081       nulo=0
36082
36083       hmax=nint(CrystalCell%cell(1)*2.0*stlmax+1.0)
36084       kmax=nint(CrystalCell%cell(2)*2.0*stlmax+1.0)
36085       lmax=nint(CrystalCell%cell(3)*2.0*stlmax+1.0)
36086       if(present(hlim)) then
36087         imin=hlim(:,1)
36088         imax=hlim(:,2)
36089       else
36090         imin=(/-hmax,-kmax,-lmax/)
36091         imax=(/ hmax, kmax, lmax/)
36092       end if
36093       od=(/3,2,1/)
36094       if(present(ord)) od=ord
36095
36096       maxref=(2*hmax+1)*(2*kmax+1)*(2*lmax+1)
36097       if(allocated(tmp_reflex)) deallocate(tmp_reflex)
36098       allocate(tmp_reflex(maxref))
36099
36100       num_ref=0
36101       ext_do: do h=imin(od(3)),imax(od(3))
36102          do k=imin(od(2)),imax(od(2))
36103             do l=imin(od(1)),imax(od(1))
36104                hh(od(3))=h
36105                hh(od(2))=k
36106                hh(od(1))=l
36107                if (hkl_equal(hh,nulo)) cycle
36108                sval=hkl_s(hh,crystalcell)
36109                if (sval > stlmax .or. sval < stlmin) cycle
36110                if (hkl_absent(hh,Spacegroup)) cycle
36111                num_ref=num_ref+1
36112                if(num_ref > maxref) then
36113                   num_ref=maxref
36114                   exit ext_do
36115                end if
36116
36117                tmp_reflex(num_ref)%h    = hh
36118                tmp_reflex(num_ref)%mult = hkl_mult(hh,SpaceGroup,.false.)
36119                tmp_reflex(num_ref)%S    = sval
36120
36121             end do
36122          end do
36123       end do ext_do
36124
36125       if(allocated(reflex%ref)) deallocate(reflex%ref)
36126       allocate(reflex%ref(num_ref))
36127       reflex%nref= num_ref
36128
36129       do i=1,num_ref
36130          reflex%Ref(i)%h    = tmp_reflex(i)%h
36131          reflex%Ref(i)%mult = tmp_reflex(i)%mult
36132          reflex%Ref(i)%S    = tmp_reflex(i)%S
36133          reflex%Ref(i)%fo    =0.0
36134          reflex%Ref(i)%sfo   =0.0
36135          reflex%Ref(i)%fc    =0.0
36136          reflex%Ref(i)%w     =0.0
36137          reflex%Ref(i)%phase =0.0
36138          reflex%Ref(i)%a     =0.0
36139          reflex%Ref(i)%b     =0.0
36140          reflex%Ref(i)%aa    =0.0
36141          reflex%Ref(i)%bb    =0.0
36142       end do
36143
36144       return
36145    End Subroutine Hkl_Gen_Sxtal_list
36146
36147
36148    !!----
36149    !!---- Subroutine  Hkl_Rp(H,Phase, Op,K, Phasen)
36150    !!----    integer/real(kind=cp), dimension(3), intent(in)  :: h
36151    !!----    real(kind=cp),                       intent(in)  :: phase
36152    !!----    type (Sym_Oper_Type),                intent(in)  :: Op
36153    !!----    integer/real(kind=cp), dimension(3), intent(out) :: k
36154    !!----    real(kind=cp),                       intent(out) :: phasen
36155    !!----
36156    !!----    Calculate the equivalent reflection and Phase
36157    !!----
36158    !!---- Update: February - 2005
36159    !!
36160
36161    !!--++
36162    !!--++ Subroutine Hkl_RpI(H,Phase,Op,K,Phasen)
36163    !!--++    integer,dimension(3),   intent(in) :: h
36164    !!--++    real(kind=cp),          intent(in) :: phase
36165    !!--++    type (Sym_Oper_Type),   intent(in) :: Op
36166    !!--++    integer,dimension(3),   intent(out):: k
36167    !!--++    real(kind=cp),          intent(out):: phasen
36168    !!--++
36169    !!--++    (OVERLOADED)
36170    !!--++    Calculate the equivalent reflection and new phase
36171    !!--++
36172    !!--++ Update: February - 2005
36173    !!
36174    Subroutine Hkl_RpI(H, Phase, Op, K, Phasen)
36175       !---- Arguments ----!
36176       integer, dimension(3), intent (in) :: h
36177       real(kind=cp),         intent (in) :: phase
36178       Type(Sym_Oper_Type),   intent (in) :: Op
36179       integer, dimension(3), intent (out):: k
36180       real(kind=cp),         intent (out):: phasen
36181
36182       k = matmul(h,Op%Rot)
36183       phasen= phase - 360.0_cp*dot_product(Op%Tr,real(h))
36184       phasen=mod(phasen+3600.0_cp,360.0_cp)
36185
36186       return
36187    End Subroutine Hkl_RpI
36188
36189    !!--++
36190    !!--++ Subroutine Hkl_RpR(H,Phase,Op,K,Phasen)
36191    !!--++     real(kind=cp),dimension(3),   intent(in) :: h
36192    !!--++     real(kind=cp),                intent(in) :: phase
36193    !!--++     type (Sym_Oper_Type),         intent(in) :: Op
36194    !!--++     real(kind=cp),dimension(3),   intent(out):: k
36195    !!--++     real(kind=cp),                intent(out):: phasen
36196    !!--++
36197    !!--++     (OVERLOADED)
36198    !!--++     Calculate the equivalent reflection and new phase
36199    !!--++
36200    !!--++ Update: February - 2005
36201    !!
36202    Subroutine Hkl_RpR(h, phase, Op, k, phasen)
36203       !---- Arguments ----!
36204       real(kind=cp), dimension(3),intent (in) :: h
36205       real(kind=cp),              intent (in) :: phase
36206       Type(Sym_Oper_Type),        intent(in)  :: Op
36207       real(kind=cp), dimension(3),intent (out):: k
36208       real(kind=cp),              intent (out):: phasen
36209
36210       k = matmul(h,Op%Rot)
36211       phasen= phase - 360.0_cp*dot_product(Op%Tr,h)
36212       phasen=mod(phasen+3600.0_cp,360.0_cp)
36213
36214       return
36215    End Subroutine Hkl_RpR
36216
36217    !!----
36218    !!---- Subroutine  Hkl_Uni(Crystalcell, Spacegroup,Friedel,Value1,Value2,Code,Num_Ref,Reflex, no_order)
36219    !!----    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell  !Cell Objet
36220    !!----    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup   !Space group Object
36221    !!----    Logical,                           intent(in) :: Friedel
36222    !!----    real(kind=cp),                     intent(in) :: value1,value2 !Range in sintheta/Lambda
36223    !!----    character(len=1),                  intent(in) :: code     !If code="r", d-spacing are input
36224    !!----    Integer            ,               intent(out):: num_Ref  !Number of generated reflections
36225    !!----    Type (Reflect_Type), dimension(:), intent(out):: reflex   !Ordered set of reflections
36226    !!----         or
36227    !!----    Type (Reflection_Type), dimension(:), intent(out):: reflex !Ordered set of reflections
36228    !!----         or
36229    !!----    Type(Reflection_List_Type),        intent(out):: reflex   !Ordered set of reflections
36230    !!----    logical,                optional,  intent(in) :: no_order
36231    !!----
36232    !!----    Calculate unique reflections between two values (value1,value2)
36233    !!----    of sin_theta/lambda. If no_order is present and .true. the sort subroutine
36234    !!----    is not invoked.
36235    !!----
36236    !!---- Update: December - 2011
36237    !!
36238
36239    !!--++
36240    !!--++ Subroutine  Hkl_Uni_Reflect(Crystalcell, Spacegroup,Friedel,Value1,Value2,Code,Num_Ref,Reflex,no_order)
36241    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell  !Cell Objet
36242    !!--++    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup   !Space group Object
36243    !!--++    Logical,                           intent(in) :: Friedel
36244    !!--++    real(kind=cp),                     intent(in) :: value1,value2 !Range in sintheta/Lambda
36245    !!--++    character(len=1),                  intent(in) :: code     !If code="r", d-spacing are input
36246    !!--++    Integer            ,               intent(out):: num_Ref  !Number of generated reflections
36247    !!--++    Type (Reflect_Type), dimension(:), intent(out):: reflex   !Ordered set of reflections
36248    !!--++    logical,                optional,  intent(in) :: no_order
36249    !!--++
36250    !!--++    (Overloaded)
36251    !!--++    Calculate unique reflections between two values (value1,value2)
36252    !!--++    of sin_theta/lambda. If no_order is present and .true. the sort subroutine
36253    !!--++    is not invoked.
36254    !!--++
36255    !!--++ Update: December - 2011
36256    !!
36257    Subroutine Hkl_Uni_Reflect(Crystalcell,Spacegroup,Friedel,Value1,Value2,Code,Num_Ref,Reflex,no_order)
36258       !---- Arguments ----!
36259       type (Crystal_Cell_Type),             intent(in)     :: crystalcell
36260       type (Space_Group_Type) ,             intent(in)     :: spacegroup
36261       Logical,                              intent(in)     :: Friedel
36262       real(kind=cp),                        intent(in)     :: value1,value2
36263       character(len=1),                     intent(in)     :: code
36264       integer,                              intent(out)    :: num_ref
36265       type (Reflect_Type),    dimension(:), intent(out)    :: reflex
36266       logical,                   optional,  intent(in)     :: no_order
36267
36268       !---- Local variables ----!
36269       real(kind=cp)                         :: vmin,vmax,sval
36270       integer                               :: h,k,l,hmin,kmin,lmin,hmax,kmax,lmax, i, maxref
36271       integer, dimension(3)                 :: hh,kk,nulo
36272       integer,  dimension(  size(reflex))   :: ind
36273       integer,  dimension(  size(reflex))   :: mul
36274       integer,  dimension(3,size(reflex))   :: hkl
36275       real(kind=cp),dimension(size(reflex)) :: sv
36276       character(len=2)                      :: inf
36277
36278       nulo=0
36279       maxref=size(reflex)
36280       vmin=min(value1,value2)
36281       vmax=max(value1,value2)
36282       if (code =="r" .or. code=="R") then
36283          vmin=1.0/(2.0*max(value1,value2))
36284          vmax=1.0/(2.0*min(value1,value2))
36285       end if
36286
36287       hmax=nint(CrystalCell%cell(1)*2.0*vmax+1.0)
36288       kmax=nint(CrystalCell%cell(2)*2.0*vmax+1.0)
36289       lmax=nint(CrystalCell%cell(3)*2.0*vmax+1.0)
36290       lmin= 0  !l positive or zero except for -3 1 m (see below)
36291
36292       !---- Select approximate region to generate reflections depending
36293       !---- on the space group. This allows a faster generation.
36294       Select Case(SpaceGroup%NumSpg)
36295          case (1:2)                   ! -1    -> hkl: l >=0; hk0: h >=0; 0k0: k >=0
36296             hmin=-hmax
36297             kmin=-kmax
36298             if(SpaceGroup%NumSpg == 1 .and. .not. Friedel) lmin=-lmax
36299
36300          case (3:15)                  ! 2/m
36301             inf=Spacegroup%info(1:2)
36302             if (inf(1:1) == "-") inf(1:1)=inf(2:2)
36303             select case (inf(1:1))
36304                case ("b")     !       -> hkl: k >=0, l >=0; hk0: h >=0
36305                   hmin=-hmax
36306                   kmin=0
36307                case ("c")     !       -> hkl: k >=0, l >=0; h0l: h >=0
36308                   hmin=-hmax
36309                   kmin=0
36310                case ("a")     !       -> hkl: h >=0, l >=0; 0kl: l >=0  Provisional (to be tested)
36311                   kmin=-kmax
36312                   hmin=0
36313             end select
36314
36315          case (16:74)         ! mmm   -> hkl: h >=0, k >=0, l >=0
36316             hmin=0
36317             kmin=0
36318
36319          case (75:88)         ! 4/m   -> hkl: h >=0, l >=0, k >=0 if h = 0
36320                               !                             k > 0 if h > 0
36321             hmin=0
36322             kmin=0
36323
36324          case (89:142)        ! 4/mmm -> hkl: h >=0, k>=0, l>=0, h >=k
36325             hmin=0
36326             kmin=0
36327
36328          case (143:148)       ! -3    -> hkl: h+k>0, l>0 ;  hk0: h>0, k>=0
36329             hmin=0
36330             kmin=-kmax
36331
36332          case (149,151,153,157,159,162,163) ! -3 1 m  -> hkl: h>=0,h>=k>0 ; h0l: h>=0,l>=0
36333             hmin=0
36334             kmin=0
36335             lmin=-lmax
36336
36337          case (150,152,154,155,156,158,160,161,164,165,166,167)
36338                              ! -3 m   -> hkl: h>=0 h>=k ; hhl: h>=0,l>=0
36339             hmin=0
36340             kmin=0
36341
36342          case (168:176)    ! 6/m   -> hkl: h>0,k>0,l>=0;  0kl k>=0,l>=0
36343             hmin=0
36344             kmin=0
36345
36346          case (177:194)    ! 6/mmm -> hkl: h >=0, k >=0, l >=0, h >=k
36347             hmin=0
36348             kmin=0
36349
36350          case (195:206)    ! m-3   -> hkl: h > l, k > l, l >=0 ; hkk: k>=0 h>=k
36351             hmin=0
36352             kmin=0
36353
36354          case (207:230)    ! m-3m  -> hkl: h >=0, k >=0, l >=0, h >=k, k >=l
36355             hmin=0
36356             kmin=0
36357
36358          case default      ! Assumed -1
36359             hmin=-hmax
36360             kmin=-kmax
36361       end select
36362
36363       num_ref=0
36364       ext_do: do h=hmin,hmax
36365          do k=kmin,kmax
36366             do l=lmin,lmax
36367
36368                hh(1)=h
36369                hh(2)=k
36370                hh(3)=l
36371
36372                if (hkl_equal(hh,nulo)) cycle
36373                sval=hkl_s(hh,crystalcell)
36374                if (sval > vmax .or. sval < vmin) cycle
36375                if (hkl_absent(hh,Spacegroup)) cycle
36376
36377                kk=asu_hkl(hh,Spacegroup)
36378                if (hkl_equal(kk,nulo)) cycle
36379                if (hkl_equal(kk,-hh) .and. Friedel) cycle
36380
36381                num_ref=num_ref+1
36382                if(num_ref > maxref) then
36383                   num_ref=maxref
36384                   exit ext_do
36385                end if
36386                hkl(:,num_ref)= kk
36387                mul(num_ref)  = hkl_mult(kk,SpaceGroup,friedel)
36388                sv(num_ref)   = sval
36389             end do
36390          end do
36391       end do ext_do
36392
36393       if(present(no_order)) then
36394         if(no_order) then
36395          ind=(/(i,i=1,num_ref)/)
36396         else
36397          call sort(sv,num_ref,ind)
36398         end if
36399       else
36400         call sort(sv,num_ref,ind)
36401       end if
36402
36403       do i=1,num_ref
36404          reflex(i)%h   = hkl(:,ind(i))
36405          reflex(i)%mult= mul(ind(i))
36406          reflex(i)%S   = sv(ind(i))
36407       end do
36408       return
36409    End Subroutine Hkl_Uni_reflect
36410
36411    !!--++
36412    !!--++ Subroutine  Hkl_Uni_Reflection(Crystalcell, Spacegroup,Friedel,Value1,Value2,Code,Num_Ref,Reflex, no_order)
36413    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell  !Cell Objet
36414    !!--++    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup   !Space group Object
36415    !!--++    Logical,                           intent(in) :: Friedel
36416    !!--++    real(kind=cp),                     intent(in) :: value1,value2 !Range in sintheta/Lambda
36417    !!--++    character(len=1),                  intent(in) :: code     !If code="r", d-spacing are input
36418    !!--++    Integer            ,               intent(out):: num_Ref  !Number of generated reflections
36419    !!--++    Type (Reflect_Type), dimension(:), intent(out):: reflex   !Ordered set of reflections
36420    !!--++    logical,                optional,  intent(in) :: no_order
36421    !!--++
36422    !!--++    (Overloaded)
36423    !!--++    Calculate unique reflections between two values (value1,value2)
36424    !!--++    of sin_theta/lambda. If no_order is present and .true. the sort subroutine
36425    !!--++    is not invoked.
36426    !!--++
36427    !!--++ Update: December - 2011
36428    !!
36429    Subroutine Hkl_Uni_Reflection(Crystalcell,Spacegroup,Friedel,Value1,Value2,Code,Num_Ref,Reflex,no_order)
36430       !---- Arguments ----!
36431       type (Crystal_Cell_Type),             intent(in)     :: crystalcell
36432       type (Space_Group_Type) ,             intent(in)     :: spacegroup
36433       Logical,                              intent(in)     :: Friedel
36434       real(kind=cp),                        intent(in)     :: value1,value2
36435       character(len=1),                     intent(in)     :: code
36436       integer,                              intent(out)    :: num_ref
36437       type (Reflection_Type), dimension(:), intent(out)    :: reflex
36438       logical,                   optional,  intent(in)     :: no_order
36439
36440       !---- Local variables ----!
36441       real(kind=cp)                         :: vmin,vmax,sval
36442       integer                               :: h,k,l,hmin,kmin,lmin,hmax,kmax,lmax, i, maxref
36443       integer, dimension(3)                 :: hh,kk,nulo
36444       integer,  dimension(  size(reflex))   :: ind
36445       integer,  dimension(  size(reflex))   :: mul
36446       integer,  dimension(3,size(reflex))   :: hkl
36447       real(kind=cp),dimension(size(reflex)) :: sv
36448       character(len=2)                      :: inf
36449
36450       nulo=0
36451       maxref=size(reflex)
36452       vmin=min(value1,value2)
36453       vmax=max(value1,value2)
36454       if (code =="r" .or. code=="R") then
36455          vmin=1.0/(2.0*max(value1,value2))
36456          vmax=1.0/(2.0*min(value1,value2))
36457       end if
36458
36459       hmax=nint(CrystalCell%cell(1)*2.0*vmax+1.0)
36460       kmax=nint(CrystalCell%cell(2)*2.0*vmax+1.0)
36461       lmax=nint(CrystalCell%cell(3)*2.0*vmax+1.0)
36462       lmin= 0  !l positive or zero except for -3 1 m (see below)
36463
36464       !---- Select approximate region to generate reflections depending
36465       !---- on the space group. This allows a faster generation.
36466       Select Case(SpaceGroup%NumSpg)
36467          case (1:2)                 ! -1    -> hkl: l >=0; hk0: h >=0; 0k0: k >=0
36468             hmin=-hmax
36469             kmin=-kmax
36470             if(SpaceGroup%NumSpg == 1 .and. .not. Friedel) lmin=-lmax
36471
36472          case (3:15)                ! 2/m
36473             inf=Spacegroup%info(1:2)
36474             if (inf(1:1) == "-") inf(1:1)=inf(2:2)
36475             select case (inf(1:1))
36476                case ("b")     !       -> hkl: k >=0, l >=0; hk0: h >=0
36477                   hmin=-hmax
36478                   kmin=0
36479                case ("c")     !       -> hkl: k >=0, l >=0; h0l: h >=0
36480                   hmin=-hmax
36481                   kmin=0
36482                case ("a")     !       -> hkl: h >=0, l >=0; 0kl: l >=0  Provisional (to be tested)
36483                   kmin=-kmax
36484                   hmin=0
36485             end select
36486
36487          case (16:74)         ! mmm   -> hkl: h >=0, k >=0, l >=0
36488             hmin=0
36489             kmin=0
36490
36491          case (75:88)         ! 4/m   -> hkl: h >=0, l >=0, k >=0 if h = 0
36492                               !                             k > 0 if h > 0
36493             hmin=0
36494             kmin=0
36495
36496          case (89:142)        ! 4/mmm -> hkl: h >=0, k>=0, l>=0, h >=k
36497             hmin=0
36498             kmin=0
36499
36500          case (143:148)       ! -3    -> hkl: h+k>0, l>0 ;  hk0: h>0, k>=0
36501             hmin=0
36502             kmin=-kmax
36503
36504          case (149,151,153,157,159,162,163) ! -3 1 m  -> hkl: h>=0,h>=k>0 ; h0l: h>=0,l>=0
36505             hmin=0
36506             kmin=0
36507             lmin=-lmax
36508
36509          case (150,152,154,155,156,158,160,161,164,165,166,167)
36510                              ! -3 m   -> hkl: h>=0 h>=k ; hhl: h>=0,l>=0
36511             hmin=0
36512             kmin=0
36513
36514          case (168:176)    ! 6/m   -> hkl: h>0,k>0,l>=0;  0kl k>=0,l>=0
36515             hmin=0
36516             kmin=0
36517
36518          case (177:194)    ! 6/mmm -> hkl: h >=0, k >=0, l >=0, h >=k
36519             hmin=0
36520             kmin=0
36521
36522          case (195:206)    ! m-3   -> hkl: h > l, k > l, l >=0 ; hkk: k>=0 h>=k
36523             hmin=0
36524             kmin=0
36525
36526          case (207:230)    ! m-3m  -> hkl: h >=0, k >=0, l >=0, h >=k, k >=l
36527             hmin=0
36528             kmin=0
36529
36530          case default      ! Assumed -1
36531             hmin=-hmax
36532             kmin=-kmax
36533       end select
36534
36535       num_ref=0
36536       ext_do: do h=hmin,hmax
36537          do k=kmin,kmax
36538             do l=lmin,lmax
36539
36540                hh(1)=h
36541                hh(2)=k
36542                hh(3)=l
36543
36544                if (hkl_equal(hh,nulo)) cycle
36545                sval=hkl_s(hh,crystalcell)
36546                if (sval > vmax .or. sval < vmin) cycle
36547                if (hkl_absent(hh,Spacegroup)) cycle
36548
36549                kk=asu_hkl(hh,Spacegroup)
36550                if (hkl_equal(kk,nulo)) cycle
36551                if (hkl_equal(kk,-hh) .and. Friedel) cycle
36552
36553                num_ref=num_ref+1
36554                if(num_ref > maxref) then
36555                   num_ref=maxref
36556                   exit ext_do
36557                end if
36558                hkl(:,num_ref)=kk
36559                mul(num_ref)  =hkl_mult(kk,SpaceGroup,friedel)
36560                sv(num_ref)   = sval
36561             end do
36562          end do
36563       end do ext_do
36564
36565       if(present(no_order)) then
36566         if(no_order) then
36567          ind=(/(i,i=1,num_ref)/)
36568         else
36569          call sort(sv,num_ref,ind)
36570         end if
36571       else
36572         call sort(sv,num_ref,ind)
36573       end if
36574
36575       do i=1,num_ref
36576          reflex(i)%h= hkl(:,ind(i))
36577          reflex(i)%mult= mul(ind(i))
36578          reflex(i)%S   = sv(ind(i))
36579       end do
36580
36581       return
36582    End Subroutine Hkl_Uni_Reflection
36583
36584    !!--++
36585    !!--++ Subroutine  Hkl_Uni_ReflList(Crystalcell, Spacegroup,Friedel,Value1,Value2,Code,MaxRef,Reflex,no_order)
36586    !!--++    Type (Crystal_Cell_Type),          intent(in) :: CrystalCell  !Cell Objet
36587    !!--++    Type (Space_Group_Type) ,          intent(in) :: SpaceGroup   !Space group Object
36588    !!--++    Logical,                           intent(in) :: Friedel
36589    !!--++    real(kind=cp),                     intent(in) :: value1,value2 !Range in sintheta/Lambda
36590    !!--++    character(len=1),                  intent(in) :: code     !If code="r", d-spacing are input
36591    !!--++    Integer            ,               intent(in) :: MaxRef   !Maximum Number of reflections to be generated
36592    !!--++    Type(Reflection_List_Type),        intent(out):: reflex   !Ordered set of reflections
36593    !!--++    logical,                optional,  intent(in) :: no_order
36594    !!--++
36595    !!--++    (OVERLOADED)
36596    !!--++    Calculate unique reflections between two values (value1,value2)
36597    !!--++    of sin_theta/lambda. If no_order is present and .true. the sort subroutine
36598    !!--++    is not invoked.
36599    !!--++
36600    !!--++ Update: December - 2011
36601    !!
36602    Subroutine Hkl_Uni_ReflList(Crystalcell,Spacegroup,Friedel,Value1,Value2,Code,MaxRef,Reflex,no_order)
36603       !---- Arguments ----!
36604       type (Crystal_Cell_Type),       intent(in)     :: crystalcell
36605       type (Space_Group_Type) ,       intent(in)     :: spacegroup
36606       Logical,                        intent(in)     :: Friedel
36607       real(kind=cp),                  intent(in)     :: value1,value2
36608       character(len=1),               intent(in)     :: code
36609       integer,                        intent(in)     :: MaxRef
36610       type (Reflection_List_Type),    intent(out)    :: reflex
36611       logical,             optional,  intent(in)     :: no_order
36612
36613       !---- Local variables ----!
36614       real(kind=cp)                   :: vmin,vmax,sval
36615       integer                         :: h,k,l,hmin,kmin,lmin,hmax,kmax,lmax, i, num_ref
36616       integer, dimension(3)           :: hh,kk,nulo
36617       integer,  dimension(  MaxRef)   :: ind
36618       integer,  dimension(  MaxRef)   :: mul
36619       integer,  dimension(3,MaxRef)   :: hkl
36620       real(kind=cp),dimension(MaxRef) :: sv
36621       character(len=2)                :: inf
36622
36623       nulo=0
36624       vmin=min(value1,value2)
36625       vmax=max(value1,value2)
36626       if (code =="r" .or. code=="R") then
36627          vmin=1.0/(2.0*max(value1,value2))
36628          vmax=1.0/(2.0*min(value1,value2))
36629       end if
36630
36631       hmax=nint(CrystalCell%cell(1)*2.0*vmax+1.0)
36632       kmax=nint(CrystalCell%cell(2)*2.0*vmax+1.0)
36633       lmax=nint(CrystalCell%cell(3)*2.0*vmax+1.0)
36634       lmin= 0  !l positive or zero except for -3 1 m (see below)
36635
36636       !---- Select approximate region to generate reflections depending
36637       !---- on the space group. This allows a faster generation.
36638       Select Case(SpaceGroup%NumSpg)
36639          case (1:2)                 ! -1    -> hkl: l >=0; hk0: h >=0; 0k0: k >=0
36640             hmin=-hmax
36641             kmin=-kmax
36642             if(SpaceGroup%NumSpg == 1 .and. .not. Friedel) lmin=-lmax
36643
36644          case (3:15)                ! 2/m
36645             inf=Spacegroup%info(1:2)
36646             if (inf(1:1) == "-") inf(1:1)=inf(2:2)
36647             select case (inf(1:1))
36648                case ("b")     !       -> hkl: k >=0, l >=0; hk0: h >=0
36649                   hmin=-hmax
36650                   kmin=0
36651                case ("c")     !       -> hkl: k >=0, l >=0; h0l: h >=0
36652                   hmin=-hmax
36653                   kmin=0
36654                case ("a")     !       -> hkl: h >=0, l >=0; 0kl: l >=0  Provisional (to be tested)
36655                   kmin=-kmax
36656                   hmin=0
36657             end select
36658
36659          case (16:74)         ! mmm   -> hkl: h >=0, k >=0, l >=0
36660             hmin=0
36661             kmin=0
36662
36663          case (75:88)         ! 4/m   -> hkl: h >=0, l >=0, k >=0 if h = 0
36664                               !                             k > 0 if h > 0
36665             hmin=0
36666             kmin=0
36667
36668          case (89:142)        ! 4/mmm -> hkl: h >=0, k>=0, l>=0, h >=k
36669             hmin=0
36670             kmin=0
36671
36672          case (143:148)       ! -3    -> hkl: h+k>0, l>0 ;  hk0: h>0, k>=0
36673             hmin=0
36674             kmin=-kmax
36675
36676          case (149,151,153,157,159,162,163) ! -3 1 m  -> hkl: h>=0,h>=k>0 ; h0l: h>=0,l>=0
36677             hmin=0
36678             kmin=0
36679             lmin=-lmax
36680
36681          case (150,152,154,155,156,158,160,161,164,165,166,167)
36682                              ! -3 m   -> hkl: h>=0 h>=k ; hhl: h>=0,l>=0
36683             hmin=0
36684             kmin=0
36685
36686          case (168:176)    ! 6/m   -> hkl: h>0,k>0,l>=0;  0kl k>=0,l>=0
36687             hmin=0
36688             kmin=0
36689
36690          case (177:194)    ! 6/mmm -> hkl: h >=0, k >=0, l >=0, h >=k
36691             hmin=0
36692             kmin=0
36693
36694          case (195:206)    ! m-3   -> hkl: h > l, k > l, l >=0 ; hkk: k>=0 h>=k
36695             hmin=0
36696             kmin=0
36697
36698          case (207:230)    ! m-3m  -> hkl: h >=0, k >=0, l >=0, h >=k, k >=l
36699             hmin=0
36700             kmin=0
36701
36702          case default      ! Assumed -1
36703             hmin=-hmax
36704             kmin=-kmax
36705       end select
36706
36707       num_ref=0
36708       ext_do: do h=hmin,hmax
36709          do k=kmin,kmax
36710             do l=lmin,lmax
36711
36712                hh(1)=h
36713                hh(2)=k
36714                hh(3)=l
36715
36716                if (hkl_equal(hh,nulo)) cycle
36717                sval=hkl_s(hh,crystalcell)
36718                if (sval > vmax .or. sval < vmin) cycle
36719                if (hkl_absent(hh,Spacegroup)) cycle
36720
36721                kk=asu_hkl(hh,Spacegroup)
36722                if (hkl_equal(kk,nulo)) cycle
36723                if (hkl_equal(kk,-hh) .and. Friedel) cycle
36724
36725                num_ref=num_ref+1
36726                if(num_ref > maxref) then
36727                   num_ref=maxref
36728                   exit ext_do
36729                end if
36730                hkl(:,num_ref)=kk
36731                mul(num_ref)  =hkl_mult(kk,SpaceGroup,friedel)
36732                sv(num_ref)   = sval
36733             end do
36734          end do
36735       end do ext_do
36736
36737       if(present(no_order)) then
36738         if(no_order) then
36739          ind=(/(i,i=1,num_ref)/)
36740         else
36741          call sort(sv,num_ref,ind)
36742         end if
36743       else
36744         call sort(sv,num_ref,ind)
36745       end if
36746
36747       if(allocated(reflex%ref)) deallocate(reflex%ref)
36748       allocate(reflex%ref(num_ref))
36749       reflex%nref= num_ref
36750
36751       do i=1,num_ref
36752          reflex%Ref(i)%h    = hkl(:,ind(i))
36753          reflex%Ref(i)%mult = mul(ind(i))
36754          reflex%Ref(i)%S    = sv(ind(i))
36755          reflex%Ref(i)%fo    =0.0
36756          reflex%Ref(i)%sfo   =0.0
36757          reflex%Ref(i)%fc    =0.0
36758          reflex%Ref(i)%w     =0.0
36759          reflex%Ref(i)%phase =0.0
36760          reflex%Ref(i)%a     =0.0
36761          reflex%Ref(i)%b     =0.0
36762          reflex%Ref(i)%aa    =0.0
36763          reflex%Ref(i)%bb    =0.0
36764       end do
36765
36766       return
36767    End Subroutine Hkl_Uni_ReflList
36768
36769
36770    !!----
36771    !!---- SUBROUTINE INIT_ERR_REFL()
36772    !!----
36773    !!----    Initialize the errors flags in this Module
36774    !!----
36775    !!---- Update: February - 2005
36776    !!
36777    Subroutine Init_Err_Refl()
36778
36779       err_refl=.false.
36780       ERR_Refl_Mess=" "
36781
36782       return
36783    End Subroutine Init_Err_Refl
36784
36785    !!----
36786    !!---- SUBROUTINE INIT_REFLIST()
36787    !!----
36788    !!----    Initialize the Reflection List Variable
36789    !!----
36790    !!---- Update: February - 2005
36791    !!
36792    Subroutine Init_RefList(Reflex,N)
36793       !---- Arguments ----!
36794       type(reflection_list_type), intent(out) :: Reflex
36795       integer, optional,          intent(in) :: N
36796
36797       !---- Local Variables ----!
36798       integer :: i
36799
36800       if (allocated(reflex%ref)) deallocate(reflex%ref)
36801       if (present(n)) then
36802          reflex%nref=n
36803          if (n > 0) then
36804             allocate(reflex%ref(n))
36805             do i=1,n
36806                reflex%ref(i)%h     =0
36807                reflex%ref(i)%mult  =0
36808                reflex%ref(i)%fo    =0.0
36809                reflex%ref(i)%sfo   =0.0
36810                reflex%ref(i)%fc    =0.0
36811                reflex%ref(i)%w     =0.0
36812                reflex%ref(i)%phase =0.0
36813                reflex%ref(i)%a     =0.0
36814                reflex%ref(i)%b     =0.0
36815                reflex%ref(i)%aa    =0.0
36816                reflex%ref(i)%bb    =0.0
36817             end do
36818          end if
36819       else
36820          reflex%nref=0
36821       end if
36822
36823       return
36824    End Subroutine Init_RefList
36825
36826
36827    !!--++
36828    !!--++ SUBROUTINE INIT_REF_COND()
36829    !!--++
36830    !!--++    Initialize the Reflection conditions information array
36831    !!--++
36832    !!--++ Update: August - 2005
36833    !!
36834    Subroutine Init_Ref_Cond()
36835
36836       Hkl_Ref_Conditions(1:20)(1:80)   = (/  &
36837             "(h k l)    h+k=2n : xy0 centred face (C)                                        " , &
36838             "(h k l)    k+l=2n : 0yz centred face (A)                                        " , &
36839             "(h k l)    h+l=2n : x0z centred face (B)                                        " , &
36840             "(h k l)  h+k+l=2n : body centred (I)                                            " , &
36841             "(h k l)  h,k,l same parity: all-face centred (F)                                " , &
36842             "(h k l) -h+k+l=3n : rhombohedrally centred (R)                                  " , &
36843             "(  0  k  l)     k=2n : (100) glide plane with b/2 translation (b)               " , &
36844             "(  0  k  l)     l=2n : (100) glide plane with c/2 translation (c)               " , &
36845             "(  0  k  l)   k+l=2n : (100) glide plane with b/2 + c/2 translations (n)        " , &
36846             "(  0  k  l)   k+l=4n : (100) glide plane with b/4 +- c/4 translations (d)       " , &
36847             "(  h  0  l)     h=2n : (010) glide plane with a/2 translation (a)               " , &
36848             "(  h  0  l)     l=2n : (010) glide plane with c/2 translation (c)               " , &
36849             "(  h  0  l)   l+h=2n : (010) glide plane with c/2 + a/2 translations (n)        " , &
36850             "(  h  0  l)   l+h=4n : (010) glide plane with c/4 +- a/4 translations (d)       " , &
36851             "(  h  k  0)     h=2n : (001) glide plane with a/2 translation (a)               " , &
36852             "(  h  k  0)     k=2n : (001) glide plane with b/2 translation (b)               " , &
36853             "(  h  k  0)   h+k=2n : (001) glide plane with a/2 + b/2 translations (n)        " , &
36854             "(  h  k  0)   h+k=4n : (001) glide plane with a/4 +- b/4 translations (d)       " , &
36855             "(  h  -h   0 l) l=2n : (11-20) glide plane with c/2 translation (c)             " , &
36856             "(  0   k  -k l) l=2n : (-2110) glide plane with c/2 translation (c)             " /)
36857       Hkl_Ref_Conditions(21:39)(1:80)   = (/  &
36858             "( -h   0   h l) l=2n : (1-210) glide plane with c/2 translation (c)             " , &
36859             "(  h   h -2h l) l=2n : (1-100) glide plane with c/2 translation (c)             " , &
36860             "(-2h   h   h l) l=2n : (01-10) glide plane with c/2 translation (c)             " , &
36861             "(  h -2h   h l) l=2n : (-1010) glide plane with c/2 translation (c)             " , &
36862             "(  h  h  l)     l=2n : (1-10) glide plane with c/2 translation (c,n)            " , &
36863             "(  h  k  k)     h=2n : (01-1) glide plane with a/2 translation (a,n)            " , &
36864             "(  h  k  h)     k=2n : (-101) glide plane with b/2 translation (b,n)            " , &
36865             "(  h  h  l)     l=2n : (1-10) glide plane with c/2 translation (c,n)            " , &
36866             "(  h  h  l)  2h+l=4n : (1-10) glide plane with a/4 +- b/4 +- c/4 translation (d)" , &
36867             "(  h -h  l)     l=2n : (110)  glide plane with c/2 translation (c,n)            " , &
36868             "(  h -h  l)  2h+l=4n : (110)  glide plane with a/4 +- b/4 +- c/4 translation (d)" , &
36869             "(  h  k  k)     h=2n : (01-1) glide plane with a/2 translation (a,n)            " , &
36870             "(  h  k  k)  2k+h=4n : (01-1) glide plane with +-a/4 + b/4 +- c/4 translation(d)" , &
36871             "(  h  k -k)     h=2n : (011)  glide plane with a/2 translation (a,n)            " , &
36872             "(  h  k -k)  2k+h=4n : (011)  glide plane with +-a/4 + b/4 +- c/4 translation(d)" , &
36873             "(  h  k  h)     k=2n : (-101) glide plane with b/2 translation (b,n)            " , &
36874             "(  h  k  h)  2h+k=4n : (-101) glide plane with +-a/4 +- b/4 + c/4 translation(d)" , &
36875             "( -h  k  h)     k=2n : (101)  glide plane with b/2 translation (b,n)            " , &
36876             "( -h  k  h)  2h+k=4n : (101)  glide plane with +-a/4 +- b/4 + c/4 translation(d)" /)
36877         Hkl_Ref_Conditions(40:58)(1:80)   = (/  &
36878             "(h 0 0)      h=2n : screw axis // [100] with  a/2 translation (21)              " , & ! monoclinic, ortho., tetra and cubic
36879             "(h 0 0)      h=2n : screw axis // [100] with 2a/4 translation (42)              " , & ! cubic
36880             "(h 0 0)      h=4n : screw axis // [100] with  a/4 translation (41)              " , & ! cubic
36881             "(h 0 0)      h=4n : screw axis // [100] with 3a/4 translation (43)              " , & ! cubic
36882             "(0 k 0)      k=2n : screw axis // [010] with  b/2 translation (21)              " , & ! monoclinic, ortho., tetra and cubic
36883             "(0 k 0)      k=2n : screw axis // [010] with 2b/4 translation (42)              " , & ! cubic
36884             "(0 k 0)      k=4n : screw axis // [010] with  b/4 translation (41)              " , & ! cubic
36885             "(0 k 0)      k=4n : screw axis // [010] with 3b/4 translation (43)              " , & ! cubic
36886             "(0 0 l)      l=2n : screw axis // [00l] with  c/2 translation (21)              " , & ! monoclinic, ortho., tetra and cubic
36887             "(0 0 l)      l=2n : screw axis // [00l] with 2c/4 translation (42)              " , & ! tetragonal and cubic
36888             "(0 0 l)      l=4n : screw axis // [00l] with  c/4 translation (41)              " , & ! tetragonal and cubic
36889             "(0 0 l)      l=4n : screw axis // [00l] with 3c/4 translation (43)              " , & ! tetragonal and cubic
36890             "(0 0 0 l)    l=2n : screw axis // [00l] axis with 3c/6 translation (63)         " , &
36891             "(0 0 0 l)    l=3n : screw axis // [00l] axis with  c/3 translation (31)         " , &
36892             "(0 0 0 l)    l=3n : screw axis // [00l] axis with 2c/3 translation (32)         " , &
36893             "(0 0 0 l)    l=3n : screw axis // [00l] axis with 2c/6 translation (62)         " , &
36894             "(0 0 0 l)    l=3n : screw axis // [00l] axis with 4c/6 translation (64)         " , &
36895             "(0 0 0 l)    l=6n : screw axis // [00l] axis with  c/6 translation (61)         " , &
36896             "(0 0 0 l)    l=6n : screw axis // [00l] axis with 5c/6 translation (65)         " /)
36897
36898       return
36899    End Subroutine Init_Ref_Cond
36900
36901    !!--++
36902    !!--++ Subroutine Integral_Conditions(Spacegroup, iunit)
36903    !!--++    type (Space_Group_Type), intent(in) :: Spacegroup
36904    !!--++    integer,optional,        intent(in) :: iunit
36905    !!--++
36906    !!--++    (PRIVATE)
36907    !!--++    Integral Conditions according with I.T. Table 2.2.13.1
36908    !!--++    space.
36909    !!--++
36910    !!--++ Update: May - 2005
36911    !!
36912    Subroutine Integral_Conditions(Spacegroup,iunit)
36913       !---- Arguments ----!
36914       type (Space_Group_Type),  intent(in)     :: spacegroup
36915       integer, optional,        intent(in)     :: iunit
36916
36917       !---- local variables ----!
36918       integer               :: h, k,l, m
36919       integer               :: n, n_ext
36920       integer, dimension(3) :: hh
36921       integer               :: num_exti
36922       logical               :: integral_condition
36923
36924       integral_condition   = .false.
36925
36926       ! 1.       h+k   = 2n                   C-face centred                      C
36927       ! 2.       k+l   = 2n                   A-face centred                      A
36928       ! 3.       h+l   = 2n                   B-face centred                      B
36929       ! 4.       h+k+l = 2n                   Body centred                        I
36930       !
36931       ! 5.       h+k   = 2n
36932       !      and k+l   = 2n
36933       !      and h+l   = 2n                   All-face centred                    F
36934       !     or h,k,l all odd
36935       !     or h,k,l all even
36936       !
36937       ! 6.      -h+k+l = 3n                   Rhombohedrally centred,             R
36938       !                                     obverse setting
36939
36940       if (present(iunit)) then
36941          write(unit=iunit,fmt=*) " "
36942          write(unit=iunit,fmt=*) " >>> Integral reflections conditions for centred lattices:"
36943          write(unit=iunit,fmt=*) "----------------------------------------------------------"
36944          write(unit=iunit,fmt=*) " "
36945       end if
36946
36947       !---- C-face centred ----!
36948       !  Hkl_Ref_Conditions(1) =   "(h k l)  h+k=2n           : xy0 centered base"
36949       num_exti = 1
36950       n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
36951       n_ext = 0   ! nombre de reflecions obeissant a la regle
36952       do h=-6, 6
36953          do k=-6, 6
36954             do l=-6, 6
36955                hh(1)=h
36956                hh(2)=k
36957                hh(3)=l
36958                m =  h+k
36959                if (m /= int(m/2)*2) then
36960                   n=n+1
36961                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
36962                end if
36963             end do   ! l loop
36964          end do    ! k loop
36965       end do     ! h loop
36966       if (n==n_ext) then
36967          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
36968          integral_condition = .true.
36969       end if
36970
36971       !---- A-face centred ----!
36972       !   Hkl_Ref_Conditions(2) =   "(h k l)  k+l=2n           : 0yz centered base"
36973       num_exti = 2
36974       n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
36975       n_ext = 0   ! nombre de reflecions obeissant a la regle
36976       do h=-6, 6
36977          do k=-6, 6
36978             do l=-6, 6
36979                hh(1)=h
36980                hh(2)=k
36981                hh(3)=l
36982                m =  k+l
36983                if (m /= int(m/2)*2) then
36984                   n=n+1
36985                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
36986                end if
36987             end do   ! l loop
36988          end do    ! k loop
36989       end do     ! h loop
36990       if (n==n_ext) then
36991          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
36992          integral_condition = .true.
36993       end if
36994
36995       !---- B-face centred ----!
36996       !  Hkl_Ref_Conditions(3) =   "(h k l)  h+l=2n           : x0z centered base"
36997       num_exti = 3
36998       n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
36999       n_ext = 0   ! nombre de reflecions obeissant a la regle
37000       do h=-6, 6
37001          do k=-6, 6
37002             do l=-6, 6
37003                hh(1)=h
37004                hh(2)=k
37005                hh(3)=l
37006                m =  h+l
37007                if (m /= int(m/2)*2) then
37008                   n=n+1
37009                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37010                end if
37011             end do   ! l loop
37012          end do    ! k loop
37013       end do     ! h loop
37014       if (n==n_ext) then
37015          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37016          integral_condition = .true.
37017       end if
37018
37019       !---- Body centred (I) ----!
37020       !  Hkl_Ref_Conditions(4) =   "(h k l)  h+k+l=2n         : body centred"
37021       num_exti = 4
37022       n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37023       n_ext = 0   ! nombre de reflecions obeissant a la regle
37024       do h=-6, 6
37025          do k=-6, 6
37026             do l=-6, 6
37027                hh(1)=h
37028                hh(2)=k
37029                hh(3)=l
37030                m =  h+k+l
37031                if (m /= int(m/2)*2) then
37032                   n=n+1
37033                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37034                end if
37035             end do   ! l loop
37036          end do    ! k loop
37037       end do     ! h loop
37038       if (n==n_ext) then
37039          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37040          integral_condition = .true.
37041       end if
37042
37043       !---- all-face centred (F) ----!
37044       ! Hkl_Ref_Conditions(5) =   "(h k l)  h,k,l same parity: all-face centred"
37045       num_exti = 5
37046       n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37047       n_ext = 0   ! nombre de reflecions obeissant a la regle
37048       do h=-6, 6
37049          do k=-6, 6
37050             do l=-6, 6
37051                hh(1)=h
37052                hh(2)=k
37053                hh(3)=l
37054                if (h /= int(h/2)*2 .and.  k /= int(k/2)*2 .and. l == int(l/2)*2 ) then
37055                   n=n+1
37056                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37057
37058                else if(h /= int(h/2)*2 .and.  k == int(k/2)*2 .and. l /= int(l/2)*2 ) then
37059                   n=n+1
37060                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37061
37062                else if(h == int(h/2)*2 .and.  k /= int(k/2)*2 .and. l /= int(l/2)*2 ) then
37063                   n=n+1
37064                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37065
37066                else if(h == int(h/2)*2 .and.  k == int(k/2)*2 .and. l /= int(l/2)*2 ) then
37067                   n=n+1
37068                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37069
37070                else if(h == int(h/2)*2 .and.  k /= int(k/2)*2 .and. l == int(l/2)*2 ) then
37071                   n=n+1
37072                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37073
37074                else if(h /= int(h/2)*2 .and.  k == int(k/2)*2 .and. l == int(l/2)*2 ) then
37075                   n=n+1
37076                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37077                end if
37078             end do   ! l loop
37079          end do    ! k loop
37080       end do     ! h loop
37081       if (n==n_ext) then
37082          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37083          integral_condition = .true.
37084       end if
37085
37086       !---- R network ----!
37087       !  Hkl_Ref_Conditions(6) =   "(h k l) -h+k+l=3n         : Rhombohedrally centred (R)"
37088       num_exti = 6
37089       n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37090       n_ext = 0   ! nombre de reflecions obeissant a la regle
37091       do h=-6, 6
37092          do k=-6, 6
37093             do l=-6, 6
37094                hh(1)=h
37095                hh(2)=k
37096                hh(3)=l
37097                m =  -h+k+l
37098                if (m /= int(m/3)*3) then
37099                   n=n+1
37100                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37101                end if
37102             end do   ! l loop
37103          end do    ! k loop
37104       end do     ! h loop
37105       if (n==n_ext) then
37106          if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37107          integral_condition = .true.
37108       end if
37109
37110       if (.not. integral_condition)   then
37111          if (present(iunit)) write(unit=iunit,fmt=*) "     =====>>> no general reflection condition"
37112       end if
37113
37114       return
37115    End Subroutine Integral_Conditions
37116
37117    !!--++
37118    !!--++ Subroutine Screw_Axis_Conditions(Spacegroup, iunit)
37119    !!--++    type (Space_Group_Type), intent(in) :: Spacegroup
37120    !!--++    integer,optional,        intent(in) :: iunit
37121    !!--++
37122    !!--++    (PRIVATE)
37123    !!--++    Reflections conditions for Screw axes Table 2.2.13.2
37124    !!--++
37125    !!--++ Update: May - 2005
37126    !!
37127    Subroutine Screw_Axis_Conditions(Spacegroup,Iunit)
37128       !---- Arguments ----!
37129       type (Space_Group_Type),       intent(in)     :: spacegroup
37130       integer, optional,             intent(in)     :: iunit
37131
37132       !---- Local variables ----!
37133       integer               :: h, k,l
37134       integer               :: n, n_ext
37135       integer, dimension(3) :: hh
37136       integer               :: num_exti
37137       logical               :: serial_condition
37138
37139       serial_condition   = .false.
37140
37141       if (present(iunit)) then
37142          write(unit=iunit,fmt=*) " "
37143          write(unit=iunit,fmt=*) " >>> Serial reflections conditions for screw axes:"
37144          write(unit=iunit,fmt=*) "---------------------------------------------------"
37145          write(unit=iunit,fmt=*) " "
37146       end if
37147
37148       !SCREW AXES:      33 extinctions
37149
37150       if (SpaceGroup%CrystalSys(1:10) == "Monoclinic" .or. SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or.   &
37151          SpaceGroup%CrystalSys(1:10) == "Tetragonal" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic" ) then
37152
37153          ! Hkl_Ref_Conditions(40) =   "(h 0 0)      h=2n : screw axis // [100] with  a/2 translation (21)"   ! monoclinic, ortho., tetra or cubic
37154          num_exti = 40
37155          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37156          n_ext = 0   ! nombre de reflecions obeissant a la regle
37157          do h=-6, 6
37158             hh(1)=h
37159             hh(2)=0
37160             hh(3)=0
37161             if (h /= int(h/2)*2) then
37162                n=n+1
37163                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37164             end if
37165          end do     ! h loop
37166          if (n==n_ext) then
37167             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37168             serial_condition = .true.
37169          end if
37170       end if ! fin de la condition "if monoclinic, ortho, tetragonal, cubic
37171
37172       if (SpaceGroup%CrystalSys(1:5) == "Cubic") then
37173          ! 41
37174          ! Hkl_Ref_Conditions(41) =   "(h 0 0)      h=2n : screw axis // [100] with  2a/4 translation (42)"   !  cubic
37175          num_exti = 41
37176          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37177          n_ext = 0   ! nombre de reflecions obeissant a la regle
37178          do h=-6, 6, 1
37179             hh(1)=h
37180             hh(2)=0
37181             hh(3)=0
37182             if (h /= int(h/2)*2) then
37183                n=n+1
37184                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37185             end if
37186          end do     ! h loop
37187          if (n==n_ext) then
37188             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37189             serial_condition = .true.
37190          end if
37191
37192          ! Hkl_Ref_Conditions(42) =   "(h 0 0)      h=4n : screw axis // [100] with  a/4 translation (41)"   ! cubic
37193          ! Hkl_Ref_Conditions(43) =   "(h 0 0)      h=4n : screw axis // [100] with 3a/4 translation (43)"   ! cubic
37194          num_exti = 42
37195          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37196          n_ext = 0   ! nombre de reflecions obeissant a la regle
37197          do h=-6, 6, 1
37198             hh(1)=h
37199             hh(2)=0
37200             hh(3)=0
37201             if (h /= int(h/4)*4) then
37202                n=n+1
37203                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37204             end if
37205          end do     ! h loop
37206          if (n==n_ext) then
37207             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37208             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+1,": ", Hkl_Ref_Conditions(num_exti+1)
37209             serial_condition = .true.
37210          end if
37211       end if ! fin de la condition "if cubic
37212
37213       if (SpaceGroup%CrystalSys(1:10) == "Monoclinic" .or. SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or.   &
37214          SpaceGroup%CrystalSys(1:10) == "Tetragonal" .or. SpaceGroup%CrystalSys(1:5)  == "Cubic" ) then
37215          ! Hkl_Ref_Conditions(44) =   "(0 k 0)      k=2n : screw axis // [010] with  b/2 translation (21)"   ! monoclinic, ortho., tetra and cubic
37216          num_exti = 44
37217          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37218          n_ext = 0   ! nombre de reflecions obeissant a la regle
37219          do k=-6, 6, 1
37220             hh(1)=0
37221             hh(2)=k
37222             hh(3)=0
37223             if (k /= int(k/2)*2) then
37224                n=n+1
37225                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37226             end if
37227          end do     ! h loop
37228          if (n==n_ext) then
37229             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37230             serial_condition = .true.
37231          end if
37232       end if   ! fin de la condition "if mono, ortho, tetra, cubic
37233
37234       if (SpaceGroup%CrystalSys(1:5) == "Cubic") then
37235          ! Hkl_Ref_Conditions(45) =   "(0 k 0)      k=2n : screw axis // [010] with  2b/4 translation (42)"   ! cubic
37236          num_exti = 45
37237          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37238          n_ext = 0   ! nombre de reflecions obeissant a la regle
37239          do k=-6, 6, 1
37240             hh(1)=0
37241             hh(2)=k
37242             hh(3)=0
37243             if (k /= int(k/2)*2) then
37244                n=n+1
37245                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37246             end if
37247          end do     ! h loop
37248          if (n==n_ext) then
37249             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37250             serial_condition = .true.
37251          end if
37252
37253          ! Hkl_Ref_Conditions(46) =   "(0 k 0)      k=4n : screw axis // [010] with  b/4 translation (41)"   ! cubic
37254          ! Hkl_Ref_Conditions(47) =   "(0 k 0)      k=4n : screw axis // [010] with 3b/4 translation (43)"   ! cubic
37255          num_exti = 46
37256          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37257          n_ext = 0   ! nombre de reflecions obeissant a la regle
37258          do k=-6, 6, 1
37259             hh(1)=0
37260             hh(2)=k
37261             hh(3)=0
37262             if (k /= int(k/4)*4) then
37263                n=n+1
37264                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37265             end if
37266          end do     ! h loop
37267          if (n==n_ext) then
37268             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37269             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+1,": ", Hkl_Ref_Conditions(num_exti+1)
37270             serial_condition = .true.
37271          end if
37272       end if ! fin de la condition "if cubic
37273
37274       if (SpaceGroup%CrystalSys(1:10) == "Monoclinic" .or. SpaceGroup%CrystalSys(1:12) == "Orthorhombic" .or.   &
37275          SpaceGroup%CrystalSys(1:5)  == "Cubic" ) then
37276          ! Hkl_Ref_Conditions(48) =   "(0 0 l)      l=2n : screw axis // [00l] with  c/2 translation (21)"   ! monoclinic, ortho. and cubic
37277          num_exti = 48
37278          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37279          n_ext = 0   ! nombre de reflecions obeissant a la regle
37280          do l=-6, 6, 1
37281             hh(1)=0
37282             hh(2)=0
37283             hh(3)=l
37284             if (l /= int(l/2)*2) then
37285                n=n+1
37286                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37287             end if
37288          end do     ! h loop
37289          if (n==n_ext) then
37290             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37291             serial_condition = .true.
37292          end if
37293       end if  ! fin de la condition mono, ortho, tetra, cubic
37294
37295       if (SpaceGroup%CrystalSys(1:5) == "Cubic" .or. SpaceGroup%CrystalSys(1:10) == "Tetragonal") then
37296          ! 49
37297          ! Hkl_Ref_Conditions(49) =   "(0 0 l)      l=2n : screw axis // [00l] with  c/2 translation (21)"   ! monoclinic, ortho. and cubic
37298          num_exti = 49
37299          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37300          n_ext = 0   ! nombre de reflecions obeissant a la regle
37301          do l=-6, 6, 1
37302             hh(1)=0
37303             hh(2)=0
37304             hh(3)=l
37305             if (l /= int(l/2)*2) then
37306                n=n+1
37307                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37308             end if
37309          end do     ! h loop
37310          if (n==n_ext) then
37311             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37312             serial_condition = .true.
37313          end if
37314
37315          ! 50 51
37316          ! Hkl_Ref_Conditions(50) =  "(0 0 l)      l=4n : screw axis // [00l] with  c/4 translation (41)"   ! tetragonal and cubic
37317          ! Hkl_Ref_Conditions(51) =  "(0 0 l)      l=4n : screw axis // [00l] with 3c/4 translation (43)"   ! tetragonal and cubic
37318          num_exti = 50
37319          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37320          n_ext = 0   ! nombre de reflecions obeissant a la regle
37321          do l=-6, 6, 1
37322             hh(1)=0
37323             hh(2)=0
37324             hh(3)=l
37325             if (l /= int(l/4)*4) then
37326                n=n+1
37327                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37328             end if
37329          end do     ! h loop
37330          if (n==n_ext) then
37331             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37332             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+1,": ", Hkl_Ref_Conditions(num_exti+1)
37333             serial_condition = .true.
37334          end if
37335       end if ! fin de la condition "if cubic
37336
37337       if (SpaceGroup%SPG_Latsy(1:1) == "h") then
37338
37339          !52:
37340          ! Hkl_Ref_Conditions(52) =   "(0 0 0 l)    l=2n : screw axis // [00l] axis with 3c/6 translation (63)"
37341          num_exti = 52
37342          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37343          n_ext = 0   ! nombre de reflecions obeissant a la regle
37344          do l=-6, 6, 1
37345             hh(1)=0
37346             hh(2)=0
37347             hh(3)=l
37348             if (l /= int(l/2)*2) then
37349                n=n+1
37350                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37351             end if
37352          end do     ! h loop
37353          if (n==n_ext) then
37354             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37355             serial_condition = .true.
37356          end if
37357
37358          !53 54 55 56
37359          ! Hkl_Ref_Conditions(53) =   "(0 0 0 l)    l=3n : screw axis // [00l] axis with  c/3 translation (31)"
37360          ! Hkl_Ref_Conditions(54) =   "(0 0 0 l)    l=3n : screw axis // [00l] axis with 2c/3 translation (32)"
37361          ! Hkl_Ref_Conditions(55) =   "(0 0 0 l)    l=3n : screw axis // [00l] axis with 2c/6 translation (62)"
37362          ! Hkl_Ref_Conditions(56) =   "(0 0 0 l)    l=3n : screw axis // [00l] axis with 4c/6 translation (64)"
37363          num_exti = 53
37364          n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37365          n_ext = 0   ! nombre de reflecions obeissant a la regle
37366          do l=-6, 6, 1
37367             hh(1)=0
37368             hh(2)=0
37369             hh(3)=l
37370             if (l /= int(l/3)*3) then
37371                n=n+1
37372                if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37373             end if
37374          end do     ! h loop
37375
37376          if (n==n_ext) then
37377                 if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37378             if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+1,": ", Hkl_Ref_Conditions(num_exti+1)
37379             if (SpaceGroup%laue(1:3) == "6/m") then
37380                  if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+2,": ", Hkl_Ref_Conditions(num_exti+2)
37381                if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+3,": ", Hkl_Ref_Conditions(num_exti+3)
37382             end if ! fin de la condition "6/m
37383             serial_condition   = .true.
37384          end if
37385
37386          if (SpaceGroup%laue(1:3) == "6/m") then
37387             !57 58:
37388             ! Hkl_Ref_Conditions(57) =   "(0 0 0 l)    l=6n : screw axis // [00l] axis with  c/6 translation (61)"
37389             ! Hkl_Ref_Conditions(58) =   "(0 0 0 l)    l=6n : screw axis // [00l] axis with 5c/6 translation (65)"
37390             num_exti = 57
37391             n = 0       ! nombre de reflections pouvant obeir a la regle d"extinction
37392             n_ext = 0   ! nombre de reflecions obeissant a la regle
37393             do l=-6, 6, 1
37394                hh(1)=0
37395                hh(2)=0
37396                hh(3)=l
37397                if (l /= int(l/6)*6) then
37398                   n=n+1
37399                   if (hkl_absent(hh,Spacegroup)) n_ext=n_ext+1
37400                end if
37401             end do     ! h loop
37402             if (n==n_ext) then
37403                  if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti,": ", Hkl_Ref_Conditions(num_exti)
37404                if (present(iunit)) write(unit=iunit,fmt="(tr5,a,i2,2a)")  "#",num_exti+1,": ", Hkl_Ref_Conditions(num_exti+1)
37405                serial_condition   = .true.
37406             end if
37407          end if ! fin de la condition "6/m
37408       end if  ! fin de la condition "if hexagonal
37409
37410       if (.not. serial_condition)   then
37411          if (present(iunit)) write(unit=iunit,fmt=*) "     =====>>> no serial reflection condition"
37412       end if
37413
37414       return
37415    End Subroutine Screw_Axis_Conditions
37416
37417    !!----
37418    !!---- Subroutine Search_Extintions(Spacegroup, iunit)
37419    !!----    type (Space_Group_Type), intent(in) :: Spacegroup
37420    !!----    integer,                 intent(in) :: iunit
37421    !!----    or
37422    !!----    type (Space_Group_Type),         intent(in) :: Spacegroup
37423    !!----    integer,                         intent(out):: nlines
37424    !!----    character(len=80), dimension(:), intent(out) :: filevar
37425    !!----
37426    !!----    Write information about the Reflections Extintion for SpaceGroup
37427    !!----
37428    !!---- Update: May - 2005
37429    !!
37430
37431    !!--++
37432    !!--++ Subroutine Search_Extintions_Iunit(Spacegroup, iunit)
37433    !!--++    type (Space_Group_Type), intent(in) :: Spacegroup
37434    !!--++    integer,                 intent(in) :: iunit
37435    !!--++
37436    !!--++    (Overloaded)
37437    !!--++    Write information about the Reflections Extintion for SpaceGroup
37438    !!--++
37439    !!--++ Update: May - 2005
37440    !!
37441    Subroutine Search_Extinctions_Iunit(Spacegroup, Iunit)
37442       !---- Arguments ----!
37443       type (Space_Group_Type), intent(in)     :: spacegroup
37444       integer,                 intent(in)     :: Iunit
37445
37446       if (.not. hkl_ref_cond_ini) then
37447          call init_ref_cond()
37448          hkl_ref_cond_ini=.true.
37449       end if
37450       call integral_conditions(spacegroup,iunit)
37451       call glide_planes_conditions(spacegroup,iunit)
37452       call screw_axis_conditions(spacegroup,iunit)
37453
37454       return
37455    End Subroutine Search_Extinctions_Iunit
37456
37457    !!--++
37458    !!--++ Subroutine Search_Extinctions_File(Spacegroup, nlines, filevar)
37459    !!--++    type (Space_Group_Type),        intent(in)  :: Spacegroup
37460    !!--++    integer,                        intent(out) :: nlines
37461    !!--++    character(len=80),dimension(:), intent(out) :: filevar
37462    !!--++
37463    !!--++    (Overloaded)
37464    !!--++    Write information about the Reflections Extintion for SpaceGroup
37465    !!--++    in filevar variable
37466    !!--++
37467    !!--++ Update: April - 2009
37468    !!
37469    Subroutine Search_Extinctions_File(Spacegroup, nlines, filevar)
37470       !---- Arguments ----!
37471       type (Space_Group_Type), intent(in)          :: Spacegroup
37472       integer,                 intent(out)         :: nlines
37473       character(len=*), dimension(:), intent(out)  :: filevar
37474
37475       !---- Local Variables ----!
37476       integer            :: iunit,ierr
37477       character(len=132) :: line
37478
37479       ! Init
37480       nlines=0
37481       filevar=' '
37482
37483       ! Load Information
37484       if (.not. hkl_ref_cond_ini) then
37485          call init_ref_cond()
37486          hkl_ref_cond_ini=.true.
37487       end if
37488
37489       call Get_LogUnit(iunit)
37490       open(unit=iunit,file='search_extin_xyx.tmp')
37491
37492       call integral_conditions(spacegroup,iunit)
37493       call glide_planes_conditions(spacegroup,iunit)
37494       call screw_axis_conditions(spacegroup,iunit)
37495
37496       rewind(unit=iunit)
37497       do
37498          read(unit=iunit,fmt='(a)', iostat=ierr) line
37499          if (ierr /=0) exit
37500          nlines=nlines+1
37501          filevar(nlines)=trim(line)
37502       end do
37503       close(unit=iunit, status='delete')
37504
37505       return
37506    End Subroutine Search_Extinctions_File
37507
37508    !!----
37509    !!---- Subroutine Write_Asu(Spacegroup, iunit)
37510    !!----    type (Space_Group_Type), intent(in) :: Spacegroup
37511    !!----    integer,optional,        intent(in) :: iunit
37512    !!----
37513    !!----    Write information about the asymmetric unit for reciprocal
37514    !!----    space.
37515    !!----
37516    !!---- Update: February - 2005
37517    !!
37518    Subroutine Write_Asu(Spacegroup, iunit)
37519       !---- Arguments ----!
37520       type (space_group_type), intent(in) :: Spacegroup
37521       integer,optional,        intent(in) :: iunit
37522
37523       !---- Local Variables ----!
37524       character(len=120)                  :: line
37525       character(len=2)                    :: inf
37526       integer                             :: lun
37527
37528       if (present(iunit)) then
37529         lun=iunit
37530       else
37531         lun=6
37532       end if
37533
37534       line(1:10)=" [     ]  "
37535       line(3:7)=spacegroup%laue
37536
37537       if (spacegroup%numspg > 0 .and. spacegroup%numspg <= 231) then
37538          select case (spacegroup%numspg)
37539             case (1:2)       ! -1
37540                line(11:)="hkl: l >=0    hk0: h >=0    0k0: k >=0"
37541
37542             case (3:15)      ! 2/m
37543                inf(1:2)=adjustl(Spacegroup%info(1:2))
37544                if(inf(1:1) == "-") inf(1:1)=inf(2:2)
37545                select case (inf(1:1))
37546                   case ("b")    ! 1 2/m 1
37547                      line(11:)="hkl: k >=0, l >=0   hk0: h >=0"
37548                   case ("c")    ! 1 1 2/m
37549                      line(11:)="hkl: k >=0, l >=0   h0l: h >=0"
37550                   case ("a")    ! 2/m 1 1
37551                      line(11:)="hkl: h >=0, l >=0   0kl: l >=0" !  Provisional (to be tested)
37552                end select
37553
37554             case (16:74)      ! mmm
37555                line(11:)="hkl: h >=0, k >=0, l >=0"
37556
37557             case (75:88)      ! 4/m
37558                line(11:)="hkl: h >=0, l >=0 with k >=0 if h =0 and k >0 if h >0"
37559
37560             case (89:142)     ! 4/mmm
37561                line(11:)="hkl: h >=0, k >=0, l >=0 and h >=k"
37562
37563             case (143:148)    ! -3
37564                line(11:)="hkl: h+k>0, l>0    hk0: h>0, k>=0"
37565
37566             case (149,151,153,157,159,162,163)  ! -3 1 m
37567                line(11:)="hkl: h >=0, h >=k >0   and  h0l: h >=0, l >=0"
37568
37569             case (150,152,154,155,156,158,160,161,164,165,166,167)   ! -3 m
37570                line(11:)="hkl: h >=0  h >=k  and   hhl: h >=0, l >=0 "
37571
37572             case (168:176)  ! 6/m
37573                line(11:)="hkl: h > 0, k > 0, l >=0   and  0kl: k >=0, l >=0 "
37574
37575             case (177:194)  ! 6/mmmm
37576                line(11:)="hkl: h >=0, k >=0, l >=0 with h >=k"
37577
37578             case (195:206)  ! m-3
37579                line(11:)="hkl: h > l, k > l, l >=0  and   hkk: k >=0, h >=k"
37580
37581             case (207:230)  ! m-3m
37582                line(11:)="hkl: h >=0, k >=0, l >=0 with h >=k  and k >=l"
37583
37584          end select
37585       else
37586          select case(SpaceGroup%Laue)
37587             case("-1   ")
37588                line(11:)="hkl: l >=0    hk0: h >=0    0k0: k >=0"
37589             case("2/m  ")
37590                line(11:)="hkl: k >=0, l >=0   hk0: h >=0"
37591             case("mmm  ")
37592                line(11:)="hkl: h >=0, k >=0, l >=0"
37593             case("4/m  ")
37594                line(11:)="hkl: h >=0, l >=0 with k >=0 if h =0 and k >0 if h >0"
37595             case("4/mmm")
37596                 line(11:)="hkl: h >=0, k >=0, l >=0 and h >=k"
37597             case("-3   ")
37598                line(11:)="hkl: h+k>0, l>0    hk0: h>0, k>=0"
37599             case("-3m  ")
37600                line(11:)="hkl: h >=0  h >=k  and   hhl: h >=0, l >=0 "
37601             case("-31m ")
37602                line(11:)="hkl: h >=0, h >=k >0   and  h0l: h >=0, l >=0"
37603             case("6/m  ")
37604                line(11:)="hkl: h > 0, k > 0, l >=0   and  0kl: k >=0, l >=0 "
37605             case("6/mmm")
37606                line(11:)="hkl: h >=0, k >=0, l >=0 with h >=k"
37607             case("m-3  ")
37608                line(11:)="hkl: h > l, k > l, l >=0  and   hkk: k >=0, h >=k"
37609             case("m-3m ")
37610                line(11:)="hkl: h >=0, k >=0, l >=0 with h >=k  and k >=l"
37611             case default
37612                err_refl=.true.
37613                ERR_Refl_Mess=" SpaceGroup Laue Wrong"
37614                return
37615          end select
37616       end if
37617
37618       write(unit=lun,fmt="(a)") " => Reciprocal Asymmetric Unit "
37619       write(unit=lun,fmt="(a)") "   "//line
37620
37621       return
37622    End Subroutine Write_Asu
37623
37624    !!----
37625    !!---- Subroutine Write_RefList_Info(Reflex, iunit)
37626    !!----    type (Reflection_List_Type), intent(in) :: Reflex
37627    !!----    integer,optional,            intent(in) :: iunit
37628    !!----
37629    !!----    Write information about the Reflection List
37630    !!----
37631    !!---- Update: February - 2005
37632    !!
37633    Subroutine Write_RefList_Info(Rfl, Iunit, Mode)
37634       !---- Arguments ----!
37635       type (Reflection_List_Type), intent(in) :: Rfl
37636       integer,optional,            intent(in) :: iunit
37637       character(len=*), optional,  intent(in) :: Mode
37638
37639       !---- Local variables ----!
37640       integer :: i,lun
37641       integer :: hmax,kmax,lmax,hmin,kmin,lmin
37642       real    :: delta
37643
37644       lun=6
37645       if (present(iunit)) lun=iunit
37646
37647       if (present(mode)) then
37648          Select Case (mode(1:3))
37649             Case("NUC","nuc")
37650                write(unit=lun,fmt="(/,/,a)") "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(NEUTRONS)"
37651                write(unit=lun,fmt="(a)")     "    ==================================================="
37652             Case default
37653                write(unit=lun,fmt="(/,/,a)") "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(X-RAYS)"
37654                write(unit=lun,fmt="(a)")     "    ================================================="
37655          End Select
37656
37657       else
37658          write(unit=lun,fmt="(a)")   "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(X-RAYS)"
37659          write(unit=lun,fmt="(a)")   "    ================================================="
37660       end if
37661
37662       hmax=maxval(rfl%ref%h(1))
37663       kmax=maxval(rfl%ref%h(2))
37664       lmax=maxval(rfl%ref%h(3))
37665
37666       hmin=minval(rfl%ref%h(1))
37667       kmin=minval(rfl%ref%h(2))
37668       lmin=minval(rfl%ref%h(3))
37669
37670       write(unit=lun,fmt="(/,a,/)") "   H   K   L   Mult  SinTh/Lda    |Fobs|      SFobs        |Fc|       Delta"
37671       do i=1,rfl%Nref
37672          delta=rfl%ref(i)%Fo-rfl%ref(i)%Fc
37673          write(unit=lun,fmt="(3i4,i5,5f12.5)") rfl%ref(i)%h, rfl%ref(i)%mult,     &
37674              rfl%ref(i)%S, rfl%ref(i)%Fo,rfl%ref(i)%SFo, rfl%ref(i)%Fc, delta
37675       end do
37676
37677       write(unit=lun,fmt="(a)") " "
37678       write(unit=lun,fmt="(a)") " "
37679       write(unit=lun,fmt="(a,i6)") " => Number of Reflections: ", rfl%nref
37680       write(unit=lun,fmt="(a,i4,tr3,a,i4,tr3,a,i4)") " => H_max: ",hmax," K_max: ",kmax," L_max: ",lmax
37681       write(unit=lun,fmt="(a,i4,tr3,a,i4,tr3,a,i4)") " => H_min: ",hmin," K_min: ",kmin," L_min: ",lmin
37682       write(unit=lun,fmt="(a)") " "
37683
37684       return
37685    End Subroutine Write_RefList_Info
37686
37687 End Module CFML_Reflections_Utilities
37688
37689!!-------------------------------------------------------
37690!!---- Crystallographic Fortran Modules Library (CrysFML)
37691!!-------------------------------------------------------
37692!!---- The CrysFML project is distributed under LGPL. In agreement with the
37693!!---- Intergovernmental Convention of the ILL, this software cannot be used
37694!!---- in military applications.
37695!!----
37696!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
37697!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
37698!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
37699!!----
37700!!---- Authors: Juan Rodriguez-Carvajal (ILL)
37701!!----          Javier Gonzalez-Platas  (ULL)
37702!!----
37703!!---- Contributors: Laurent Chapon     (ILL)
37704!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
37705!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
37706!!----               Tierry Roisnel     (CDIFX,Rennes France)
37707!!----               Eric Pellegrini    (ILL)
37708!!----
37709!!---- This library is free software; you can redistribute it and/or
37710!!---- modify it under the terms of the GNU Lesser General Public
37711!!---- License as published by the Free Software Foundation; either
37712!!---- version 3.0 of the License, or (at your option) any later version.
37713!!----
37714!!---- This library is distributed in the hope that it will be useful,
37715!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
37716!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
37717!!---- Lesser General Public License for more details.
37718!!----
37719!!---- You should have received a copy of the GNU Lesser General Public
37720!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
37721!!----
37722!!---- MODULE: CFML_Atom_TypeDef
37723!!----   INFO: Subroutines related to Atoms definitions
37724!!----
37725!!---- HISTORY
37726!!----    Update: 06/03/2011
37727!!----
37728!!----
37729!!---- DEPENDENCIES
37730!!----
37731!!--++    Use CFML_GlobalDeps,                only: Cp, Pi
37732!!--++    Use CFML_Math_General,              only: Modulo_Lat, Equal_Vector
37733!!--++    Use CFML_Math_3D,                   only: matrix_diageigen, determ_a,
37734!!--++    Use CFML_String_Utilities,          only: setnum_std
37735!!--++    Use CFML_Crystal_Metrics,           only: Crystal_Cell_Type, convert_b_betas,    &
37736!!--++                                              convert_b_u, convert_betas_b,          &
37737!!--++                                              convert_betas_u, convert_u_b,          &
37738!!--++                                              convert_u_betas, u_equiv
37739!!--++    Use CFML_Crystallographic_Symmetry, only: Space_Group_Type, ApplySo, Lattice_Trans, &
37740!!--++                                              Get_Multip_Pos, Get_Stabilizer
37741!!--++
37742!!----
37743!!---- VARIABLES
37744!!----    ATOM_TYPE
37745!!----    ATOMS_CELL_TYPE
37746!!----    ATOM_LIST_TYPE
37747!!----    MATOM_TYPE
37748!!----    MATOM_LIST_TYPE
37749!!----    ERR_ATMD
37750!!----    ERR_ATMD_MESS
37751!!--++    R_ATOM           [Private]
37752!!----
37753!!---- PROCEDURES
37754!!----    Functions:
37755!!----       EQUIV_ATM
37756!!----       WRT_LAB
37757!!----
37758!!----    Subroutines:
37759!!----       ALLOCATE_ATOMS_CELL
37760!!----       ALLOCATE_ATOM_LIST
37761!!----       ALLOCATE_MATOM_LIST
37762!!----       ATLIST1_EXTENCELL_ATLIST2
37763!!----       ATOMS_CELL_TO_LIST
37764!!----       ATOM_LIST_TO_CELL
37765!!----       ATOM_UEQUI_LIST
37766!!----       COPY_ATOM_LIST
37767!!----       DEALLOCATE_ATOMS_CELL
37768!!----       DEALLOCATE_ATOM_LIST
37769!!----       DEALLOCATE_MATOM_LIST
37770!!----       GET_ATOM_2ND_TENSOR_CTR
37771!!----       INIT_ATOM_TYPE
37772!!----       INIT_ERR_ATMD
37773!!----       MERGE_ATOMS_PEAKS
37774!!----       MULTI
37775!!----       READ_BIN_ATOM_LIST
37776!!----       SET_ATOM_EQUIV_LIST
37777!!----       WRITE_ATOM_LIST
37778!!----       WRITE_BIN_ATOM_LIST
37779!!----
37780!!
37781 Module CFML_Atom_TypeDef
37782
37783    !---- Use Modules ----!
37784    Use CFML_GlobalDeps,                only: Cp, Pi
37785    Use CFML_Math_General,              only: Modulo_Lat, Equal_Vector
37786    Use CFML_String_Utilities,          only: setnum_std
37787    Use CFML_Math_3D,                   only: matrix_diageigen
37788    Use CFML_Crystal_Metrics,           only: Crystal_Cell_Type, convert_b_betas,    &
37789                                              Convert_b_u, convert_betas_b,          &
37790                                              convert_betas_u, convert_u_b,          &
37791                                              convert_u_betas, u_equiv
37792    Use CFML_Crystallographic_Symmetry, only: Space_Group_Type, ApplySo, Lattice_Trans, &
37793                                              Get_Multip_Pos, Get_Stabilizer
37794
37795    !---- Variables ----!
37796    implicit none
37797
37798    private
37799
37800    !---- List of public overloaded procedures: subroutines ----!
37801
37802    !---- List of public functions ----!
37803    public :: Equiv_Atm, Wrt_Lab
37804
37805    !---- List of public subroutines ----!
37806    public :: Allocate_Atoms_Cell, Allocate_Atom_List, Atlist1_Extencell_Atlist2,     &
37807              Atoms_Cell_To_List, Atom_List_To_Cell, Atom_Uequi_List, Copy_Atom_list, &
37808              Deallocate_Atoms_Cell, Deallocate_Atom_List, Init_Atom_Type,            &
37809              Init_Err_Atmd, Merge_Atoms_Peaks, Multi, Write_Atom_List,               &
37810              Allocate_mAtom_list, Deallocate_mAtom_list,                             &
37811              Init_mAtom_Type, Read_Bin_Atom_List, Write_Bin_Atom_List,               &
37812              Set_Atom_Equiv_List, Get_Atom_2nd_Tensor_Ctr
37813
37814    !---- List of private Subroutines ----!
37815
37816    !---- Definitions ----!
37817
37818     !!---- Type, Public :: Atom_Equiv_Type
37819     !!----    integer                                        :: mult
37820     !!----    character(len=2)                               :: ChemSymb
37821     !!----    character(len=10),allocatable, dimension(:)    :: Lab
37822     !!----    real(kind=sp),    allocatable, dimension(:,:)  :: x
37823     !!---- End Type Atom_Equiv_Type
37824     !!----
37825     !!----  Updated: January 2014
37826     !!
37827     Type, Public :: Atom_Equiv_Type
37828        integer                                        :: mult
37829        character(len=2)                               :: ChemSymb
37830        character(len=20),allocatable, dimension(:)    :: Lab
37831        real(kind=cp),    allocatable, dimension(:,:)  :: x
37832     End Type Atom_Equiv_Type
37833
37834     !!---- Type, Public :: Atom_Equiv_List_Type
37835     !!----    integer                                           :: nauas
37836     !!----    type (Atom_Equiv_Type), allocatable, dimension(:) :: atm
37837     !!---- End Type Atom_Equiv_List_Type
37838     !!----
37839     !!----  Updated: January 2014
37840     !!
37841     Type, Public :: Atom_Equiv_List_Type
37842        integer                                           :: nauas
37843        type (Atom_Equiv_Type), allocatable, dimension(:) :: atm
37844     End Type Atom_Equiv_List_Type
37845
37846    !!----
37847    !!---- TYPE :: ATOM_TYPE
37848    !!--..
37849    !!---- Type, public :: Atom_Type
37850    !!----    character(len=20)                       :: Lab           ! Label
37851    !!----    character(len=2)                        :: ChemSymb      ! Chemical Symbol
37852    !!----    character(len=4)                        :: SfacSymb      ! Symbol for Scattering Factor
37853    !!----    character(len=1)                        :: wyck          ! Wyckoff letter
37854    !!----    logical                                 :: active        ! Control for different purposes
37855    !!----    integer                                 :: Z             ! Atomic number
37856    !!----    integer                                 :: mult          ! multiplicity of the site
37857    !!----    real(kind=cp),dimension(3)              :: x             ! Fractional coordinates
37858    !!----    real(kind=cp),dimension(3)              :: x_std         ! Standard deviations
37859    !!----    real(kind=cp),dimension(3)              :: mx            ! Multiplier parameters of coordinates
37860    !!----    integer,      dimension(3)              :: lx            ! Numbers in the LSQ list of LSQ parameters for coordinates
37861    !!----    real(kind=cp)                           :: occ           ! occupation factor
37862    !!----    real(kind=cp)                           :: occ_std       ! Standard deviation of occupation factor
37863    !!----    real(kind=cp)                           :: mOcc          !
37864    !!----    integer                                 :: lOcc          !
37865    !!----    real(kind=cp)                           :: Biso          ! Isotropic B-factor
37866    !!----    real(kind=cp)                           :: Biso_std      ! Standard deviation of Isotropic B-factor
37867    !!----    real(kind=cp)                           :: mBiso         !
37868    !!----    integer                                 :: lBiso         !
37869    !!----    character(len=4)                        :: utype         ! type of anisotropic thermal parameters: u_ij, b_ij, beta, none
37870    !!----    character(len=5)                        :: thtype        ! "isotr","aniso","other"
37871    !!----    real(kind=cp),dimension(6)              :: U             ! U11, U22, U33, U12, U13, U23
37872    !!----    real(kind=cp),dimension(6)              :: U_std         ! Standar_Deviations of U"s
37873    !!----    real(kind=cp)                           :: Ueq           ! Uequiv
37874    !!----    real(kind=cp),dimension(6)              :: mU            !
37875    !!----    integer,dimension(6)                    :: lU            !
37876    !!----    real(kind=cp)                           :: Charge        ! Charge
37877    !!----    real(kind=cp)                           :: Moment        ! Moment
37878    !!----    integer, dimension(5)                   :: Ind           ! Index for different purposes
37879    !!----    integer                                 :: Nvar          !
37880    !!----    real(kind=cp),dimension(25)             :: VarF          ! Free variables used for different purposes (1,2,3 reserved for occupations, not refinable)
37881    !!----    real(kind=cp),dimension(25)             :: MVarF         ! Multiplier parameters
37882    !!----    integer,      dimension(25)             :: LVarF         ! Numbers
37883    !!----    character(len=40)                       :: AtmInfo       ! Information string
37884    !!---- End Type Atom_Type
37885    !!----
37886    !!---- Update: May - 2009
37887    !!
37888    Type, public :: Atom_Type
37889       character(len=20)                        :: Lab
37890       character(len=2)                         :: ChemSymb
37891       character(len=4)                         :: SfacSymb
37892       character(len=1)                         :: wyck
37893       logical                                  :: Active
37894       integer                                  :: Z
37895       integer                                  :: Mult
37896       real(kind=cp),dimension(3)               :: X
37897       real(kind=cp),dimension(3)               :: X_Std
37898       real(kind=cp),dimension(3)               :: MX
37899       integer,      dimension(3)               :: LX
37900       real(kind=cp)                            :: Occ
37901       real(kind=cp)                            :: Occ_Std
37902       real(kind=cp)                            :: MOcc
37903       integer                                  :: LOcc
37904       real(kind=cp)                            :: Biso
37905       real(kind=cp)                            :: Biso_std
37906       real(kind=cp)                            :: MBiso
37907       integer                                  :: LBiso
37908       character(len=4)                         :: Utype
37909       character(len=5)                         :: ThType
37910       real(kind=cp),dimension(6)               :: U
37911       real(kind=cp),dimension(6)               :: U_std
37912       real(kind=cp)                            :: Ueq
37913       real(kind=cp),dimension(6)               :: MU
37914       integer,      dimension(6)               :: LU
37915       real(kind=cp)                            :: Charge
37916       real(kind=cp)                            :: Moment
37917       integer, dimension(5)                    :: Ind
37918       integer                                  :: NVar
37919       real(kind=cp),dimension(25)              :: VarF
37920       real(kind=cp),dimension(25)              :: MVarF
37921       integer,      dimension(25)              :: LVarF
37922       character(len=40)                        :: AtmInfo
37923    End Type Atom_Type
37924
37925    !!----
37926    !!---- TYPE :: atoms_cell_type
37927    !!--..
37928    !!---- Type, public :: atoms_cell_type
37929    !!----    integer                                      :: nat         ! -> Total number of atoms
37930    !!----    character(len=20), dimension(:), allocatable :: noms        ! -> Name of atoms   (nat)
37931    !!----    real(kind=cp),   dimension(:,:), allocatable :: xyz         ! -> Fractional coordinates (3,nat)
37932    !!----    real(kind=cp),     dimension(:), allocatable :: charge
37933    !!----    real(kind=cp),     dimension(:), allocatable :: moment
37934    !!----    real(kind=cp),   dimension(:,:), allocatable :: Var_free    ! -> Free variables (10,nat)
37935    !!----    integer,           dimension(:), allocatable :: neighb      ! -> Number of neighbours (nat)
37936    !!----    integer,        dimension( :,:), allocatable :: neighb_atom ! -> Ptr.->neighbour (# in list)(nat,idp)
37937    !!----    real(kind=cp),  dimension( :,:), allocatable :: distance    ! -> Corresponding distances (nat,idp)
37938    !!----    real(kind=cp),dimension(:, :,:), allocatable :: trans       ! -> Lattice translations   (3,nat,idp)
37939    !!----    integer                                      :: ndist       ! -> Number of distinct distances
37940    !!----    real(kind=cp),     dimension(:), allocatable :: ddist       ! -> List of distinct distances(nat*idp)
37941    !!----    character(len=20), dimension(:), allocatable :: ddlab       ! -> Labels of atoms at ddist (nat*idp)
37942    !!---- End Type atoms_cell_type
37943    !!----
37944    !!---- This type is mostly used for distance-angle and Bond-valence calculations.
37945    !!---- It holds the position and coordination of all the atoms in the conventional
37946    !!---- unit cell as well as their distances to neighbours atoms.
37947    !!----
37948    !!---- Update: February - 2005
37949    !!
37950    Type, public :: Atoms_Cell_Type
37951       integer                                            :: nat
37952       character (len=20),      dimension(:), allocatable :: noms
37953       real(kind=cp),         dimension(:,:), allocatable :: xyz
37954       real(kind=cp),           dimension(:), allocatable :: charge
37955       real(kind=cp),           dimension(:), allocatable :: moment
37956       real(kind=cp),         dimension(:,:), allocatable :: var_free
37957       integer,                 dimension(:), allocatable :: neighb
37958       integer,              dimension( :,:), allocatable :: neighb_atom
37959       real(kind=cp),        dimension( :,:), allocatable :: distance
37960       real(kind=cp),      dimension(:, :,:), allocatable :: trans
37961       integer                                            :: ndist
37962       real(kind=cp),           dimension(:), allocatable :: ddist
37963       character (len=20),      dimension(:), allocatable :: ddlab
37964    End Type Atoms_Cell_Type
37965
37966    !!----
37967    !!---- TYPE :: ATOM_LIST_TYPE
37968    !!--..
37969    !!---- Type, public :: atom_list_type
37970    !!----    integer                                    :: natoms  ! total number of atoms in the list
37971    !!----    type(Atom_Type),dimension(:),allocatable   :: atom    ! individual atoms
37972    !!---- End Type atom_list_type
37973    !!----
37974    !!---- Update: February - 2005
37975    !!
37976    Type, public :: Atom_List_Type
37977       integer                                  :: natoms
37978       type(Atom_Type),dimension(:),allocatable :: atom
37979    End type Atom_List_Type
37980
37981    !!----
37982    !!---- TYPE :: MATOM_TYPE
37983    !!--..
37984    !!---- Type, public :: mAtom_Type
37985    !!----    character(len=10)                       :: Lab           ! Label
37986    !!----    character(len=2)                        :: ChemSymb      ! Chemical Symbol
37987    !!----    character(len=4)                        :: SfacSymb      ! Chemical Symbol for SF
37988    !!----    character(len=1)                        :: wyck          ! Wyckoff letter
37989    !!----    logical                                 :: active        ! Control for different purposes
37990    !!----    integer                                 :: Z             ! Atomic number
37991    !!----    integer                                 :: mult          ! multiplicity of the site
37992    !!----    real(kind=cp),dimension(3)              :: x             ! Fractional coordinates
37993    !!----    real(kind=cp),dimension(3)              :: x_std         ! Standar deviations
37994    !!----    real(kind=cp),dimension(3)              :: mx            ! Multiplier parameters of coordinates
37995    !!----    integer,      dimension(3)              :: lx            ! Numbers of LSQ parameters for coordinates
37996    !!----    real(kind=cp)                           :: occ           ! occupation factor
37997    !!----    real(kind=cp)                           :: occ_std       ! Standard deviation of occupation factor
37998    !!----    real(kind=cp)                           :: mOcc          !
37999    !!----    integer                                 :: lOcc          !
38000    !!----    real(kind=cp)                           :: Biso          ! Isotropic B-factor
38001    !!----    real(kind=cp)                           :: Biso_std      ! Standard deviation of Isotropic B-factor
38002    !!----    real(kind=cp)                           :: mBiso         !
38003    !!----    integer                                 :: lBiso         !
38004    !!----    character(len=4)                        :: utype         ! type of anisotropic thermal parameters: u_ij, b_ij, beta, none
38005    !!----    character(len=5)                        :: thtype        ! "isotr","aniso","other"
38006    !!----    real(kind=cp),dimension(6)              :: U             ! U11, U22, U33, U12, U13, U23
38007    !!----    real(kind=cp),dimension(6)              :: U_std         ! Standar_Deviations of U"s
38008    !!----    real(kind=cp)                           :: Ueq           ! Uequiv
38009    !!----    real(kind=cp),dimension(6)              :: mU            !
38010    !!----    real(kind=cp),dimension(6)              :: lU            !
38011    !!----    real(kind=cp)                           :: Charge        ! Charge
38012    !!----    real(kind=cp)                           :: Moment        ! Moment
38013    !!----    integer, dimension(5)                   :: Ind           ! Index for different purposes
38014    !!----    integer                                 :: Nvar          !
38015    !!----    real(kind=cp),dimension(25)             :: VarF          ! Free parameters to load
38016    !!----    real(kind=cp),dimension(25)             :: mVarF
38017    !!----    integer,      dimension(25)             :: LVarF
38018    !!----    character(len=40)                       :: AtmInfo       ! Information string
38019    !!----                           ===================
38020    !!----                           Magnetic parameters
38021    !!----                           ===================
38022    !!----    integer                                 :: nvk           ! Number of propagation vectors (excluding -k)
38023    !!----    integer,      dimension(12)             :: imat          ! Number of the magnetic matrices/irrep set to be applied
38024    !!----    real(kind=cp),dimension(3,12)           :: SkR           ! Real part of Fourier Coefficient
38025    !!----    real(kind=cp),dimension(3,12)           :: SkR_std       ! Standard deviations of the Real part of Fourier Coefficient
38026    !!----    real(kind=cp),dimension(3,12)           :: Spher_SkR     ! Real part of Fourier Coefficient in spherical components
38027    !!----    real(kind=cp),dimension(3,12)           :: Spher_SkR_std ! Standard deviations of Real part of Fourier Coefficient in spherical components
38028    !!----    real(kind=cp),dimension(3,12)           :: mSkR          ! Multipliers for the real part of Fourier coefficients
38029    !!----    integer,      dimension(3,12)           :: lskr          ! Numbers in the list of LSQ parameters
38030    !!----    real(kind=cp),dimension(3,12)           :: SkI           ! Imaginary part of Fourier Coefficient
38031    !!----    real(kind=cp),dimension(3,12)           :: SkI_std       ! Standard deviations of Imaginary part of Fourier Coefficient
38032    !!----    real(kind=cp),dimension(3,12)           :: Spher_SkI     ! Imaginary part of Fourier Coefficient in spherical components
38033    !!----    real(kind=cp),dimension(3,12)           :: Spher_SkI_std ! Standard deviations of Imaginary part of Fourier Coefficient in spherical components
38034    !!----    real(kind=cp),dimension(3,12)           :: mSki          ! Multipliers for the imaginary part of Fourier coefficients
38035    !!----    integer,      dimension(3,12)           :: lski          ! Numbers in the list of LSQ parameters
38036    !!----    real(kind=cp),dimension(12)             :: mphas         ! Magnetic Phase in fractions of 2pi
38037    !!----    real(kind=cp),dimension(12)             :: mphas_std     ! Standard deviations of Magnetic Phase in fractions of 2pi
38038    !!----    real(kind=cp),dimension(12)             :: mmphas        ! Multiplier for the magnetic phase
38039    !!----    integer,dimension(12)                   :: lmphas        ! Number in the list of LSQ parameters
38040    !!----    real(kind=cp),dimension(12,12)          :: cbas          ! Coefficients of the basis functions of irreps, the second index is 1:nvk
38041    !!----    real(kind=cp),dimension(12,12)          :: cbas_std      ! Standard deviations of Coefficients of the basis functions of irreps, the second index is 1:nvk
38042    !!----    real(kind=cp),dimension(12,12)          :: mbas          ! multiplier for the coefficients of the basis functions of irreps
38043    !!----    integer,dimension(12,12)                :: lbas          ! Numbers in the list of LSQ parameters
38044    !!----    character(len=5)                        :: chitype       ! "isotr","aniso"
38045    !!----    real(kind=cp),dimension(6)              :: chi           ! chi11, chi22, chi33, chi12, chi13, chi23
38046    !!----    real(kind=cp),dimension(6)              :: chi_std       ! Standar_Deviations of chi's
38047    !!----    real(kind=cp)                           :: Chieq         ! Chi equiv
38048    !!----    real(kind=cp),dimension(6)              :: mchi          !
38049    !!----    real(kind=cp),dimension(6)              :: lchi          !
38050    !!---- End Type mAtom_Type
38051    !!----
38052    !!---- Updated: April - 2005
38053    !!---- Updated: November 3, 2013 (include standard deviations of magnetic parameters,JRC)
38054    !!---- Updated: June 25, 2014 (include local magnetic susceptibility tensor,JRC)
38055    !!
38056    Type, public :: mAtom_Type
38057       character(len=10)                        :: Lab
38058       character(len=2)                         :: ChemSymb
38059       character(len=4)                         :: SfacSymb
38060       character(len=1)                         :: wyck
38061       logical                                  :: Active
38062       integer                                  :: Z
38063       integer                                  :: Mult
38064       real(kind=cp),dimension(3)               :: X
38065       real(kind=cp),dimension(3)               :: X_Std
38066       real(kind=cp),dimension(3)               :: MX
38067       integer,      dimension(3)               :: LX
38068       real(kind=cp)                            :: Occ
38069       real(kind=cp)                            :: Occ_Std
38070       real(kind=cp)                            :: MOcc
38071       integer                                  :: LOcc
38072       real(kind=cp)                            :: Biso
38073       real(kind=cp)                            :: Biso_std
38074       real(kind=cp)                            :: MBiso
38075       integer                                  :: LBiso
38076       character(len=4)                         :: Utype
38077       character(len=5)                         :: ThType
38078       real(kind=cp),dimension(6)               :: U
38079       real(kind=cp),dimension(6)               :: U_std
38080       real(kind=cp)                            :: Ueq
38081       real(kind=cp),dimension(6)               :: MU
38082       integer,      dimension(6)               :: LU
38083       real(kind=cp)                            :: Charge
38084       real(kind=cp)                            :: Moment
38085       integer, dimension(5)                    :: Ind
38086       integer                                  :: NVar
38087       real(kind=cp),dimension(25)              :: VarF
38088       real(kind=cp),dimension(25)              :: mVarF
38089       integer,      dimension(25)              :: LVarF
38090       character(len=40)                        :: AtmInfo
38091
38092       integer                                 :: nvk
38093       integer,      dimension(12)             :: imat
38094
38095       real(kind=cp),dimension(3,12)           :: SkR
38096       real(kind=cp),dimension(3,12)           :: SkR_std
38097       real(kind=cp),dimension(3,12)           :: Spher_SkR
38098       real(kind=cp),dimension(3,12)           :: Spher_SkR_std
38099       real(kind=cp),dimension(3,12)           :: mSkR
38100       integer,      dimension(3,12)           :: lskr
38101
38102       real(kind=cp),dimension(3,12)           :: SkI
38103       real(kind=cp),dimension(3,12)           :: SkI_std
38104       real(kind=cp),dimension(3,12)           :: Spher_SkI
38105       real(kind=cp),dimension(3,12)           :: Spher_SkI_std
38106       real(kind=cp),dimension(3,12)           :: mSki
38107       integer,      dimension(3,12)           :: lski
38108
38109       real(kind=cp),dimension(12)             :: mphas
38110       real(kind=cp),dimension(12)             :: mphas_std
38111       real(kind=cp),dimension(12)             :: mmphas
38112       integer,dimension(12)                   :: lmphas
38113
38114       real(kind=cp),dimension(12,12)          :: cbas
38115       real(kind=cp),dimension(12,12)          :: cbas_std
38116       real(kind=cp),dimension(12,12)          :: mbas
38117       integer,dimension(12,12)                :: lbas
38118
38119       character(len=5)                        :: chitype
38120       real(kind=cp),dimension(6)              :: chi
38121       real(kind=cp),dimension(6)              :: chi_std
38122       real(kind=cp)                           :: Chieq
38123       real(kind=cp),dimension(6)              :: mchi
38124       real(kind=cp),dimension(6)              :: lchi
38125
38126    End Type mAtom_Type
38127
38128    !!----
38129    !!---- TYPE :: MATOM_LIST_TYPE
38130    !!--..
38131    !!---- Type, public :: mAtom_list_type
38132    !!----    integer                                   :: natoms     ! total number of atoms in the list
38133    !!----    logical                                   :: suscept    ! true if magnetic moments are calculated from local susceptibility
38134    !!----    real(kind=cp)                             :: MagField   ! Applied magnetic field strength in Tesla
38135    !!----    real(kind=cp), dimension(3)               :: dir_MField ! Direction of magnetic field in crystallographic system
38136    !!----    type(mAtom_Type),dimension(:),allocatable :: Atom       ! individual atoms
38137    !!---- End Type mAtom_list_type
38138    !!----
38139    !!---- Updated: April - 2005, June - 2014
38140    !!
38141    Type, public :: mAtom_List_Type
38142       integer                                   :: natoms
38143       logical                                   :: suscept    ! true if magnetic moments are calculated from local susceptibility
38144       real(kind=cp)                             :: MagField   ! Applied magnetic field strength in Tesla
38145       real(kind=cp), dimension(3)               :: dir_MField ! Direction of magnetic field in crystallographic system
38146       type(mAtom_Type),dimension(:),allocatable :: Atom
38147    End type mAtom_List_Type
38148    !!----
38149    !!---- ERR_ATMD
38150    !!----    logical, public  :: err_atmd
38151    !!----
38152    !!----    Logical Variable taking the value .true. if an error in the module ATOM_DISTANCES occurs.
38153    !!----
38154    !!---- Update: February - 2005
38155    !!
38156    logical, public  :: ERR_Atmd
38157
38158    !!----
38159    !!---- ERR_ATMD_MESS
38160    !!----    character(len=150), public:: Err_Atmd_Mess
38161    !!----
38162    !!----    String containing information about the last error
38163    !!----
38164    !!---- Update: February - 2005
38165    !!
38166    character(len=150), public :: Err_Atmd_Mess
38167
38168    !!--++
38169    !!--++ R_ATOM
38170    !!--++    real(kind=cp), parameter, private :: r_atom=1.1
38171    !!--++
38172    !!--++    (PRIVATE)
38173    !!--++    Average atomic radius. Value taken for internal calculations.
38174    !!--++
38175    !!--++ Update: February - 2005
38176    !!
38177    real(kind=cp), parameter, private :: r_atom=1.1
38178
38179Contains
38180
38181    !---- Functions ----!
38182
38183    !!----
38184    !!---- Logical Function Equiv_Atm(Nam1,Nam2,NameAt) Result(Equiv_Atom)
38185    !!----    character (len=*), intent (in) :: nam1       !  In -> Atom Nam1
38186    !!----    character (len=*), intent (in) :: nam2       !  In -> Atom Nam2
38187    !!----    character (len=*), intent (in) :: NameAt     !  In -> String containing atom names
38188    !!----    logical                        :: equiv_atom !  Result .true. or .false.
38189    !!----
38190    !!----    Determine whether the atoms of names "nam1" and "nam2" are included in
38191    !!----    the longer string "name" (constructed by function "wrt_lab").
38192    !!----
38193    !!---- Update: February - 2005
38194    !!
38195    Function Equiv_Atm(Nam1,Nam2,NameAt) Result(Equiv_Atom)
38196       !---- Arguments ----!
38197       character (len=*), intent (in) :: nam1,nam2
38198       character (len=*), intent (in) :: NameAt
38199       logical                        :: equiv_atom
38200
38201       !---- Local variables ----!
38202       integer :: i1,i2
38203
38204       equiv_atom = .false.
38205
38206       i1=index(nam1,"_")-1
38207       i2=index(nam2,"_")-1
38208       if (i1 < 0 .or. i2 < 0 ) return
38209       if (nam1(1:i1) == nameat(1:i1) .and. nam2(1:i2) == nameat(5:4+i2) ) then
38210          equiv_atom = .true.
38211       else if(nam1(1:i1) == nameat(5:4+i1) .and. nam2(1:i2) == nameat(1:i2) ) then
38212          equiv_atom = .true.
38213       end if
38214
38215       return
38216    End Function Equiv_Atm
38217
38218    !!----
38219    !!---- Function Wrt_Lab(Nam1,Nam2) Result(Bilabel)
38220    !!----    character (len=*), intent (in) :: nam1     !  In -> Atom name 1
38221    !!----    character (len=*), intent (in) :: nam2     !  In -> Atom name 2
38222    !!----    character (len=8)              :: bilabel  ! Result -> Composed string with underscores
38223    !!----
38224    !!----    Character function merging the main part of the labels
38225    !!----    (before underscore "_") of the atoms "nam1" and "nam2" into
38226    !!----    the string "bilabel"
38227    !!----
38228    !!---- Update: February - 2005
38229    !!
38230    Function Wrt_Lab(Nam1,Nam2) Result(Bilabel)
38231       !---- Arguments ----!
38232       character (len=*), intent (in) :: nam1,nam2
38233       character (len=8)              :: bilabel
38234
38235       !---- Local variables ----!
38236       integer :: i1,i2
38237
38238       bilabel=" "
38239
38240       i1=index(nam1,"_")-1
38241       i2=index(nam2,"_")-1
38242       if (i1 < 0 ) then
38243          bilabel(1:4) = nam1(1:4)
38244       else
38245          bilabel(1:i1) = nam1(1:i1)
38246       end if
38247
38248       if (i2 < 0 ) then
38249          bilabel(5:8) = nam2(1:4)
38250       else
38251          bilabel(5:4+i2) = nam2(1:i2)
38252       end if
38253
38254       return
38255    End Function Wrt_Lab
38256
38257    !---- Subroutines ----!
38258
38259    !!----
38260    !!---- Subroutine Allocate_Atoms_Cell(Nasu,Mul,Dmax,Ac)
38261    !!----    integer, intent(in)                      :: nasu    !  In -> Number of atoms in asymmetric unit
38262    !!----    integer, intent(in)                      :: mul     !  In -> General multiplicity of the Space Group
38263    !!----    real(kind=cp),    intent(in)             :: dmax    !  In -> Maximun distance to be calculated
38264    !!----    type (atoms_cell_type), intent(in out)   :: Ac      !  In -> Object of type atoms_cell_type
38265    !!----                                                          Out -> Allocated and initialized object Ac
38266    !!----
38267    !!----    Allocation of objet "Ac" of type Atoms_Cell. "Ac" contains
38268    !!----    components with ALLOCATABLE attribute with dimension depending
38269    !!----    on the input arguments "Nasu", "Mul" and "Dmax". The variables used for calculating the
38270    !!----    de dimensions are:
38271    !!--<<
38272    !!----          natcel=nasu*mul       and      id=idp=nint(0.74048*(dmax/r_atom)**3)
38273    !!-->>
38274    !!----    This subroutine should be called before using the subroutines of this module with
38275    !!----    dummy arguments of type Atoms_Cell.
38276    !!----
38277    !!---- Update: February - 2005
38278    !!
38279    Subroutine Allocate_Atoms_Cell(Nasu,Mul,Dmax,Ac)
38280       !---- Arguments ----!
38281       integer,                intent(in)     :: nasu
38282       integer,                intent(in)     :: mul
38283       real(kind=cp),          intent(in)     :: dmax
38284       type (atoms_cell_type), intent(in out) :: Ac
38285
38286       !---- local variables ----!
38287       integer :: natcel,id
38288
38289       natcel=nasu*mul
38290       id=nint(0.74048*(dmax/r_atom)**3)
38291       id=max(id,natcel)
38292
38293       if (.not. allocated(Ac%noms        ))   allocate (Ac%noms          (natcel))
38294       if (.not. allocated(Ac%xyz         ))   allocate (Ac%xyz         (3,natcel))
38295       if (.not. allocated(Ac%charge      ))   allocate (Ac%charge        (natcel))
38296       if (.not. allocated(Ac%moment      ))   allocate (Ac%moment        (natcel))
38297       if (.not. allocated(Ac%var_free    ))   allocate (Ac%var_free   (10,natcel))
38298       if (.not. allocated(Ac%neighb      ))   allocate (Ac%neighb        (natcel))
38299       if (.not. allocated(Ac%neighb_atom ))   allocate (Ac%neighb_atom(id,natcel))
38300       if (.not. allocated(Ac%distance    ))   allocate (Ac%distance   (id,natcel))
38301       if (.not. allocated(Ac%trans       ))   allocate (Ac%trans    (3,id,natcel))
38302       if (.not. allocated(Ac%ddist       ))   allocate (Ac%ddist      (natcel*id))
38303       if (.not. allocated(Ac%ddlab       ))   allocate (Ac%ddlab      (natcel*id))
38304
38305       Ac%nat         = natcel
38306       Ac%noms        = " "
38307       Ac%xyz         = 0.0
38308       Ac%charge      = 0.0
38309       Ac%moment      = 0.0
38310       Ac%var_free    = 0.0
38311       Ac%neighb      = 0
38312       Ac%neighb_atom = 0
38313       Ac%distance    = 0.0
38314       Ac%trans       = 0
38315       Ac%ddist       = 0.0
38316       Ac%ddlab       = " "
38317
38318       return
38319    End Subroutine Allocate_Atoms_Cell
38320
38321    !!----
38322    !!---- Subroutine Allocate_Atom_List(N,A, Fail)
38323    !!----    integer, intent(in)                    :: n    !  In -> Number of elements of A
38324    !!----    type (atom_list_type), intent(in out)  :: A    !  In -> Objet to be allocated
38325    !!----    logical, optional,     intent(out)     :: fail
38326    !!----
38327    !!----    Allocation of objet A of type atom_list. This subroutine
38328    !!----    should be called before using an object of type atom_list.
38329    !!----
38330    !!---- Update: March - 2005
38331    !!
38332    Subroutine Allocate_Atom_List(N,A,Fail)
38333       !---- Arguments ----!
38334       integer,               intent(in)       :: n  !# atoms in asymmetric unit
38335       type (atom_list_type), intent(in out)   :: A  !Objet to be allocated
38336       logical, optional,     intent(out)      :: fail
38337
38338       !---- Local Variables ----!
38339       integer :: i,ier
38340
38341       A%natoms = n
38342       if (present(fail)) fail=.false.
38343       if (allocated(A%Atom)) deallocate(A%Atom)
38344       allocate (A%atom(n),stat=ier)
38345       if (ier /= 0) then
38346          A%natoms = 0
38347          if (present(fail)) fail=.true.
38348          return
38349       end if
38350       do i=1,n
38351          call init_atom_type(A%atom(i))
38352       end do
38353
38354       return
38355    End Subroutine Allocate_atom_list
38356
38357    !!----
38358    !!---- Subroutine Allocate_Matom_List(N,A)
38359    !!----    integer,                              intent(in)     :: n    !  In -> Number of elements of A
38360    !!----    type (mAtom_list_type),               intent(in out) :: A    !  In -> Objet to be allocated
38361    !!----    real(kind=cp), optional,              intent(in)     :: MField
38362    !!----    real(kind=cp), optional,dimension(3), intent(in)     :: dirF
38363    !!----
38364    !!----    Allocation of objet A of type mAtom_list. This subroutine
38365    !!----    should be called before using an object of type mAtom_list.
38366    !!----
38367    !!---- Updated: April - 2005, June -2014
38368    !!
38369    Subroutine Allocate_Matom_List(N,A,MField,dirF)
38370       !---- Arguments ----!
38371       integer,                              intent(in)     :: n  !# atoms in asymmetric magnetic unit
38372       type (mAtom_list_type),               intent(in out) :: A  !Objet to be allocated
38373       real(kind=cp), optional,              intent(in)     :: MField
38374       real(kind=cp), optional,dimension(3), intent(in)     :: dirF
38375
38376       !---- Local Variables ----!
38377       integer :: i
38378
38379       A%natoms = n
38380       A%suscept=.false.
38381       A%MagField=0.0
38382       A%dir_MField=(/0.0,0.0,1.0/)
38383       if (allocated(A%Atom)) deallocate(A%Atom)
38384       allocate (A%Atom(n))
38385       if(present(MField)) then
38386          A%suscept=.true.
38387          A%MagField=MField
38388       end if
38389       if(present(dirF))   A%dir_MField=dirF
38390
38391       do i=1,n
38392          call init_mAtom_type(A%Atom(i))
38393       end do
38394
38395       return
38396    End Subroutine Allocate_mAtom_list
38397
38398    !!----
38399    !!---- Subroutine Atlist1_Extencell_Atlist2(Spg,A,B,Conven)
38400    !!----    type(Space_Group_Type), intent(in)     :: SpG       !  In -> Space Group Information
38401    !!----    type(atom_list_type),  intent(in)      :: A         !  In -> Atom List (asymmetric unit)
38402    !!----    type(atom_list_type),  intent(out)     :: B         ! Out -> Atoms in unit cell
38403    !!----    logical,                intent(in)     :: conven    !  In -> .true. for using the whole conventional unit cell
38404    !!----
38405    !!----    Subroutine to generate atoms in the primitive (conven=.false.) or the conventional
38406    !!----    unit cell (conven=.true.), Excluding atoms with A%atom(:)%active=.false.
38407    !!----
38408    !!---- Update: February - 2005
38409    !!
38410    Subroutine AtList1_ExtenCell_AtList2(Spg,A,C,Conven)
38411       !---- Arguments ----!
38412       type(Space_Group_Type), intent(in)     :: SpG
38413       type(atom_list_type),   intent(in)     :: A
38414       type(atom_list_type),   intent(out)    :: C
38415       logical,                intent(in)     :: Conven
38416
38417       !---- Local Variables ----!
38418       type(atom_list_type)                  :: b
38419       real(kind=cp),dimension(3)            :: xo,xx
38420       real(kind=cp),dimension(3,Spg%multip) :: u
38421       integer                               :: k,j,l,nt,npeq,n
38422       character(len=4)                      :: fmm
38423
38424       npeq=SpG%numops
38425       if (SpG%centred == 2) npeq=npeq*2
38426       if (conven) npeq=SpG%multip
38427
38428       !---- Init proccess ----!
38429       call allocate_atom_list(npeq*A%natoms,b)
38430
38431       n=0
38432       do k=1,A%natoms
38433          if (.not. A%atom(k)%active) cycle
38434          l=1
38435          n=n+1
38436          B%Atom(n)=A%Atom(k)
38437          xo    = modulo_lat(A%atom(k)%x)
38438          u(:,l)= xo
38439          B%Atom(n)%x=xo
38440
38441          do_eq:do j=2,npeq
38442             xx=ApplySO(SpG%SymOp(j),xo)
38443             xx=modulo_lat(xx)
38444             do nt=1,l
38445                if (equal_vector(u(:,nt),xx,3)) then
38446                   B%atom(n-(l-nt))%occ=B%atom(n-(l-nt))%occ+A%atom(k)%occ
38447                   cycle do_eq
38448                end if
38449             end do
38450             l=l+1
38451             u(:,l)=xx(:)
38452             n=n+1
38453             select case (l)
38454                case(:9)
38455                   write(unit=fmm,fmt="(i1)") l
38456                case(10:99)
38457                   write(unit=fmm,fmt="(i2)") l
38458                case(100:999)
38459                   write(unit=fmm,fmt="(i3)") l
38460             end select
38461             B%Atom(n)=A%Atom(k)
38462
38463             B%Atom(n)%lab      =trim(A%Atom(k)%lab)//"_"//adjustl(fmm)
38464             B%Atom(n)%x        =xx
38465             B%Atom(n)%active   =.true.
38466             B%Atom(n)%Mult     =1.0
38467
38468          end do do_eq
38469       end do
38470
38471       B%natoms=n
38472
38473       call allocate_atom_list(n,C)
38474
38475       C%natoms=n
38476       C%atom(1:n)=B%atom(1:n)
38477
38478       call deallocate_atom_list(B)
38479
38480       return
38481    End Subroutine AtList1_ExtenCell_AtList2
38482
38483    !!----
38484    !!---- Subroutine Atoms_Cell_To_List(Ac,A)
38485    !!----    Type(atoms_cell_type),  Intent(In)        :: Ac   !  In -> instance of atoms_cell_type
38486    !!----    type(atom_list_type),   intent(in out)    :: A    !  In -> instance of atom_list_type
38487    !!----                                                         Out-> Initialize atom_list_type components
38488    !!----
38489    !!----    Subroutine to construct an Atom List object "A" from an Atoms_Cell
38490    !!----    object "Ac". It is supposed that both objects have been previouly
38491    !!----    allocated using the appropriate procedures: direct allocation
38492    !!----    for A and call to Allocate_Atoms_Cell for Ac.
38493    !!----
38494    !!---- Update: February - 2005
38495    !!
38496    Subroutine Atoms_Cell_To_List(Ac,A)
38497       !---- Arguments ----!
38498       type(atoms_cell_type), intent(in)       :: Ac
38499       type(atom_list_type),  intent(in out)   :: A
38500
38501       !---- Local Variables ----!
38502       integer :: i
38503
38504       A%natoms=Ac%nat
38505       do i=1,Ac%nat
38506          A%atom(i)%Lab      = Ac%noms(i)
38507          A%atom(i)%ChemSymb = Ac%noms(i)(1:2)
38508          A%atom(i)%x(:)     = Ac%xyz(:,i)
38509          A%atom(i)%occ      = 1.0
38510          A%atom(i)%Biso     = 0.0
38511          A%atom(i)%mult     = 1.0
38512          A%atom(i)%Z        = 0
38513          A%atom(i)%varf     = Ac%var_free(:,i)
38514          A%atom(i)%charge   = Ac%charge(i)
38515          A%atom(i)%moment   = Ac%moment(i)
38516       end do
38517
38518       return
38519    End Subroutine Atoms_Cell_To_List
38520
38521    !!----
38522    !!---- Subroutine atom_list_To_Cell(A,Ac)
38523    !!----    type(atom_list_type),  intent(in)         :: A    !  In -> instance of atom_list_type
38524    !!----    type(atoms_cell_type),  intent(in out)    :: Ac   !  In -> instance of atoms_cell_type
38525    !!----                                                         Out-> Initialize atoms_cell_type components
38526    !!----
38527    !!----    Subroutine to construct an Atom Cell object "Ac" from an atom_list
38528    !!----    object "A". It is supposed that both objects have been previouly
38529    !!----    allocated using the appropriate procedures.
38530    !!----
38531    !!---- Update: February - 2005
38532    !!
38533    Subroutine Atom_List_To_Cell(A,Ac)
38534       !---- Arguments ----!
38535       type(atom_list_type),  intent(in)        :: A
38536       type(atoms_cell_type), intent(in out)    :: Ac
38537
38538       !---- Local Variables ----!
38539       integer :: i
38540
38541       Ac%nat=A%natoms
38542       do i=1,Ac%nat
38543          Ac%noms(i)        = A%atom(i)%lab
38544          Ac%xyz (:,i)      = A%Atom(i)%x
38545          Ac%var_free(:,i)  = A%Atom(i)%varf
38546       end do
38547
38548       return
38549    End Subroutine atom_list_To_Cell
38550
38551    !!----
38552    !!---- Subroutine Atom_Uequi_List(Cell, Ac)
38553    !!----    type(Crystal_Cell_Type), intent(in)    :: Cell    !  In -> Cell variable
38554    !!----    type(atom_list_type),   intent(in out) :: Ac      !  In -> Atom list
38555    !!----                                                         Out ->
38556    !!----
38557    !!----    Subroutine to obtain the U equiv from U11 U22 U33 U12 U13 U23
38558    !!----
38559    !!---- Update: February - 2005
38560    !!
38561    Subroutine Atom_Uequi_List(Cell, Ac)
38562       !---- Arguments ----!
38563       type (Crystal_cell_type), intent(in)       :: Cell
38564       type (atom_list_type),    intent(in out)   :: Ac
38565
38566       !---- Local variables ----!
38567       integer                    :: i
38568       real(kind=cp),dimension(6) :: u
38569
38570       do i=1,Ac%natoms
38571          u=Ac%atom(i)%u(1:6)
38572          Ac%atom(i)%Ueq = U_Equiv(Cell,u)
38573       end do
38574
38575       return
38576    End Subroutine Atom_Uequi_List
38577
38578    !!----
38579    !!---- Subroutine Copy_Atom_List(A, Ac)
38580    !!----    type(atom_list_type),   intent(in)  :: A      !  In -> Atom list
38581    !!----    type(atom_list_type),   intent(out) :: Ac     !   Out -> Atom list
38582    !!----
38583    !!----
38584    !!----    Subroutine to copy an atom list to another one
38585    !!----
38586    !!---- Update: May - 2009
38587    !!
38588    Subroutine Copy_Atom_List(A, Ac)
38589       !---- Arguments ----!
38590       type (atom_list_type),    intent(in)   :: A
38591       type (atom_list_type),    intent(out)  :: Ac
38592
38593       !---- Local variables ----!
38594       integer                    :: n
38595
38596       n=A%natoms
38597       call Allocate_Atom_List(n,Ac)
38598       Ac%atom(1:n)=A%atom(1:n)
38599       return
38600    End Subroutine Copy_Atom_List
38601
38602    !!----
38603    !!---- Subroutine Deallocate_Atoms_Cell(Ac)
38604    !!----    type (atoms_cell_type), intent(in out)   :: Ac   !  In -> Object of atoms_cell_type
38605    !!----                                                     ! Out -> The object is removed from memory.
38606    !!----
38607    !!----    Deallocation of objet Ac of type Atoms_Cell.  Ac contains
38608    !!----    components with ALLOCATABLE attribute. This subroutine should
38609    !!----    be called after using this module.
38610    !!----
38611    !!---- Update: February - 2003
38612    !!
38613    Subroutine Deallocate_Atoms_Cell(Ac)
38614       !---- Arguments ----!
38615       type (atoms_cell_type), intent(in out)   :: Ac
38616
38617       if (allocated(Ac%noms)       )   deallocate (Ac%noms)
38618       if (allocated(Ac%xyz)        )   deallocate (Ac%xyz)
38619       if (allocated(Ac%var_free)   )   deallocate (Ac%var_free)
38620       if (allocated(Ac%neighb)     )   deallocate (Ac%neighb)
38621       if (allocated(Ac%neighb_atom))   deallocate (Ac%neighb_atom)
38622       if (allocated(Ac%distance)   )   deallocate (Ac%distance)
38623       if (allocated(Ac%trans)      )   deallocate (Ac%trans)
38624       if (allocated(Ac%ddist)      )   deallocate (Ac%ddist)
38625       if (allocated(Ac%ddlab)      )   deallocate (Ac%ddlab)
38626
38627       return
38628    End Subroutine Deallocate_Atoms_Cell
38629
38630    !!----
38631    !!---- Subroutine Deallocate_atom_list(A)
38632    !!----    type (atom_list_type), intent(in out)   :: A  ! In/ Out -> Objet to be deallocated
38633    !!----
38634    !!----    De-allocation of objet A of type atom_list. This subroutine
38635    !!----    should be after using an object of type atom_list that is no
38636    !!----    more needed.
38637    !!----
38638    !!---- Update: February - 2003
38639    !!
38640    Subroutine Deallocate_atom_list(A)
38641       !---- Arguments ----!
38642       type (atom_list_type), intent(in out)   :: A  !Objet to be deallocated
38643
38644       if (allocated(A%atom)) deallocate (A%atom)
38645
38646       return
38647    End Subroutine Deallocate_atom_list
38648
38649    !!----
38650    !!---- Subroutine Deallocate_mAtom_list(A)
38651    !!----    type (mAtom_list_type), intent(in out)   :: A  ! In/ Out -> Objet to be deallocated
38652    !!----
38653    !!----    De-allocation of objet A of type atom_list. This subroutine
38654    !!----    should be invoked after using an object of type mAtom_list
38655    !!----    that is no more needed.
38656    !!----
38657    !!---- Update: April - 2005
38658    !!
38659    Subroutine Deallocate_mAtom_list(A)
38660       !---- Arguments ----!
38661       type (mAtom_list_type), intent(in out)   :: A  !Objet to be deallocated
38662
38663       if (allocated(A%Atom)) deallocate (A%Atom)
38664
38665       return
38666    End Subroutine Deallocate_mAtom_list
38667
38668    !!----
38669    !!----  Subroutine Get_Atom_2nd_Tensor_Ctr(x,TensVal,Spgr,Codini,Icodes,Multip,Ord,Ss,Ipr)
38670    !!----     real(kind=cp), dimension(3),             intent(in    ) :: x         !Atom position (fractional coordinates)
38671    !!----     real(kind=cp), dimension(6),             intent(in out) :: TensVal   !Second order symmetric tensor
38672    !!----     type(Space_Group_type),                  intent(ix    ) :: Spgr      !Space Group
38673    !!----     Integer,                                 intent(in out) :: Codini    !Last attributed parameter
38674    !!----     Integer, dimension(6),                   intent(in out) :: Icodes    !codewords for TensVal only number
38675    !!----     real(kind=cp), dimension(6),             intent(in out) :: Multip    !Multipliers
38676    !!----     integer,                       optional, intent(in    ) :: Ord       !Order of the stabilizer
38677    !!----     integer, dimension(:),         optional, intent(in    ) :: Ss        !Pointer to SymmOp. of stabilizer
38678    !!----     integer,                       optional, intent(in    ) :: Ipr       !Printing unit for debug
38679    !!----
38680    !!----  Subroutine to get the appropriate constraints in the refinement codes of
38681    !!----  second order symmetric tensor atomic property parameters.
38682    !!----  New algorithm based in the Wigner theorem.
38683    !!----  The matrix Bet = Sum { R Beta RT} displays the symmetry constraints to be
38684    !!----  applied to the 2nd order symmetric tensor components. The sum runs over all rotational
38685    !!----  symmetry operators of the stabilizer of the particular atom position in the given
38686    !!----  space group.
38687    !!----  There are a total of 29 kind of relations that may appear in the Bet matrix:
38688    !!----
38689    !!----     1    A A A 0   0   0  -> m-3m, -43m, 432, m-3,23, 3[111].2[001]
38690    !!----     2    A A C 0   0   0  -> 4/mmm, -42m, 4mm, 422, 4/m, -4,4, 4[001]
38691    !!----     3    A B A 0   0   0  -> 4[010]
38692    !!----     4    A B B 0   0   0  -> 4[100]
38693    !!----     5    A A A D   D   D  -> -3m, 3m, 32, -3, 3   3[111]
38694    !!----     6    A A A D  -D  -D  -> 3[11-1]
38695    !!----     7    A A A D  -D   D  -> 3[1-11]
38696    !!----     8    A A A D   D  -D  -> 3[-111]
38697    !!----     9    A A C A/2 0   0  -> 6/mmm, -6m2, 6mm, 622, 6/m, 6,-6,-3m, 32,-3, 3:  h 3[001]
38698    !!----    10    A B C 0   0   0  -> mmm, mm2, 222  2[001] 2[100]
38699    !!----    11    A A C D   0   0  -> 2[001], 2[110]    w
38700    !!----    12    A B A 0   E   0  -> 2[010], 2[101]
38701    !!----    13    A B B 0   0   F  -> 2[100], 2[011]
38702    !!----    14    A B C B/2 0   0  -> 2[001], 2[100]    h
38703    !!----    15    A B C A/2 0   0  -> 2[001], 2[010]    h
38704    !!----    16    A B C D   0   0  -> 2/m, m, 2: 2[001] w
38705    !!----    17    A B C 0   E   0  -> 2[010]
38706    !!----    18    A B C 0   0   F  -> 2[100]
38707    !!----    19    A A C D   E  -E  -> 2[110]            w
38708    !!----    20    A A C D   E   E  -> 2[1-10]           w
38709    !!----    21    A B A D   E  -D  -> 2[101]
38710    !!----    22    A B A D   E   D  -> 2[10-1]
38711    !!----    23    A B B D  -D   F  -> 2[011]
38712    !!----    24    A B B D   D   F  -> 2[01-1]
38713    !!----    25    A B C B/2 F/2 F  -> 2[100]            h
38714    !!----    26    A B C A/2 0   F  -> 2[210]            h
38715    !!----    27    A B C B/2 E   0  -> 2[120]            h
38716    !!----    28    A B C A/2 E   E/2-> 2[010]            h
38717    !!----    29    A B C D   E   F  -> 1, -1
38718    !!----
38719    !!----   Updated: 27 June 2014 (JRC)
38720    !!----
38721    Subroutine Get_Atom_2nd_Tensor_Ctr(x,TensVal,Spgr,Codini,Icodes,Multip,Ord,Ss,Ipr)
38722       real(kind=cp), dimension(3),             intent(in    ) :: x
38723       real(kind=cp), dimension(6),             intent(in out) :: TensVal
38724       type(Space_Group_type),                  intent(in    ) :: Spgr
38725       Integer,                                 intent(in out) :: Codini
38726       Integer, dimension(6),                   intent(in out) :: Icodes
38727       real(kind=cp), dimension(6),             intent(in out) :: Multip
38728       integer,                       optional, intent(in    ) :: Ord
38729       integer, dimension(:),         optional, intent(in    ) :: Ss
38730       integer,                       optional, intent(in    ) :: Ipr
38731
38732       ! Local variables
38733       character (len=1), dimension(6)   :: cdd
38734       integer                           :: i,j,order
38735       integer,           dimension(48)  :: ss_ptr
38736       integer,           dimension(6)   :: codd
38737       integer,           dimension(3,3) :: Rsym
38738       real(kind=cp),     dimension(3,3) :: bet,bett,Rs
38739       real(kind=cp),     dimension(6)   :: cod
38740       real(kind=cp),     dimension(3,48):: atr
38741       real(kind=cp),     parameter      :: epss=0.01_cp
38742
38743       cod=real(icodes)
38744
38745       do j=1,6
38746          if (cod(j) < 1.0 .and. abs(multip(j)) > epss)  then
38747             codini=codini+1
38748             cod(j) = real(codini)
38749          end if
38750       end do
38751
38752       if (present(ord) .and. present(ss)) then
38753          order=ord
38754          ss_ptr(1:order) = ss(1:ord)
38755       else
38756          call get_stabilizer(x,Spgr,order,ss_ptr,atr)
38757       end if
38758
38759       bet=reshape((/17.0, 7.0,3.0,  &
38760                     7.0,13.0,5.0,  &
38761                     3.0, 5.0,11.0/),(/3,3/))
38762       bett=bet
38763       if (order > 1 ) then
38764          do j=2,order
38765             Rsym=Spgr%SymOp(ss_ptr(j))%Rot
38766             Rs=real(Rsym)
38767             bett=bett+ matmul(Rs,matmul(bet,transpose(Rs)))
38768          end do
38769       end if
38770       Rsym=nint(1000.0*bett)
38771       codd=(/Rsym(1,1),Rsym(2,2),Rsym(3,3),Rsym(1,2),Rsym(1,3),Rsym(2,3)/)
38772       cdd=(/'a','b','c','d','e','f'/)
38773       multip=1.0
38774       !Search systematically all the possible constraints
38775
38776       if(codd(1) == codd(2) .and. codd(1) == codd(3)) then ! a a a
38777         if(codd(4) == codd(5) .and. codd(4) == codd(6) ) then ! a a a d d d
38778           if(codd(4) == 0) then
38779             cdd=(/'a','a','a','0','0','0'/)     ! 1 A A A 0   0   0
38780             multip=(/1.0,1.0,1.0,0.0,0.0,0.0/)
38781             TensVal(4:6)=0.0
38782             TensVal(2:3)=TensVal(1)
38783             cod(2:3)=cod(1); cod(4:6)=0.0
38784           else
38785             cdd=(/'a','a','a','d','d','d'/)     ! 5 A A A D   D   D
38786             multip=(/1.0,1.0,1.0,1.0,1.0,1.0/)
38787             TensVal(5:6)=TensVal(4)
38788             TensVal(2:3)=TensVal(1)
38789             cod(2:3)=cod(1); cod(5:6)=cod(4)
38790           end if
38791         else if(codd(4) == -codd(5) .and. codd(4) == -codd(6) ) then !a a a d -d -d
38792           cdd=(/'a','a','a','d','d','d'/)       ! 6 A A A D  -D  -D
38793           multip=(/1.0,1.0,1.0,1.0,-1.0,-1.0/)
38794           TensVal(5:6)=-TensVal(4)
38795           TensVal(2:3)=TensVal(1)
38796           cod(2:3)=cod(1); cod(5:6)=cod(4)
38797         else if(codd(4) == -codd(5) .and. codd(4) ==  codd(6) ) then !a a a d -d  d
38798           cdd=(/'a','a','a','d','d','d'/)       ! 7 A A A D  -D   D
38799           multip=(/1.0,1.0,1.0,1.0,-1.0, 1.0/)
38800           TensVal(5)=-TensVal(4); TensVal(6)=TensVal(4)
38801           TensVal(2:3)=TensVal(1)
38802           cod(2:3)=cod(1); cod(5:6)= cod(4)
38803         else if(codd(4) ==  codd(5) .and. codd(4) == -codd(6) ) then !a a a d  d -d
38804           cdd=(/'a','a','a','d','d','d'/)       ! 8 A A A D   D  -D
38805           multip=(/1.0,1.0,1.0,1.0, 1.0,-1.0/)
38806           TensVal(6)=-TensVal(4); TensVal(5)=TensVal(4)
38807           TensVal(2:3)=TensVal(1)
38808           cod(2:3)=cod(1); cod(5:6)= cod(4)
38809         end if
38810
38811       else if(codd(1) == codd(2)) then ! a a c
38812         if(codd(4) == codd(5) .and. codd(4) == codd(6) .and. codd(4) == 0) then ! a a c 0 0 0
38813             cdd=(/'a','a','c','0','0','0'/)     ! 2 A A C 0   0   0
38814             multip=(/1.0,1.0,1.0,0.0,0.0,0.0/)
38815             TensVal(4:6)=0.0
38816             TensVal(2)=TensVal(1)
38817             cod(2)=cod(1); cod(4:6)= 0.0
38818         else if(codd(5) == codd(6) .and. codd(5) == 0) then ! a a c x 0 0
38819             if(codd(4) == codd(1)/2) then
38820               cdd=(/'a','a','c','a','0','0'/)     ! 9 A A C A/2 0   0
38821               multip=(/1.0,1.0,1.0,0.5,0.0,0.0/)
38822               TensVal(5:6)=0.0; TensVal(4)=TensVal(1)*0.5
38823               TensVal(2)=TensVal(1)
38824               cod(2)=cod(1); cod(4)= cod(1); cod(5:6)=0.0
38825             else
38826               cdd=(/'a','a','c','d','0','0'/)     !11 A A C D   0   0
38827               multip=(/1.0,1.0,1.0,1.0,0.0,0.0/)
38828               TensVal(5:6)=0.0
38829               TensVal(2)=TensVal(1)
38830               cod(2)=cod(1); cod(5:6)=0.0
38831             end if
38832         else
38833             if(codd(5) == codd(6)) then  ! a a c d e e
38834               cdd=(/'a','a','c','d','e','e'/)     !20 A A C D   E   E
38835               multip=(/1.0,1.0,1.0,1.0,1.0,1.0/)
38836               TensVal(6)=TensVal(5)
38837               TensVal(2)=TensVal(1)
38838               cod(2)=cod(1); cod(6)=cod(5)
38839             else if(codd(5) == -codd(6)) then  ! a a c d e -e
38840               cdd=(/'a','a','c','d','e','e'/)     !19 A A C D   E  -E
38841               multip=(/1.0,1.0,1.0,1.0,1.0,-1.0/)
38842               TensVal(6)=-TensVal(5)
38843               TensVal(2)=TensVal(1)
38844               cod(2)=cod(1); cod(6)=cod(5)
38845             end if
38846         end if
38847
38848       else if(codd(1) == codd(3)) then ! a b a
38849         if(codd(4) == codd(6)) then    ! a b a d x d
38850           if(codd(4) == 0) then  ! a b a 0 x 0
38851             if(codd(5) == 0) then ! a b a 0 0 0
38852               cdd=(/'a','b','a','0','0','0'/)     ! 3 A B A 0   0   0
38853               multip=(/1.0,1.0,1.0,0.0,0.0,0.0/)
38854               TensVal(4:6)=0.0
38855               TensVal(3)=TensVal(1)
38856               cod(3)=cod(1); cod(4:6)=0.0
38857             else                  ! a b a 0 e 0
38858               cdd=(/'a','b','a','0','e','0'/)     !12 A B A 0   E   0
38859               multip=(/1.0,1.0,1.0,0.0,1.0,0.0/)
38860               TensVal(4)=0.0;  TensVal(6)=0.0
38861               TensVal(3)=TensVal(1)
38862               cod(3)=cod(1); cod(4)=0.0;  cod(6)=0.0
38863             end if
38864           else  !! a b a d e d
38865             cdd=(/'a','b','a','d','e','d'/)       !22 A B A D   E   D
38866             multip=(/1.0,1.0,1.0,1.0,1.0,1.0/)
38867             TensVal(6)=TensVal(4)
38868             TensVal(3)=TensVal(1)
38869             cod(3)=cod(1); cod(6)=cod(4)
38870          end if
38871
38872         else if(codd(4) == -codd(6)) then ! a b a d e -d
38873           cdd=(/'a','b','a','d','e','d'/)         !21 A B A D   E  -D
38874           multip=(/1.0,1.0,1.0,1.0,1.0,-1.0/)
38875           TensVal(6)=-TensVal(4)
38876           TensVal(3)=TensVal(1)
38877           cod(3)=cod(1); cod(6)=cod(4)
38878         end if
38879
38880       else if(codd(2) == codd(3)) then ! a b b
38881         if(codd(4) == codd(5)) then    ! a b b d d x
38882           if(codd(4) == 0) then  ! a b b 0 0 x
38883             if(codd(6) == 0) then ! a b b 0 0 0
38884               cdd=(/'a','b','b','0','0','0'/)     ! 4 A B B 0   0   0
38885               multip=(/1.0,1.0,1.0,0.0,0.0,0.0/)
38886               TensVal(4:6)=0.0
38887               TensVal(3)=TensVal(2)
38888               cod(3)=cod(2); cod(4:6)=0.0
38889             else                  ! a b b 0 0 f
38890               cdd=(/'a','b','b','0','0','f'/)     !13 A B B 0   0   F
38891               multip=(/1.0,1.0,1.0,0.0,0.0,1.0/)
38892               TensVal(4:5)=0.0
38893               TensVal(3)=TensVal(2)
38894               cod(3)=cod(2); cod(4:5)=0.0
38895             end if
38896           else  !! a b b d d f
38897             cdd=(/'a','b','b','d','d','f'/)       !24 A B B D   D   F
38898             multip=(/1.0,1.0,1.0,1.0,1.0,1.0/)
38899             TensVal(5)=TensVal(4)
38900             TensVal(3)=TensVal(2)
38901             cod(3)=cod(2); cod(5)=cod(4)
38902           end if
38903         else if(codd(4) == -codd(5)) then ! a b b d -d e
38904           cdd=(/'a','b','b','d','d','f'/)         !23 A B B D  -D   F
38905           multip=(/1.0,1.0,1.0,1.0,-1.0,1.0/)
38906           TensVal(5)=-TensVal(4)
38907           TensVal(3)=TensVal(2)
38908           cod(3)=cod(2); cod(5)=cod(4)
38909         end if
38910
38911       else !Now a /= b /= c
38912
38913         if(codd(4) == codd(5) .and. codd(4) == 0) then ! a b c 0 0 x
38914           if(codd(6) == 0) then ! a b c 0 0 0
38915             cdd=(/'a','b','c','0','0','0'/)          !10 A B C 0   0   0
38916             multip=(/1.0,1.0,1.0,0.0,0.0,0.0/)
38917             TensVal(4:6)=0.0
38918             cod(4:6)=0.0
38919           else
38920             cdd=(/'a','b','c','0','0','f'/)          !18 A B C 0   0   F
38921             multip=(/1.0,1.0,1.0,0.0,0.0,1.0/)
38922             TensVal(4:5)=0.0
38923             cod(4:5)=0.0
38924           end  if
38925         else if(codd(5) == codd(6) .and. codd(5) == 0) then  ! a b c x 0 0
38926           if(codd(4) == codd(1)/2) then ! a b c a/2 0 0
38927             cdd=(/'a','b','c','a','0','0'/)          !15 A B C A/2 0   0
38928             multip=(/1.0,1.0,1.0,0.5,0.0,0.0/)
38929             TensVal(5:6)=0.0; TensVal(4)=TensVal(1)*0.5
38930             cod(4)=cod(1); cod(5:6)=0.0
38931           else if(codd(4) == codd(2)/2) then    !a b c b/2 0 0
38932             cdd=(/'a','b','c','b','0','0'/)          !14 A B C B/2 0   0
38933             multip=(/1.0,1.0,1.0,0.5,0.0,0.0/)
38934             TensVal(5:6)=0.0; TensVal(4)=TensVal(2)*0.5
38935             cod(4)=cod(2); cod(5:6)=0.0
38936           else
38937             cdd=(/'a','b','c','d','0','0'/)          !16 A B C D   0   0
38938             multip=(/1.0,1.0,1.0,1.0,0.0,0.0/)
38939             TensVal(5:6)=0.0
38940             cod(5:6)=0.0
38941           end  if
38942         else if(codd(4) == codd(6) .and. codd(4) == 0) then !a b c 0 e 0
38943           cdd=(/'a','b','c','0','e','0'/)            !17 A B C 0   E   0
38944           multip=(/1.0,1.0,1.0,0.0,1.0,0.0/)
38945           TensVal(4)=0.0; TensVal(6)=0.0
38946           cod(4)=0.0; cod(6)=0.0
38947         else if(codd(4) == codd(1)/2 .and. codd(5) == 0) then !a b c a/2 0 f
38948           cdd=(/'a','b','c','a','0','f'/)            !26 A B C A/2 0   F
38949           multip=(/1.0,1.0,1.0,0.5,0.0,1.0/)
38950           TensVal(4)=TensVal(1)*0.5; TensVal(5)=0.0
38951           cod(4)=cod(1); cod(5)=0.0
38952         else if(codd(4) == codd(2)/2 .and. codd(6) == 0) then !a b c b/2 e 0
38953           cdd=(/'a','b','c','b','e','0'/)            !27 A B C B/2 E   0
38954           multip=(/1.0,1.0,1.0,0.5,1.0,0.0/)
38955           TensVal(4)=TensVal(2)*0.5; TensVal(6)=0.0
38956           cod(4)=cod(2); cod(6)=0.0
38957         else if(codd(4) == codd(2)/2 .and. codd(5) == codd(6)/2) then !a b c b/2 f/2 f
38958           cdd=(/'a','b','c','b','f','f'/)            !25 A B C B/2 F/2 F
38959           multip=(/1.0,1.0,1.0,0.5,0.5,1.0/)
38960           TensVal(4)=TensVal(2)*0.5; TensVal(5)=TensVal(6)*0.5
38961           cod(4)=cod(2); cod(5)=cod(6)
38962         else if(codd(4) == codd(1)/2 .and. codd(6) == codd(5)/2) then !a b c a/2 e e/2
38963           cdd=(/'a','b','c','a','e','e'/)            !28 A B C A/2 E   E/2
38964           multip=(/1.0,1.0,1.0,0.5,1.0,0.5/)
38965           TensVal(4)=TensVal(1)*0.5; TensVal(6)=TensVal(5)*0.5
38966           cod(4)=cod(1); cod(6)=cod(5)
38967         else
38968           cdd=(/'a','b','c','d','e','f'/)            !29 A B C D   E   F
38969           multip=(/1.0,1.0,1.0,1.0,1.0,1.0/)
38970         end if
38971       end if
38972
38973       do j=1,6
38974          if (multip(j) < epss .or. cdd(j) == "0" ) then
38975             icodes(j) = 0
38976          else
38977             icodes(j) = nint(cod(j))
38978          end if
38979       end do
38980
38981       if(present(Ipr)) then
38982         Write(Ipr,'(a,6i5)')           '     Codes on TensVal       :  ',Icodes
38983         Write(Ipr,'(a,6(a,1x),6f7.3)') '     Codes and multipliers:  ',cdd,multip
38984         Write(Ipr,'(a)')               '     Tensor_TOT matrix:  '
38985         Do I=1,3
38986          Write(Ipr,'(a,3f12.4)')       '                      ',bett(i,:)
38987         End Do
38988       end if
38989       return
38990    End Subroutine Get_Atom_2nd_Tensor_Ctr
38991
38992    !!----
38993    !!---- Subroutine Init_Atom_Type(A)
38994    !!----    type (Atom_Type),  intent(in out) :: A   ! In / Out -> Atom type
38995    !!----
38996    !!----    Initialize Atom_Type
38997    !!----
38998    !!---- Update: March - 2005
38999    !!
39000    Subroutine Init_Atom_Type(A)
39001       !---- Arguments ----!
39002       type (Atom_Type), intent(in out)   :: A
39003
39004       A%Lab      =" "
39005       A%ChemSymb =" "
39006       A%SfacSymb =" "
39007       A%Wyck     ="."
39008       A%Active   =.true.
39009       A%Z        =0
39010       A%Mult     =0
39011       A%X        =0.0
39012       A%X_Std    =0.0
39013       A%MX       =0.0
39014       A%LX       =0
39015       A%Occ      =0.0
39016       A%Occ_Std  =0.0
39017       A%MOcc     =0.0
39018       A%LOcc     =0
39019       A%Biso     =0.0
39020       A%Biso_std =0.0
39021       A%MBiso    =0.0
39022       A%LBiso    =0
39023       A%Utype    ="none"
39024       A%ThType   ="isotr"
39025       A%U        =0.0
39026       A%U_std    =0.0
39027       A%Ueq      =0.0
39028       A%MU       =0.0
39029       A%LU       =0
39030       A%Charge   =0.0
39031       A%Moment   =0.0
39032       A%Ind      =0
39033       A%NVar     =0
39034       A%VarF     =0.0
39035       A%LVarF    =0
39036       A%mVarF    =0.0
39037       A%AtmInfo  ="None"
39038       return
39039    End Subroutine Init_Atom_Type
39040
39041    !!----
39042    !!---- Subroutine Init_mAtom_Type(A)
39043    !!----    type (mAtom_Type),  intent(in out) :: A   ! In / Out -> mAtom type
39044    !!----
39045    !!----    Initialize mAtom_Type
39046    !!----
39047    !!---- Updated: November 3 - 2013
39048    !!
39049    Subroutine Init_mAtom_Type(A)
39050       !---- Arguments ----!
39051       type (mAtom_Type), intent(in out)   :: A
39052
39053       A%Lab      =" "
39054       A%ChemSymb =" "
39055       A%SfacSymb =" "
39056       A%Wyck     ="."
39057       A%Active   =.true.
39058       A%Z =0; A%Mult=1
39059       A%X=0.0; A%X_Std=0.0; A%MX=0.0; A%LX=0
39060       A%Occ=0.0; A%Occ_Std=0.0; A%MOcc=0.0; A%LOcc=0
39061       A%Biso=0.0; A%Biso_std=0.0; A%MBiso=0.0; A%LBiso=0
39062       A%Utype    ="none"
39063       A%ThType   ="isotr"
39064       A%U=0.0; A%U_std=0.0; A%Ueq=0.0; A%MU=0.0; A%LU=0
39065       A%Charge=0.0; A%Moment=0.0
39066       A%Ind=0
39067       A%NVar=0; A%VarF=0.0
39068       A%AtmInfo  =" "
39069       !Magnetic parameters
39070       A%nvk =0
39071       A%imat=0
39072       A%SkR=0.0; A%SkR_std=0.0; A%Spher_SkR=0.0; A%Spher_SkR_std=0.0; A%mSkR=0.0; A%lSkR=0
39073       A%SkI=0.0; A%SkI_std=0.0; A%Spher_SkI=0.0; A%Spher_SkI_std=0.0; A%mSkI=0.0; A%lSkI=0
39074       A%mphas=0.0; A%mphas_std=0.0; A%mmphas=0.0; A%lmphas=0
39075       A%cbas=0.0; A%cbas_std=0.0; A%mbas=0.0; A%lbas=0
39076       A%chitype="none"
39077       A%chi=0.0; A%chi_std=0.0; A%mchi=0.0; A%lchi=0; A%Chieq=0.0
39078
39079       return
39080    End Subroutine Init_mAtom_Type
39081
39082    !!----
39083    !!---- Subroutine Init_Err_Atmd()
39084    !!----
39085    !!----    Initialize the errors flags in this Module
39086    !!----
39087    !!---- Update: February - 2003
39088    !!
39089    Subroutine Init_Err_Atmd()
39090
39091       ERR_Atmd=.false.
39092       ERR_Atmd_Mess=" "
39093
39094       return
39095    End Subroutine Init_Err_Atmd
39096
39097    !!----
39098    !!---- Subroutine Merge_Atoms_Peaks(Cell,Atm,Npks,Pks,Grp,NAtm)
39099    !!----    type(Crystal_Cell_Type),        intent(in) :: Cell  ! Cell object
39100    !!----    type(atom_list_type),           intent(in) :: Atm   ! Atoms List
39101    !!----    integer,                        intent(in) :: Npks  ! Number of Peaks on Pks
39102    !!----    real(kind=cp), dimension(:,:),  intent(in) :: Pks   ! Lis of Peaks
39103    !!----    type(Space_Group_Type),         intent(in) :: Grp   ! Space Group Information
39104    !!----    type(atom_list_type),           intent(out):: NAtm  ! New Atoms+Peaks List
39105    !!----
39106    !!----    This routine merge atoms and peaks on a new List.
39107    !!--<<        Atom        Peak    -->        Label      Symb
39108    !!----    ------------------------------------------------------
39109    !!----         *            *                Atom       "Pk"
39110    !!----         *            -                 Atom information
39111    !!----         -            *                "Pks"        "**"
39112    !!-->>
39113    !!---- Update: February - 2005
39114    !!
39115    Subroutine Merge_Atoms_Peaks(Cell,Atm,Npks,Pks,Grp,NAtm)
39116       !---- Arguments ----!
39117       type(Crystal_Cell_Type),       intent(in) :: Cell
39118       type(atom_list_type),          intent(in) :: Atm
39119       integer,                       intent(in) :: Npks
39120       real(kind=cp), dimension(:,:), intent(in) :: Pks
39121       type(Space_Group_Type),        intent(in) :: Grp
39122       type(atom_list_type),          intent(out):: NAtm
39123
39124       !---- Local variables ----!
39125       character(len=4)                   :: car
39126       integer                            :: i,j,k,nc,ntot,ier
39127       integer, dimension(:), allocatable :: np
39128       real(kind=cp)                      :: dis
39129       real(kind=cp), dimension(3)        :: pto1,pto2,xr
39130
39131       !---- Calculating the new dimension for NAtm ----!
39132       if (allocated(np)) deallocate(np)
39133       if (atm%natoms > 0) then
39134          allocate(np(atm%natoms))
39135          np=0
39136       end if
39137
39138       nc=0
39139       do i=1,atm%natoms
39140          pto1=mod(atm%atom(i)%x+10.0_cp,1.0_cp)
39141          do j=1,npks
39142             do k=1,grp%multip
39143                pto2=ApplySO(grp%Symop(k),pks(1:3,j))
39144                pto2=mod(pto2+10.0_cp,1.0_cp)
39145                xr = matmul(cell%Cr_Orth_cel,pto2-pto1)
39146                dis=sqrt(dot_product(xr,xr))
39147                if (dis <= 0.25_cp) then
39148                   nc=nc+1
39149                   np(i)=j
39150                   exit
39151                end if
39152             end do
39153          end do
39154       end do
39155
39156       ntot=0
39157       if (atm%natoms > 0) then   !New way to calculate ntot
39158         ntot=atm%natoms          !in order to avoid that nc>ntot below
39159         do i=1,npks
39160            k=0
39161            do j=1,atm%natoms
39162               if (np(j)==i) k=j
39163            end do
39164            if (k /= 0) cycle
39165            ntot=ntot+1
39166         end do
39167       else
39168         ntot=npks
39169       end if
39170
39171       call Deallocate_atom_list(NAtm)
39172       call Allocate_atom_list(ntot,NAtm)
39173
39174       nc=0
39175       if (atm%natoms > 0) then
39176         !---- Atoms & Peak Information ----!
39177          do i=1,atm%natoms
39178             if (np(i) == 0) cycle
39179             nc=nc+1
39180             Natm%atom(nc)=atm%atom(i)
39181             write(unit=Natm%atom(nc)%ChemSymb,fmt="(i2)",iostat=ier) np(i)
39182             if(ier /= 0) cycle
39183          end do
39184
39185          !---- Only Atoms Information ----!
39186          do i=1,atm%natoms
39187             if (np(i) /= 0) cycle
39188             nc=nc+1
39189             Natm%atom(nc)=atm%atom(i)
39190          end do
39191
39192          !---- Only Peaks Information ----!
39193          do i=1,npks
39194             k=0
39195             do j=1,atm%natoms
39196                if (np(j)==i) k=j
39197             end do
39198             if (k /= 0) cycle
39199             nc=nc+1
39200             write(unit=car,fmt="(i4)") nc
39201             natm%atom(nc)%lab="Pk_"//adjustl(car)
39202             natm%atom(nc)%ChemSymb="**"
39203             natm%atom(nc)%x=pks(1:3,i)
39204             natm%atom(nc)%occ=pks(4,i)
39205             natm%atom(nc)%active=.true.
39206             natm%atom(nc)%Mult=Get_Multip_Pos(pks(1:3,i),Grp)
39207          end do
39208       else
39209          do i=1,npks
39210             nc=nc+1
39211             write(unit=car,fmt="(i4)") nc
39212             natm%atom(nc)%lab="Pk_"//adjustl(car)
39213             natm%atom(nc)%ChemSymb="**"
39214             natm%atom(nc)%x=pks(1:3,i)
39215             natm%atom(nc)%occ=pks(4,i)
39216             natm%atom(nc)%active=.true.
39217             natm%atom(nc)%Mult=Get_Multip_Pos(pks(1:3,i),Grp)
39218          end do
39219       end if
39220
39221       return
39222    End Subroutine Merge_Atoms_Peaks
39223
39224    !!----
39225    !!---- Subroutine Multi(Lun,Iprin,Conven,Spg,A,Ac)
39226    !!----    integer,                intent(in)     :: lun     !  In -> Logical Unit for writing
39227    !!----    logical,                intent(in)     :: iprin   !  In -> .true. for writing in Lun
39228    !!----    logical,                intent(in)     :: conven  !  In -> .true. for using the whole conventional unit cell
39229    !!----    type(Space_Group_Type), intent(in)     :: SpG     !  In -> Space Group Information
39230    !!----    type(atom_list_type),  intent(in out) :: A        !  In -> Atom List (asymmetric unit)
39231    !!----                                                        Out -> Updated Atom List (multiplicity of sites)
39232    !!----    type(atoms_cell_type),  intent(out)    :: Ac      ! Out -> Atoms in unit cell
39233    !!----
39234    !!----    Subroutine to obtain multiplicities and coordinates of all atoms in
39235    !!----    the conventional unit cell. Calculates  "A%At(k)%mult" and constructs,
39236    !!----    partially, the object "Ac" of type "Atoms_Cell". The generated atoms constitute the
39237    !!----    content of the primitive (conven=.false.) or the conventional unit cell (conven=.true.).
39238    !!----
39239    !!---- Update: February - 2003
39240    !!
39241    Subroutine Multi(Lun,Iprin,Conven,Spg,A,Ac)
39242       !---- Arguments ----!
39243       integer,                intent(in)     :: lun
39244       logical,                intent(in)     :: iprin,conven
39245       type(Space_Group_Type), intent(in)     :: SpG
39246       type(atom_list_type),   intent(in out) :: A
39247       type(atoms_cell_type),  intent(in out) :: Ac
39248
39249       !---- Local Variables ----!
39250       real(kind=cp),dimension(3)            :: xx,xo,v
39251       integer                               :: k,j,l,nt,npeq,n
39252       character (len=6)                     :: fmm
39253       character (len=5)                     :: nam, namn, nami
39254       real(kind=cp)                         :: qc, mom, qcn, momn
39255       real(kind=cp),dimension(3,Spg%multip) :: u
39256
39257       npeq=SpG%numops
39258       if (SpG%centred == 2) npeq=npeq*2
39259       if (conven) npeq=SpG%multip
39260       n=0
39261       if (iprin)  then
39262          if (conven) then
39263             write(unit=lun,fmt="(/,a)") "     LIST OF ATOMS INSIDE THE CONVENTIONAL UNIT CELL "
39264             write(unit=lun,fmt="(a,/)") "     =============================================== "
39265          else
39266             write(unit=lun,fmt="(/,a)") "     LIST OF ATOMS CONTAINED IN A PRIMITIVE CELL "
39267             write(unit=lun,fmt="(a,/)") "     =========================================== "
39268          end if
39269       end if
39270       do k=1,A%natoms
39271          L=1
39272          n=n+1
39273          u(:,L)=a%atom(k)%x
39274          xo(:)=A%atom(k)%x(:)
39275          nami=A%atom(k)%lab
39276          if (iprin) write(unit=lun,fmt="(/,a,a)") " => Equivalent positions of atom: ",nami
39277          mom=A%atom(k)%moment
39278          qc=A%atom(k)%charge
39279          fmm="(a,i1)"
39280          write(unit=Ac%noms(n),fmt=fmm) trim(A%Atom(k)%lab)//"_",L
39281          nam= Ac%noms(n)
39282          if (iprin) write(unit=lun,fmt="(a,a,a,3f10.5,2(a,f6.3))")"       ",   &
39283                           nam,"  ", xo(:), "   M = ", mom ," Q = ", qc
39284          Ac%xyz(:,n)=xo(:)
39285          Ac%charge(n)=qc
39286          Ac%moment(n)=mom
39287          do_eq:DO j=2,npeq
39288             xx=ApplySO(SpG%SymOp(j),xo)
39289             xx=modulo_lat(xx)
39290             DO nt=1,L
39291                v=u(:,nt)-xx(:)
39292                if (Lattice_trans(v,SpG%spg_lat)) cycle do_eq
39293             END DO
39294             L=L+1
39295             u(:,L)=xx(:)
39296             n=n+1
39297             if ( L > 9) fmm="(a,i2)"
39298             write(unit=Ac%noms(n),fmt=fmm) trim(A%Atom(k)%lab)//"_",L
39299             Ac%xyz(:,n)=xx(:)
39300             Ac%charge(n)=A%Atom(k)%charge
39301             Ac%moment(n)=A%Atom(k)%moment
39302             namn=Ac%noms(n)
39303             momn=Ac%moment(n)
39304             qcn=Ac%charge(n)
39305             if (iprin) WRITE(unit=lun,fmt="(a,a,a,3f10.5,2(a,f6.3))")"       ",   &
39306                              namn, "  ", xx(:), "   M = ", momn ," Q = ", qcn
39307          end do do_eq
39308          A%Atom(k)%mult=L
39309       end do
39310       if (iprin)  write(unit=lun,fmt="(/)")
39311       Ac%nat=n
39312
39313       return
39314    End Subroutine Multi
39315
39316    !!----
39317    !!---- Subroutine Read_Bin_Atom_List(Ats,Lun,ok)
39318    !!----    Type (atom_list_type),dimension(:),  intent(in out) :: Ats     !  In out -> Atom List
39319    !!----    integer,                             intent(in)     :: lun     !  In -> Unit to write
39320    !!----    logical,                             intent(out)    :: ok      ! True is everything is OK!
39321    !!----
39322    !!----    Reads the atoms in the asymmetric unit in a binary file of logical unit Lun.
39323    !!----    The file should have been opened with the access="stream" attribute. The procedure
39324    !!----    reads in the given order a series of bytes corresponding to the components of the
39325    !!----    type Ats. The full structure is re-allocated inside the procedure before reading the
39326    !!----    components. The number of atoms is the first element read in the file.
39327    !!----
39328    !!---- Update: February - 2013
39329    !!
39330    Subroutine Read_Bin_Atom_List(Ats,Lun,ok)
39331       !---- Arguments ----!
39332       type (atom_list_type),            intent(in out) :: Ats
39333       integer,                          intent(in)     :: Lun
39334       logical,                          intent(out)    :: ok
39335       !---- Local Variables ----!
39336       integer                        :: i,ier
39337       logical                        :: Fail
39338
39339       ok=.true.
39340       read(unit=lun,iostat=ier) Ats%natoms    !Number of atoms in the list
39341       if(ier /= 0) then
39342         ok=.false.
39343         return
39344       end if
39345       if( Ats%natoms == 0) return
39346       call Allocate_Atom_List(ats%natoms,Ats,Fail)
39347       if(Fail) then
39348        ok=.false.
39349        return
39350       end if
39351       do i=1,ats%natoms
39352         read(unit=lun,iostat=ier)     &
39353           Ats%atom(i)%Lab,            &
39354           Ats%atom(i)%ChemSymb,       &
39355           Ats%atom(i)%SfacSymb,       &
39356           Ats%atom(i)%Active,         &
39357           Ats%atom(i)%Z,              &
39358           Ats%atom(i)%Mult,           &
39359           Ats%atom(i)%X,              &
39360           Ats%atom(i)%X_Std,          &
39361           Ats%atom(i)%MX,             &
39362           Ats%atom(i)%LX,             &
39363           Ats%atom(i)%Occ,            &
39364           Ats%atom(i)%Occ_Std,        &
39365           Ats%atom(i)%MOcc,           &
39366           Ats%atom(i)%LOcc,           &
39367           Ats%atom(i)%Biso,           &
39368           Ats%atom(i)%Biso_std,       &
39369           Ats%atom(i)%MBiso,          &
39370           Ats%atom(i)%LBiso,          &
39371           Ats%atom(i)%Utype,          &
39372           Ats%atom(i)%ThType,         &
39373           Ats%atom(i)%U,              &
39374           Ats%atom(i)%U_std,          &
39375           Ats%atom(i)%Ueq,            &
39376           Ats%atom(i)%MU,             &
39377           Ats%atom(i)%LU,             &
39378           Ats%atom(i)%Charge,         &
39379           Ats%atom(i)%Moment,         &
39380           Ats%atom(i)%Ind,            &
39381           Ats%atom(i)%NVar,           &
39382           Ats%atom(i)%VarF,           &
39383           Ats%atom(i)%mVarF,          &
39384           Ats%atom(i)%LVarF,          &
39385           Ats%atom(i)%AtmInfo
39386           if(ier /= 0) then
39387             ok=.false.
39388             return
39389           end if
39390       end do
39391       return
39392    End Subroutine Read_Bin_atom_list
39393
39394    !!----
39395    !!----    Subroutine Set_Atom_Equiv_List(SpG,cell,A,Ate,lun)
39396    !!----      type(Crystal_Cell_Type),    intent(in) :: Cell
39397    !!----      type(Space_Group_Type) ,    intent(in) :: SpG
39398    !!----      type(Atom_list_Type)   ,    intent(in) :: A
39399    !!----      type(Atom_Equiv_List_Type), intent(out):: Ate
39400    !!----      integer, optional,          intent(in) :: lun
39401    !!----
39402    !!---- Subroutine constructing the list of all atoms in the unit cell.
39403    !!---- The atoms are in a structure of type "Atom_Equiv_List_Type" containing
39404    !!---- the fractional coordinates of all the atoms in the cell.
39405    !!----
39406    !!---- Updated: January 2014
39407    !!
39408    Subroutine Set_Atom_Equiv_List(SpG,cell,A,Ate,lun)
39409     type(Crystal_Cell_Type),    intent(in) :: Cell
39410     type(Space_Group_Type) ,    intent(in) :: SpG
39411     type(Atom_list_Type)   ,    intent(in) :: A
39412     type(Atom_Equiv_List_Type), intent(out):: Ate
39413     integer, optional,          intent(in) :: lun
39414
39415     ! local variables
39416     real(kind=cp),  dimension(3)     :: xx,xo,v,xc
39417     real(kind=cp),  dimension(3,192) :: u
39418     character(len=20),dimension(192) :: label
39419     integer                          :: k,j,L,nt
39420     character (len=6)                :: fmm
39421     character (len=20)               :: nam
39422     real(kind=cp), parameter         :: epsi = 0.002
39423
39424     if (.not. allocated (Ate%atm)) allocate(Ate%atm(A%natoms))
39425     ate%nauas=A%natoms
39426     if (present(lun))  then
39427        write(unit=lun,fmt="(/,a)") "     LIST OF ATOMS INSIDE THE CONVENTIONAL UNIT CELL "
39428        write(unit=lun,fmt="(a,/)") "     =============================================== "
39429     end if
39430     do k=1,A%natoms
39431        ate%atm(k)%ChemSymb = A%atom(k)%ChemSymb
39432        xo(:) =Modulo_Lat(A%atom(k)%x(:))
39433        L=1
39434        u(:,L)=xo(:)
39435        !!!!Ate%atm(k)%x(:,L)= xo(:)
39436        xc =matmul(cell%Cr_Orth_cel,xo)
39437    !    Ate%atm(k)%c_coord(:,L)=xc
39438        if (present(lun))then
39439         write(unit=lun,fmt="(/,a,a)") " => Equivalent positions of atom: ",A%atom(k)%lab
39440         write(unit=lun,fmt="(a)")  &
39441         "                                    x         y         z          Xc        Yc        Zc"
39442        end if
39443        fmm="(a,i1)"
39444        !!!!write(unit=Ate%atm(k)%lab(L),fmt=fmm) trim(A%Atom(k)%lab)//"_",L
39445        write(unit=label(L),fmt=fmm) trim(A%Atom(k)%lab)//"_",L
39446        !!!!nam=Ate%atm(k)%lab(L)
39447        nam=label(L)
39448        if (present(lun)) write(unit=lun,fmt="(3a,3f10.5,a,3f10.5)") "       ",nam,"  ", xo,"  ", xc
39449
39450        do_eq:DO j=2,SpG%multip
39451           xx=ApplySO(SpG%SymOp(j),xo)
39452           xx=modulo_lat(xx)
39453           DO nt=1,L
39454              v=u(:,nt)-xx(:)
39455             ! if (Lattice_trans(v,SpG%spg_lat)) cycle do_eq
39456               if (sum(abs((v))) < epsi ) cycle do_eq
39457           END DO
39458           L=L+1
39459           u(:,L)=xx(:)
39460           if ( L > 9 .and. L < 100)  fmm="(a,i2)"
39461           if ( L >= 100 )  fmm="(a,i3)"
39462           !!!!write(unit=Ate%atm(k)%lab(L),fmt=fmm) trim(A%Atom(k)%lab)//"_",L
39463           write(unit=label(L),fmt=fmm) trim(A%Atom(k)%lab)//"_",L
39464           !!!nam=Ate%atm(k)%lab(L)
39465           nam=Label(L)
39466           !!! Ate%atm(k)%x(:,L)=xx(:)
39467           xc=matmul(cell%Cr_Orth_cel,xx)
39468           if (present(lun)) write(unit=lun,fmt="(3a,3f10.5,a,3f10.5)") "       ",nam,"  ", xx,"  ", xc
39469        end do do_eq
39470
39471        if(allocated(Ate%Atm(k)%Lab)) deallocate(Ate%Atm(k)%Lab)
39472        allocate(Ate%Atm(k)%lab(L))
39473        if(allocated(Ate%Atm(k)%x)) deallocate(Ate%Atm(k)%x)
39474        allocate(Ate%Atm(k)%x(3,L))
39475
39476        Ate%Atm(k)%mult=L
39477        do j=1,Ate%Atm(k)%mult
39478          Ate%Atm(k)%lab(j)=Label(j)
39479          Ate%Atm(k)%x(:,j)=u(:,j)
39480        end do
39481     end do
39482     if (present(lun))  write(unit=lun,fmt="(/)")
39483     return
39484    End Subroutine Set_Atom_Equiv_List
39485
39486    !!----
39487    !!---- Subroutine Write_Atom_List(Ats,Level,Lun,Cell)
39488    !!----    Type (atom_list_type),dimension(:),  intent(in) :: Ats     !  In -> Atom List
39489    !!----    integer, optional,                   intent(in) :: Level   !  In -> Level of printed information
39490    !!----    integer, optional,                   intent(in) :: lun     !  In -> Unit to write
39491    !!----    Type(Crystal_Cell_Type), optional,   intent(in) :: Cell    !  In -> Transform to thermal parameters
39492    !!----
39493    !!----    Write the atoms in the asymmetric unit
39494    !!----
39495    !!---- Update: February - 2003
39496    !!
39497    Subroutine Write_Atom_List(Ats,Level,Lun,Cell)
39498       !---- Arguments ----!
39499       type (atom_list_type),            intent(in) :: Ats
39500       integer, optional,                intent(in) :: Level
39501       integer, optional,                intent(in) :: Lun
39502       Type(Crystal_Cell_Type), optional,intent(in) :: Cell
39503
39504       !---- Local Variables ----!
39505       character(len=1)               :: car
39506       integer                        :: i, j, lv,iunit
39507       real(kind=cp)                  :: biso
39508       real(kind=cp), dimension(3)    :: rms
39509       real(kind=cp), dimension(6)    :: u,b,bet
39510       real(kind=cp), dimension(3,3)  :: beta,eigen
39511       logical                        :: aniso
39512
39513
39514       iunit=6
39515       if (present(lun)) iunit=lun
39516       if(ats%natoms == 0) then
39517         write(unit=iunit,fmt="(/,a,/)") "  => No atoms provided!"
39518         return
39519       end if
39520
39521       lv=0
39522       if (present(level)) lv=level
39523       write(unit=iunit,fmt="(/,a)")    "        Atoms information:"
39524       write(unit=iunit,fmt="(a,/)")    "        ------------------"
39525
39526       select case (lv)
39527          case (0)
39528             write (unit=iunit,fmt="(T5,a)") &
39529                   "Atom      Chem        x/a       y/b       z/c       Biso     Occ       Mult"
39530             write (unit=iunit,fmt="(T5,a)") &
39531                   "==========================================================================="
39532          case (1)
39533             write (unit=iunit,fmt="(T5,a)") &
39534                   "Atom      Chem        x/a       y/b       z/c       Biso      Occ     Moment    Charge   Active   Mult"
39535             write (unit=iunit,fmt="(T5,a)") &
39536                   "======================================================================================================"
39537       end select
39538
39539       aniso=.false.
39540       do i=1,ats%natoms
39541          car=" "
39542          if (.not. ats%atom(i)%active) car="-"
39543          if(ats%atom(i)%thtype == "aniso") aniso=.true.
39544          select case (lv)
39545             case (0)
39546                write(unit=iunit,fmt="(T5,a,T16,a,T21,5f10.4,i9,a)") &
39547                     ats%atom(i)%lab, ats%atom(i)%chemsymb, ats%atom(i)%x, &
39548                     ats%atom(i)%biso,ats%atom(i)%occ,ats%atom(i)%mult,trim("  "//ats%atom(i)%AtmInfo)
39549             case (1)
39550                write(unit=iunit,fmt="(T5,a,T16,a,T21,7f10.4,T96,a,t97,i9,a)") &
39551                     ats%atom(i)%lab, ats%atom(i)%chemsymb, ats%atom(i)%x, &
39552                     ats%atom(i)%biso,ats%atom(i)%occ,ats%atom(i)%moment,ats%atom(i)%charge,&
39553                     car,ats%atom(i)%mult,trim("  "//ats%atom(i)%AtmInfo)
39554          end select
39555       end do
39556
39557       if (aniso) then
39558          write(unit=iunit,fmt="(/,/,T5,a)") &
39559               "Atom       Type      T_11        T_22        T_33        T_12        T_13        T_23"
39560          write (unit=iunit,fmt="(T5,a)") &
39561               "====================================================================================="
39562          do i=1,ats%natoms
39563             if (ats%atom(i)%thtype == "aniso") then
39564
39565                if (ats%atom(i)%utype == "beta") then
39566                   bet=ats%atom(i)%u(1:6)
39567                   write(unit=iunit,fmt="(T5,a,t16,a,6f12.6)") ats%atom(i)%lab,ats%atom(i)%utype, bet
39568                   if (present(Cell)) then
39569                      u=convert_betas_u(bet,cell)
39570                      write(unit=iunit,fmt="(T16,a,6f12.6)") "U_ij", u
39571                      b=convert_betas_b(bet,cell)
39572                      write(unit=iunit,fmt="(T16,a,6f12.6)") "B_ij", b
39573                   end if
39574                else if(ats%atom(i)%thtype == "u_ij") then
39575                   u=ats%atom(i)%u(1:6)
39576                   write(unit=iunit,fmt="(T5,a,t16,a,6f12.6)") ats%atom(i)%lab,ats%atom(i)%utype, u
39577                   b=convert_u_b(u)
39578                   write(unit=iunit,fmt="(T16,a,6f12.6,a)") "B_ij", b
39579                   if (present(Cell)) then
39580                      bet=convert_u_betas(u,cell)
39581                      write(unit=iunit,fmt="(T16,a,6f12.6,a)") "Beta", bet
39582                   end if
39583                else if(ats%atom(i)%thtype == "b_ij") then
39584                   b=ats%atom(i)%u(1:6)
39585                   write(unit=iunit,fmt="(T5,a,t16,a,6f12.6)") ats%atom(i)%lab,ats%atom(i)%utype, b
39586                   u=convert_b_u(b)
39587                   write(unit=iunit,fmt="(T16,a,6f12.6,a)") "U_ij", u
39588                   if (present(Cell)) then
39589                      bet=convert_b_betas(b,cell)
39590                      write(unit=iunit,fmt="(T16,a,6f12.6,a)") "Beta", bet
39591                   end if
39592                end if
39593
39594                if (present(cell)) then
39595                  beta=reshape((/bet(1),bet(4),bet(5), bet(4),bet(2),bet(6), bet(5),bet(6),bet(3) /),(/3,3/))
39596                   beta=beta*0.5/pi/pi
39597                   beta=matmul(matmul(Cell%Cr_Orth_cel,beta),transpose(Cell%Cr_Orth_cel))
39598                   call matrix_diageigen(beta,rms,eigen)
39599                   write(unit=lun,fmt="(a)")  &
39600                        "               U-Eigen Value(A**2) ----       Eigen vector(Orth. syst.)     R.M.S (Angstroms)"
39601                   do j =1,3
39602                      if (rms(j) < 0.0)  then
39603                         write(unit=iunit,fmt="((t16,f10.5,a,3(tr1,f10.5),a))")     rms(j), &
39604                              "          --- ", eigen(:,j),"   -> Matrix U non-positive definite!"
39605                      else
39606                         write(unit=iunit,fmt="((t16,f10.5,a,3(tr1,f10.5),a,f14.5))") rms(j),&
39607                              "          ---(", eigen(:,j),")", sqrt(rms(j))
39608                      end if
39609                   end do
39610                   biso=sum(rms)/3.0
39611                   write(unit=iunit,fmt="(a,f8.4)") "               Isotropic temperature factor Uequiv(A**2): ",biso
39612                   biso=biso*8.0*pi*pi
39613                   write(unit=iunit,fmt="(a,f8.4,/)") "               Isotropic temperature factor Bequiv(A**2): ",biso
39614                end if
39615
39616             end if
39617          end do
39618       end if
39619
39620       return
39621    End Subroutine Write_atom_list
39622    !!----
39623    !!---- Subroutine Write_Bin_Atom_List(Ats,Lun)
39624    !!----    Type (atom_list_type),dimension(:),  intent(in) :: Ats     !  In -> Atom List
39625    !!----    integer,                             intent(in) :: lun     !  In -> Unit to write
39626    !!----
39627    !!----    Write the atoms in the asymmetric unit in a binary file of logical unit Lun.
39628    !!----    The file should have been opened with the access="stream" attribute. The procedure
39629    !!----    writes in the given order a series of bytes corresponding to the components of the
39630    !!----    type Ats. For reading back an atom list from a binary file the subroutine Read_Bin_Atom_List
39631    !!----    has to be used.
39632    !!----
39633    !!---- Update: February - 2013
39634    !!
39635    Subroutine Write_Bin_Atom_List(Ats,Lun)
39636       !---- Arguments ----!
39637       type (atom_list_type),            intent(in) :: Ats
39638       integer,                          intent(in) :: Lun
39639       !---- Local Variables ----!
39640       integer                        :: i
39641
39642       write(unit=lun) ats%natoms    !Number of atoms in the list
39643       do i=1,ats%natoms
39644         write(unit=lun)               &
39645           ats%atom(i)%Lab,            &
39646           ats%atom(i)%ChemSymb,       &
39647           ats%atom(i)%SfacSymb,       &
39648           ats%atom(i)%Active,         &
39649           ats%atom(i)%Z,              &
39650           ats%atom(i)%Mult,           &
39651           ats%atom(i)%X,              &
39652           ats%atom(i)%X_Std,          &
39653           ats%atom(i)%MX,             &
39654           ats%atom(i)%LX,             &
39655           ats%atom(i)%Occ,            &
39656           ats%atom(i)%Occ_Std,        &
39657           ats%atom(i)%MOcc,           &
39658           ats%atom(i)%LOcc,           &
39659           ats%atom(i)%Biso,           &
39660           ats%atom(i)%Biso_std,       &
39661           ats%atom(i)%MBiso,          &
39662           ats%atom(i)%LBiso,          &
39663           ats%atom(i)%Utype,          &
39664           ats%atom(i)%ThType,         &
39665           ats%atom(i)%U,              &
39666           ats%atom(i)%U_std,          &
39667           ats%atom(i)%Ueq,            &
39668           ats%atom(i)%MU,             &
39669           ats%atom(i)%LU,             &
39670           ats%atom(i)%Charge,         &
39671           ats%atom(i)%Moment,         &
39672           ats%atom(i)%Ind,            &
39673           ats%atom(i)%NVar,           &
39674           ats%atom(i)%VarF,           &
39675           ats%atom(i)%mVarF,          &
39676           ats%atom(i)%LVarF,          &
39677           ats%atom(i)%AtmInfo
39678       end do
39679       return
39680    End Subroutine Write_Bin_atom_list
39681
39682 End Module CFML_Atom_TypeDef
39683!!-------------------------------------------------------
39684!!---- Crystallographic Fortran Modules Library (CrysFML)
39685!!-------------------------------------------------------
39686!!---- The CrysFML project is distributed under LGPL. In agreement with the
39687!!---- Intergovernmental Convention of the ILL, this software cannot be used
39688!!---- in military applications.
39689!!----
39690!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
39691!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
39692!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
39693!!----
39694!!---- Authors: Juan Rodriguez-Carvajal (ILL)
39695!!----          Javier Gonzalez-Platas  (ULL)
39696!!----
39697!!---- Contributors: Laurent Chapon     (ILL)
39698!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
39699!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
39700!!----               Tierry Roisnel     (CDIFX,Rennes France)
39701!!----               Eric Pellegrini    (ILL)
39702!!----
39703!!---- This library is free software; you can redistribute it and/or
39704!!---- modify it under the terms of the GNU Lesser General Public
39705!!---- License as published by the Free Software Foundation; either
39706!!---- version 3.0 of the License, or (at your option) any later version.
39707!!----
39708!!---- This library is distributed in the hope that it will be useful,
39709!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
39710!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
39711!!---- Lesser General Public License for more details.
39712!!----
39713!!---- You should have received a copy of the GNU Lesser General Public
39714!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
39715!!----
39716!!----
39717!!---- MODULE: CFML_Geometry_Calc
39718!!----   INFO: Routines for Geometry Calculations
39719!!----
39720!!---- HISTORY
39721!!----    Update: 06/03/2011
39722!!----
39723!!----
39724!!---- DEPENDENCIES
39725!!--++    CFML_Math_3D:  Cross_Product
39726!!--++    CFML_GlobalDeps: Eps, Pi, Cp, Sp, To_Rad, To_Deg
39727!!--++    CFML_Math_General: Acosd, Cosd, Sind
39728!!--++    CFML_Crystal_Metrics: Crystal_Cell_Type
39729!!----
39730!!---- VARIABLES
39731!!----    COORDINATION_TYPE
39732!!----    COORD_INFO
39733!!--++    EPSI
39734!!----    ERR_GEOM
39735!!----    ERR_GEOM_MESS
39736!!----    POINT_LIST_TYPE
39737!!----
39738!!---- PROCEDURES
39739!!----    Functions:
39740!!----       ANGLE_DIHEDRAL
39741!!--++       ANGLE_DIHEDRAL_IJKN            [Overloaded]
39742!!--++       ANGLE_DIHEDRAL_UVW             [Overloaded]
39743!!----       ANGLE_MOD
39744!!--++       ANGLE_MODN                     [Overloaded]
39745!!--++       ANGLE_MODV                     [Overloaded]
39746!!----       ANGLE_UV
39747!!--++       ANGLE_UVI                      [Overloaded]
39748!!--++       ANGLE_UVR                      [Overloaded]
39749!!----       COORD_MOD
39750!!--++       COORD_MODN                     [Overloaded]
39751!!--++       COORD_MODV                     [Overloaded]
39752!!----       DISTANCE
39753!!--++       DISTANCE_FR                    [Overloaded]
39754!!--++       DISTANCE_FR_DP                 [Overloaded]
39755!!--++       DISTANCE_SC                    [Overloaded]
39756!!----       MATRIX_PHITHECHI
39757!!----       MATRIX_RX
39758!!----       MATRIX_RY
39759!!----       MATRIX_RZ
39760!!----
39761!!----    Subroutines:
39762!!----       ALLOCATE_COORDINATION_TYPE
39763!!----       ALLOCATE_POINT_LIST
39764!!----       CALC_DIST_ANGLE
39765!!----       CALC_DIST_ANGLE_SIGMA
39766!!----       DEALLOCATE_COORDINATION_TYPE
39767!!----       DEALLOCATE_POINT_LIST
39768!!----       DISTANCE_AND_SIGMA
39769!!----       GET_ANGLEN_AXIS_FROM_ROTMAT
39770!!----       GET_EULER_FROM_FRACT
39771!!----       GET_MATRIX_MOVING_V_TO_U
39772!!----       GET_OMEGACHIPHI
39773!!----       GET_PHITHECHI
39774!!----       GET_TRANSF_LIST
39775!!----       INIT_ERR_GEOM
39776!!----       P1_DIST
39777!!----       PRINT_DISTANCES
39778!!----       SET_NEW_ASYMUNIT
39779!!----       SET_ORBITS_INLIST
39780!!----       SET_ROTATION_MATRIX
39781!!----       SET_TDIST_COORDINATION
39782!!----       SET_TDIST_PARTIAL_COORDINATION
39783!!----
39784!!
39785 Module CFML_Geometry_Calc
39786
39787    !---- Use Modules ----!
39788    use CFML_GlobalDeps,                 only: Sp, Cp, dp, eps, pi, to_rad, to_deg
39789    use CFML_Math_General,               only: acosd, cosd, sind, Modulo_Lat
39790    use CFML_Math_3D,                    only: Cross_Product, Matrix_Inverse, determ_A
39791    use CFML_String_Utilities,           only: Frac_Trans_1Dig, L_Case,U_Case,pack_string,setnum_std, get_logunit
39792    use CFML_Crystal_Metrics,            only: Crystal_Cell_Type, Get_Deriv_Orth_Cell,Rot_Matrix
39793    use CFML_Atom_TypeDef,               only: atom_list_type,Atoms_Cell_Type,Equiv_Atm, Wrt_Lab, Atom_Equiv_List_Type, &
39794                                               allocate_atom_list
39795    use CFML_Crystallographic_Symmetry,  only: Space_Group_Type, ApplySo, Lattice_Trans, Get_Multip_Pos, &
39796                                               searchop, Read_SymTrans_Code, Write_SymTrans_Code, Get_Orbit
39797
39798    implicit none
39799
39800    private
39801
39802    !---- List of public functions ----!
39803
39804    !---- List of public overloaded procedures: functions ----!
39805    public :: Angle_Dihedral, Angle_Mod, Angle_Uv, Coord_Mod, Distance, Matrix_PhiTheChi, Matrix_Rx, &
39806              Matrix_Ry, Matrix_Rz
39807
39808    !---- List of public subroutines ----!
39809    public :: Allocate_Coordination_Type, Allocate_Point_List, Calc_Dist_Angle, Calc_Dist_Angle_Sigma, &
39810              Deallocate_Coordination_Type, Deallocate_Point_List, Distance_and_Sigma, Get_Euler_From_Fract, &
39811              Get_PhiTheChi, init_err_geom, P1_Dist, Print_Distances, Set_Orbits_InList, Set_TDist_Coordination, &
39812              Get_Transf_List, Set_TDist_Partial_Coordination, Get_Anglen_Axis_From_RotMat, Get_Matrix_moving_v_to_u, &
39813              Get_OmegaChiPhi, Set_Rotation_Matrix, Set_New_AsymUnit
39814
39815    !---- List of public overloaded procedures: subroutines ----!
39816
39817    !---- List of private functions ----!
39818    private :: Angle_Dihedral_Uvw,  Angle_Dihedral_Ijkn, Angle_Uvi, Angle_Uvr, Angle_Modn, Angle_Modv, &
39819               Coord_Modn, Coord_Modv, Distance_fr, Distance_fr_dp, Distance_sc
39820
39821    !---- Definitions ----!
39822
39823    !!----
39824    !!---- TYPE :: COORDINATION_TYPE
39825    !!--..
39826    !!---- Type, public :: Coordination_Type
39827    !!----    integer                                      :: Natoms    ! number of atoms
39828    !!----    integer                                      :: Max_Coor  ! Maximum number of connected atoms to a given one
39829    !!----    integer,       dimension(:),     allocatable :: Coord_Num ! Counter of distances connected to the current atom
39830    !!----    integer,       dimension(:,:),   allocatable :: N_Cooatm  ! Pointer to the ordinal number in the list of the attached
39831    !!----                                                              ! atom to the atom given by the first index
39832    !!----    integer,       dimension(:,:),   allocatable :: N_Sym     !
39833    !!----    real(kind=cp), dimension(:,:),   allocatable :: Dist      ! List of distances related to an atom
39834    !!----    real(kind=cp), dimension(:,:),   allocatable :: S_Dist    ! List of Sigma(distances)
39835    !!----    real(kind=cp), dimension(:,:,:), allocatable :: Tr_coo    !
39836    !!---- End type Coordination_Type
39837    !!----
39838    !!---- Update: February - 2005
39839    !!
39840    Type, public :: Coordination_Type
39841       integer                                      :: Natoms    ! number of atoms
39842       integer                                      :: Max_Coor  ! Maximum number of connected atoms to a given one
39843       integer,       dimension(:),     allocatable :: Coord_Num ! Counter of distances connected to the current atom
39844       integer,       dimension(:,:),   allocatable :: N_Cooatm  ! Pointer to the ordinal number in the list of the attached
39845                                                                 ! atom to the atom given by the first index
39846       integer,       dimension(:,:),   allocatable :: N_Sym     ! Number of symmetry operator to apply to N_Cooatm
39847       real(kind=cp), dimension(:,:),   allocatable :: Dist      ! List of distances related to an atom
39848       real(kind=cp), dimension(:,:),   allocatable :: S_Dist    ! List of Sigma(distances)
39849       real(kind=cp), dimension(:,:,:), allocatable :: Tr_coo
39850    End type Coordination_Type
39851
39852    !!----
39853    !!---- COORD_INFO
39854    !!----    type(Coordination_Type), public :: coord_info
39855    !!----
39856    !!----    Coordination Information
39857    !!----
39858    !!---- Update: March - 2005
39859    !!
39860    type(Coordination_Type), public :: coord_info
39861
39862    !!--++
39863    !!--++ EPSI
39864    !!--++    real(kind=cp), parameter :: epsi=0.001
39865    !!--++
39866    !!--++    (PRIVATE)
39867    !!--++    Epsilon for roughly comparing distances
39868    !!--++
39869    !!--++ Update: February - 2005
39870    !!
39871    real(kind=cp), parameter, private :: epsi=0.001
39872
39873    !!----
39874    !!---- ERR_GEOM
39875    !!----    logical, public  :: err_geom
39876    !!----
39877    !!----    Logical Variable indicating an error in CFML_Geometry_Calc module
39878    !!----
39879    !!---- Update: February - 2005
39880    !!
39881    logical, public  :: err_geom
39882
39883    !!----
39884    !!---- ERR_Geom_Mess
39885    !!----    character(len=150), public :: ERR_Geom_Mess
39886    !!----
39887    !!----    String containing information about the last error
39888    !!----
39889    !!---- Update: February - 2005
39890    !!
39891    character(len=150), public :: ERR_Geom_Mess
39892
39893
39894    !!----
39895    !!---- TYPE :: POINT_LIST_TYPE
39896    !!--..
39897    !!---- Type, public :: Point_List_Type
39898    !!----    integer                                       :: np   !number of points in list
39899    !!----    character(len=12), dimension(:),  allocatable :: nam  !name/label associated to each point
39900    !!----    integer,           dimension(:),  allocatable :: p    !integer pointer for various purposes
39901    !!----    real(kind=cp)      dimension(:,:),allocatable :: x    !fractional coordinates of points
39902    !!---- End type Point_List_Type
39903    !!----
39904    !!---- Update: February - 2005
39905    !!
39906    Type, public :: point_list_type
39907       integer                                       :: np   !number of points in list
39908       character(len=12), dimension(:),  allocatable :: nam  !name/label associated to each point
39909       integer,           dimension(:),  allocatable :: p    !integer pointer for various purposes
39910       real(kind=cp),     dimension(:,:),allocatable :: x    !fractional coordinates of points
39911    End type point_list_type
39912
39913
39914    !---- Interfaces - Overlapp ----!
39915    Interface  Angle_Dihedral
39916       Module Procedure Angle_Dihedral_Ijkn
39917       Module Procedure Angle_Dihedral_Uvw
39918    End Interface
39919
39920    Interface  Angle_Uv
39921       Module Procedure Angle_UvI
39922       Module Procedure Angle_UvR
39923    End Interface
39924
39925    Interface  Angle_Mod
39926       Module Procedure Angle_ModN
39927       Module Procedure Angle_ModV
39928    End Interface
39929
39930    Interface  Coord_Mod
39931       Module Procedure Coord_ModN
39932       Module Procedure Coord_ModV
39933    End Interface
39934
39935    Interface  Distance
39936       Module Procedure Distance_FR_DP
39937       Module Procedure Distance_FR
39938       Module Procedure Distance_SC
39939    End Interface
39940
39941 Contains
39942
39943    !---- Functions ----!
39944
39945    !!----
39946    !!---- Function Angle_Dihedral(U,V,W) Or (Ri,Rj,Rk,Rn)   Result(Angle)
39947    !!----    real(kind=cp), dimension(3), intent( in) :: u       !  In -> Vector 1
39948    !!----    real(kind=cp), dimension(3), intent( in) :: v       !  In -> Vector 2
39949    !!----    real(kind=cp), dimension(3), intent( in) :: w       !  In -> Vector 3
39950    !!----    or
39951    !!----    real(kind=cp), dimension(3), intent( in) :: ri      !  In -> Vector position ri
39952    !!----    real(kind=cp), dimension(3), intent( in) :: rj      !  In -> Vector position rj
39953    !!----    real(kind=cp), dimension(3), intent( in) :: rk      !  In -> Vector position rk
39954    !!----    real(kind=cp), dimension(3), intent( in) :: rl      !  In -> Vector position rn
39955    !!----    real(kind=cp)                            :: angle   ! Out -> Dihedral angle
39956    !!----
39957    !!----    Calculates the dihedral angle between planes "u-v" and "v-w", where vectors U,V,W
39958    !!----    are given in cartesian components.
39959    !!----    Calculates the dihedral angle corresponding to the four points (ri,rj,rk,rn)
39960    !!----    given in cartesian components. The definition used for the dihedral angle
39961    !!----    is the following:
39962    !!--<<
39963    !!----    Phi(i,j,k,n) = acos { (rij x rjk) (rjk x rkn) / |rij x rjk| / |rjk x rkn| }
39964    !!----
39965    !!----    with this definition the sign of Phi is positive if the vector product
39966    !!----    (rij x rjk) x (rjk x rkn) is in the same direction as rjk, and negative if
39967    !!----    the direction is opposite.
39968    !!-->>
39969    !!----
39970    !!---- Update: February - 2005
39971    !!
39972
39973    !!--++
39974    !!--++ Function Angle_Dihedral_Ijkn(Ri,Rj,Rk,Rn) Result(Angle)
39975    !!--++    real(kind=cp), dimension(3), intent( in) :: ri       !  In -> Vector position ri
39976    !!--++    real(kind=cp), dimension(3), intent( in) :: rj       !  In -> Vector position rj
39977    !!--++    real(kind=cp), dimension(3), intent( in) :: rk       !  In -> Vector position rk
39978    !!--++    real(kind=cp), dimension(3), intent( in) :: rl       !  In -> Vector position rn
39979    !!--++    real(kind=cp)                            :: angle    ! Out -> Dihedral angle
39980    !!--++
39981    !!--++    (OVERLOADED)
39982    !!--++    Calculates the dihedral angle corresponding to the four points (ri,rj,rk,rn)
39983    !!--++    given in cartesian components. The definition used for the dihedral angle
39984    !!--++    is the following:
39985    !!--++
39986    !!--++    Phi(i,j,k,n) = acos { (rij x rjk) (rjk x rkn) / |rij x rjk| / |rjk x rkn| }
39987    !!--++
39988    !!--++    with this definition the sign of Phi is positive if the vector product
39989    !!--++    (rij x rjk) x (rjk x rkn) is in the same direction as rjk, and negative if
39990    !!--++    the direction is opposite.
39991    !!--++
39992    !!--++ Update: February - 2005
39993    !!
39994    Function Angle_Dihedral_Ijkn(ri,rj,rk,rn) result(angle)
39995       !---- Arguments ----!
39996       real(kind=cp), dimension(3), intent( in) :: ri,rj,rk,rn
39997       real(kind=cp)                            :: angle
39998
39999       angle=Angle_Dihedral_Uvw(rj-ri ,rk-rj, rn-rk )
40000
40001       return
40002    End Function Angle_Dihedral_Ijkn
40003
40004    !!--++
40005    !!--++ Function Angle_Dihedral_Uvw(U,V,W) Result(Angle)
40006    !!--++    real(kind=cp), dimension(3), intent( in) :: u       !  In -> Vector 1
40007    !!--++    real(kind=cp), dimension(3), intent( in) :: v       !  In -> Vector 2
40008    !!--++    real(kind=cp), dimension(3), intent( in) :: w       !  In -> Vector 3
40009    !!--++    real(kind=cp)                            :: angle   ! Out -> Dihedral angle
40010    !!--++
40011    !!--++    (OVERLOADED)
40012    !!--++    Calculates the dihedral angle between planes u-v and v-w
40013    !!--++    Vectors u,v,w are given in cartesian components.
40014    !!--++
40015    !!--++ Update: February - 2005
40016    !!
40017    Function Angle_Dihedral_Uvw(u,v,w) result(angle)
40018       !---- Argument ----!
40019       real(kind=cp), dimension(3), intent( in) :: u,v,w
40020       real(kind=cp)                            :: angle
40021
40022       !---- Local variables ----!
40023       real(kind=cp)               :: uvmod, vwmod, sig
40024       real(kind=cp), dimension(3) :: uv,vw
40025
40026       angle=0.0
40027
40028       uv=cross_product(u,v)
40029       vw=cross_product(v,w)
40030       sig = -sign(1.0_cp, dot_product(cross_product(uv,vw),v))
40031       uvmod=sqrt(dot_product(uv,uv))
40032       vwmod=sqrt(dot_product(vw,vw))
40033       if (uvmod < eps .or. vwmod < eps) return
40034       angle=acosd(dot_product(uv,vw)/uvmod/vwmod)*sig
40035
40036       return
40037    End Function Angle_Dihedral_Uvw
40038
40039    !!----
40040    !!---- Function Angle_Mod(X) Result (Y)
40041    !!----     real(kind=cp),               intent(in) :: x
40042    !!----                  or
40043    !!----     real(kind=cp), dimension(:), intent(in) :: x
40044    !!----
40045    !!----     Calculates the angle [-pi,pi)
40046    !!----
40047    !!---- Update: February - 2005
40048    !!
40049
40050    !!--++
40051    !!--++ Function Angle_Modn(Angle) Result(AngMod)
40052    !!--++    real(kind=cp), intent(in) :: Angle    !  In/Out -> Angle
40053    !!--++
40054    !!--++    (OVERLOADED)
40055    !!--++    Transforms angle in radians between -pi and +pi
40056    !!--++
40057    !!--++ Update: February - 2005
40058    !!
40059    Function Angle_ModN(Angle) Result(AngMod)
40060       !---- Arguments ----!
40061       real(kind=cp), intent(in) :: Angle
40062       real(kind=cp)             :: AngMod
40063
40064       AngMod=mod(angle+6.0*pi,2.0*pi)
40065       if (angmod > pi) angmod=angmod-2.0*pi
40066
40067       return
40068    End Function Angle_ModN
40069
40070    !!--++
40071    !!--++ Function Angle_Modv(V_Angle) Result(VAngMod)
40072    !!--++    real(kind=cp), dimension(:), intent(in) :: V_Angle
40073    !!--++
40074    !!--++    (OVERLOADED)
40075    !!--++    Transforms angles in radians between -pi and +pi
40076    !!--++
40077    !!--++ Update: February - 2005
40078    !!
40079    Function Angle_ModV(V_Angle) Result(VAngMod)
40080       !---- Arguments ----!
40081       real(kind=cp), dimension(:),intent(in) :: V_Angle
40082       real(kind=cp), dimension(size(V_Angle)):: VAngMod
40083
40084       !---- Local Variables ----!
40085       integer :: i
40086
40087       VAngMod=mod(V_Angle+6.0*pi,2.0*pi)
40088       do i=1,size(V_Angle)
40089          if (VAngMod(i) > pi) VAngMod(i)=VAngMod(i)-2.0*pi
40090       end do
40091
40092       return
40093    End Function Angle_ModV
40094
40095    !!----
40096    !!---- Function Angle_Uv(U,V,G) Result(Angle)
40097    !!----    integer/real(kind=cp), dimension(:), intent( in)     :: u      !  In -> Vector 1
40098    !!----    integer/real(kind=cp), dimension(:), intent( in)     :: v      !  In -> Vector 2
40099    !!----    real(kind=cp), dimension(:,:), intent( in), optional :: g      !  In -> Metric tensor
40100    !!----    real(kind=cp)                                        :: angle  ! Out -> Angle
40101    !!----
40102    !!----    Calculates the angle between vectors u and v given in cartesian
40103    !!----    components. If g is not given cartesian components are assumed.
40104    !!----
40105    !!---- Update: February - 2005
40106    !!
40107
40108    !!--++
40109    !!--++ Function Angle_UvI(Ui,Vi,G) Result(Angle)
40110    !!--++    integer, dimension(:),                   intent(in) :: ui      !  In -> Vector 1
40111    !!--++    integer, dimension(:),                   intent(in) :: vi      !  In -> Vector 2
40112    !!--++    real(kind=cp), dimension(:,:), optional, intent(in) :: g       !  In -> Metric tensor
40113    !!--++    real(kind=cp)                                       :: angle   ! Out -> Angle
40114    !!--++
40115    !!--++    (OVERLOADED)
40116    !!--++    Calculates the angle between vectors u and v given in cartesians
40117    !!--++    or fractional components. If g is not given cartesian components
40118    !!--++    are assumed.
40119    !!--++
40120    !!--++ Update: February - 2005
40121    !!
40122    Function Angle_UvI(Ui,Vi,G) Result(Angle)
40123       !---- Argument ----!
40124       integer, dimension(:),   intent( in)                 :: ui
40125       integer, dimension(:),   intent( in)                 :: vi
40126       real(kind=cp), dimension(:,:), intent( in), optional :: g   !metric tensor
40127       real(kind=cp)                                        :: angle
40128
40129       !---- Local variables ----!
40130       real(kind=cp)                      :: umod, vmod
40131       real(kind=cp), dimension(size(ui)) :: u
40132       real(kind=cp), dimension(size(vi)) :: v
40133
40134       angle=0.0
40135
40136       u=real(ui)
40137       v=real(vi)
40138
40139       if (present(g)) then
40140          umod = sqrt(dot_product(u,matmul(g,u)))
40141          vmod = sqrt(dot_product(v,matmul(g,v)))
40142          if (umod < eps .or. vmod < eps) return
40143          angle=acosd(dot_product(u,matmul(g,v))/umod/vmod)
40144       else
40145          umod=sqrt(dot_product(u,u))
40146          vmod=sqrt(dot_product(v,v))
40147          if (umod < eps .or. vmod < eps) return
40148          angle=acosd(dot_product(u,v)/umod/vmod)
40149       end if
40150
40151       return
40152    End Function Angle_uvi
40153
40154    !!--++
40155    !!--++ Function Angle_Uvr(U,V,G) Result(Angle)
40156    !!--++    real(kind=cp), dimension(:), intent( in)             :: u      !  In -> Vector 1
40157    !!--++    real(kind=cp), dimension(:), intent( in)             :: v      !  In -> Vector 2
40158    !!--++    real(kind=cp), dimension(:,:), intent( in), optional :: g      !  In -> Metric tensor
40159    !!--++    real(kind=cp)                                        :: angle  ! Out -> Angle
40160    !!--++
40161    !!--++    (OVERLOADED)
40162    !!--++    Calculates the angle between vectors u and v given in cartesian
40163    !!--++    or fractional components. If g is not given cartesian components
40164    !!--++    are assumed.
40165    !!--++
40166    !!--++ Update: February - 2005
40167    !!
40168    Function Angle_UvR(u,v,g) result(angle)
40169       !---- Argument ----!
40170       real(kind=cp), dimension(:),   intent( in)           :: u
40171       real(kind=cp), dimension(:),   intent( in)           :: v
40172       real(kind=cp), dimension(:,:), intent( in), optional :: g   !metric tensor
40173       real(kind=cp)                                        :: angle
40174
40175       !---- Local variables ----!
40176       real(kind=cp)   :: umod, vmod
40177
40178       angle=0.0
40179
40180       if (present(g)) then
40181          umod = sqrt(dot_product(u,matmul(g,u)))
40182          vmod = sqrt(dot_product(v,matmul(g,v)))
40183          if (umod < eps .or. vmod < eps) return
40184          angle=acosd(dot_product(u,matmul(g,v))/umod/vmod)
40185       else
40186          umod=sqrt(dot_product(u,u))
40187          vmod=sqrt(dot_product(v,v))
40188          if (umod < eps .or. vmod < eps) return
40189          angle=acosd(dot_product(u,v)/umod/vmod)
40190       end if
40191
40192       return
40193    End Function Angle_uvr
40194
40195    !!----
40196    !!---- Function Coord_Mod(X) Result (Y)
40197    !!----    Real(Kind=Cp),               intent(in) :: x
40198    !!----                  or
40199    !!----    real(kind=cp), dimension(:), intent(in) :: x
40200    !!----
40201    !!----    Calculates the coordinates between [0,1)
40202    !!----
40203    !!---- Update: February - 2005
40204    !!
40205
40206    !!--++
40207    !!--++ Function Coord_Modn(X) Result (XMod)
40208    !!--++    real(kind=cp), intent(in) :: x
40209    !!--++
40210    !!--++    (OVERLOADED)
40211    !!--++    Transforms reduced the value between 0 and 1
40212    !!--++
40213    !!--++ Update: February - 2005
40214    !!
40215    Function Coord_ModN(x) result(Xmod)
40216       !---- Arguments ----!
40217       real(kind=cp), intent(in) :: x
40218       real(kind=cp)             :: xmod
40219
40220       xmod=mod(x+10.0_cp,1.0_cp)
40221
40222       return
40223    End Function Coord_ModN
40224
40225    !!--++
40226    !!--++ Function Coord_Modv(X) Result(XMod)
40227    !!--++    real(kind=cp), dimension(:), intent(in) :: x
40228    !!--++
40229    !!--++    (OVERLOADED)
40230    !!--++    Transforms reduced coordinate between 0 and 1
40231    !!--++
40232    !!--++ Update: February - 2005
40233    !!
40234    Function Coord_ModV(x) Result(Xmod)
40235       !---- Arguments ----!
40236       real(kind=cp), dimension(:), intent(in) :: x
40237       real(kind=cp), dimension(size(x))       :: xmod
40238
40239       xmod=mod(x+10.0_cp,1.0_cp)
40240
40241       return
40242    End Function Coord_ModV
40243
40244    !!----
40245    !!---- Function Distance(X0,X1,Cell or Code) Result(D)
40246    !!----    real(kind=cp), dimension(3),        intent(in) :: x0     !  In -> Point 1
40247    !!----    real(kind=cp), dimension(3),        intent(in) :: x1     !  In -> Point 2
40248    !!----    Type (Crystal_Cell_Type),           intent(in) :: Cell   !  In -> Cell parameters
40249    !!----    Or
40250    !!----    real(kind=dp), dimension(3),        intent(in) :: x0     !  In -> Point 1
40251    !!----    real(kind=dp), dimension(3),        intent(in) :: x1     !  In -> Point 2
40252    !!----    Type (Crystal_Cell_Type),           intent(in) :: Cell   !  In -> Cell parameters
40253    !!----    Or
40254    !!----    character(len=*), optional,         intent(in) :: Code
40255    !!----    real(kind=cp)                                  :: d      ! Out -> Distance
40256    !!----
40257    !!----    Calculate distance between two points.
40258    !!----       Fractional Coordinates: Use Cell
40259    !!----       Cartesian Coordiantes: Code="C" or Code=" "
40260    !!----       Spherical Coordinates: Code="S"
40261    !!----
40262    !!---- Update: February - 2005
40263    !!
40264
40265    !!--++
40266    !!--++ Function Distance_Fr(X0,X1,Celda) Result(D)
40267    !!--++    real(kind=cp), dimension(3),  intent(in) :: x0     !  In -> Point 1
40268    !!--++    real(kind=cp), dimension(3),  intent(in) :: x1     !  In -> Point 2
40269    !!--++    Type (Crystal_Cell_Type),     intent(in) :: Celda  !  In -> Cell parameters
40270    !!--++    real(kind=cp)                                  :: d      ! Put -> Distance
40271    !!--++
40272    !!--++    (OVERLOADED)
40273    !!--++    Calculate distance between two points in Fractional
40274    !!--++
40275    !!--++ Update: February - 2005
40276    !!
40277    Function Distance_Fr(X0,X1,Celda) Result(Dis)
40278       !---- Arguments ----!
40279       real(kind=cp), dimension(3), intent(in) :: x0,x1
40280       type (Crystal_Cell_Type),    intent(in) :: Celda
40281       real(kind=cp)                           :: dis
40282
40283       !---- Local Variables ----!
40284       real(kind=cp), dimension(3) :: xr
40285
40286       xr = matmul(celda%Cr_Orth_cel,x1-x0)
40287       dis=sqrt(dot_product(xr,xr))
40288
40289       return
40290    End Function Distance_Fr
40291
40292    !!--++
40293    !!--++ Function Distance_Fr_dp(X0,X1,Celda) Result(D)
40294    !!--++    real(kind=dp), dimension(3),  intent(in) :: x0     !  In -> Point 1
40295    !!--++    real(kind=dp), dimension(3),  intent(in) :: x1     !  In -> Point 2
40296    !!--++    Type (Crystal_Cell_Type),     intent(in) :: Celda  !  In -> Cell parameters
40297    !!--++    real(kind=dp)                            :: d      ! Put -> Distance
40298    !!--++
40299    !!--++    (OVERLOADED)
40300    !!--++    Calculate distance between two points in Fractional
40301    !!--++
40302    !!--++ Update: February - 2015
40303    !!
40304    Function Distance_Fr_dp(X0,X1,Celda) Result(Dis)
40305       !---- Arguments ----!
40306       real(kind=dp), dimension(3), intent(in) :: x0,x1
40307       type (Crystal_Cell_Type),    intent(in) :: Celda
40308       real(kind=dp)                           :: dis
40309
40310       !---- Local Variables ----!
40311       real(kind=dp), dimension(3) :: xr
40312
40313       xr = matmul(celda%Cr_Orth_cel,x1-x0)
40314       dis=sqrt(dot_product(xr,xr))
40315
40316       return
40317    End Function Distance_Fr_dp
40318
40319    !!--++
40320    !!--++ Function Distance_SC(X0,X1,Code) Result(D)
40321    !!--++    real(kind=cp), dimension(3),        intent(in) :: x0     !  In -> Point 1
40322    !!--++    real(kind=cp), dimension(3),        intent(in) :: x1     !  In -> Point 2
40323    !!--++    character(len=*), optional,         intent(in) :: Code
40324    !!--++    real(kind=cp)                                  :: d      ! Put -> Distance
40325    !!--++
40326    !!--++    (OVERLOADED)
40327    !!--++    Calculate distance between two points in Cartesian or Spherical
40328    !!--++    If Code =="C" or Blank or not present then the coordinates are Cartesian.
40329    !!--++    If Code =="S" then the coordinates are spherical (R, Theta, Phi).
40330    !!--++
40331    !!--++ Update: February - 2005
40332    !!
40333    Function Distance_SC(X0,X1,Code) Result(Dis)
40334       !---- Arguments ----!
40335       real(kind=cp), dimension(3), intent(in) :: x0,x1
40336       character(len=*), optional,  intent(in) :: Code
40337       real(kind=cp)                           :: dis
40338
40339       !---- Local Variables ----!
40340       real(kind=cp), dimension(3) :: xr,xi,xj
40341
40342       xr=0.0
40343       if (present(code)) then
40344          select case (code(1:1))
40345             case("S","s") ! Spherical
40346                xi(1)=x0(1)*cosd(x0(3))*sind(x0(2))  ! R * cos(Phi) * sin(Theta)
40347                xi(2)=x0(1)*sind(x0(3))*sind(x0(2))  ! R * sin(Phi) * sin(Theta)
40348                xi(3)=x0(1)*cosd(x0(2))              ! R * cos(Theta)
40349
40350                xj(1)=x1(1)*cosd(x1(3))*sind(x1(2))  ! R * cos(Phi) * sin(Theta)
40351                xj(2)=x1(1)*sind(x1(3))*sind(x1(2))  ! R * sin(Phi) * sin(Theta)
40352                xj(3)=x1(1)*cosd(x1(2))              ! R * cos(Theta)
40353
40354                xr=xi-xj
40355             case("C","c") ! Cartesian
40356                xr=x1-x0
40357          end select
40358       else
40359          !---- Cartesian ----!
40360          xr=x1-x0
40361       end if
40362       dis=sqrt(dot_product(xr,xr))
40363
40364       return
40365    End Function Distance_SC
40366
40367    !!----
40368    !!---- Function Matrix_Phithechi(Phi,Theta,Chi,Code) Result(M)
40369    !!----    real(kind=cp),                intent(in) :: Phi
40370    !!----    real(kind=cp),                intent(in) :: Theta
40371    !!----    real(kind=cp),                intent(in) :: Chi
40372    !!----    character(len=*), optional,   intent(in) :: Code
40373    !!----    real(kind=cp), dimension(3,3)            :: M    ! Put -> Active Rotation Matrix
40374    !!----
40375    !!----    Calculate the active rotation matrix corresponding to the composition
40376    !!----    of a positive rotation around z of angle Chi, followed by a positive rotation
40377    !!----    of angle Theta around the y-axis and a subsequent positive rotation of angle Phi
40378    !!----    around z. "Positive" means counter-clockwise.
40379    !!----    The matrix is M = Rz(Phi) . Ry(Theta) . Rz(Chi)
40380    !!----    The colums represent the components of the unitary vectors {u,v,w} that
40381    !!----    may be considered as an alternative orthonormal frame to the canonical {i,j,k}.
40382    !!----    Applying the matrix M to a point in {i,j,k} gives another point in {i,j,k} obtained
40383    !!----    by the successive application of the three rotations given above. The transpose
40384    !!----    (inverse) of the M-matrix, when applied to a point in {i,j,k}, gives the coordinates
40385    !!----    of the same point referred to the frame {u,v,w}. This transpose matrix corresponds
40386    !!----    to a passive (change or Cartesian frame) rotation leaving the points in the same
40387    !!----    position with respect to the  {i,j,k} frame.
40388    !!----    The matrix M when applied to a column vector containing the coordinates of a point
40389    !!----    with respect to the {u,v,w} frame provides the coordinates of the same point with
40390    !!----    respect to the {i,j,k} frame.
40391    !!----    If Code =="R" or Blank or not present then the input angles are given in radians.
40392    !!----    If Code =="D" then the input angles are given in degrees (Phi, Theta, Chi).
40393    !!----
40394    !!---- Update: February - 2005
40395    !!
40396    Function Matrix_Phithechi(Phi,Theta,Chi,Code) Result(Mt)
40397       !---- Arguments ----!
40398       real(kind=cp),                intent(in) :: Phi
40399       real(kind=cp),                intent(in) :: Theta
40400       real(kind=cp),                intent(in) :: Chi
40401       character(len=*), optional,   intent(in) :: Code
40402       real(kind=cp), dimension(3,3)            :: Mt
40403
40404       !---- Local Variables ----!
40405       real(kind=cp) :: p,t,c
40406
40407       if (present(code)) then
40408          select case (code(1:1))
40409             case("D","d") ! degrees
40410                p=Phi*to_rad
40411                t=Theta*to_rad
40412                c=Chi*to_rad
40413             case default ! radians
40414                p=Phi
40415                t=Theta
40416                c=Chi
40417          end select
40418       else
40419          !---- radians ----!
40420          p=Phi
40421          t=Theta
40422          c=Chi
40423       end if
40424       Mt(1,1)= cos(p)*cos(t)*cos(c)-sin(p)*sin(c)    !
40425       Mt(2,1)= sin(p)*cos(t)*cos(c)+cos(p)*sin(c)    !  u
40426       Mt(3,1)=-sin(t)*cos(c)                         !
40427       Mt(1,2)=-cos(p)*cos(t)*sin(c)-sin(p)*cos(c)    !
40428       Mt(2,2)=-sin(p)*cos(t)*sin(c)+cos(p)*cos(c)    !  v
40429       Mt(3,2)= sin(t)*sin(c)                         !
40430       Mt(1,3)= cos(p)*sin(t)                         !
40431       Mt(2,3)= sin(p)*sin(t)                         !  w
40432       Mt(3,3)= cos(t)                                !
40433
40434       return
40435    End Function Matrix_Phithechi
40436
40437    !!----
40438    !!---- Function Matrix_Rx(Ang,Code) Result(M)
40439    !!----    real(kind=cp),                      intent(in) :: Ang
40440    !!----    character(len=*), optional,         intent(in) :: Code
40441    !!----    real(kind=cp), dimension(3,3)                  :: M    ! Put -> Active Rotation Matrix
40442    !!----
40443    !!----    Calculate the active rotation matrix corresponding to the positive rotation
40444    !!----    of an angle Phi around the x-axis. The transpose matrix corresponds to a
40445    !!----    passive rotation that changes the orthogonal system to {u,v,w} leaving the point
40446    !!----    at the same position w.r.t. the canonical {i,j,k} frame.
40447    !!----    If Code =="R" or Blank or not present then the input angle is given in radians.
40448    !!----    If Code =="D" then the input angle is given in degrees.
40449    !!----
40450    !!---- Update: February - 2005
40451    !!
40452    Function Matrix_Rx(Ang,Code) Result(Mt)
40453       !---- Arguments ----!
40454       real(kind=cp),               intent(in) :: Ang
40455       character(len=*), optional,  intent(in) :: Code
40456       real(kind=cp), dimension(3,3)           :: Mt
40457
40458       !---- Local Variables ----!
40459       real(kind=cp) :: p
40460
40461       if (present(code)) then
40462          select case (code(1:1))
40463             case("D","d") ! degrees
40464                p=Ang*to_rad
40465             case default ! radians
40466                p=Ang
40467          end select
40468       else
40469          !---- radians ----!
40470          p=Ang
40471       end if
40472       Mt(1,1)= 1.0        !              1  0  0
40473       Mt(2,1)= 0.0        !  u           0  c -s     Rx
40474       Mt(3,1)= 0.0        !              0  s  c
40475       Mt(1,2)= 0.0        !
40476       Mt(2,2)= cos(p)     !  v
40477       Mt(3,2)= sin(p)     !
40478       Mt(1,3)= 0.0        !
40479       Mt(2,3)=-sin(p)     !  w
40480       Mt(3,3)= cos(p)     !
40481
40482       return
40483    End Function Matrix_Rx
40484
40485    !!----
40486    !!---- Function Matrix_Ry(Ang,Code) Result(M)
40487    !!----    real(kind=cp),                      intent(in) :: Ang
40488    !!----    character(len=*), optional,         intent(in) :: Code
40489    !!----    real(kind=cp), dimension(3,3)                  :: M    ! Put -> Active Rotation Matrix
40490    !!----
40491    !!----    Calculate the active rotation matrix corresponding to the positive rotation
40492    !!----    of an angle Phi around the y-axis. The transpose matrix corresponds to a
40493    !!----    passive rotation that changes the orthogonal system to {u,v,w} leaving the point
40494    !!----    at the same position w.r.t. the canonical {i,j,k} frame.
40495    !!----    If Code =="R" or Blank or not present then the input angle is given in radians.
40496    !!----    If Code =="D" then the input angle is given in degrees.
40497    !!----
40498    !!---- Update: February - 2005
40499    !!
40500    Function Matrix_Ry(Ang,Code) Result(Mt)
40501       !---- Arguments ----!
40502       real(kind=cp),               intent(in) :: Ang
40503       character(len=*), optional,  intent(in) :: Code
40504       real(kind=cp), dimension(3,3)           :: Mt
40505
40506       !---- Local Variables ----!
40507       real(kind=cp) :: p
40508
40509       if (present(code)) then
40510          select case (code(1:1))
40511             case("D","d") ! degrees
40512                p=Ang*to_rad
40513             case default ! radians
40514                p=Ang
40515          end select
40516       else
40517          !---- radians ----!
40518          p=Ang
40519       end if
40520       Mt(1,1)= cos(p)  !             c  0  s
40521       Mt(2,1)= 0.0     !  u          0  1  0      Ry
40522       Mt(3,1)=-sin(p)  !            -s  0  c
40523       Mt(1,2)= 0.0     !
40524       Mt(2,2)= 1.0     !  v
40525       Mt(3,2)= 0.0     !
40526       Mt(1,3)= sin(p)  !
40527       Mt(2,3)= 0.0     !  w
40528       Mt(3,3)= cos(p)  !
40529
40530       return
40531    End Function Matrix_Ry
40532
40533    !!----
40534    !!---- Function Matrix_Rz(Ang,Code) Result(M)
40535    !!----    real(kind=cp),                      intent(in) :: Ang
40536    !!----    character(len=*), optional,         intent(in) :: Code
40537    !!----    real(kind=cp), dimension(3,3)                  :: M    ! Put -> Active Rotation Matrix
40538    !!----
40539    !!----    Calculate the active rotation matrix corresponding to the positive rotation
40540    !!----    of an angle Phi around the z-axis. The transpose matrix corresponds to a
40541    !!----    passive rotation that changes the orthogonal system to {u,v,w} leaving the point
40542    !!----    at the same position w.r.t. the canonical {i,j,k} frame.
40543    !!----    If Code =="R" or Blank or not present then the input angle is given in radians.
40544    !!----    If Code =="D" then the input angle is given in degrees.
40545    !!----
40546    !!---- Update: February - 2005
40547    !!
40548    Function Matrix_Rz(Ang,Code) Result(Mt)
40549       !---- Arguments ----!
40550       real(kind=cp),               intent(in) :: Ang
40551       character(len=*), optional,  intent(in) :: Code
40552       real(kind=cp), dimension(3,3)           :: Mt
40553
40554       !---- Local Variables ----!
40555       real(kind=cp) :: p
40556
40557       if (present(code)) then
40558          select case (code(1:1))
40559             case("D","d") ! degrees
40560                p=Ang*to_rad
40561             case default ! radians
40562                p=Ang
40563          end select
40564       else
40565          !---- radians ----!
40566          p=Ang
40567       end if
40568       Mt(1,1)= cos(p)  !                 c  -s  0
40569       Mt(2,1)= sin(p)  !  u              s   c  0    Rz
40570       Mt(3,1)= 0.0     !                 0   0  1
40571       Mt(1,2)=-sin(p)  !
40572       Mt(2,2)= cos(p)  !  v
40573       Mt(3,2)= 0.0     !
40574       Mt(1,3)= 0.0     !
40575       Mt(2,3)= 0.0     !  w
40576       Mt(3,3)= 1.0     !
40577
40578       return
40579    End Function Matrix_Rz
40580
40581    !---------------------!
40582    !---- Subroutines ----!
40583    !---------------------!
40584
40585    !!----
40586    !!---- Subroutine Allocate_Coordination_Type(nasu,numops,dmax,Max_Coor)
40587    !!----    integer,       intent(in) :: nasu      !  In -> Number of atoms in asymmetric unit
40588    !!----    integer,       intent(in) :: numops    !  In -> Number of S.O. excluding lattice centerings
40589    !!----    real(kind=cp), intent(in) :: dmax      !  In -> Maximun distance to be calculated
40590    !!----    integer,      intent(out) :: Max_Coor  !  Maximum coordination allowed
40591    !!----
40592    !!----    Allocation of Coordination_Type.
40593    !!----    Should be called before using this module.
40594    !!----
40595    !!---- Update: March - 2005
40596    !!
40597    Subroutine Allocate_Coordination_Type(nasu,numops,dmax,Max_Coor)
40598       !---- Arguments ----!
40599       integer,       intent(in) :: nasu
40600       integer,       intent(in) :: numops
40601       real(kind=cp), intent(in) :: dmax
40602       integer,      intent(out) :: Max_Coor
40603
40604       !---- local variables ----!
40605       real(kind=cp), parameter :: r_atom=0.4_cp !Radius of a typical atom
40606
40607       if (allocated(Coord_Info%Coord_Num)) deallocate(Coord_Info%Coord_Num)
40608       if (allocated(Coord_Info%N_Cooatm))  deallocate(Coord_Info%N_Cooatm)
40609       if (allocated(Coord_Info%N_Sym))     deallocate(Coord_Info%N_Sym)
40610       if (allocated(Coord_Info%Dist))      deallocate(Coord_Info%Dist)
40611       if (allocated(Coord_Info%S_Dist))    deallocate(Coord_Info%S_Dist)
40612       if (allocated(Coord_Info%Tr_Coo))    deallocate(Coord_Info%Tr_Coo)
40613
40614
40615       max_coor= (dmax/r_atom)**3
40616       max_coor=max(max_coor,nasu*numops)
40617
40618       !---- Assigninmg the new values ----!
40619       Coord_Info%Natoms=nasu
40620       Coord_Info%Max_Coor= max_coor
40621
40622       allocate (Coord_Info%Coord_Num(nasu))
40623       allocate (Coord_Info%N_Cooatm(max_coor,nasu))
40624       allocate (Coord_Info%N_Sym(max_coor,nasu))
40625       allocate (Coord_Info%Dist(max_coor,nasu))
40626       allocate (Coord_Info%S_Dist(max_coor,nasu))
40627       allocate (Coord_Info%Tr_Coo(3,max_coor,nasu))
40628
40629       Coord_Info%Coord_Num=0
40630       Coord_Info%N_Cooatm =0
40631       Coord_Info%N_Sym    =0
40632       Coord_Info%Dist     =0.0
40633       Coord_Info%S_Dist   =0.0
40634       Coord_Info%Tr_Coo   =0.0
40635
40636       return
40637    End Subroutine Allocate_Coordination_Type
40638
40639    !!----
40640    !!---- Subroutine Allocate_Point_List(N,Pl,Ier)
40641    !!----    integer,               intent(in)     :: n      !  In -> Dimension for allocating components of the type
40642    !!----    type(point_list_type), intent(in out) :: pl     !  In Out-> Type with allocatable components
40643    !!----    integer,               intent(out)    :: ier    !  Out -> if ier /= 0 an error occurred.
40644    !!----
40645    !!----    Allocation of an objet of type Point_List_Type
40646    !!----
40647    !!---- Update: February - 2005
40648    !!
40649    Subroutine Allocate_Point_List(n,Pl,Ier)
40650       !---- Arguments ----!
40651       integer,               intent(in)     :: n
40652       type(point_list_type), intent(in out) :: pl
40653       integer,               intent(out)    :: ier
40654
40655       ier=0
40656       if (n <= 0) then
40657          ier=1
40658          return
40659       end if
40660
40661       if ( .not. allocated(pl%nam) ) allocate(pl%nam(n),stat=ier)
40662       if ( .not. allocated(pl%p) )   allocate(pl%p(n),stat=ier)
40663       if ( .not. allocated(pl%x) )   allocate(pl%x(3,n),stat=ier)
40664
40665       pl%nam= " "
40666       pl%np=0
40667       pl%p=0
40668       pl%x=0.0
40669
40670       return
40671    End subroutine Allocate_Point_List
40672
40673    !!----
40674    !!---- Subroutine Calc_Dist_Angle(Dmax, Dangl, Cell, Spg, A, Lun)
40675    !!----    real(kind=cp),            intent(in)             :: dmax   !  In -> Max. Distance to calculate
40676    !!----    real(kind=cp),            intent(in)             :: dangl  !  In -> Max. distance for angle calculations
40677    !!----    type (Crystal_cell_type), intent(in)             :: Cell   !  In -> Object of Crytal_Cell_Type
40678    !!----    type (Space_Group_type),  intent(in)             :: SpG    !  In -> Object of Space_Group_Type
40679    !!----    type (atom_list_type),   intent(in)             :: A      !  In -> Object of atom_list_type
40680    !!----    integer,                  optional, intent(in)   :: lun    !  In -> Logical Unit for writing
40681    !!----
40682    !!----    Subroutine to calculate distances and angles, below the prescribed distances
40683    !!----    "dmax" and "dangl" (angles of triplets at distance below "dangl" to an atom),
40684    !!----    without standard deviations. If dangl=0.0, no angle calculations are done.
40685    !!----    Needs as input the objects Cell (of type Crystal_cell), SpG (of type Space_Group)
40686    !!----    and A (of type atom_list, that should be allocated in the calling program).
40687    !!----    Writes results in file (unit=lun) if lun is present
40688    !!----    Control for error is present.
40689    !!----
40690    !!---- Update: February - 2005
40691    !!
40692    Subroutine Calc_Dist_Angle(Dmax, Dangl, Cell, Spg, A, Lun)
40693       !---- Arguments ----!
40694       real(kind=cp),            intent(in)   :: Dmax, Dangl
40695       type (Crystal_cell_Type), intent(in)   :: Cell
40696       type (Space_Group_Type),  intent(in)   :: SpG
40697       type (atom_list_type),    intent(in)   :: A
40698       integer, optional,        intent(in)   :: lun
40699
40700       !---- Local Variables ----!
40701       logical                            :: iprin
40702       integer                            :: i,j,k,lk,i1,i2,i3,jl,npeq,nn,L,nlines, max_coor,ico
40703       character(len= 80), dimension(12)  :: texto = " "
40704       character(len=  5)                 :: nam,nam1,nam2
40705       character(len= 40)                 :: transla
40706       character(len=160)                 :: form3
40707       character(len= 90)                 :: form2= "(a,3I4,a,a,a,a,a,f9.4,a,3F8.4,a,t85,a)"  !  JRC feb 2014 &   ! TR 4 fev. 2013
40708                                           !  "("" "",3I4,""  ("",a,"")-("",a,""):"",f9.4,""   "",3F8.4,""  "",a,""  "",a)"
40709       integer, dimension(3)              :: ic1,ic2
40710       real(kind=cp),    dimension(3)     :: xx,x1,xo,Tn,xr, QD
40711       real(kind=cp)                      :: T,dd, da1,da2,da12,cang12,ang12,cang1,ang2,ang1
40712
40713       real(kind=cp), allocatable,dimension(:,:) :: uu
40714       real(kind=cp), allocatable,dimension(:,:) :: bcoo
40715
40716       iprin=.false.
40717       if (present(lun)) then
40718          if (lun > 0) iprin=.true.
40719       end if
40720
40721       call init_err_geom()
40722
40723       call allocate_coordination_type(A%natoms,Spg%multip,Dmax,Max_coor)
40724       if(allocated(uu)) deallocate(uu)
40725       allocate(uu(3,Max_coor))
40726       if(allocated(bcoo)) deallocate(bcoo)
40727       allocate(bcoo(3,Max_coor))
40728
40729       qd(:)=1.0/cell%rcell(:)
40730       ic2(:)= nint(dmax/cell%cell(:)+2.5_cp)
40731       ic1(:)=-ic2(:)
40732       npeq=spg%numops
40733       if (dangl > epsi .and. iprin ) then
40734          form3="(""    ("",a,"")-("",a,"")-("",a,""):"",f8.3/"
40735          form3=trim(form3)//"""    ("",a,"")-("",a,"")-("",a,""):"",f8.3/"
40736          form3=trim(form3)//"""    ("",a,"")-("",a,"")-("",a,""):"",f8.3/"
40737          form3=trim(form3)//"""         ("",a,"") :"",3f8.4,""  ("",a,"") :"",3f8.4)"
40738       end if
40739
40740       if (spg%centred == 2) then
40741          npeq=2*npeq
40742          if (iprin) then
40743             write(unit=lun,fmt="(/,a)")" => Symmetry operators combined with inversion centre:"
40744             nlines=1
40745             do i=SpG%NumOps+1,npeq
40746                if (mod(i,2) == 0) then
40747                   write(unit=texto(nlines)(36:70),fmt="(a,i2,a,a)") &
40748                               " => SYMM(",i,"): ",trim(SpG%SymopSymb(i))
40749                   nlines=nlines+1
40750                else
40751                   write(unit=texto(nlines)( 1:34),fmt="(a,i2,a,a)")  &
40752                               " => SYMM(",i,"): ",trim(SpG%SymopSymb(i))
40753                end if
40754             end do
40755             do i=1,min(nlines,12)
40756                write(unit=lun,fmt="(a)") texto(i)
40757             end do
40758          end if
40759       end if
40760
40761       do i=1,a%natoms
40762          xo(:)=a%atom(i)%x(:)
40763          nam=a%atom(i)%lab
40764          if (iprin) then
40765             write(unit=lun,fmt="(/,/,a)")"    -------------------------------------------------------------------"
40766             write(unit=lun,fmt="(a,f8.4,a,a,3f8.4)")   &
40767                       "    Distances less than",dmax,"  to atom: ",nam, xo
40768             write(unit=lun,fmt="(a,/,/)")"    -------------------------------------------------------------------"
40769             write(unit=lun,fmt="(/,/,a,/,/)") & ! TR 4 fev. 2013
40770             " Orig. extr. p.equiv.           Distance      x_ext   y_ext   z_ext  (tx,ty,tz)     Sym. op."
40771          end if
40772          Coord_Info%Coord_Num(i)=0
40773          ico=0
40774          do k=1,a%natoms
40775             lk=1
40776             uu(:,lk)=xo(:)
40777             nam1=a%atom(k)%lab
40778             do j=1,npeq
40779                xx=ApplySO(Spg%SymOp(j),a%atom(k)%x)
40780                do i1=ic1(1),ic2(1)
40781                   do i2=ic1(2),ic2(2)
40782                      do i3=ic1(3),ic2(3)
40783                         do_jl:do jl=1,Spg%NumLat
40784                            Tn(:)=real((/i1,i2,i3/))+Spg%Latt_trans(:,jl)
40785                            x1(:)=xx(:)+tn(:)
40786                            do l=1,3
40787                               t=abs(x1(l)-xo(l))*qd(l)
40788                               if (t > dmax) cycle do_jl
40789                            end do
40790                            do nn=1,lk
40791                               if (sum(abs(uu(:,nn)-x1(:)))  <= epsi) cycle do_jl
40792                            end do
40793                            xr = matmul(cell%cr_orth_cel,x1-xo)
40794                            dd=sqrt(dot_product(xr,xr))
40795                            if (dd > dmax .or. dd < 0.001) cycle
40796                            ico=ico+1
40797
40798                            if (Coord_Info%Coord_Num(i) > Coord_Info%Max_Coor) then
40799                               err_geom=.true.
40800                               ERR_Geom_Mess=" => Too many distances around atom: "//nam
40801                               return
40802                            end if
40803
40804                            lk=lk+1
40805                            uu(:,lk)=x1(:)
40806                            Coord_Info%Dist(ico,i)=dd
40807                            Coord_Info%N_Cooatm(ico,i)=k
40808                            bcoo(:,ico)=x1(:)
40809                            Coord_Info%Tr_Coo(:,ico,i)=tn
40810                            if (iprin) then
40811                               call Frac_Trans_1Dig(tn,transla)
40812                               write(unit=lun,fmt=form2) " ",i,k,j,"  (",nam,")-(",nam1,"):",dd,"   ",x1(:), "  "//transla, &
40813                                                         trim(Spg%SymOpSymb(j)) !JRC Feb2014
40814                            end if
40815                         end do do_jl
40816                      end do !i3
40817                   end do !i2
40818                end do !i1
40819             end do !j
40820          end do !k
40821
40822          Coord_Info%Coord_Num(i)=ico
40823          if (dangl <= epsi) cycle     !loop on "i" still running
40824
40825          !---- Angle calculations for bonded atoms at distance lower than DANGL
40826
40827          if (iprin) then
40828                write(unit=lun,fmt="(/,/,a)")       "   -------------------------------------------------------"
40829                write(unit=lun,fmt="(a,a,3f8.4)")   "   -  Angles around atom: ",nam, xo
40830                write(unit=lun,fmt="(a,/)")         "   -------------------------------------------------------"
40831          end if
40832          do j=1,Coord_Info%Coord_Num(i)
40833             if (Coord_Info%dist(j,i) < epsi .or. Coord_Info%dist(j,i) > dangl) cycle
40834             da1=Coord_Info%dist(j,i)
40835             i1=Coord_Info%N_Cooatm(j,i)
40836             nam1=a%atom(i1)%lab
40837             do k=j+1,Coord_Info%Coord_Num(i)
40838                if (Coord_Info%dist(k,i) < epsi .OR. Coord_Info%dist(k,i) > dangl) cycle
40839                da2=Coord_Info%dist(k,i)
40840                i2=Coord_Info%N_Cooatm(k,i)
40841                nam2=a%atom(i2)%lab
40842                xx(:)=bcoo(:,k)-bcoo(:,j)
40843                xr = matmul(Cell%Cr_Orth_cel,xx)
40844                da12=sqrt(dot_product(xr,xr))
40845                cang12=0.5_cp*(da1/da2+da2/da1-da12*da12/da1/da2)
40846                ang12=acosd(cang12)
40847                cang1=0.5_cp*(da12/da2+da2/da12-da1*da1/da12/da2)
40848                ang1=acosd(cang1)
40849                ang2=180.0_cp-ang1-ang12
40850
40851                if (iprin) then
40852                    write(unit=lun,fmt="(/,3(a,f8.4))")  &
40853                         "     Atm-1   Atm-2   Atm-3            d12 =",da1,"  d23 =",da2,"   d13 =",da12
40854                    write(unit=lun,fmt=form3)  nam1,nam,nam2,ang12,   &
40855                         nam,nam2,nam1,ang1, nam,nam1,nam2,ang2,  &
40856                         nam1,bcoo(:,j),nam2, bcoo(:,k)
40857                end if
40858             end do !k
40859          end do !j
40860       end do !i
40861
40862       return
40863    End Subroutine Calc_Dist_Angle
40864
40865    !!----
40866    !!---- Subroutine Calc_Dist_Angle_Sigma(Dmax, Dangl, Cell, Spg, A, Lun, Lun_cons, Lun_cif,filen,rdmax,ramin)
40867    !!----    real(kind=cp),             intent(in)   :: dmax     !  In -> Max. Distance to calculate
40868    !!----    real(kind=cp),             intent(in)   :: dangl    !  In -> Max. distance for angle calculations
40869    !!----    type (Crystal_cell_type),  intent(in)   :: Cell     !  In -> Object of Crytal_Cell_Type
40870    !!----    type (Space_Group_type),   intent(in)   :: SpG      !  In -> Object of Space_Group_Type
40871    !!----    type (atom_list_type),     intent(in)   :: A        !  In -> Object of atom_list_type
40872    !!----    integer, optional,         intent(in)   :: lun      !  In -> Logical Unit for writing
40873    !!----    integer, optional,         intent(in)   :: lun_cons !  In -> Logical unit for writing restraints
40874    !!----    integer, optional,         intent(in)   :: lun_cif  !  In -> Logical unit for writing CIF file with distances and angles
40875    !!----    character(len=*), optional,intent(in)   :: filrest  !  In -> Name of file for writing restraints
40876    !!----    real(kind=cp),    optional,intent(in)   :: rdmax,ramin  !  Maximum distan and minimum angle for output in restraints file
40877    !!----
40878    !!----    Subroutine to calculate distances and angles, below the prescribed distances
40879    !!----    "dmax" and "dangl" (angles of triplets at distance below "dangl" to an atom),
40880    !!----    with standard deviations. If dangl=0.0, no angle calculations are done.
40881    !!----    Needs as input the objects Cell (of type Crystal_cell), SpG (of type Space_Group)
40882    !!----    and A (or type atom_list, that should be allocated in the calling program).
40883    !!----    Writes results in file (unit=lun) if the argument lun is present. In case
40884    !!----    lun_cif is provided, the program writes in the already opened CIF file (in
40885    !!----    the calling program) the items related to distances. If lun_cons is provided
40886    !!----    the program writes items containing restraints to the file CFML_restraints.tpcr
40887    !!----    or to file "filrest" if provided as argument.
40888    !!----    Control for error is present.
40889    !!----
40890    !!---- Update: February - 2005
40891    !!
40892    Subroutine Calc_Dist_Angle_Sigma(Dmax, Dangl, Cell, Spg, A, Lun, Lun_cons, Lun_cif,filrest,rdmax,ramin)
40893       !---- Arguments ----!
40894       real(kind=cp),             intent(in)   :: dmax, dangl
40895       type (Crystal_cell_Type),  intent(in)   :: Cell
40896       type (Space_Group_Type),   intent(in)   :: SpG
40897       type (Atom_list_type),     intent(in)   :: A
40898       integer, optional,         intent(in)   :: lun
40899       integer, optional,         intent(in)   :: lun_cons
40900       integer, optional,         intent(in)   :: lun_cif
40901       character(len=*), optional,intent(in)   :: filrest
40902       real(kind=cp),    optional,intent(in)   :: rdmax, ramin
40903
40904       !---- Local Variables ----!
40905       logical                            :: iprin
40906       integer,parameter                  :: nconst=500
40907       integer                            :: i,j,k,lk,i1,i2,i3,jl,nn,L,&
40908                                             itnum1,itnum2,num_const, max_coor,num_angc,ico
40909       character(len=  6)                 :: nam,nam1,nam2
40910       character(len= 40)                 :: transla
40911       character(len= 20)                 :: text,tex,texton
40912       character(len=132)                 :: line
40913       character(len=160)                 :: form3
40914       character(len= 90)                 :: form2= "(a,3i4,a,a,a,a,a,a12,3F8.4,a,t85,a)"  !  JRC feb 2014 form2= &   ! TR 4 fev. 2013
40915                                             !"("" "",3I4,""  ("",a,"")-("",a,""):"",f9.4,""   "",3F8.4,""  "",a,""  "",a)"
40916       integer, dimension(3)              :: ic1,ic2
40917       integer, dimension(192)            :: itnum
40918       real(kind=cp),dimension(3,3,6)     :: DerM
40919       real(kind=cp),    dimension(3)     :: xx,x1,xo,Tn, QD,so,ss,s1,s2,x2,tr1,tr2
40920       real(kind=cp)                      :: T,dd, da1,da2,da12,cang12,ang12,cang1,ang2,ang1,rest_d,rest_a
40921       real(kind=cp)                      :: sdd,sda1,sda2,sda12,sang12,sang2,sang1,srel1,srel2,srel12
40922
40923       real(kind=cp), allocatable, dimension(:,:) :: uu
40924       real(kind=cp), allocatable, dimension(:,:) :: bcoo
40925       real(kind=cp), allocatable, dimension(:,:) :: sbcoo
40926       real(kind=cp), allocatable, dimension(:,:) :: trcoo
40927
40928       character(len=132), dimension(:), allocatable  :: const_text
40929       character(len=132), dimension(:), allocatable  :: dist_text
40930       character(len=132), dimension(:), allocatable  :: angl_text
40931
40932       character(len=8) :: codesym
40933       logical :: esta
40934
40935       !--- write CIF ---------------------------------------------------------------------
40936       integer, parameter                             :: max_cif_dist_text = 1500
40937       integer, parameter                             :: max_cif_angl_text = 6000
40938       integer                                        :: n_cif_dist_text
40939       integer                                        :: n_cif_angl_text
40940       character (len=12)                             :: CIF_bond_site_symm_2
40941       character (len=12)                             :: CIF_angle_site_symm_1
40942       character (len=12)                             :: CIF_angle_site_symm_3
40943       character (len=132), dimension(:), allocatable :: cif_dist_text
40944       character (len=132), dimension(:), allocatable :: cif_angl_text
40945       !-----------------------------------------------------------------------------------
40946
40947
40948       iprin=.false.
40949       if (present(lun)) then
40950          if (lun > 0) iprin=.true.
40951       end if
40952       rest_d=dmax
40953       rest_a=45.0
40954       if(present(rdmax)) rest_d=rdmax
40955       if(present(ramin)) rest_a=ramin
40956       call init_err_geom()
40957       call Allocate_Coordination_Type(A%natoms,Spg%Multip,Dmax,max_coor)
40958
40959       if(allocated(uu)) deallocate(uu)
40960       allocate(uu(3,max_coor))
40961       if(allocated(bcoo)) deallocate(bcoo)
40962       allocate(bcoo(3,max_coor))
40963       if(allocated(sbcoo)) deallocate(sbcoo)
40964       allocate(sbcoo(3,max_coor))
40965       if(allocated(trcoo)) deallocate(trcoo)
40966       allocate(trcoo(3,max_coor))
40967
40968
40969       call get_deriv_Orth_cell(cell,DerM,"A")
40970
40971       if (present(lun_cons)) then
40972          num_angc=0
40973          num_const=0
40974          if(present(filrest)) then
40975            open (unit=lun_cons, file=trim(filrest), status="replace", action="write")
40976          else
40977            open (unit=lun_cons, file="CFML_Restraints.tpcr", status="replace", action="write")
40978          end if
40979          write(unit=lun_cons,fmt="(a)") " FILE with lines for soft distance and angle constraints (restraints)."
40980          write(unit=lun_cons,fmt="(a)") " It is intended to help editing PCR files with restraints by pasting, "
40981          write(unit=lun_cons,fmt="(a)") " after correcting the values as wished, to the appropriate lines.  "
40982          write(unit=lun_cons,fmt="(a)") " Lines with repeated identical distances have been excluded because symmetry "
40983          write(unit=lun_cons,fmt="(a)") " already force a hard constraint."
40984          write(unit=lun_cons,fmt="(a)") " Accidental coincidences have also been excluded, check that in list of distances! "
40985          write(unit=lun_cons,fmt="(/,a)")   " Warning! "
40986          write(unit=lun_cons,fmt="(a,/,a/)") " Symmetry constrained angles have not been eliminated,",&
40987                                              " this has to be performed by hand!"
40988
40989          !---- Set ITnum ----!
40990          i=0
40991          i1=1
40992          i2=24
40993          if (spg%hexa) then
40994             i1=25
40995             i2=36
40996          end if
40997          do j=1,Spg%multip
40998             call searchop(SpG%Symop(j)%Rot(:,:),i1,i2,i)
40999             Itnum(j)=i
41000          end do
41001          if (allocated(const_text)) deallocate(const_text)
41002          allocate(const_text(nconst)) !Maximum number of restraints
41003          const_text(:)(1:132)=" "
41004          if (allocated(dist_text)) deallocate(dist_text)
41005          allocate(dist_text(nconst)) !Maximum number of restraints
41006          dist_text(:)(1:132)=" "
41007          if (allocated(angl_text)) deallocate(angl_text)
41008          allocate(angl_text(nconst)) !Maximum number of restraints
41009          angl_text(:)(1:132)=" "
41010       end if
41011
41012       if (present(lun_cif)) then
41013          write(unit=lun_cif, fmt='(a)') " "
41014          write(unit=lun_cif, fmt='(a)') "#=============================================================================#"
41015          write(unit=lun_cif, fmt='(a)') "#                      UNIT CELL INFORMATION                                  #"
41016          write(unit=lun_cif, fmt='(a)') "#=============================================================================#"
41017          write(unit=lun_cif, fmt='(a)') "_symmetry_cell_setting                "//trim(SPG%CrystalSys)
41018          write(unit=lun_cif, fmt='(a)') "_symmetry_space_group_name_H-M       '"//trim(SPG%SPG_symb)//"'"
41019          write(unit=lun_cif, fmt='(a)') "_symmetry_space_group_name_Hall      '"//trim(SPG%Hall)//"'"
41020          write(unit=lun_cif, fmt='(a)') " "
41021          write(unit=lun_cif, fmt='(a)') "loop_"
41022          write(unit=lun_cif, fmt='(a)') "    _symmetry_equiv_pos_as_xyz   #<--must include 'x,y,z'"
41023
41024          do i=1,SPG%multip
41025             write(unit=lun_cif, fmt='(a)') "'"//trim(SPG%SymopSymb(i))//"'"
41026          end do
41027          write(unit=lun_cif, fmt='(a)') " "
41028
41029          write(unit=lun_cif, fmt='(a)') "#=============================================================================#"
41030          write(unit=lun_cif, fmt='(a)') "#                       MOLECULAR GEOMETRY                                    #"
41031          write(unit=lun_cif, fmt='(a)') "#=============================================================================#"
41032
41033          if (allocated(CIF_dist_text)) deallocate(CIF_dist_text)
41034          allocate(CIF_dist_text(max_cif_dist_text)) !Maximum number of distances
41035          CIF_dist_text(:)(1:132)=" "
41036          if (allocated(CIF_angl_text)) deallocate(CIF_angl_text)
41037          allocate(CIF_angl_text(max_cif_angl_text)) !Maximum number of angles
41038          CIF_angl_text(:)(1:132)=" "
41039          n_cif_dist_text = 0
41040          n_cif_angl_text = 0
41041       end if
41042
41043       qd(:)=1.0/cell%rcell(:)
41044       ic2(:)= nint(dmax/cell%cell(:)+2.5_cp)
41045       ic1(:)=-ic2(:)
41046       if (dangl > epsi .and. iprin ) then
41047          form3=            "(""    ("",a,"")-("",a,"")-("",a,""):"",a12/"
41048          form3=trim(form3)//"""    ("",a,"")-("",a,"")-("",a,""):"",a12/"
41049          form3=trim(form3)//"""    ("",a,"")-("",a,"")-("",a,""):"",a12/"
41050          form3=trim(form3)//"""         ("",a,"") :"",3f9.5,""  ("",a,"") :"",3f9.5)"
41051       end if
41052       do i=1,a%natoms
41053          xo(:)=a%atom(i)%x(:)
41054          so(:)=a%atom(i)%x_std(:)
41055          nam=a%atom(i)%lab
41056          Select Case (len_trim(nam))
41057             case(1)
41058                nam="  "//trim(nam)
41059             case(2:5)
41060                nam=" "//trim(nam)
41061          End Select
41062          if (iprin) then
41063             write(unit=lun,fmt="(/,/,a)")"    -------------------------------------------------------------------"
41064             write(unit=lun,fmt="(a,f8.4,a,a,3f8.4)")   &
41065                       "    Distances less than",dmax,"  to atom: ",nam, xo
41066             write(unit=lun,fmt="(a,/,/)")"    -------------------------------------------------------------------"
41067             write(unit=lun,fmt="(/,/,a,/,/)") &		! TR 4 fev. 2013
41068                  " Orig. extr. p.equiv.           Distance      x_ext   y_ext   z_ext  (tx,ty,tz)     Sym. op."
41069          end if
41070
41071          ico=0
41072          do k=1,a%natoms
41073             lk=1
41074             uu(:,lk)=xo(:)
41075             nam1=a%atom(k)%lab
41076             Select Case (len_trim(nam1))
41077               case(1)
41078                  nam1="  "//trim(nam1)
41079               case(2:5)
41080                  nam1=" "//trim(nam1)
41081             End Select
41082             ss(:)=A%atom(k)%x_std(:)
41083             do j=1,Spg%Multip
41084                xx=ApplySO(Spg%SymOp(j),a%atom(k)%x)
41085
41086                do i1=ic1(1),ic2(1)
41087                   do i2=ic1(2),ic2(2)
41088                      do_i3:do i3=ic1(3),ic2(3)
41089
41090                            Tn(:)=real((/i1,i2,i3/))
41091                            x1(:)=xx(:)+tn(:)
41092                            do l=1,3
41093                               t=abs(x1(l)-xo(l))*qd(l)
41094                               if (t > dmax) cycle  do_i3
41095                            end do
41096                            do nn=1,lk
41097                               if (sum(abs(uu(:,nn)-x1(:)))  <= epsi) cycle  do_i3
41098                            end do
41099                            call distance_and_sigma(Cell,DerM,xo,x1,so,ss,dd,sdd)
41100                            if (dd > dmax .or. dd < 0.001) cycle
41101                            ico=ico+1
41102                            if (Coord_Info%Coord_Num(i) > Coord_Info%Max_Coor) then
41103                               err_geom=.true.
41104                               ERR_Geom_Mess=" => Too many distances around atom: "//nam
41105                               return
41106                            end if
41107                            lk=lk+1
41108                            uu(:,lk)=x1(:)
41109
41110                            Coord_Info%Dist(ico,i)=dd
41111                            Coord_Info%S_Dist(ico,i)=sdd
41112                            Coord_Info%N_Cooatm(ico,i)=k
41113                            Coord_Info%N_sym(ico,i)=j
41114                            Coord_Info%Tr_Coo(:,ico,i)=tn
41115
41116                            bcoo(:,ico)=x1(:)
41117                            sbcoo(:,ico)=ss(:)
41118                            trcoo(:,ico)=Tn(:)
41119                            if (iprin) then
41120                               call Frac_Trans_1Dig(tn,transla)
41121                               call setnum_std(dd,sdd,text)
41122                               !write(unit=lun,fmt=form2) i,k,j,nam,nam1,dd,x1(:), transla, trim(Spg%SymOpSymb(j))! TR 4 fev. 2013
41123                               write(unit=lun,fmt=form2) " ",i,k,j,"  (",nam,")-(",nam1,"):",text,x1(:), "  "//transla, &
41124                                                         trim(Spg%SymOpSymb(j)) !JRC Feb2014
41125                            end if
41126
41127                            if(present(lun_cons) .and. dd <= rest_d) then
41128                              esta=.false.
41129                              write(unit=line,fmt="(a4,tr2,a4,i5,3f10.5,tr5,2f7.4)") A%atom(i)%lab ,A%atom(k)%lab ,&
41130                                     Itnum(j), tn(:)+SpG%Symop(j)%tr(:) ,dd, sdd
41131                              if(num_const == 0) then
41132                                const_text(1)=line(1:132)
41133                                num_const=1
41134                                write(unit=dist_text(1),fmt="(a,2f9.5,a)") "DFIX ",dd,sdd, &
41135                                                                           "  "//trim(A%atom(i)%lab)//"  "//trim(A%atom(k)%lab)
41136                                call Write_SymTrans_Code(j,tn,codesym)
41137                                dist_text(1)=trim(dist_text(1))//codesym
41138                              else
41139                                do l=num_const,1,-1
41140                                 if( (line(1:4) == const_text(l)(1:4) .and. line(7:10) == const_text(l)(7:10)) .or. &
41141                                     (line(1:4) == const_text(l)(7:10) .and. line(7:10) == const_text(l)(1:4)) ) then
41142                                   if(line(51:132) == const_text(l)(51:132)) then
41143                                        esta=.true.
41144                                        exit
41145                                   end if
41146                                 end if
41147                                end do
41148                                if(.not. esta) then
41149                                  num_const=num_const+1
41150                                  if(num_const > NCONST) then
41151                                     num_const=num_const-1
41152                                  end if
41153                                  const_text(num_const)=line(1:132)
41154                                  write(unit=dist_text(num_const),fmt="(a,2f9.5,a)") "DFIX ",dd,sdd,&
41155                                        "  "//trim(A%atom(i)%lab)//"  "//trim(A%atom(k)%lab)
41156                                  call Write_SymTrans_Code(j,tn,codesym)
41157                                  dist_text(num_const)=trim(dist_text(num_const))//trim(codesym)
41158                                end if
41159                              end if
41160                            end if
41161
41162                            if(present(lun_cif) .and. n_cif_dist_text < max_cif_dist_text) then
41163                               call setnum_std(dd,sdd,text)
41164                               n_cif_dist_text = n_cif_dist_text + 1
41165
41166                               !if(i1==0 .and. i2==0 .and. i3==0 .and. j==1) then
41167                               ! write(unit=CIF_bond_site_symm_2, fmt='(a)') "       . ?"
41168                               !else
41169                                write(unit=CIF_bond_site_symm_2, fmt='(a,i3, a, 3i1,a)') " ", j, "_", nint(tn+5.0), " ?"
41170                               !end if
41171
41172                               write(unit=CIF_dist_text(n_cif_dist_text), fmt='(6a)') &
41173                                     A%atom(i)%lab(1:4), "  ", A%atom(k)%lab(1:4), " ", text(1:12), CIF_bond_site_symm_2
41174                            end if
41175                      end do do_i3 !i3
41176                   end do !i2
41177                end do !i1
41178             end do !j
41179          end do !k
41180
41181          Coord_Info%Coord_Num(i)=ico
41182          if (dangl <= epsi) cycle     !loop on "i" still running
41183
41184          !---- Angle calculations for bonded atoms at distance lower than DANGL
41185          if (present(lun_cons)) write(unit=lun_cons,fmt="(a,a)")"=> Help for possible angle restraints around atom ",A%atom(i)%lab
41186
41187          if (iprin) then
41188             write(unit=lun,fmt="(/,/,a)")       "   -------------------------------------------------------"
41189             write(unit=lun,fmt="(a,a,3f8.4)")   "   -  Angles around atom: ",nam, xo
41190             write(unit=lun,fmt="(a,/)")         "   -------------------------------------------------------"
41191          end if
41192          do j=1,Coord_Info%Coord_Num(i)
41193             if (Coord_Info%Dist(j,i) < epsi .or. Coord_Info%Dist(j,i) > dangl) cycle
41194             da1=Coord_Info%Dist(j,i)
41195             sda1=Coord_Info%S_Dist(j,i)
41196             i1=Coord_Info%N_Cooatm(j,i)
41197             nam1=a%atom(i1)%lab
41198             Select Case (len_trim(nam1))
41199               case(1)
41200                  nam1="  "//trim(nam1)
41201               case(2:5)
41202                  nam1=" "//trim(nam1)
41203             End Select
41204             if (present(lun_cons)) then
41205               itnum1=itnum(Coord_Info%N_sym(j,i))
41206               tr1(:)=trcoo(:,j)+SpG%Symop(Coord_Info%N_sym(j,i))%tr(:)
41207             end if
41208             do k=j+1,Coord_Info%Coord_Num(i)
41209                if (Coord_Info%Dist(k,i) < epsi .OR. Coord_Info%Dist(k,i) > dangl) cycle
41210                da2=Coord_Info%Dist(k,i)
41211                sda2=Coord_Info%S_Dist(k,i)
41212                i2=Coord_Info%N_Cooatm(k,i)
41213                nam2=a%atom(i2)%lab
41214                Select Case (len_trim(nam2))
41215                  case(1)
41216                     nam2="  "//trim(nam2)
41217                  case(2:5)
41218                     nam2=" "//trim(nam2)
41219                End Select
41220                if (present(lun_cons)) then
41221                  itnum2=itnum(Coord_Info%N_sym(k,i))
41222                  tr2(:)=trcoo(:,k)+SpG%Symop(Coord_Info%N_sym(k,i))%tr(:)
41223                end if
41224                x1(:)=bcoo(:,k)
41225                x2(:)=bcoo(:,j)
41226                s1(:)=sbcoo(:,k)
41227                s2(:)=sbcoo(:,j)
41228                call distance_and_sigma(Cell,derM,x1,x2,s1,s2,da12,sda12)
41229                if( da12 < 0.0001) cycle
41230
41231                cang12=0.5_cp*(da1/da2+da2/da1-da12*da12/da1/da2)
41232                ang12=ACOSd(cang12)
41233                cang1=0.5_cp*(da12/da2+da2/da12-da1*da1/da12/da2)
41234                ang1=ACOSd(cang1)
41235                ang2=180.0_cp-ang1-ang12
41236
41237               ! if(abs(abs(cang12)-1.0) < 0.0001) then
41238               !   sang12=0.0
41239               ! else
41240               !  dcang121=(1.0/da2-cang12/da1)**2
41241               !  dcang122=(1.0/da1-cang12/da2)**2
41242               !  dcang1212=(da12/da2/da1)**2
41243               !  sang12=sqrt((dcang121*sda1**2+dcang122*sda2**2+dcang1212*sda12**2)/(1.0-cang12**2))*to_deg
41244               ! end if
41245               ! if(abs(abs(cang1)-1.0) < 0.0001) then
41246               !   sang1=0.0
41247               ! else
41248               !  dcang112=(1.0/da2-cang1/da12)**2
41249               !  dcang12=(1.0/da12-cang1/da2)**2
41250               !  dcang11=(da1/da2/da12)**2
41251               !  sang1=sqrt((dcang11*sda1**2+dcang12*sda2**2+dcang112*sda12**2)/(1.0-cang1**2))*to_deg
41252               ! end if
41253               ! sang2=sqrt(sang1**2+sang12**2)
41254
41255
41256                !---- Alternative calculation of angles' sigmas ----!
41257                srel1=(sda1/da1)**2
41258                srel12=(sda12/da12)**2
41259                srel2=(sda2/da2)**2
41260                sang12=SQRT(srel1+srel2+(sda12*da12/da1/da2)**2)*to_deg
41261                sang1=SQRT(srel12+srel2+(sda1*da1/da2/da12)**2)*to_deg
41262                sang2=SQRT(srel12+srel1+(sda2*da2/da1/da12)**2)*to_deg
41263
41264                if (iprin) then
41265                   call setnum_std(da1,sda1,tex)
41266                   call setnum_std(da2,sda2,text)
41267                   call setnum_std(da12,sda12,texton)
41268                   write(unit=lun,fmt="(/,a,3a21)")  &
41269                        "     Atm-1   Atm-2   Atm-3           "," d12 ="//tex,"  d23 ="//text,"   d13 ="//texton
41270                   call setnum_std(ang12,sang12,tex)
41271                   call setnum_std(ang1,sang1,text)
41272                   call setnum_std(ang2,sang2,texton)
41273                   write(unit=lun,fmt=form3)  nam1,nam,nam2,tex,    &
41274                                              nam,nam2,nam1,text,   &
41275                                              nam,nam1,nam2,texton, &
41276                                              nam1,bcoo(:,j),  nam2, bcoo(:,k)
41277                end if
41278
41279                if (present(lun_cons)) then
41280
41281                  if(ang2 >= rest_a) &
41282                  write(unit=lun_cons,fmt="(3(a6,tr1),i3,i4,tr1,3f8.4,tr1,3f8.4,2f7.2)") &
41283                  A%atom(i)%lab ,nam1 ,nam2 ,itnum1,itnum2,tr1(:),tr2(:),ang2,sang2
41284
41285                  if(ang1 >= rest_a) &
41286                  write(unit=lun_cons,fmt="(3(a6,tr1),i3,i4,tr1,3f8.4,tr1,3f8.4,2f7.2)") &  !Another angle of the same triangle
41287                  A%atom(i)%lab ,nam2 ,nam1 ,itnum2,itnum1,tr2(:),tr1(:),ang1,sang1
41288
41289                  if(ang12 >= rest_a .and. itnum1==1 .and. sum(abs(tr1)) < 0.001) & !Good constraint
41290                  write(unit=lun_cons,fmt="(3(a6,tr1),i3,i4,tr1,3f8.4,tr1,3f8.4,2f7.2)") &
41291                  adjustl(nam1),A%atom(i)%lab ,nam2 ,itnum1,itnum2,tr1(:),tr2(:),ang12,sang12
41292
41293                  if(ang12 >= rest_a .and. itnum2==1 .and. sum(abs(tr2)) < 0.001) & !Good constraint
41294                  write(unit=lun_cons,fmt="(3(a6,tr1),i3,i4,tr1,3f8.4,tr1,3f8.4,2f7.2)") &  !Another angle of the same triangle
41295                  adjustl(nam2)," "//A%atom(i)%lab ,nam1 ,itnum2,itnum1,tr2(:),tr1(:),ang12,sang12
41296
41297                  if(num_angc == 0) then
41298
41299                    if(ang2 >= rest_a) then
41300                      num_angc=num_angc+1
41301                      line=" "
41302                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang2,sang2,&
41303                                                         "  "//trim(A%atom(i)%lab)//" "//trim(nam1)
41304                      call Write_SymTrans_Code(Coord_Info%N_sym(j,i),trcoo(:,j),codesym)
41305                      line=trim(line)//trim(codesym)//" "//trim(nam2)
41306                      call Write_SymTrans_Code(Coord_Info%N_sym(k,i),trcoo(:,k),codesym)
41307                      line=trim(line)//trim(codesym)
41308                      angl_text(1)=line(1:132)
41309                    end if
41310                    !Repeating with another angle of the same triangle
41311                    if(ang1 >= rest_a) then
41312                      num_angc=num_angc+1
41313                      line=" "
41314                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang1,sang1,&
41315                                                         "  "//trim(A%atom(i)%lab)//" "//trim(nam2)
41316                      call Write_SymTrans_Code(Coord_Info%N_sym(k,i),trcoo(:,k),codesym)
41317                      line=trim(line)//trim(codesym)//" "//trim(nam1)
41318                      call Write_SymTrans_Code(Coord_Info%N_sym(j,i),trcoo(:,j),codesym)
41319                      line=trim(line)//trim(codesym)
41320                      angl_text(num_angc)=line(1:132)
41321                    end if
41322
41323                    if(ang12 >= rest_a .and. itnum1==1 .and. sum(abs(tr1)) < 0.001) then
41324                      num_angc=num_angc+1
41325                      line=" "
41326                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang12,sang12,&
41327                                                         " "//trim(nam1)//"  "//trim(A%atom(i)%lab)
41328                      call Write_SymTrans_Code(1,(/0.0,0.0,0.0/),codesym)
41329                      line=trim(line)//trim(codesym)//" "//trim(nam2)
41330                      call Write_SymTrans_Code(Coord_Info%N_sym(k,i),trcoo(:,k),codesym)
41331                      line=trim(line)//trim(codesym)
41332                      angl_text(num_angc)=line(1:132)
41333                    end if
41334
41335                    if(ang12 >= rest_a .and. itnum2==1 .and. sum(abs(tr2)) < 0.001) then
41336                      num_angc=num_angc+1
41337                      line=" "
41338                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang12,sang12,&
41339                                                         " "//trim(nam2)//"  "//trim(A%atom(i)%lab)
41340                      call Write_SymTrans_Code(1,(/0.0,0.0,0.0/),codesym)
41341                      line=trim(line)//trim(codesym)//" "//trim(nam1)
41342                      call Write_SymTrans_Code(Coord_Info%N_sym(j,i),trcoo(:,j),codesym)
41343                      line=trim(line)//trim(codesym)
41344                      angl_text(num_angc)=line(1:132)
41345                    end if
41346
41347                  else
41348
41349                    if(ang2 >= rest_a) then
41350                      line=" "
41351                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang2,sang2,&
41352                                                         "  "//trim(A%atom(i)%lab)//" "//trim(nam1)
41353                      call Write_SymTrans_Code(Coord_Info%N_sym(j,i),trcoo(:,j),codesym)
41354                      line=trim(line)//trim(codesym)//" "//trim(nam2)
41355                      call Write_SymTrans_Code(Coord_Info%N_sym(k,i),trcoo(:,k),codesym)
41356                      line=trim(line)//trim(codesym)
41357
41358                      esta=.false.
41359                      jl=index(line,"_")
41360                      if(jl == 0) jl=len_trim(line)
41361                      do l=num_angc,1,-1
41362                       if( line(1:jl) == angl_text(l)(1:jl)) then
41363                           esta=.true.
41364                           exit
41365                       end if
41366                      end do
41367                      if(.not. esta) then
41368                        num_angc=num_angc+1
41369                        if(num_angc > NCONST) num_angc=NCONST
41370                        angl_text(num_angc)=line(1:132)
41371                      end if
41372                    end if
41373
41374                    if(ang1 >= rest_a) then
41375                      !Repeating with another angle of the same triangle
41376                      line=" "
41377                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang1,sang1,&
41378                                                         "  "//trim(A%atom(i)%lab)//" "//trim(nam2)
41379                      call Write_SymTrans_Code(Coord_Info%N_sym(k,i),trcoo(:,k),codesym)
41380                      line=trim(line)//trim(codesym)//" "//trim(nam1)
41381                      call Write_SymTrans_Code(Coord_Info%N_sym(j,i),trcoo(:,j),codesym)
41382                      line=trim(line)//trim(codesym)
41383
41384                      esta=.false.
41385                      jl=index(line,"_")
41386                      if(jl == 0) jl=len_trim(line)
41387                      do l=num_angc,1,-1
41388                       if( line(1:jl) == angl_text(l)(1:jl)) then
41389                           esta=.true.
41390                           exit
41391                       end if
41392                      end do
41393                      if(.not. esta) then
41394                        num_angc=num_angc+1
41395                        if(num_angc > NCONST) num_angc=NCONST
41396                        angl_text(num_angc)=line(1:132)
41397                      end if
41398                    end if
41399
41400                    if(ang12 >= rest_a .and. itnum1==1 .and. sum(abs(tr1)) < 0.001) then
41401                      !Repeating with another angle of the same triangle
41402                      line=" "
41403                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang12,sang12,&
41404                                                          " "//trim(nam1)//"  "//trim(A%atom(i)%lab)
41405                      call Write_SymTrans_Code(1,(/0.0,0.0,0.0/),codesym)
41406                      line=trim(line)//trim(codesym)//" "//trim(nam2)
41407                      call Write_SymTrans_Code(Coord_Info%N_sym(k,i),trcoo(:,k),codesym)
41408                      line=trim(line)//trim(codesym)
41409
41410                      esta=.false.
41411                      jl=index(line,"_")
41412                      if(jl == 0) jl=len_trim(line)
41413                      do l=num_angc,1,-1
41414                       if( line(1:jl) == angl_text(l)(1:jl)) then
41415                           esta=.true.
41416                           exit
41417                       end if
41418                      end do
41419                      if(.not. esta) then
41420                        num_angc=num_angc+1
41421                        if(num_angc > NCONST) num_angc=NCONST
41422                        angl_text(num_angc)=line(1:132)
41423                      end if
41424                    end if
41425
41426                    if(ang12 >= rest_a .and. itnum1==2 .and. sum(abs(tr2)) < 0.001) then
41427                      !Repeating with another angle of the same triangle
41428                      line=" "
41429                      write(unit=line,fmt="(a,2f9.3,a)") "AFIX ",ang12,sang12,&
41430                                                          " "//trim(nam2)//"  "//trim(A%atom(i)%lab)
41431                      call Write_SymTrans_Code(1,(/0.0,0.0,0.0/),codesym)
41432                      line=trim(line)//trim(codesym)//" "//trim(nam1)
41433                      call Write_SymTrans_Code(Coord_Info%N_sym(j,i),trcoo(:,j),codesym)
41434                      line=trim(line)//trim(codesym)
41435
41436                      esta=.false.
41437                      jl=index(line,"_")
41438                      if(jl == 0) jl=len_trim(line)
41439                      do l=num_angc,1,-1
41440                       if( line(1:jl) == angl_text(l)(1:jl)) then
41441                           esta=.true.
41442                           exit
41443                       end if
41444                      end do
41445                      if(.not. esta) then
41446                        num_angc=num_angc+1
41447                        if(num_angc > NCONST) num_angc=NCONST
41448                        angl_text(num_angc)=line(1:132)
41449                      end if
41450                    end if
41451
41452                  end if
41453
41454                end if !present(lun_cons)
41455
41456                if (present(lun_cif) .and. n_cif_angl_text < max_cif_angl_text .and. ang12 > 45.0) then
41457                   !--- Change: I have included the condition ang12 > 45 for selecting the angle to write in
41458                   !            the CIF file, normally the angles below that value are irrelevant from the
41459                   !            chemical point of view.
41460                   ! j: indice de l'operateur de symetrie pour atome 1 ----! No!, Now j and k correspond to indices
41461                   ! k: indice de l'operateur de symetrie pour atome 2 ----!      running on coordination around atom i!
41462                   ! tr1: translation associee a op_j ----No!      =>  trcoo(:,j)!
41463                   ! tr2: translation associee a op_k ?  ----No!   =>  trcoo(:,k)!
41464                   n_cif_angl_text = n_cif_angl_text + 1
41465
41466                   !  The commented lines correspond to wrong selections of translations!!!!!!!
41467                   !  Moreover the indices j and k were taken as the ordinal numbers of the
41468                   !  symmetry operators and that's not true!
41469                   !if (j==1 .and. nint(tr1(1))==0 .and. nint(tr1(2))==0 .and. nint(tr1(3))==0) then
41470                   !   write(unit=CIF_angle_site_symm_1, fmt='(a)') "       ."
41471                   !else
41472                   !   write(unit=CIF_angle_site_symm_1, fmt='(a,i3, a, 3I1)') " ", j, "_",  &
41473                   !         nint(tr1(1)+5.0), nint(tr1(2)+5.0), nint(tr1(3)+5.0)
41474                   !end if
41475                   !if (k==1 .and. nint(tr2(1))==0 .and. nint(tr2(2))==0 .and. nint(tr2(3))==0) then
41476                   !   write(unit=CIF_angle_site_symm_3, fmt='(a)') "  .  ?"
41477                   !else
41478                   !   write(unit=CIF_angle_site_symm_3, fmt='(a,i3, a, 3I1,a)') " ", k, "_", &
41479                   !         nint(tr2(1)+5.0), nint(tr2(2)+5.0), nint(tr2(3)+5.0), " ?"
41480                   !end if
41481
41482                   write(unit=CIF_angle_site_symm_1, fmt='(a,i3, a, 3I1)') " ", &
41483                         Coord_Info%N_sym(j,i), "_", nint(trcoo(:,j)+5.0)
41484                   write(unit=CIF_angle_site_symm_3, fmt='(a,i3, a, 3I1,a)') " ", &
41485                         Coord_Info%N_sym(k,i), "_", nint(trcoo(:,k)+5.0), " ?"
41486
41487                   write(unit=CIF_angl_text(n_cif_angl_text), fmt='(10a)')        &
41488                         nam1(1:4)," ", nam(1:4), " ",nam2, tex(1:12), " ",       &
41489                         trim(CIF_angle_site_symm_1), " ", trim(CIF_angle_site_symm_3)
41490
41491                end if
41492             end do !k
41493          end do !j
41494       end do !i
41495
41496       if (present(lun_cons)) then
41497          write(unit=lun_cons,fmt="(/,a,i5)")"=> Total number of independent distances: ",num_const
41498          write(unit=lun_cons,fmt="(a,/)")   "   List of possible restraints: "
41499          write(unit=lun_cons,fmt="(a)")" At1   At2  ITnum     T1        T2        T3          DIST   SIGMA"
41500          do i=1,num_const
41501             write(unit=lun_cons,fmt="(2x,a)") trim(const_text(i))
41502          end do
41503
41504          write(unit=lun_cons,fmt="(/,a)")   "   ========================================= "
41505          write(unit=lun_cons,fmt="(a  )")   "   List of possible restraints in CFL format "
41506          write(unit=lun_cons,fmt="(a,/)")   "   ========================================= "
41507
41508
41509          write(unit=lun_cons,fmt="(/a,i5)")"=> Total number of independent distance restraints: ",num_const
41510          do i=1,num_const
41511             write(unit=lun_cons,fmt="(a)") trim(dist_text(i))
41512          end do
41513          write(unit=lun_cons,fmt="(/a,i5)")"=> Total number of possible angle restraints: ",num_angc
41514          do i=1,num_angc
41515             write(unit=lun_cons,fmt="(a)") trim(angl_text(i))
41516          end do
41517          close(unit=lun_cons)
41518       end if
41519
41520       if (present(lun_cif)) then
41521          if (n_CIF_dist_text /=0) then
41522             write(unit=lun_cif, fmt='(a)') "loop_"
41523             write(unit=lun_cif, fmt='(a)') "   _geom_bond_atom_site_label_1"
41524             write(unit=lun_cif, fmt='(a)') "   _geom_bond_atom_site_label_2"
41525             write(unit=lun_cif, fmt='(a)') "   _geom_bond_distance"
41526             write(unit=lun_cif, fmt='(a)') "   _geom_bond_site_symmetry_2"
41527             write(unit=lun_cif, fmt='(a)') "   _geom_bond_publ_flag"
41528
41529             do i=1, n_CIF_dist_text
41530                write(unit=lun_CIF, fmt='(a)') trim(CIF_dist_text(i))
41531             end do
41532          end if
41533
41534          if (n_CIF_angl_text /=0) then
41535             write(unit=lun_cif, fmt='(a)') ""
41536             write(unit=lun_cif, fmt='(a)') "loop_"
41537             write(unit=lun_cif, fmt='(a)') "   _geom_angle_atom_site_label_1"
41538             write(unit=lun_cif, fmt='(a)') "   _geom_angle_atom_site_label_2"
41539             write(unit=lun_cif, fmt='(a)') "   _geom_angle_atom_site_label_3"
41540             write(unit=lun_cif, fmt='(a)') "   _geom_angle"
41541             write(unit=lun_cif, fmt='(a)') "   _geom_angle_site_symmetry_1"
41542             write(unit=lun_cif, fmt='(a)') "   _geom_angle_site_symmetry_3"
41543             write(unit=lun_cif, fmt='(a)') "   _geom_angle_publ_flag"
41544
41545             do i=1, n_CIF_angl_text
41546              write(unit=lun_CIF, fmt='(a)') trim(CIF_angl_text(i))
41547             end do
41548          end if
41549       end if
41550
41551       return
41552    End Subroutine Calc_Dist_Angle_Sigma
41553
41554    !!----
41555    !!---- Subroutine Deallocate_Coordination_Type()
41556    !!----
41557    !!----    Deallocation of Coordination_Type.
41558    !!----
41559    !!---- Update: March - 2005
41560    !!
41561    Subroutine Deallocate_Coordination_Type()
41562
41563       if (allocated(Coord_Info%Coord_Num)) deallocate(Coord_Info%Coord_Num)
41564       if (allocated(Coord_Info%N_Cooatm))  deallocate(Coord_Info%N_Cooatm)
41565       if (allocated(Coord_Info%N_Sym))     deallocate(Coord_Info%N_Sym)
41566       if (allocated(Coord_Info%Dist))      deallocate(Coord_Info%Dist)
41567       if (allocated(Coord_Info%S_Dist))    deallocate(Coord_Info%S_Dist)
41568       if (allocated(Coord_Info%Tr_Coo))    deallocate(Coord_Info%Tr_Coo)
41569
41570       !---- Assigninmg the new values ----!
41571       Coord_Info%Natoms=0
41572       Coord_Info%Max_Coor= 0
41573
41574       return
41575    End Subroutine Deallocate_Coordination_Type
41576
41577    !!----
41578    !!---- Subroutine Deallocate_Point_List(Pl)
41579    !!----    type(point_list_type), intent(in out) :: pl  !  In Out-> Type with allocatable components
41580    !!----
41581    !!----     De-allocation of an objet of type point_list_type
41582    !!----
41583    !!---- Update: February - 2005
41584    !!
41585    Subroutine Deallocate_Point_List(Pl)
41586       !---- Arguments ----!
41587       type(point_list_type), intent(in out) :: pl
41588
41589       if (allocated(pl%nam) ) deallocate(pl%nam)
41590       if (allocated(pl%p) )   deallocate(pl%p)
41591       if (allocated(pl%x) )   deallocate(pl%x)
41592
41593       return
41594    End Subroutine Deallocate_Point_List
41595
41596    !!----
41597    !!---- Subroutine Distance_and_Sigma(Cellp,DerM,x0,x1,s0,s1,dis,s)
41598    !!----    Type(Crystal_Cell_Type),         intent(in)  :: Cellp         ! Cell object
41599    !!----    real(kind=cp), dimension(3,3,6), intent(in)  :: DerM          ! Matrix of derivatives of Cellp%Cr_Orth_cel
41600    !!----    real(kind=cp), dimension(3),     intent(in)  :: x0,x1,s0,s1   ! Two points in fractional coordinates and sigmas
41601    !!----    real(kind=cp),                   intent(out) :: dis,s         ! Distance and sigma
41602    !!----
41603    !!---- Update: February - 2005
41604    !!
41605    Subroutine Distance_and_Sigma(Cellp,DerM,x0,x1,s0,s1,dis,s)
41606       !---- Arguments ----!
41607       Type(Crystal_Cell_Type),         intent(in)  :: Cellp         ! Cell object
41608       real(kind=cp), dimension(3,3,6), intent(in)  :: DerM          ! Matrix of derivatives of Cellp%Cr_Orth_cel
41609       real(kind=cp), dimension(3),     intent(in)  :: x0,x1,s0,s1   ! Two points in fractional coordinates and sigmas
41610       real(kind=cp),                   intent(out) :: dis,s         ! Distance and sigma
41611
41612       !---- Local variables ----!
41613       integer                     :: i
41614       real(kind=cp), dimension(3) :: xc,xf
41615       real(kind=cp), dimension(6) :: dc,df
41616
41617       xf=x1-x0
41618       xc = matmul(cellp%Cr_Orth_cel,xf)
41619       dis=sqrt(dot_product(xc,xc))
41620       do i=1,6
41621          dc(i) = dot_product(xc,matmul(DerM(:,:,i),xf))
41622       end do
41623       do i=1,3
41624          df(i) = dot_product(xc,Cellp%Cr_Orth_cel(:,i))
41625       end do
41626       df(4:6) =-df(1:3)
41627       s=0.0
41628       do i=1,3
41629          s = s + (dc(i)*Cellp%cell_std(i))**2
41630          s = s + (dc(i+3)*Cellp%ang_std(i)*to_rad)**2
41631          s = s + (df(i)*s1(i))**2 + (df(i+3)*s0(i))**2
41632       end do
41633       s=sqrt(s)/dis
41634
41635       return
41636    End Subroutine Distance_and_Sigma
41637
41638    !!----
41639    !!----  Subroutine Get_Anglen_Axis_From_RotMat(R,axis,angle)
41640    !!----    real(kind=cp), dimension(3,3), intent(in) :: R             !Input orthogonal matrix
41641    !!----    real(kind=cp), dimension(3),   intent(out):: axis          !Non normalized rotation axis
41642    !!----    real(kind=cp),                 intent(out):: angle         !Angle of rotation
41643    !!----
41644    !!----  Subroutine to obtain the axis and angle of rotation corresponding to
41645    !!----  an input orthogonal matrix. A Cartesian frame is assumed
41646    !!----
41647    !!---- Update: January - 2011
41648    !!----
41649    Subroutine Get_Anglen_Axis_From_RotMat(R,axis,angle)
41650      Real(kind=cp), dimension(3,3), intent(in) :: R
41651      Real(kind=cp), dimension(3),   intent(out):: axis
41652      Real(kind=cp),                 intent(out):: angle
41653      !--- Local variables ---!
41654      Real(kind=cp) :: va
41655
41656      va=(R(1,1)+R(2,2)+R(3,3)-1.0_cp)*0.5_cp
41657      if(va < -1.0_cp) va=-1.0_cp
41658      if(va >  1.0_cp) va= 1.0_cp
41659      angle= acosd(va)
41660      if(abs(abs(angle)-180.0_cp) < epsi) then
41661         axis= (/                sqrt(R(1,1)+1.0_cp), &
41662                sign(1.0_cp,R(1,2))*sqrt(R(2,2)+1.0_cp), &
41663                sign(1.0_cp,R(1,3))*sqrt(R(3,3)+1.0_cp) /)
41664      else
41665         axis= (/  R(2,3)-R(3,2), &
41666                   R(3,1)-R(1,3), &
41667                   R(1,2)-R(2,1) /)
41668      end if
41669      return
41670    End Subroutine Get_Anglen_Axis_From_RotMat
41671
41672    !!----
41673    !!----  Subroutine Get_Euler_From_Fract(X1,X2,X3,Mt,Phi,Theta,Chi,Eum,Code)
41674    !!----    real(kind=cp),           dimension(3),   intent (in) :: x1,x2,x3
41675    !!----    real(kind=cp),           dimension(3,3), intent (in) :: M !Matrix transforming to Cartesian coordinates
41676    !!----    real(kind=cp),                           intent(out) :: theta,phi,chi
41677    !!----    real(kind=cp), optional, dimension(3,3), intent(out) :: EuM
41678    !!----    character(len=*), optional,              intent (in) :: Code
41679    !!----
41680    !!----  Subroutine to obtain the Euler angles (2nd setting) of a Cartesian frame having
41681    !!----  as origin the point x3, the z-axis along x1-x3 and the "xz" plane coincident with
41682    !!----  the plane generated by the two vectors (x2-x3,x1-x3). The
41683    !!----
41684    !!---- Update: February - 2005
41685    !!
41686    Subroutine Get_Euler_From_Fract(X1,X2,X3,Mt,Phi,Theta,Chi,Eum,Code)
41687       !---- Arguments ----!
41688       real(kind=cp),           dimension(3),   intent (in) :: x1,x2,x3
41689       real(kind=cp),           dimension(3,3), intent (in) :: Mt
41690       real(kind=cp),                           intent(out) :: theta,phi,chi
41691       real(kind=cp), optional, dimension(3,3), intent(out) :: EuM
41692       character(len=*), optional,              intent (in) :: Code
41693
41694       !---- Local variables ----!
41695       real(kind=cp), dimension(3)   :: u,v,w
41696       real(kind=cp), dimension(3,3) :: rot
41697
41698!  U = ( cosPhi cosTheta cosChi - sinPhi sinChi,   sinPhi cosTheta cosChi+cosPhi sinChi,  -sinTheta cosChi)
41699!  V = (-sinPhi cosChi   - cosPhi cosTheta sinChi, cosPhi cosChi -sinPhi cosTheta sinChi,  sinTheta sinChi)
41700!  W = ( cosPhi sinTheta, sinPhi sinTheta,  cosTheta)
41701!
41702!     This corresponds to Euler angles defined in the following way:
41703!
41704!     In the starting position the cartesian frame (u,v,w) coincides with the crystallographic
41705!     cartesian frame (e1//a, e2 in the a-b plane and e3= e1 x e2). First a rotation Chi around
41706!     the e3 axis is applied, then a rotation Theta around the e2 axis and finally a rotation Phi
41707!     around e3. The total rotation matrix is
41708!
41709!          R(Phi,Theta,Chi) = R(e3,Phi) R(e2,Theta) R(e3,Chi) = [[ u, v, w]]
41710!
41711!     The columns of the active rotation matrix are the components of the unitary vectors u,v,w.
41712
41713       w=matmul(Mt,x1-x3)
41714       w=w/sqrt(dot_product(w,w))
41715       u=matmul(Mt,x2-x3)
41716       u=u/sqrt(dot_product(u,u))
41717       v=cross_product(w,u)
41718       v=v/sqrt(dot_product(v,v))
41719       u=cross_product(v,w) !already normalized
41720       rot(:,1)=u; rot(:,2)=v;  rot(:,3)=w  !Matrix Rot ([u,v,w] columns)
41721       if (present(EuM)) EuM=rot
41722       if (present(Code)) then
41723          call get_PhiTheChi(rot,phi,theta,chi,Code)
41724       else
41725          call get_PhiTheChi(rot,phi,theta,chi)
41726       end if
41727
41728       return
41729    End Subroutine Get_Euler_From_Fract
41730
41731    !!---- Subroutine Get_Matrix_moving_v_to_u(v,u,R,w,ang)
41732    !!----   real(kind=cp), dimension(3),           intent(in)  :: v,u   !Starting and final vectors
41733    !!----   real(kind=cp), dimension(3,3),         intent(out) :: R     !Rotation matrix moving v to u:  u=Rv
41734    !!----   real(kind=cp), optional,               intent(out) :: ang   !angle between the two vectors
41735    !!----   real(kind=cp), optional,dimension(3),  intent(out) :: w     !axis normal to plane of the two vectors
41736    !!----
41737    !!----   Subroutine to get the orthogonal matrix that rotates a vector v
41738    !!----   to orient it along the vector u. Makes use of Cross_Product and
41739    !!----   Rot_matrix (Gibbs matrix)
41740    !!----
41741    !!----    Created: February 2010 (JRC)
41742    !!----    Updated: March 2013 (JRC)
41743    !!----
41744    !!
41745    Subroutine Get_Matrix_moving_v_to_u(v,u,R,w,ang)
41746      real(kind=cp), dimension(3),           intent(in)  :: v,u
41747      real(kind=cp), dimension(3,3),         intent(out) :: R
41748      real(kind=cp), optional,               intent(out) :: ang
41749      real(kind=cp), optional,dimension(3),  intent(out) :: w
41750      !--- Local variables ---!
41751      integer                        :: i,iu,iv
41752      real(kind=cp), parameter       :: ep=1.0e-5_cp
41753      real(kind=cp)                  :: mv,mu,mvu,phi,c
41754      logical                        :: co_linear
41755      real(kind=cp), dimension(3)    :: vu
41756      integer, dimension(1)          :: im
41757      real(kind=cp), parameter, dimension(3,3):: ident=reshape((/1.0_cp,0.0_cp,0.0_cp, &
41758                                                                 0.0_cp,1.0_cp,0.0_cp, &
41759                                                                 0.0_cp,0.0_cp,1.0_cp/),(/3,3/))
41760
41761      if(present(ang)) ang=0.0
41762      if(present(w))   w=0.0
41763      !First determine if the two input vectors are co-linear
41764      im=maxloc(abs(v))
41765      iv=im(1)
41766      im=maxloc(abs(u))
41767      iu=im(1)
41768      co_linear=.true.
41769      if(iu == iv) then ! may be co-linear
41770        if(abs(u(iu)) > ep) then
41771          c=v(iv)/u(iu)
41772          do i=1,3
41773            if(abs( v(i)-c*u(i) ) > ep ) then
41774               co_linear=.false.
41775               exit
41776            end if
41777          end do
41778        end if
41779      else
41780        co_linear=.false.
41781      end if
41782      if(co_linear) then
41783        mvu=v(iv)*u(iu)
41784        if(mvu < 0.0) then   !opposed vectors
41785          R=-ident
41786        else                 !parallel vectors
41787          R=ident
41788        end if
41789      else
41790        ! non co-linear
41791        vu=Cross_Product(v,u)      !Rotation axis
41792        mv=sqrt(dot_product(v,v))
41793        mu=sqrt(dot_product(u,u))
41794        phi=dot_product(u,v)/mv/mu
41795        phi=acosd(phi)        !Angle between the two input vectors
41796        R=Rot_matrix(vu,phi)  !Gibbs matrix
41797        if(present(ang)) ang=phi
41798        if(present(w)) w=vu
41799      end if
41800      return
41801    End Subroutine Get_Matrix_moving_v_to_u
41802
41803    !!----
41804    !!---- Subroutine Get_OmegaChiPhi(Mt,Omega,Chi,Phi,Code)
41805    !!----    real(kind=cp), dimension(3,3),intent(in)  :: Mt
41806    !!----    real(kind=cp),                intent(out) :: Omega
41807    !!----    real(kind=cp),                intent(out) :: Chi
41808    !!----    real(kind=cp),                intent(out) :: Phi
41809    !!----    character(len=*), optional,   intent(in)  :: Code
41810    !!----
41811    !!----    Calculate the Euler Angles corresponding to an orthogonal matrix
41812    !!----    The definition of the Euler angles in this case correspond to the
41813    !!----    rotation matrix of Busing and Levy for diffractometry obtained from
41814    !!----    the composition of a rotation around z of angle Phi, followed by a
41815    !!----    rotation of angle Chi around the y-axis and a subsequent rotation of angle
41816    !!----    Omega around z.
41817    !!----    The matrix is supposed to be of the form: M = Rz(Omega).Ry(Chi).Rz(Phi)
41818    !!----    If Code =="R" or not present then the output angles are provided in radians.
41819    !!----    If Code =="D" then the output angles are provided in degrees.
41820    !!----    A checking of the input matrix is given before calculating the angles.
41821    !!----    The user must check the logical variable "ERR_RotMat" after calling this
41822    !!----    subroutine. If ERR_RotMat=.true. it means that the input matrix is not orthogonal.
41823    !!----    The obtained rotations should be interpreted as changes of reference systems, the
41824    !!----    angles correspond to the motor settings to put a reciprocal vector in Cartesian
41825    !!----    coordinates w.r.t. the L-system (all angles equal to zero) in the position given
41826    !!----    by the active rotation matrix Mt:  z4= Mt z1.
41827    !!----
41828    !!---- Updated: March - 2013
41829    !!
41830    Subroutine Get_OmegaChiPhi(Mt,Omega,Chi,Phi,Code)  !Conventional Euler angles of diffractometry
41831       !---- Arguments ----!
41832       real(kind=cp), dimension(3,3),intent(in)  :: Mt
41833       real(kind=cp),                intent(out) :: Omega
41834       real(kind=cp),                intent(out) :: Chi
41835       real(kind=cp),                intent(out) :: Phi
41836       character(len=*), optional,   intent(in)  :: Code
41837
41838       !---- Local Variables ----!
41839       real(kind=cp), dimension(3,3):: MTT
41840       real(kind=cp), parameter, dimension(3,3) :: &
41841                      identity = reshape ( (/1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0/),(/3,3/))
41842
41843       MTT=transpose(Mt)
41844       MTT=matmul(MTT,Mt)-identity
41845       if (sum(abs(MTT)) > 5.0*eps) then
41846          ERR_Geom=.true.
41847          ERR_Geom_Mess=" Error in Get_OmegaChiPhi ... the input matrix is not orthogonal! "
41848          return
41849       end if
41850       if (abs(Mt(3,3)-1.0) < eps) then  !M(3,3)=cos(Chi)=1
41851          Chi=0.0
41852          Omega=0.0                       ! Omega and Phi have the same axis, we select Omega=0
41853          !Phi=acos(Mt(1,1))              ! M(1,1)=cos(Omega)cos(Chi)cos(Phi)-sin(Omega)sin(Phi)
41854          Phi=atan2(Mt(1,2),Mt(1,1))      ! M(1,2)=cos(Omega)cos(Chi)sin(Phi)+sin(Omega)cos(Phi)
41855       else if(abs(Mt(3,3)+1.0) < eps) then  !M(3,3)=cos(Chi)=-1
41856          Chi=pi
41857          Omega=0.0                       ! Omega and Phi have the same axis, we select Omega=0
41858          !Phi=acos(-Mt(1,1))             ! We use also the elements (11) and (12)
41859          Phi=atan2(-Mt(1,2),Mt(1,1))
41860       else
41861          !Chi=acos(Mt(3,3))  !Better use the relation below (In BL there is an error in eqn 48 for omega)
41862          Omega=atan2(-Mt(2,3),Mt(1,3))       !M(1,3)=  cos(Omega)sin(Chi)   M(2,3)= -sin(Omega)sin(Chi)
41863          Phi=atan2(-Mt(3,2),-Mt(3,1))        !M(3,1)= -sin(Chi)cos(Phi)     M(3,2)= -sin(Chi)sin(Phi)
41864          Chi=atan2( Sqrt(Mt(3,1)*Mt(3,1)+Mt(3,2)*Mt(3,2)), Mt(3,3) )
41865       end if
41866       if (present(Code)) then
41867          if (code(1:1)=="D" .or. code(1:1)=="d") then
41868             Phi=Phi*to_deg
41869             Omega=Omega*to_deg
41870             Chi=Chi*to_deg
41871          end if
41872       end if
41873
41874       return
41875    End Subroutine Get_OmegaChiPhi
41876
41877    !!----
41878    !!---- Subroutine Get_PhiTheChi(Mt,Phi,Theta,Chi,Code)
41879    !!----    real(kind=cp), dimension(3,3),intent(in)  :: Mt
41880    !!----    real(kind=cp),                intent(out) :: Phi
41881    !!----    real(kind=cp),                intent(out) :: Theta
41882    !!----    real(kind=cp),                intent(out) :: Chi
41883    !!----    character(len=*), optional,   intent(in)  :: Code
41884    !!----
41885    !!----    Calculate the Euler Angles corresponding to an orthogonal matrix
41886    !!----    The definition of the Euler angles in this case correspond to the
41887    !!----    active rotation matrix obtained from the composition of a rotation
41888    !!----    around z of angle Chi, followed by a rotation of angle Theta
41889    !!----    around the y-axis and a subsequent rotation of angle Phi around z.
41890    !!----    The matrix is supposed to be of the form: M = Rz(Phi).Ry(Theta).Rz(Chi)
41891    !!----    If Code =="R" or not present then the output angles are provided in radians.
41892    !!----    If Code =="D" then the output angles are provided in degrees.
41893    !!----    A checking of the input matrix is given before calculating the angles.
41894    !!----    The user must check the logical variable "err_geom" after calling this
41895    !!----    subroutine. If err_geom=.true. it means that the input matrix is not orthogonal.
41896    !!----
41897    !!---- Update: February - 2005
41898    !!
41899    Subroutine Get_PhiTheChi(Mt,Phi,Theta,Chi,Code)
41900       !---- Arguments ----!
41901       real(kind=cp), dimension(3,3),intent(in)  :: Mt
41902       real(kind=cp),                intent(out) :: Phi
41903       real(kind=cp),                intent(out) :: Theta
41904       real(kind=cp),                intent(out) :: Chi
41905       character(len=*), optional,   intent(in)  :: Code
41906
41907       !---- Local Variables ----!
41908       real(kind=cp), dimension(3,3):: MTT
41909       real(kind=cp), parameter, dimension(3,3) :: &
41910                      identity = reshape ( (/1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0/),(/3,3/))
41911
41912       MTT=transpose(Mt)
41913       MTT=matmul(MTT,Mt)-identity
41914       if (sum(abs(MTT)) > 5.0*eps) then
41915          err_geom=.true.
41916          ERR_Geom_Mess=" Error in Get_PhiTheChi ... the input matrix is not orthogonal! "
41917          return
41918       end if
41919       if (abs(Mt(3,3)-1.0) < eps) then  !M(3,3)=cos(Theta)
41920          Theta=0.0
41921          Phi=0.0
41922          Chi=acos(Mt(1,1))               !M(1,1)=cos(Phi)cos(Theta)cos(Chi)-sin(Phi)sin(Chi)
41923       else if(abs(Mt(3,3)+1.0) < eps) then
41924          Theta=pi
41925          Phi=0.0
41926          Chi=acos(-Mt(1,1))
41927       else
41928          Theta=acos(Mt(3,3))
41929          Phi=atan2(Mt(2,3),Mt(1,3))     !M(1,3)=cos(Phi)sin(Theta)  M(2,3)=sin(phi)sin(Theta)
41930          Chi=atan2(Mt(3,2),-Mt(3,1))    !M(3,1)= -sin(Theta)cos(Chi)   M(3,2)= sin(Theta)sin(Chi)
41931       end if
41932       if (present(Code)) then
41933          if (code(1:1)=="D" .or. code(1:1)=="d") then
41934             Phi=Phi*to_deg
41935             Theta=Theta*to_deg
41936             Chi=Chi*to_deg
41937          end if
41938       end if
41939
41940       return
41941    End Subroutine Get_PhiTheChi
41942
41943    !!----
41944    !!---- Subroutine Get_Transf_List(Trans,Ox,Pl,Npl,Ifail)
41945    !!----   real(kind=cp), dimension(3,3), intent(in)     :: trans   !Matrix transforming the basis
41946    !!----   real(kind=cp), dimension(3  ), intent(in)     :: ox      !Coordinates of origin of the new basis
41947    !!----   type(point_list_type),         intent(in)     :: pl      !Input List of points
41948    !!----   type(point_list_type),         intent(in out) :: npl     !Output list of transformed points
41949    !!----   integer,                       intent(out)    :: ifail   !If ifail/=0 matrix inversion failed
41950    !!----
41951    !!----  Subroutine to get the fractional coordinates of the points of the input list "pl" in the
41952    !!----  new transformed cell ( a'= trans a) displaced to the new origing "ox". The coordinates
41953    !!----  are generated using only lattice translations. All coordinates are reduced to be
41954    !!----  between 0.0 and 1.0, so that  0.0 <= x,y,z < 1.0
41955    !!----
41956    !!---- Update: February - 2005
41957    !!
41958    Subroutine Get_Transf_List(trans,ox,pl,npl,ifail)
41959       !---- Arguments ----!
41960       real(kind=cp),         dimension(3,3), intent(in)     :: trans
41961       real(kind=cp),         dimension(3  ), intent(in)     :: ox
41962       type(point_list_type),                 intent(in)     :: pl
41963       type(point_list_type),                 intent(in out) :: npl
41964       integer,                               intent(out)    :: ifail
41965
41966       !---- local variables ----!
41967       integer                       :: i,j,ia,ib,ic,nat,mm
41968       integer, dimension(3)         :: mini,maxi
41969       real(kind=cp), dimension(7,3) :: vecpar
41970       real(kind=cp), dimension(3,3) :: si
41971       real(kind=cp), dimension(3  ) :: xx, xxn,v
41972
41973       ifail=0
41974       call matrix_inverse(trans,si,ifail)
41975       if (ifail == 1) return
41976
41977       !----  Construction of the 7 vertices of the new cell
41978       !----  1:a, 2:b, 3:c, 4:a+b, 5:a+c, 6:b+c 7:a+b+c
41979       do j=1,3
41980          do i=1,3
41981             vecpar(i,j)=trans(i,j)
41982          end do
41983          vecpar(4,j)=trans(1,j)+trans(2,j)
41984          vecpar(5,j)=trans(1,j)+trans(3,j)
41985          vecpar(6,j)=trans(2,j)+trans(3,j)
41986          vecpar(7,j)=trans(1,j)+trans(2,j)+trans(3,j)
41987       end do
41988
41989       !---- Exploration of the vertex matrix
41990       mini(:)=1000
41991       maxi(:)=-1000
41992       do j=1,3
41993          do i=1,7
41994             if (vecpar(i,j) < mini(j)) mini(j)=nint(min(vecpar(i,j),0.0_cp))
41995             if (vecpar(i,j) > maxi(j)) maxi(j)=nint(max(vecpar(i,j),1.0_cp))
41996          end do
41997       end do
41998
41999       !
42000       !   Explore the region  a-> min(1)---max(1)  where atoms will be generated
42001       !                       b-> min(2)---max(2)
42002       !                       c-> min(3)---max(3)
42003       !   and select those belonging to the interior of the new cell before
42004       !   translation to the new origin.
42005       !   set the translation to the new origin, put the atoms inside the new
42006       !   unit cell and, finally, print atoms coordinates
42007       !
42008       nat=0
42009       do mm=1,pl%np
42010          do ia=mini(1),maxi(1)
42011             xx(1)=pl%x(1,mm)+real(ia)
42012             do ib=mini(2),maxi(2)
42013                xx(2)=pl%x(2,mm)+real(ib)
42014                do_ic: do ic=mini(3),maxi(3)
42015                   xx(3)=pl%x(3,mm)+real(ic)
42016                   xxn=matmul(xx-ox,si)
42017                   xxn=Modulo_Lat(xxn)
42018                   do i=nat,1,-1
42019                      v=npl%x(:,i)-xxn(:)
42020                      if (Lattice_trans(v,"P") ) cycle do_ic
42021                   end do
42022                   nat=nat+1
42023                   npl%x(:,nat)= xxn
42024                   if ( nat < 10) then
42025                      write(unit=npl%nam(nat),fmt="(a,i1)") trim(pl%nam(mm))//"_",nat
42026                   else if( nat < 100) then
42027                      write(unit=npl%nam(nat),fmt="(a,i2)") trim(pl%nam(mm))//"_",nat
42028                   else
42029                      write(unit=npl%nam(nat),fmt="(a,i3)") trim(pl%nam(mm))//"_",nat
42030                   end if
42031                end do do_ic
42032             end do
42033          end do
42034       end do
42035       npl%np=nat
42036
42037       return
42038    End Subroutine Get_Transf_List
42039
42040    !!----
42041    !!---- Subroutine Init_Err_Geom()
42042    !!----
42043    !!----    Initialize the errors flags in CFML_Geometry_Calc
42044    !!----
42045    !!---- Update: February - 2005
42046    !!
42047    Subroutine Init_Err_Geom()
42048
42049       err_geom=.false.
42050       ERR_Geom_Mess=" "
42051
42052       return
42053    End Subroutine Init_Err_Geom
42054
42055    !!----
42056    !!---- Subroutine P1_Dist(Dmax, Cell, Spg, Ac, Lun)
42057    !!----    real(kind=cp),            intent(in)    :: dmax      !  In -> Max. Distance to be calculated
42058    !!----    type (Crystal_cell_Type), intent(in)    :: Cell      !  In -> Object of Crystal_cell_Type
42059    !!----    type (Space_Group_Type),  intent(in)    :: SpG       !  In -> Object of Space_Group_Type
42060    !!----    type (Atoms_Cell_Type),   intent(in out):: Ac        !  In -> Object of Atoms_Cell_Type
42061    !!----                                                           Out -> Updated Object of Atoms_Cell_Type
42062    !!----    integer,optional,         intent(in)    :: lun       !  In -> Logical Unit for writing
42063    !!----
42064    !!----    Subroutine calculate distances, below the prescribed distances "dmax",
42065    !!----    without standard deviations. No symmetry is applied: only lattice translations.
42066    !!----    Need as input the objects "Cell" (of type Crystal_cell_type), "SpG" (of type Space_Group_Type)
42067    !!----    and "Ac" (or type Atoms_Cell). Complete the construction of Ac.
42068    !!----    Control for error is present.
42069    !!----
42070    !!---- Update: February - 2005
42071    !!
42072    Subroutine P1_Dist(Dmax, Cell, Spg, Ac, Lun)
42073       !---- Arguments ----!
42074       real(kind=cp),            intent(in)       :: dmax
42075       type (Crystal_cell_Type), intent(in)       :: Cell
42076       type (Space_Group_Type),  intent(in)       :: SpG
42077       type (Atoms_Cell_Type),   intent(in out)   :: Ac
42078       integer, optional,        intent(in)       :: lun
42079
42080       !---- Local Variables ----!
42081       logical                                :: iprint
42082       character(len=6 )                      :: nam,nam1
42083       character(len=40)                      :: transla
42084       character(len=90)                      :: form1,form2="(a,2i4,a,a,a,a,a,f10.4,a,t62,3F8.4)"
42085       integer                                :: i,k,lk,i1,i2,i3,jl,nn,L,inew,ne,id
42086       integer, dimension(3)                  :: ic1,ic2
42087       integer, dimension(Ac%nat,Ac%nat)      :: mn  !neighbouring matrix
42088       real(kind=cp)                          :: T,dd
42089       real(kind=cp), dimension(3)            :: xx,x1,xo,Tn,xr, QD
42090       real(kind=cp), dimension(3,Ac%nat*Ac%nat*spg%multip) :: u
42091
42092       iprint=.false.
42093       if (present(lun)) then
42094          if (lun > 0) iprint=.true.
42095       end if
42096       call init_err_geom()
42097       id=3*nint(0.74048*(dmax/1.1)**3)
42098
42099       qd(:)=1.0/cell%rcell(:)
42100       ic2(:)= nint(dmax/cell%cell(:)+3.0)
42101       ic1(:)=-ic2(:)
42102       mn(:,:) = 0
42103       inew=0
42104       do i=1,ac%nat
42105          xo(:)=Ac%xyz(:,i)
42106          nam= Ac%noms(i)
42107          if (iprint) then
42108             write(unit=lun,fmt="(/,/,a)")"    -------------------------------------------------------------------"
42109             write(unit=lun,fmt="(a,f8.4,a,a,3f8.4)")   &
42110                       "    Distances less than",dmax,"  to atom: ",nam, xo(:)
42111             write(unit=lun,fmt="(a,/,/)")"    -------------------------------------------------------------------"
42112             write(unit=lun,fmt="(/,/,a,/,/)") &
42113                       " Orig. extr.                    Distance     tx   ty   tz       x_ext   y_ext   z_ext"
42114          end if
42115          ne=0
42116          do k=1,Ac%nat
42117             lk=1
42118             u(:,lk)=xo(:)
42119             xx(:)=Ac%xyz(:,k)
42120             nam1= Ac%noms(k)
42121             do i1=ic1(1),ic2(1)
42122                do i2=ic1(2),ic2(2)
42123                   do i3=ic1(3),ic2(3)
42124                      do_jl:do jl=1,Spg%NumLat
42125                         Tn(:)=(/real(i1),real(i2),real(i3)/)+Spg%Latt_trans(:,jl)
42126                         x1(:)=xx(:)+tn(:)
42127                         do l=1,3
42128                            t=abs(x1(l)-xo(l))*qd(l)
42129                            if (t > dmax) cycle do_jl
42130                         end do
42131                         do nn=1,lk
42132                            if (sum(abs(u(:,nn)-x1(:)))  <= epsi) cycle do_jl
42133                         end do
42134                         xr = matmul(cell%cr_orth_cel,x1-xo)
42135                         dd=sqrt(dot_product(xr,xr))
42136                         if (dd > dmax .or. dd < 0.001) cycle
42137                         lk=lk+1
42138                         u(:,lk)=x1(:)
42139                         call Frac_Trans_1Dig(tn,transla)
42140                         if (iprint) write(unit=lun,fmt=form2)" ",i,k,"   (",nam,")-(",nam1,"):",dd,"  "//transla,x1(:)
42141                         mn(i,k)=mn(i,k)+1
42142                         ne=ne+1
42143                         IF (ne > id) THEN
42144                            err_geom=.true.
42145                            ERR_Geom_Mess="Too many connected atoms! in sub. P1_dist"
42146                            return
42147                         END IF
42148                         Ac%neighb_atom(ne,i)=k    !Pointer to the number of atom connected to i
42149                         Ac%distance   (ne,i)=dd   !Corresponding distance
42150                         Ac%trans(:,ne,i)=tn(:)    !corresponding lattice translation
42151                         do nn=1,inew
42152                            if (abs(dd-Ac%ddist(nn)) <= epsi) then
42153                               if (equiv_atm(nam,nam1,Ac%ddlab(nn)))  cycle do_jl
42154                            end if
42155                         end do
42156                         inew=inew+1
42157                         Ac%ddist(inew)=dd
42158                         Ac%ddlab(inew)=wrt_lab(nam,nam1)
42159                      end do do_jl
42160                   end do !i3
42161                end do !i2
42162             end do !i1
42163          end do !k
42164          Ac%neighb(i)=ne
42165       end do !i
42166       Ac%ndist=inew
42167       if (iprint) then
42168          write(unit=lun,fmt="(/,/,a)") " -------------------"
42169          write(unit=lun,fmt="(a)"  )   " Neighbouring matrix"
42170          write(unit=lun,fmt="(a)")     " -------------------"
42171          write(unit=lun,fmt="(a)")
42172          write(unit=form1,fmt="(a,i4,a)") "(a,",Ac%nat,"i3)"
42173          write(unit=lun,fmt=form1)"     ",(i,i=1,Ac%nat)
42174          write(unit=lun,fmt="(a)")
42175          write(unit=form1,fmt="(a,i4,a)") "(i3,a,",Ac%nat,"i3)"
42176          do i=1,ac%nat
42177             write(unit=lun,fmt=form1) i,"  ",(mn(i,k),k=1,Ac%nat)
42178          end do
42179          write(unit=lun,fmt="(a,/,/,/)")
42180       end if
42181
42182       return
42183    End Subroutine P1_Dist
42184
42185    !!----
42186    !!---- Subroutine Print_Distances(Lun, Dmax, Cell, Spg, A)
42187    !!----    integer,                  intent(in)   :: lun    !  In -> Logical Unit for writing
42188    !!----    real(kind=cp),            intent(in)   :: dmax   !  In -> Max. Distance to be calculated
42189    !!----    type (Crystal_cell_Type), intent(in)   :: Cell   !  In -> Object of Crystal_cell_Type
42190    !!----    type (Space_Group_Type),  intent(in)   :: SpG    !  In -> Object of Space_Group_Type
42191    !!----    type (atom_list_type),   intent(in)   :: A      !  In -> Object of atom_list_type
42192    !!----
42193    !!----    Subroutine to print distances, below the prescribed distances
42194    !!----    "dmax", without standard deviations.
42195    !!----    Need as input the objects "Cell" (of type Crystal_cell_type), "SpG"
42196    !!----    (of type Space_Group_type) and "A" (or type atom_list_type, that should be
42197    !!----    allocated in the calling program).
42198    !!----
42199    !!---- Update: February - 2005
42200    !!
42201    Subroutine Print_Distances(Lun, Dmax, Cell, Spg, A)
42202       !-- Arguments --!
42203       integer,                  intent(in)   :: lun
42204       real(kind=cp),            intent(in)   :: dmax
42205       type (Crystal_cell_Type), intent(in)   :: Cell
42206       type (Space_Group_Type),  intent(in)   :: SpG
42207       type (atom_list_type),    intent(in)   :: A
42208
42209       !---- Local Variables ----!
42210       integer                           :: i,j,k,lk,i1,i2,i3,jl,npeq,nn,L,nlines
42211       character(len=80), dimension(12)  :: texto=" "
42212       character(len=5 )                 :: nam,nam1
42213       character(len=40)                 :: transla
42214       character(len=54)                 :: form2="(a,3i4,a,a,a,a,a,f10.4,a,t66,3F8.4)" !&
42215                                            !"("" "",3I4,""  ("",a,"")-("",a,""):"",f9.4,""   "",a,""  "",3F8.4)"
42216       integer,          dimension(3)    :: ic1,ic2
42217       real(kind=cp),    dimension(3)    :: xx,x1,xo,Tn,xr, QD
42218       real(kind=cp)                     :: T,dd
42219       real(kind=cp), dimension(3,A%Natoms*Spg%multip) :: uu
42220
42221       qd(:)=1.0/cell%rcell(:)
42222       ic2(:)= nint(dmax/cell%cell(:)+1.0)
42223       ic1(:)=-ic2(:)
42224       npeq=spg%numops
42225
42226       if (Spg%Centred == 2) then
42227          npeq=2*npeq
42228          write(unit=lun,fmt="(a)")" => Symmetry operators combined with inversion centre:"
42229          nlines=1
42230          do i=SpG%NumOps+1,npeq
42231             if (mod(i,2) == 0) then
42232                write(unit=texto(nlines)(36:70),fmt="(a,i2,a,a)") &
42233                                           " => SYMM(",i,"): ",trim(SpG%SymopSymb(i))
42234                nlines=nlines+1
42235             else
42236                write(unit=texto(nlines)( 1:34),fmt="(a,i2,a,a)")  &
42237                                           " => SYMM(",i,"): ",trim(SpG%SymopSymb(i))
42238             end if
42239          end do
42240          do i=1,min(nlines,12)
42241             write(unit=lun,fmt="(a)") texto(i)
42242          end do
42243       end if
42244
42245       do i=1,A%natoms
42246          nam=a%atom(i)%lab
42247          xo(:)=a%atom(i)%x(:)
42248          write(unit=lun,fmt="(/,/,a)")"    -------------------------------------------------------------------"
42249          write(unit=lun,fmt="(a,f8.4,a,a,3f8.4)")   &
42250                    "    Distances less than",dmax,"  to atom: ",nam, xo(:)
42251          write(unit=lun,fmt="(a,/,/)")"    -------------------------------------------------------------------"
42252          write(unit=lun,fmt="(/,/,a,/,/)") &
42253                    " Orig. extr. p.equiv.           Distance     tx   ty   tz       x_ext   y_ext   z_ext"
42254          do k=1,a%natoms
42255             lk=1
42256             uu(:,lk)=xo(:)
42257             nam1=a%atom(k)%lab
42258             do j=1,npeq
42259                xx=ApplySO(Spg%SymOp(j),a%atom(k)%x)
42260                do i1=ic1(1),ic2(1)
42261                   do i2=ic1(2),ic2(2)
42262                      do i3=ic1(3),ic2(3)
42263                         do_jl:do jl=1,Spg%NumLat
42264                            Tn(:)=real((/i1,i2,i3/))+Spg%Latt_trans(:,jl)
42265                            x1(:)=xx(:)+tn(:)
42266                            do l=1,3
42267                               t=abs(x1(l)-xo(l))*qd(l)
42268                               if (t > dmax) cycle do_jl
42269                            end do
42270                            do nn=1,lk
42271                               if (sum(abs(uu(:,nn)-x1(:)))  <= epsi) cycle do_jl
42272                            end do
42273                            xr = matmul(cell%cr_orth_cel,x1-xo)
42274                            dd=sqrt(dot_product(xr,xr))
42275                            if (dd > dmax .or. dd < 0.001) cycle
42276                            lk=lk+1
42277                            uu(:,lk)=x1(:)
42278                            call Frac_Trans_1Dig(tn,transla)
42279                            write(unit=lun,fmt=form2)" ",i,k,j,"   (",nam,")-(",nam1,"):",dd,"  "//transla,x1(:)
42280                            !write(unit=lun,fmt=form2)i,k,j,nam ,nam1,dd,transla,x1(:)
42281                                        !    "("" "",3I4,""  ("",a,"")-("",a,""):"",f9.4,""   "",a,""  "",3F8.4)"
42282                         end do do_jl
42283                      end do !i3
42284                   end do !i2
42285                end do !i1
42286             end do !j
42287          end do !k
42288       end do !i
42289
42290       return
42291    End Subroutine Print_Distances
42292
42293    !!---- Subroutine Set_New_AsymUnit(SpGn,Ate,Mat,orig,A_n,matkind,debug)
42294    !!----    type (Space_Group_Type) ,      intent(in    ) :: SpGn    !New space group that has been previously set
42295    !!----    type (Atom_Equiv_List_Type),   intent(in    ) :: Ate     !In old group
42296    !!----    real(kind=cp), dimension (3,3),intent(in    ) :: Mat     !Transformation matrix from the old to the new setting
42297    !!----    real(kind=cp), dimension (  3),intent(in    ) :: orig    !Displacement of the origin in the old setting
42298    !!----    type (Atom_list_Type),         intent(in out) :: A_n     !New atom list
42299    !!----    character (len=*), optional,   intent(in    ) :: matkind !Kind of transformation matrix
42300    !!----    character (len=*), optional,   intent(in    ) :: debug
42301    !!----
42302    !!----    Updated: January 2014 (JRC)
42303    !!----
42304    !!----
42305    Subroutine Set_New_AsymUnit(SpGn,Ate,Mat,orig,A_n,matkind,debug)
42306       type (Space_Group_Type) ,      intent(in    ) :: SpGn
42307       type (Atom_Equiv_List_Type),   intent(in    ) :: Ate !In old group
42308       real(kind=cp), dimension (3,3),intent(in    ) :: Mat
42309       real(kind=cp), dimension (  3),intent(in    ) :: orig
42310       type (Atom_list_Type),         intent(out   ) :: A_n
42311       character (len=*), optional,   intent(in    ) :: matkind
42312       character (len=*), optional,   intent(in    ) :: debug
42313       ! Local variables
42314       integer                           :: i,j,k,m,ifail,L,n,Ls,ip,L1
42315       integer                           :: i1,i2,i3,maxa,maxp,maxm,mult
42316       real(kind=cp), dimension (3,3)    :: S,Sinv
42317       real(kind=cp)                     :: determ
42318       logical                           :: newp,fail
42319       real(kind=cp), dimension (  3)    :: pos
42320       real(kind=cp), dimension (3,192)  :: orb
42321       type(point_list_type)             :: pl
42322       type (Atom_list_Type)             :: A
42323       character(len=*),parameter,dimension(26) :: let=(/"a","b","c","d","e","f","g","h", &
42324          "i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"/)
42325       real(kind=cp), allocatable, dimension (:,:) :: vec
42326       integer,parameter         :: lu=93
42327       real(kind=cp), parameter  :: epsi = 0.002
42328
42329       if(present(matkind)) then
42330        if(matkind(1:2) == "it" .or. matkind(1:2) == "IT" ) then
42331          S=Mat             !Atoms positions X'=inv(Mat) (X-O)
42332        else
42333          S=transpose(Mat)  !Atoms positions X'=inv(MatT)(X-O)
42334        end if
42335       else
42336          S=transpose(Mat)
42337       end if
42338       call matrix_inverse(S,Sinv,ifail) !Atoms positions X'= Sinv X
42339       if (ifail /= 0) then
42340         err_geom=.true.
42341         err_geom_Mess= "Inversion Matrix Failed on: Change_Setting_SG"
42342         return
42343       end if
42344       if(present(debug)) then
42345         open(unit=lu,file="similar_debug.lis",status="replace",action="write")
42346         write(unit=lu,fmt="(a)")  "  Debugging SIMILAR calculations  "
42347         write(unit=lu,fmt="(a/)") "  ============================== "
42348       end if
42349
42350       determ=determ_a(S)
42351       determ=abs(determ)
42352
42353       m=0
42354       if(determ > 1.0001) then  !Generate indices for lattice translations to be applied
42355         i1=max(nint(maxval(abs(S(:,1))))-1,1)
42356         i2=max(nint(maxval(abs(S(:,2))))-1,1)
42357         i3=max(nint(maxval(abs(S(:,3))))-1,1)
42358         allocate(vec(3,(i1+1)*(i2+1)*(i3+1)))
42359         do i=0,i1
42360          do j=0,i2
42361           do k=0,i3
42362            if(i==0 .and.j==0 .and. k==0) cycle
42363            m=m+1
42364            vec(:,m) = real((/i,j,k/))
42365            !write(*,*) "  vect: ",m," :",vec(:,m)
42366           end do
42367          end do
42368         end do
42369       end if
42370
42371       maxm=m    !maximum number of translations to be applied before changing the basis
42372       maxa=maxval(Ate%Atm(:)%mult)  !highest multiplicity of the atom sequence list
42373       !Factor 2
42374       maxp=2*maxa*determ    !maximum multiplicity in the new cell of a particular atom type
42375       !write(*,*) " Allocating atoms_list and Point list for ", maxp*Ate%nauas, " and ", maxp, " values"
42376       call Allocate_Atom_List(maxp*Ate%nauas,A)  !Atom list in the new cell, we must use "maxp"*Ate%nauas and not "maxa"
42377       Call Allocate_Point_List(maxp*Ate%nauas,Pl,Ifail)
42378       if(ifail /= 0) then
42379         !write(*,*) " Error allocating PL for ",maxp," values"
42380          err_geom=.true.
42381          write(unit=err_geom_Mess,fmt="(a,i8,a)")  " Error allocating PL for ",maxp," values"
42382          return
42383       end if
42384       Ls=0
42385
42386       !write(*,*) " Allocating PL and A successful "
42387
42388       do i=1,Ate%nauas
42389         Ls=Ls+1
42390         !Setting pl object
42391           ip=index(Ate%Atm(i)%Lab(1),"_")
42392           if(ip /= 0) then
42393              pl%nam(i)=Ate%Atm(i)%Lab(1)(1:ip-1)
42394           else
42395              pl%nam(i)=Ate%Atm(i)%Lab(1)
42396           end if
42397           pl%x=0.0
42398           pl%p=0.0
42399         !
42400         n=0
42401         do j=1,Ate%Atm(i)%mult
42402           n=n+1
42403           pos(:)    = Ate%Atm(i)%x(:,j)-orig(:)
42404           !write(*,*) " n=",n
42405           pl%x(:,n) = matmul(Sinv,pos)  !Complete list in new coordinate system of atoms of type i
42406           if(present(debug)) then
42407             write(unit=lu,fmt="(i4,2(a,3f8.4),a)") n,"  Atom: "//pl%nam(i)//" at (", &
42408                                         Ate%Atm(i)%x(:,j),") trasform to (",pl%x(:,n),")"
42409           end if
42410           pl%x(:,n) = Modulo_Lat(pl%x(:,n))  !Complete list in new coordinate system of atoms of type i
42411         end do
42412         if(determ > 1.0) then
42413          doj:do j=1,Ate%Atm(i)%mult
42414               do m=1,maxm
42415                 pos(:) = Ate%Atm(i)%x(:,j)-orig(:)+ vec(:,m)
42416                 pos(:) = Modulo_Lat(matmul(Sinv,pos))
42417                 newp=.true.
42418                 do k=1,n
42419                    if (sum(abs(pos(:)-pl%x(:,k))) < epsi) then
42420                       newp=.false.
42421                       exit
42422                    end if
42423                 end do
42424                 if (newp) then ! new position
42425                    n=n+1
42426                    !write(*,*) "  n=",n
42427                    pl%x(:,n) = pos(:)
42428                    if(present(debug)) then
42429                      write(unit=lu,fmt="(i4,2(a,3f8.4),a)") n,"  Atom: "//pl%nam(i)//" at (", &
42430                                                  Ate%Atm(i)%x(:,j),") trasform to (",pl%x(:,n),")"
42431                    end if
42432                    if(n == maxp) exit doj
42433                 end if
42434               end do
42435             end do doj
42436         end if
42437
42438         pl%np=n
42439         A%atom(Ls)%Lab =pl%nam(i)
42440         A%atom(Ls)%x(:)=pl%x(:,1)
42441         !write(*,"(2i5,a,i5,a)") i,Ls, "  "//Ate%Atm(i)%Lab(1), Ate%Atm(i)%mult,"   "//A%atom(Ls)%Lab
42442
42443         !Determine the number of independent orbits for this point
42444         call Set_Orbits_Inlist(Spgn,pl)
42445         L=1; L1=1
42446         do j=2,n
42447           if(pl%p(j) > L) then
42448            Ls=Ls+1
42449            A%atom(Ls)%x(:)=pl%x(:,j)
42450            !write(unit=let,fmt="(i3.3)") L
42451            A%atom(Ls)%Lab =trim(pl%nam(i))//let(L1)
42452           ! write(*,"(2i5,a,i5,a)") i,Ls, "  "//Ate%Atm(i)%Lab(1), Ate%Atm(i)%mult,"   "//A%atom(Ls)%Lab
42453            L=L+1
42454            L1=L1+1  !using a different counter for the label
42455            if(L1 > 26) L1=1 !re-start the labelling with the same letter
42456           end if
42457         end do
42458
42459       end do  !i=1,Ate%nauas
42460
42461       !write(*,*) "  Orbits correct"
42462       !write(*,*) "  Allocate_Atom_List for ",Ls," atoms"
42463       call Allocate_Atom_List(Ls,A_n,fail)
42464       if(fail) then
42465         if(present(debug)) then
42466          !write(*,*) "  Error on Allocate_Atom_List for ",A_n%natoms," atoms"
42467          write(unit=lu,fmt="(a,i4,a)") "  Error on Allocate_Atom_List for ",A_n%natoms," atoms"
42468         end if
42469       else
42470         ! write(*,*) "  Success on Allocate_Atom_List for ",A_n%natoms," atoms"
42471       end if
42472       do i=1,A_n%natoms
42473         A_n%atom(i)%x= A%atom(i)%x
42474         A_n%atom(i)%Lab= A%atom(i)%Lab
42475         call Get_Orbit(A_n%atom(i)%x,Spgn,Mult,orb)
42476         A_n%atom(i)%Mult=mult
42477         A_n%atom(i)%occ=real(mult)/real(Spgn%Multip)
42478       end do
42479       if(allocated(A%atom)) deallocate(A%atom)
42480       if(present(debug)) close(unit=lu)
42481       return
42482    End Subroutine Set_New_AsymUnit
42483
42484
42485    !!----
42486    !!---- Subroutine Set_Orbits_Inlist(Spg,Pl)
42487    !!----    type(space_group_type), intent(in)     :: SpG     !  In -> Space group
42488    !!----    type(point_list_type),  intent(in out) :: pl      !  In -> list of points
42489    !!----
42490    !!----    Set up of the integer pointer "pl%p" in the object "pl" of type point_list_type.
42491    !!----    Each point is associated with the number of an orbit. This pointer is useful
42492    !!----    to get the asymmetric unit with respect to the input space group of an arbitrary
42493    !!----    list of points (atom coordinates).
42494    !!----
42495    !!---- Update: February - 2005
42496    !!
42497    Subroutine Set_Orbits_Inlist(Spg,Pl)
42498       !---- Arguments ----!
42499       type(space_group_type), intent(in)     :: SpG
42500       type(point_list_type),  intent(in out) :: pl
42501
42502       !--- Local variables ---!
42503       integer                     :: i,j,norb,nt
42504       real(kind=cp), dimension(3) :: x,xx,v
42505
42506       norb=0
42507       pl%p=0
42508       do i=1,pl%np
42509          if (pl%p(i) == 0) then
42510             norb=norb+1
42511             pl%p(i)=norb
42512             x=pl%x(:,i)
42513             do j=1,Spg%multip
42514                xx=ApplySO(Spg%SymOp(j),x)
42515                xx=modulo_lat(xx)
42516                do nt=1,pl%np
42517                   if (pl%p(nt) /= 0) cycle
42518                   v=pl%x(:,nt)-xx(:)
42519                   if (Lattice_trans(v,Spg%spg_lat)) pl%p(nt)=norb
42520                end do
42521             end do
42522          end if
42523       end do
42524
42525       return
42526    End Subroutine Set_Orbits_Inlist
42527
42528    !!---- Subroutine Set_Rotation_Matrix(ang,Rot)
42529    !!----   real(kind=cp), dimension(3),   intent( in) :: ang
42530    !!----   real(kind=cp), dimension(3,3), intent(out) :: Rot
42531    !!----
42532    !!----  Subroutine calculating the rotation matrix Rot corresponding to
42533    !!----  the application (active rotations) of the following succesive rotations:
42534    !!----
42535    !!----  Rot = Rx(ang(3)) . Ry(ang(2)) . Rz(ang(1))
42536    !!----
42537    !!----    Created: October 2009  (JRC)
42538    !!----    Updated: March 2013 (JRC)
42539    !!----
42540
42541    Subroutine Set_Rotation_Matrix(ang,Rot)
42542      real(kind=cp), dimension(3),   intent( in) :: ang
42543      real(kind=cp), dimension(3,3), intent(out) :: Rot
42544      !Local variables
42545      real(kind=cp), dimension(3,3) :: Rx,Ry,Rz
42546      Rx=Matrix_Rx(ang(1),"D")
42547      Ry=Matrix_Ry(ang(2),"D")
42548      Rz=Matrix_Rz(ang(3),"D")
42549      Rot=Matmul(Rx,matmul(Ry,Rz))
42550      return
42551    End Subroutine Set_Rotation_Matrix
42552
42553    !!----
42554    !!---- Subroutine Set_TDist_Coordination(Max_coor,Dmax, Cell, Spg, A)
42555    !!----    integer,                  intent(in)   :: max_coor !  Maximum expected coordination
42556    !!----    real(kind=cp),            intent(in)   :: dmax     !  In -> Max. Distance to calculate
42557    !!----    real(kind=cp),            intent(in)   :: dangl    !  In -> Max. distance for angle calculations
42558    !!----    type (Crystal_cell_type), intent(in)   :: Cell     !  In -> Object of Crytal_Cell_Type
42559    !!----    type (Space_Group_type),  intent(in)   :: SpG      !  In -> Object of Space_Group_Type
42560    !!----    type (atom_list_type),   intent(in)    :: A        !  In -> Object of atom_list_type
42561    !!----
42562    !!----    Subroutine to calculate distances, below the prescribed distance "dmax"
42563    !!----    Sets up the coordination type: Coord_Info for each atom in the asymmetric unit
42564    !!----    Needs as input the objects Cell (of type Crystal_cell), SpG (of type Space_Group)
42565    !!----    and A (of type atom_list, that should be allocated in the calling program).
42566    !!----    The input argument Max_Coor is obtained, before calling the present procedure,
42567    !!----    by a call to Allocate_Coordination_Type with arguments:(A%natoms,Spg%Multip,Dmax,max_coor)
42568    !!----    Further calls to this routine do not need a previous call to Allocate_Coordination_Type.
42569    !!----
42570    !!---- Update: February - 2005
42571    !!
42572    Subroutine Set_TDist_Coordination(max_coor,Dmax, Cell, Spg, A)
42573       !---- Arguments ----!
42574       integer,                  intent(in)   :: max_coor
42575       real(kind=cp),            intent(in)   :: dmax
42576       type (Crystal_cell_Type), intent(in)   :: Cell
42577       type (Space_Group_Type),  intent(in)   :: SpG
42578       type (atom_list_type),    intent(in)   :: A
42579
42580       !---- Local Variables ----!
42581       integer                              :: i,j,k,lk,i1,i2,i3,nn,L,ico
42582       integer,       dimension(3)          :: ic1,ic2
42583       real(kind=cp), dimension(3)          :: xx,x1,xo,Tn,xr, QD
42584       real(kind=cp)                        :: T,dd
42585       real(kind=cp), dimension(3,max_coor) :: uu
42586
42587      ! call init_err_geom()  !Control of error
42588
42589       qd(:)=1.0/cell%rcell(:)
42590       !ic2(:)= nint(dmax/cell%cell(:)+1.5)
42591       ic2(:)= int(dmax/cell%cell(:))+1
42592       ic1(:)=-ic2(:)
42593       do i=1,a%natoms
42594          xo(:)=a%atom(i)%x(:)
42595
42596          ico=0
42597          do k=1,a%natoms
42598             lk=1
42599             uu(:,lk)=xo(:)
42600             do j=1,Spg%Multip
42601                xx=ApplySO(Spg%SymOp(j),a%atom(k)%x)
42602                do i1=ic1(1),ic2(1)
42603                   do i2=ic1(2),ic2(2)
42604                      do_i3:do i3=ic1(3),ic2(3)
42605                            Tn(1)=real(i1); Tn(2)=real(i2); Tn(3)=real(i3)
42606                            x1(:)=xx(:)+tn(:)
42607                            do l=1,3
42608                               t=abs(x1(l)-xo(l))*qd(l)
42609                               if (t > dmax) cycle  do_i3
42610                            end do
42611                            do nn=1,lk
42612                               if (sum(abs(uu(:,nn)-x1(:)))  <= epsi) cycle  do_i3
42613                            end do
42614                            xr = matmul(cell%cr_orth_cel,x1-xo)
42615                            dd=sqrt(dot_product(xr,xr))
42616                            if (dd > dmax .or. dd < 0.001) cycle
42617                            ico=ico+1
42618                           ! Control not performed ... it is supposed that max_coor is large enough
42619                           !if (Coord_Info%Coord_Num(i) > Coord_Info%Max_Coor) then
42620                           !   err_geom=.true.
42621                           !   ERR_Geom_Mess=" => Too many distances around an atom"
42622                           !   return
42623                           !end if
42624                            lk=lk+1
42625                            uu(:,lk)=x1(:)
42626                            Coord_Info%Dist(ico,i)=dd
42627                            Coord_Info%N_Cooatm(ico,i)=k
42628                            Coord_Info%N_sym(ico,i)=j
42629
42630                            ! Added by JGP
42631                            Coord_Info%Tr_Coo(:,ico,i)=tn
42632                      end do do_i3 !i3
42633                   end do !i2
42634                end do !i1
42635             end do !j
42636          end do !k
42637          Coord_Info%Coord_Num(i)=ico
42638       end do !i
42639
42640       return
42641    End Subroutine Set_TDist_Coordination
42642
42643    !!----
42644    !!---- Subroutine Set_TDist_Partial_Coordination(List,Max_coor,Dmax, Cell, Spg, A)
42645    !!----    integer,                  intent(in)   :: List     !  Modified atom
42646    !!----    integer,                  intent(in)   :: max_coor !  Maximum expected coordination
42647    !!----    real(kind=cp),            intent(in)   :: dmax     !  In -> Max. Distance to calculate
42648    !!----    real(kind=cp),            intent(in)   :: dangl    !  In -> Max. distance for angle calculations
42649    !!----    type (Crystal_cell_type), intent(in)   :: Cell     !  In -> Object of Crytal_Cell_Type
42650    !!----    type (Space_Group_type),  intent(in)   :: SpG      !  In -> Object of Space_Group_Type
42651    !!----    type (atom_list_type),   intent(in)    :: A        !  In -> Object of atom_list_type
42652    !!----
42653    !!----    Modify the coordination type: Coord_Info for the atoms affected by the change of atom "List"
42654    !!----    Needs as input the objects Cell (of type Crystal_cell), SpG (of type Space_Group)
42655    !!----    and A (or type atom_list, that should be allocated in the calling program).
42656    !!----    This routine is a modification of Set_TDist_Coordination to avoid superfluous calculations
42657    !!----    in global optimization methods. It assumes that Set_TDist_Coordination has previously been
42658    !!----    called and the object "Coord_Info" has already been set.
42659    !!----
42660    !!---- Update: May - 2009
42661    !!
42662    Subroutine Set_TDist_Partial_Coordination(List,max_coor,Dmax, Cell, Spg, A)
42663       !---- Arguments ----!
42664       integer,                  intent(in)   :: List
42665       integer,                  intent(in)   :: max_coor
42666       real(kind=cp),            intent(in)   :: dmax
42667       type (Crystal_cell_Type), intent(in)   :: Cell
42668       type (Space_Group_Type),  intent(in)   :: SpG
42669       type (atom_list_type),    intent(in)   :: A
42670
42671       !---- Local Variables ----!
42672       integer                              :: i,j,k,lk,i1,i2,i3,nn,L,ic,ico
42673       integer,       dimension(3)          :: ic1,ic2
42674       integer,       dimension(A%natoms)   :: po,pn
42675       real(kind=cp), dimension(3)          :: xx,x1,xo,Tn,xr, QD
42676       real(kind=cp)                        :: T,dd
42677       real(kind=cp), dimension(3,max_coor) :: uu
42678
42679      ! call init_err_geom()  !Control of error
42680
42681       po=0; pn=0
42682       po(List)=1 !This atom has a modified coordination sphere
42683       ic=Coord_Info%Coord_Num(List)
42684       do i=1,ic
42685         po(Coord_Info%N_Cooatm(i,List))=1  !This atom has a modified coordination sphere
42686       end do
42687
42688       qd(:)=1.0/cell%rcell(:)
42689       ic2(:)= int(dmax/cell%cell(:))+1
42690       ic1(:)=-ic2(:)
42691       !Determine the new coordination sphere of the changed atom
42692       i=List
42693       xo(:)=a%atom(i)%x(:)
42694
42695       ico=0
42696       do k=1,a%natoms
42697          lk=1
42698          uu(:,lk)=xo(:)
42699          do j=1,Spg%Multip
42700             xx=ApplySO(Spg%SymOp(j),a%atom(k)%x)
42701             do i1=ic1(1),ic2(1)
42702                do i2=ic1(2),ic2(2)
42703                   do_i3:do i3=ic1(3),ic2(3)
42704                         Tn(:)=real((/i1,i2,i3/))
42705                         x1(:)=xx(:)+tn(:)
42706                         do l=1,3
42707                            t=abs(x1(l)-xo(l))*qd(l)
42708                            if (t > dmax) cycle  do_i3
42709                         end do
42710                         do nn=1,lk
42711                            if (sum(abs(uu(:,nn)-x1(:)))  <= epsi) cycle  do_i3
42712                         end do
42713                         xr = matmul(cell%cr_orth_cel,x1-xo)
42714                         dd=sqrt(dot_product(xr,xr))
42715                         if (dd > dmax .or. dd < 0.001) cycle
42716                         ico=ico+1
42717                         lk=lk+1
42718                         uu(:,lk)=x1(:)
42719                         Coord_Info%Dist(ico,i)=dd
42720                         Coord_Info%N_Cooatm(ico,i)=k
42721                         Coord_Info%N_sym(ico,i)=j
42722                   end do do_i3 !i3
42723                end do !i2
42724             end do !i1
42725          end do !j
42726       end do !k
42727       Coord_Info%Coord_Num(i)=ico
42728       pn(list)=0
42729       po(list)=0
42730
42731       ic=Coord_Info%Coord_Num(List)    !New coordination number of atom List
42732       do i=1,ic
42733         pn(Coord_Info%N_Cooatm(i,List))=1  !This atom has now a newly modified coordination sphere
42734       end do
42735       !Look now the changed coordinaion spheres
42736       do i=1,a%natoms
42737         if(pn(i) == 0 .and. po(i) == 0) cycle
42738         !if(po(i) == 1 .and. pn(i) == 1) then !the atom remains in the coordination sphere, only recalculation of distance is needed
42739         !  ic=Coord_Info%Coord_Num(i)
42740         !  do k=1,ic
42741         !   if(List == Coord_Info%N_Cooatm(k,i)) then
42742         !   end if
42743         !  end do
42744         !end if
42745         !DO ALL WAITING FOR A MORE EFFICIENT ALGORITHM
42746         xo(:)=a%atom(i)%x(:)
42747
42748         ico=0
42749         do k=1,a%natoms
42750            lk=1
42751            uu(:,lk)=xo(:)
42752            do j=1,Spg%Multip
42753               xx=ApplySO(Spg%SymOp(j),a%atom(k)%x)
42754               do i1=ic1(1),ic2(1)
42755                  do i2=ic1(2),ic2(2)
42756                     do_inter:do i3=ic1(3),ic2(3)
42757                           Tn(:)=real((/i1,i2,i3/))
42758                           x1(:)=xx(:)+tn(:)
42759                           do l=1,3
42760                              t=abs(x1(l)-xo(l))*qd(l)
42761                              if (t > dmax) cycle  do_inter
42762                           end do
42763                           do nn=1,lk
42764                              if (sum(abs(uu(:,nn)-x1(:)))  <= epsi) cycle  do_inter
42765                           end do
42766                           xr = matmul(cell%cr_orth_cel,x1-xo)
42767                           dd=sqrt(dot_product(xr,xr))
42768                           if (dd > dmax .or. dd < 0.001) cycle
42769                           ico=ico+1
42770                           lk=lk+1
42771                           uu(:,lk)=x1(:)
42772                           Coord_Info%Dist(ico,i)=dd
42773                           Coord_Info%N_Cooatm(ico,i)=k
42774                           Coord_Info%N_sym(ico,i)=j
42775                     end do do_inter !i3
42776                  end do !i2
42777               end do !i1
42778            end do !j
42779         end do !k
42780         Coord_Info%Coord_Num(i)=ico
42781       end do !i
42782
42783       return
42784    End Subroutine Set_TDist_Partial_Coordination
42785
42786 End Module CFML_Geometry_Calc
42787!!-------------------------------------------------------
42788!!---- Crystallographic Fortran Modules Library (CrysFML)
42789!!-------------------------------------------------------
42790!!---- The CrysFML project is distributed under LGPL. In agreement with the
42791!!---- Intergovernmental Convention of the ILL, this software cannot be used
42792!!---- in military applications.
42793!!----
42794!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
42795!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
42796!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
42797!!----
42798!!---- Authors: Juan Rodriguez-Carvajal (ILL)
42799!!----          Javier Gonzalez-Platas  (ULL)
42800!!----
42801!!---- Contributors: Laurent Chapon     (ILL)
42802!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
42803!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
42804!!----               Tierry Roisnel     (CDIFX,Rennes France)
42805!!----               Eric Pellegrini    (ILL)
42806!!----
42807!!---- This library is free software; you can redistribute it and/or
42808!!---- modify it under the terms of the GNU Lesser General Public
42809!!---- License as published by the Free Software Foundation; either
42810!!---- version 3.0 of the License, or (at your option) any later version.
42811!!----
42812!!---- This library is distributed in the hope that it will be useful,
42813!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
42814!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
42815!!---- Lesser General Public License for more details.
42816!!----
42817!!---- You should have received a copy of the GNU Lesser General Public
42818!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
42819!!----
42820!!----
42821!!---- MODULE: CFML_Molecular_Crystals
42822!!----   INFO: Module to define molecules on Crystals
42823!!----
42824!!---- HISTORY
42825!!----    Update: 07/03/2011
42826!!----
42827!!---- COMMENTARY
42828!!--..    Explanations about Eulerian angles, active and passive rotations
42829!!--..    Ref. Texture Analysis in Material Science, H.J. Bunge.
42830!!--..    Ed Butterworths London 1970?
42831!!--..
42832!!--..
42833!!--..    First variant:
42834!!--..    -------------
42835!!--..    Eulerian angles g={phi1,PHI,phi2}, positive rotations: anti-clockwise
42836!!--..
42837!!--..     1: Rotation around the common Z,Zm axis of an angle phi1
42838!!--..     2: Rotation around the new Xm axis of an angle PHI
42839!!--..     3: Rotation around the new Zm-axis of an angle phi2
42840!!--..
42841!!--..          g = gZm(phi2) . gXm(PHI) . gZm(Zm)
42842!!--..
42843!!--..
42844!!--..                   (  cosphi2  sinphi2    0  )                     (   1      0       0      )
42845!!--..
42846!!--..       gZm(phi2) =(  -sinphi2  cosphi2    0   )        gXm(PHI)  =(    0    cosPHI  sinPHI    )
42847!!--..
42848!!--..                   (    0         0       1  )                     (   0   -sinPHI  cosPHI   )
42849!!--..
42850!!--..
42851!!--..
42852!!--..                   (  cosphi1  sinphi1    0  )
42853!!--..
42854!!--..       gZm(phi1) =(  -sinphi1  cosphi1    0   )
42855!!--..
42856!!--..                   (    0         0       1  )
42857!!--..
42858!!--..
42859!!--..
42860!!--..    Second variant:
42861!!--..    ---------------
42862!!--..     Eulerian angles g={PSI,THETA,PHI}, positive rotations: anti-clockwise
42863!!--..
42864!!--..     1: Rotation around the common Z,Zm axis of an angle PSI   (PHI)
42865!!--..     2: Rotation around the new Ym axis of an angle THETA      (THETA) <--- FullProf
42866!!--..     3: Rotation around the new Zm-axis of an angle PHI        (CHI)
42867!!--..
42868!!--..       phi1=PSI+pi/2   PHI = THETA   phi2=PHI - pi/2
42869!!--..
42870!!--..
42871!!--..
42872!!--..    Rotation Axis and Rotation Angle
42873!!--..    --------------------------------
42874!!--..
42875!!--..    The rotation axis is given by the unit vector u represented by its polar
42876!!--..    coordinates (theta,phi) and the rotation angle (omega) around u, so that
42877!!--..    one can write the rotation g={u,omega}={theta,phi,omega}
42878!!--..
42879!!--..    Passive rotations: one looks for the coordinates of a unique point respect
42880!!--..                       to two rotated frames
42881!!--..
42882!!--..                             ( cosphi  sinphi)
42883!!--..         -----\--------  M = (               )     is the matrix relating the basis (e)=M(i)
42884!!--..         |\    \             (-sinphi  cosphi)
42885!!--..         | \    \
42886!!--..         |  \    r        The point r  has coordinates (x,y) and coordinates (x',y')
42887!!--..         |   \ /          w.r.t. the rotated axes the relation is:
42888!!--..         |    \
42889!!--..         | phi \          (x')   ( cosphi  sinphi)  (x)     x'= x cosphi + y sinphi
42890!!--..                          (  ) = (               )  ( )  => y'=-x sinphi + y cosphi
42891!!--..                          (y')   (-sinphi  cosphi)  (y)
42892!!--..
42893!!--..     Active  rotations: one looks for the new coordinates of a point respect
42894!!--..                       to the same frame when a rotation is applied
42895!!--..
42896!!--..
42897!!--..                             ( cosphi -sinphi)
42898!!--..         --------------  R = (               )
42899!!--..         |\                  ( sinphi  cosphi)
42900!!--..         | \
42901!!--..         |  \   r'           x'= x cosphi - y sinphi
42902!!--..         | r \               y'= x sinphi + y cosphi
42903!!--..         |    \
42904!!--..         | phi \
42905!!--..
42906!!--..
42907!!--..      The representative matrices are one the inverse of the other. R=Minv=Mt
42908!!--..
42909!!--..      In molecular crystals one looks for determining the position of each atom of
42910!!--..      the molecule in the crystallographic frame when one knows the internal coordinates
42911!!--..      of the atoms, the position of the origin of the internal frame in the crystallographic
42912!!--..      frame and the orientation (Euler or Euler-like angles) of the internal frame with
42913!!--..      respect to the crystallographic frame.
42914!!--..
42915!!--..      The problem is to define a simple set of orientational angles
42916!!--..
42917!!--..      We shall adopt the conventional definition of Euler angles but we will call then
42918!!--..      a=phi1, b=PHI, c=phi2. The above matrices correspond to passive rotations, so that
42919!!--..      when applied to a fixed point their product will give the coordinates of this point
42920!!--..      with respect to the rotated system. In our case will give the position of an external
42921!!--..      point (cartesian crystal  frame, CCF) w.r.t the cartesian molecular frame (CMF).
42922!!--..      Taking the transpose of the final matrix one obtains an active rotation matrix that
42923!!--..      applied to a point moves it to a new point referred to the CCF.
42924!!--..
42925!!--..
42926!!--..
42927!!--..               ( cosa cosc - sina sinc cosb     sina cosc + cosa sinc cosb    sinc sinb )
42928!!--..
42929!!--..    g(a,b,c) =( -cosa sinc - sina cosc cosb    -sina sinc + cosa cosc cosb    cosc sinb  )
42930!!--..
42931!!--..               (         sina  sinb                   -cosa sinb                 cosb   )
42932!!--..
42933!!--..
42934!!--..               ( cosa cosc - sina sinc cosb    -cosa sinc - sina cosc cosb    sina sinb )
42935!!--..
42936!!--..   gt(a,b,c) =(  sina cosc + cosa sinc cosb    -sina sinc + cosa cosc cosb   -cosa sinb  )
42937!!--..
42938!!--..               (      sinc sinb                      cosc sinb                   cosb   )
42939!!--..
42940!!--..
42941!!--..
42942!!--..     The matrix g applied to a point with coordinates given w.r.t. CCF, provides the coordinates
42943!!--..     w.r.t. CMF. If we take a point in the CMF and we apply the matrix gt we obtain the coordinates
42944!!--..     of this point w.r.t. CCF.
42945!!--..
42946!!--..     Orientational angles used in FullProf
42947!!--..     -------------------------------------
42948!!--..
42949!!--..     The molecular frame (CMF) is supposed to coincide at the begining with the Cartesian
42950!!--..     crystallographic frame (CCF). To position a molecule in an arbitrary position the
42951!!--..     total movement is decomposed in the following way:
42952!!--..
42953!!--..     1) Perform a rotation of angle CHI around the Z,Zm-axis : the rotation matrix relating
42954!!--..        the two unitary bases (Em and E in form of columns) is the following:
42955!!--..
42956!!--..                       (cosCHI    sinCHI   0 )            (e1)           (i)
42957!!--..                                                          (  )           ( )
42958!!--..             Rz(CHI) =(-sinCHI    cosCHI   0  )        Em=(e2) = Rz(CHI) (j) = Rz(CHI) E
42959!!--..                                                          (  )           ( )
42960!!--..                       (  0         0      1 )            (e3)           (k)
42961!!--..
42962!!--..        An active rotation is obtained transposing Rz(CHI)t = Az(CHI). This matrix is
42963!!--..        applied to a point in CCF and provides the new coordinates in the CCF after
42964!!--..        the rotation of angle CHI around Z.
42965!!--..
42966!!--..
42967!!--..     2) Perform a rotation of angle THE around the Y-axis : the rotation matrix relating
42968!!--..        the two unitary bases (Em and E in form of columns) is now the following:
42969!!--..
42970!!--..                       (cosTHE   0   -sinTHE )            (e1)           (i)
42971!!--..                                                          (  )           ( )
42972!!--..             Ry(THE) =(   0      1      0     )        Em=(e2) = Ry(THE) (j) = Ry(THE) E
42973!!--..                                                          (  )           ( )
42974!!--..                       (sinTHE   0    cosTHE )            (e3)           (k)
42975!!--..
42976!!--..        An active rotation is obtained transposing Ry(THE)t = Ay(THE). This matrix is
42977!!--..        applied to a point in CCF and provides the new coordinates in the CCF after
42978!!--..        the rotation of angle THE around Y.
42979!!--..
42980!!--..     3) Perform a rotation of angle PHI around the Z-axis : the rotation matrix relating
42981!!--..        the two unitary bases (Em and E in form of columns) is the following:
42982!!--..
42983!!--..                       (cosPHI    sinPHI   0 )            (e1)           (i)
42984!!--..                                                          (  )           ( )
42985!!--..             Rz(PHI) =(-sinPHI    cosPHI   0  )        Em=(e2) = Rz(PHI) (j) = Rz(PHI) E
42986!!--..                                                          (  )           ( )
42987!!--..                       (  0         0      1 )            (e3)           (k)
42988!!--..
42989!!--..        An active rotation is obtained transposing Rz(PHI)t = Az(PHI). This matrix is
42990!!--..        applied to a point in CCF and provides the new coordinates in the CCF after
42991!!--..        the rotation of angle PHI around Z.
42992!!--..
42993!!--..    With this rotational angles the interpretation of the angles (THE,PHI) correspond to
42994!!--..    the spherical angles of the CMF Zm-axis with respect to the CCF. The total active
42995!!--..    matrix to be applied to atoms of the molecule in the initial position (when the two
42996!!--..    frames coincide) to get the final coordinates is the following:
42997!!--..
42998!!--..
42999!!--..                 M = Az(PHI) . Ay(THE) . Az(CHI) =  XA(PHI,THE)  . XAp(CHI)
43000!!--..
43001!!--..
43002!!--..     In the initial state the Cartesian coordinates of atoms (x), in columns, are
43003!!--..     the same in both frames, the positions after the total rotation are given by:
43004!!--..
43005!!--..                         (x)-final =   M (x)
43006!!--..
43007!!--..     To obtain the internal coordinates of a point in the CCF one must apply the
43008!!--..     following formula:
43009!!--..
43010!!--..                   X-internal  =  Mt  X = XAp(CHI)t . XA(PHI,THE)t  X
43011!!--..
43012!!--..     the final expressions of the different matrices are the following:
43013!!--..
43014!!--..
43015!!--..                    (cosPHI cosTHE      -sinPHI      cosPHI sinTHE )
43016!!--..
43017!!--..     XA(PHI,THE) = ( sinPHI cosTHE       cosPHI      sinPHI sinTHE  )
43018!!--..
43019!!--..                    (  -sinTHE             0             cosTHE    )
43020!!--..
43021!!--..
43022!!--..                   (cosCHI   -sinCHI   0 )
43023!!--..
43024!!--..        XAp(CHI) =( sinCHI    cosCHI   0  )
43025!!--..
43026!!--..                   (  0         0      1 )
43027!!--..
43028!!--..
43029!!--..               ( cosa cosc - sina sinc cosb     sina cosc + cosa sinc cosb    sinc sinb )
43030!!--..
43031!!--..    g(a,b,c) =( -cosa sinc - sina cosc cosb    -sina sinc + cosa cosc cosb    cosc sinb  )
43032!!--..
43033!!--..               (         sina  sinb                   -cosa sinb                 cosb   )
43034!!--..
43035!!--..
43036!!--..               ( cosa cosc - sina sinc cosb    -cosa sinc - sina cosc cosb    sina sinb )
43037!!--..
43038!!--..   gt(a,b,c) =(  sina cosc + cosa sinc cosb    -sina sinc + cosa cosc cosb   -cosa sinb  )
43039!!--..
43040!!--..               (      sinc sinb                      cosc sinb                   cosb   )
43041!!--..
43042!!--..
43043!!--..
43044!!--..
43045!!--..
43046!!--..
43047!!--..  M(PHI,THE,CHI) =
43048!!--..
43049!!--..     (cosPHI cosTHE cosCHI - sinPHI sinCHI   -cosPHI cosTHE sinCHI - sinPHI cosCHI    cosPHI sinTHE)
43050!!--..
43051!!--..   =( sinPHI cosTHE cosCHI + cosPHI sinCHI   -sinPHI cosTHE sinCHI + cosPHI cosCHI    sinPHI sinTHE )
43052!!--..
43053!!--..     (       -sinTHE cosCHI                           sinTHE sinCHI                      cosTHE    )
43054!!--..
43055!!--..
43056!!--..
43057!!--..   Comparing the matrix M(THE,PHI,CHI) with the matrix gt(a,b,c)=gt(alpha,beta,gamma)=gt(phi1,PHI,phi2)
43058!!--..
43059!!--..   One can see that both matrices are identical if we take:
43060!!--..
43061!!--..        alpha=phi1=PHI+pi/2     beta=PHI=THETA   gamma=phi2=CHI-pi/2
43062!!--..
43063!!--..         (phi1=PSI+pi/2   PHI = THETA   phi2=PHI - pi/2)
43064!!--..
43065!!--..
43066!!--..      The angles used in FullProf correspond to the second variant of Euler angles making the
43067!!--..      sustitution:
43068!!--..
43069!!--..        (PSI,THETA,PHI)  --->   (PHI, THETA, CHI)
43070!!--..
43071!!--..            2nd variant   -->      FullProf
43072!!--..
43073!!--..      This is clear from the following. If we take passive rotations as for deriving the matrix
43074!!--..  corresponding to the Euler angles the matrix Mt should be the result
43075!!--..
43076!!--..      Mt = (  Az(PHI) . Ay(THE) . Az(CHI) )t = Rz(CHI) . Ry(THE) . Rz(PHI)
43077!!--..
43078!!--..  Then the interpretation of the rotations are strictly the same as given in the description
43079!!--..  of the second variant of Euler angles.
43080!!--..
43081!!--..
43082!!----
43083!!---- DEPENDENCIES
43084!!----
43085!!---- VARIABLES
43086!!----    ERR_MOLEC
43087!!----    ERR_MOLEC_MESS
43088!!----    MOLECULE_TYPE
43089!!----    MOLECULAR_CRYSTAL_TYPE
43090!!----
43091!!---- PROCEDURES
43092!!----    Functions:
43093!!----
43094!!----    Subroutines:
43095!!----       CARTESIAN_TO_FRACTIONAL
43096!!----       CARTESIAN_TO_SPHERICAL
43097!!----       CARTESIAN_TO_ZMATRIX
43098!!--++       CREATE_CONNECTIVITY_CARTESIAN   [Private]
43099!!----       EMPIRIC_FORMULA
43100!!--++       EMPIRIC_FORMULA_FATOM           [Overloaded]
43101!!--++       EMPIRIC_FORMULA_MOLCRYS         [Overloaded]
43102!!--++       EMPIRIC_FORMULA_MOLEC           [Overloaded]
43103!!----       FIX_REFERENCE
43104!!----       FIX_ORIENT_CARTESIAN
43105!!----       FRACTIONAL_TO_CARTESIAN
43106!!----       FRACTIONAL_TO_SPHERICAL
43107!!----       FRACTIONAL_TO_ZMATRIX
43108!!--++       GET_CARTESIAN_FROM_Z            [Private]
43109!!--++       GET_Z_FROM_CARTESIAN            [Private]
43110!!----       INIT_ERR_MOLEC
43111!!----       INIT_MOLECULE
43112!!----       MOLCRYS_TO_ATOMLIST
43113!!----       MOLEC_TO_ATOMLIST
43114!!----       READ_FREE_ATOMS
43115!!----       READ_MOLECULE
43116!!--++       READ_MOLECULE_IN_FILE           [Overloaded]
43117!!--++       READ_MOLECULE_IN_VAR            [Overloaded]
43118!!----       SET_EULER_MATRIX
43119!!----       SPHERICAL_TO_CARTESIAN
43120!!----       SPHERICAL_TO_FRACTIONAL
43121!!----       SPHERICAL_TO_ZMATRIX
43122!!----       WRITE_FREE_ATOMS
43123!!----       WRITE_MOLECULAR_CRYSTAL
43124!!----       WRITE_MOLECULE
43125!!----       ZMATRIX_TO_CARTESIAN
43126!!----       ZMATRIX_TO_FRACTIONAL
43127!!----       ZMATRIX_TO_SPHERICAL
43128!!----
43129!!
43130 Module CFML_Molecular_Crystals
43131
43132    !---- Use Modules ----!
43133    use CFML_GlobalDeps,                only: cp, eps, to_rad
43134    use CFML_Math_General,              only: acosd, asind, cosd, sind
43135    use CFML_Math_3D,                   only: cross_product, Get_Spheric_Coord
43136    use CFML_Crystallographic_Symmetry, only: Space_Group_type, Write_SpaceGroup
43137    use CFML_Atom_TypeDef,              only: Atom_Type, Atom_List_Type, Allocate_Atom_List, Deallocate_Atom_List,&
43138                                              Init_Atom_Type
43139    use CFML_Crystal_Metrics,           only: Crystal_Cell_Type, Set_Crystal_Cell,Err_crys, Err_Crys_Mess, &
43140                                              Write_Crystal_Cell
43141    use CFML_String_Utilities,          only: u_case, l_case, getword, getnum, cutst
43142    use CFML_Geometry_Calc,             only: angle_dihedral,distance,Get_PhiTheChi
43143    use CFML_Scattering_Chemical_Tables,only: Num_Chem_Info,Chem_Info,Set_Chem_Info,Remove_Chem_Info,Get_ChemSymb
43144
43145    implicit none
43146
43147    private
43148
43149    !---- List of public functions ----!
43150
43151    !---- List of public overloaded procedures: functions ----!
43152
43153    !---- List of public subroutines ----!
43154    public :: Init_Err_Molec, Init_Molecule, Read_Free_Atoms, Read_Molecule,             &
43155              Write_Molecule, Write_Molecular_Crystal, Write_Free_Atoms
43156
43157    public :: Cartesian_to_Fractional, Cartesian_to_Spherical, Cartesian_to_Zmatrix,     &
43158              Fractional_to_Cartesian, Fractional_to_Spherical, Fractional_to_Zmatrix,   &
43159              Zmatrix_to_Cartesian, Zmatrix_to_Fractional, Zmatrix_to_Spherical,         &
43160              Spherical_to_Cartesian, Spherical_to_Zmatrix,Spherical_to_Fractional,      &
43161              Fix_Reference,Fix_Orient_Cartesian, Set_Euler_Matrix, Molcrys_to_AtomList, &
43162              Molec_to_AtomList, Empiric_Formula,Init_Mol_Crys
43163
43164    !---- List of private functions ----!
43165
43166    !---- List of private Subroutines ----!
43167    private :: Create_Connectivity_Cartesian, Get_Cartesian_From_Z, Get_Z_From_Cartesian, &
43168               Empiric_Formula_FAtom, Empiric_Formula_Molcrys, Empiric_Formula_Molec
43169
43170
43171    !---- Definitions ----!
43172
43173    !!----
43174    !!---- ERR_MOLEC
43175    !!----    logical, public :: err_molec
43176    !!----
43177    !!----    Logical Variable indicating an error in MOLECULAR_CRYSTAL module
43178    !!----
43179    !!---- Update: February - 2005
43180    !!
43181    logical, public          :: Err_Molec
43182
43183    !!----
43184    !!---- ERR_MOLEC_MESS
43185    !!----    character(len=150), public :: ERR_Molec_Mess
43186    !!----
43187    !!----    String containing information about the last error
43188    !!----
43189    !!---- Update: February - 2005
43190    !!
43191    character(len=150), public :: ERR_Molec_Mess
43192
43193    !!----
43194    !!----  TYPE :: MOLECULE_TYPE
43195    !!--..
43196    !!----  Type, public :: Molecule_Type
43197    !!----     character(len=80)                               :: Name_mol     !Global name for the molecule
43198    !!----     integer                                         :: natoms       !Number of atoms
43199    !!----     logical                                         :: in_xtal      !True if global coordinates xcentre, orient are defined
43200    !!----     logical                                         :: is_EulerMat  !True if the Euler Matrix has been set
43201    !!----     logical                                         :: is_connect   !True if the connectivity is correct
43202    !!----     character(len=1)                                :: rot_type     !Type of rotational angles
43203    !!----                                                                     !"E": Conventional Euler angles (alpha,beta,gamma)
43204    !!----                                                                     !"P": Second variant of Euler angles (default)
43205    !!----                                                                     !     Polar:(theta,phi,chi)
43206    !!----     character(len=1)                                :: coor_type    !Type of internal coordinates
43207    !!----                                                                     !"Z": Z-matrix
43208    !!----                                                                     !"C": Cartesian
43209    !!----                                                                     !"S": Spherical
43210    !!----                                                                     !"F": Fractional coordinates (only if in_xtal = .true.)
43211    !!----     character(len=3)                                :: therm_type   !Type of thermal factor
43212    !!----                                                                     !"ISO": No collective motion
43213    !!----                                                                     !"T  ": Translational
43214    !!----                                                                     !"TL ": Translational + Librational
43215    !!----                                                                     !"TLS": Translational + Librational + Correlation
43216    !!----     real(kind=cp), dimension(3)                     :: xcentre      !Fractional coordinates of the centre
43217    !!----     real(kind=cp), dimension(3)                     :: mxcentre     !Refinement codes (or multipliers) of Fractional coordinates of the centre
43218    !!----     integer,       dimension(3)                     :: lxcentre     !Numbers of LSQ parameters for Fractional coordinates of the centre
43219    !!----     real(kind=cp), dimension(3)                     :: Orient       !Orientation angles (Euler angles or variant ...)
43220    !!----     real(kind=cp), dimension(3)                     :: mOrient      !Refinement codes (or multipliers) of Orientation angles (Euler angles or variant ...)
43221    !!----     integer,       dimension(3)                     :: lOrient      !Numbers of LSQ parameters for Orientation angles (Euler angles or variant ...)
43222    !!----     real(kind=cp), dimension(6)                     :: T_TLS        !Translational Thermal factor tensor
43223    !!----     real(kind=cp), dimension(6)                     :: mT_TLS       !Refinement codes (or multipliers) of Translational Thermal factor tensor
43224    !!----     integer,       dimension(6)                     :: lT_TLS       !Numbers of LSQ parameters for Translational Thermal factor tensor
43225    !!----     real(kind=cp), dimension(6)                     :: L_TLS        !Librational Thermal factor tensor
43226    !!----     real(kind=cp), dimension(6)                     :: mL_TLS       !Refinement codes (or multipliers) of Librational Thermal factor tensor
43227    !!----     integer,       dimension(6)                     :: lL_TLS       !Numbers of LSQ parameters for Librational Thermal factor tensor
43228    !!----     real(kind=cp), dimension(3,3)                   :: S_TLS        !TL-correlation Thermal factor
43229    !!----     real(kind=cp), dimension(3,3)                   :: mS_TLS       !Refinement codes (or multipliers) of TL-correlation Thermal factor
43230    !!----     integer,       dimension(3,3)                   :: lS_TLS       !Numbers of LSQ parameters for TL-correlation Thermal factor
43231    !!----     real(kind=cp), dimension(3,3)                   :: Euler        !Euler matrix
43232    !!----     character(len=6),  allocatable, dimension(  :)  :: AtName       !Atom Name
43233    !!----     character(len=4),  allocatable, dimension(  :)  :: AtSymb       !Atom species
43234    !!----     integer,           allocatable, dimension(  :)  :: AtZ          !Atomic Number
43235    !!----     integer,           allocatable, dimension(:,:)  :: Ptr          !Pointer to scat.factors (first index -> pattern)
43236    !!----     real(kind=cp),     allocatable, dimension(:,:)  :: I_coor       !Internal coordinates (d,ang,dang)
43237    !!----     real(kind=cp),     allocatable, dimension(:,:)  :: mI_coor      !Refinement codes (or multipliers) of internal coordinates
43238    !!----     integer,           allocatable, dimension(:,:)  :: lI_coor      !Numbers of LSQ parameters for internal coordinates
43239    !!----     real(kind=cp),     allocatable, dimension(  :)  :: biso         !Isotropic temperature factor
43240    !!----     real(kind=cp),     allocatable, dimension(  :)  :: mbiso        !Refinement codes (or multipliers) of Isotropic temperature factor
43241    !!----     integer,           allocatable, dimension(  :)  :: lbiso        !Numbers of LSQ parameters for Isotropic temperature factor
43242    !!----     real(kind=cp),     allocatable, dimension(  :)  :: occ          !Occupation factor
43243    !!----     real(kind=cp),     allocatable, dimension(  :)  :: mocc         !Refinement codes (or multipliers) of Occupation factor
43244    !!----     integer,           allocatable, dimension(  :)  :: locc         !Numbers of LSQ parameters for Occupation factor
43245    !!----     integer,           allocatable, dimension(  :)  :: Nb           !Number of neighbours
43246    !!----     integer,           allocatable, dimension(:,:)  :: inb          !Index of neighbours
43247    !!----     integer,           allocatable, dimension(:,:)  :: Tb           !Type of bonds
43248    !!----     integer,           allocatable, dimension(:,:)  :: conn         !Conectivity (N1,N2,N3)
43249    !!----  End Type Molecule_Type
43250    !!----
43251    !!---- Update: February - 2005
43252    !!
43253    Type, public :: Molecule_type
43254       character(len=80)                               :: Name_mol     !Global name for the molecule
43255       integer                                         :: natoms       !Number of atoms
43256       logical                                         :: in_xtal      !True if global coordinates xcentre, orient are defined
43257       logical                                         :: is_EulerMat  !True if the Euler Matrix has been set
43258       logical                                         :: is_connect   !True if the connectivity is given and correct
43259       character(len=1)                                :: rot_type     !Type of rotational angles
43260                                                                       !"E": Conventional Euler angles (alpha,beta,gamma)
43261                                                                       !"P": Second variant of Euler angles (default)
43262                                                                       !     Polar:(theta,phi,chi)
43263       character(len=1)                                :: coor_type    !Type of internal coordinates
43264                                                                       !"Z": Z-matrix
43265                                                                       !"C": Cartesian
43266                                                                       !"S": Spherical
43267                                                                       !"F": Fractional coordinates (only if in_xtal = .true.)
43268       character(len=3)                                :: therm_type   !Type of thermal factor
43269                                                                       !"ISO": No collective motion
43270                                                                       !"T  ": Translational
43271                                                                       !"TL ": Translational + Librational
43272                                                                       !"TLS": Translational + Librational + Correlation
43273       real(kind=cp), dimension(3)                     :: xcentre      !Fractional coordinates of the centre
43274       real(kind=cp), dimension(3)                     :: mxcentre     !Refinement codes (or multipliers) of Fractional coordinates of the centre
43275       integer,       dimension(3)                     :: lxcentre     !Numbers of LSQ parameters for Fractional coordinates of the centre
43276       real(kind=cp), dimension(3)                     :: Orient       !Orientation angles (Euler angles or variant ...)
43277       real(kind=cp), dimension(3)                     :: mOrient      !Refinement codes (or multipliers) of Orientation angles (Euler angles or variant ...)
43278       integer,       dimension(3)                     :: lOrient      !Numbers of LSQ parameters for Orientation angles (Euler angles or variant ...)
43279       real(kind=cp), dimension(6)                     :: T_TLS        !Translational Thermal factor tensor
43280       real(kind=cp), dimension(6)                     :: mT_TLS       !Refinement codes (or multipliers) of Translational Thermal factor tensor
43281       integer,       dimension(6)                     :: lT_TLS       !Numbers of LSQ parameters for Translational Thermal factor tensor
43282       real(kind=cp), dimension(6)                     :: L_TLS        !Librational Thermal factor tensor
43283       real(kind=cp), dimension(6)                     :: mL_TLS       !Refinement codes (or multipliers) of Librational Thermal factor tensor
43284       integer,       dimension(6)                     :: lL_TLS       !Numbers of LSQ parameters for Librational Thermal factor tensor
43285       real(kind=cp), dimension(3,3)                   :: S_TLS        !TL-correlation Thermal factor
43286       real(kind=cp), dimension(3,3)                   :: mS_TLS       !Refinement codes (or multipliers) of TL-correlation Thermal factor
43287       integer,       dimension(3,3)                   :: lS_TLS       !Numbers of LSQ parameters for TL-correlation Thermal factor
43288       real(kind=cp), dimension(3,3)                   :: Euler        !Euler matrix
43289       character(len=20), allocatable, dimension(  :)  :: AtName       !Atom Name
43290       character(len=4),  allocatable, dimension(  :)  :: AtSymb       !Atom species
43291       integer,           allocatable, dimension(  :)  :: AtZ          !Atomic Number
43292       integer,           allocatable, dimension(:,:)  :: Ptr          !Pointer to scat.factors (first index -> pattern)
43293       real(kind=cp),     allocatable, dimension(:,:)  :: I_coor       !Internal coordinates (d,ang,dang)
43294       real(kind=cp),     allocatable, dimension(:,:)  :: mI_Coor      !Refinement codes (or multipliers) of internal coordinates
43295       integer,           allocatable, dimension(:,:)  :: lI_coor      !Numbers of LSQ parameters for internal coordinates
43296       real(kind=cp),     allocatable, dimension(  :)  :: biso         !Isotropic temperature factor
43297       real(kind=cp),     allocatable, dimension(  :)  :: mbiso        !Refinement codes (or multipliers) of Isotropic temperature factor
43298       integer,           allocatable, dimension(  :)  :: lbiso        !Numbers of LSQ parameters for Isotropic temperature factor
43299       real(kind=cp),     allocatable, dimension(  :)  :: occ          !Occupation factor
43300       real(kind=cp),     allocatable, dimension(  :)  :: mocc         !Refinement codes (or multipliers) of Occupation factor
43301       integer,           allocatable, dimension(  :)  :: locc         !Numbers of LSQ parameters for Occupation factor
43302       integer,           allocatable, dimension(  :)  :: Nb           !Number of neighbours
43303       integer,           allocatable, dimension(:,:)  :: INb          !Index of neighbours
43304       integer,           allocatable, dimension(:,:)  :: Tb           !Type of Bonds
43305       integer,           allocatable, dimension(:,:)  :: Conn         !Conectivity (N1,N2,N3)
43306    End Type Molecule_type
43307
43308    !!----
43309    !!----  TYPE :: MOLECULAR_CRYSTAL_TYPE
43310    !!--..
43311    !!----  Type, public :: Molecular_Crystal_Type
43312    !!----     integer                                              :: N_free      !Number of free atoms
43313    !!----     integer                                              :: N_mol       !Number of Molecules
43314    !!----     integer                                              :: N_species   !Number of species
43315    !!----     integer                                              :: Npat        !
43316    !!----     type(Crystal_Cell_type)                              :: Cell        !Cell Information
43317    !!----     type(Space_Group_type)                               :: SpG         !Space Group Information
43318    !!----     type(Atom_type),         allocatable, dimension(  :) :: Atm         !Free Atoms
43319    !!----     type(Molecule_type ),    allocatable, dimension(  :) :: Mol         !Molecules
43320    !!----  End type Molecular_Crystal_Type
43321    !!----
43322    !!---- Update: February - 2005
43323    !!
43324    Type, public :: Molecular_Crystal_Type
43325       integer                                              :: N_Free
43326       integer                                              :: N_Mol
43327       integer                                              :: N_Species
43328       integer                                              :: Npat
43329       type(Crystal_Cell_type)                              :: Cell
43330       type(Space_Group_type)                               :: SpG
43331       type(Atom_type),         allocatable, dimension(  :) :: Atm
43332       type(Molecule_type ),    allocatable, dimension(  :) :: Mol
43333    End type Molecular_Crystal_Type
43334
43335    !---- Overloading Section ----!
43336    Interface Empiric_Formula
43337       Module Procedure Empiric_Formula_FAtom
43338       Module Procedure Empiric_Formula_Molec
43339       Module Procedure Empiric_Formula_Molcrys
43340    End Interface
43341
43342    Interface Read_Molecule
43343       Module Procedure Read_Molecule_in_File
43344       Module Procedure Read_Molecule_in_Var
43345    End Interface
43346
43347 Contains
43348    !---- Subroutines ----!
43349
43350    !!----
43351    !!---- Subroutine Cartesian_to_Fractional(Molecule,Cell,NewMolecule)
43352    !!----    type (Molecule_type), intent(in out)           :: Molecule
43353    !!----    type (Crystal_Cell_Type), intent(in)           :: Cell
43354    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
43355    !!----
43356    !!----    Subroutine to transform the internal coordinates of a
43357    !!----    molecule from cartesian coordinates to  fractional coordinates.
43358    !!----    If a third argument is present the subroutine creates a new
43359    !!----    molecule (copy of the old one) with fractional coordinates,
43360    !!----    preserving the input molecule in Cartesian Coordinates. Otherwise
43361    !!----    the input molecule is changed on output.
43362    !!----    Control of error is present
43363    !!--..       Xc= Euler.Xic  (Cartesian in the crystal frame)
43364    !!--..       xf= Orth_Cr_cel Xc (fractional before translating to the centre)
43365    !!--..       Xf = Orth_Cr_cel (Euler.Xic) + Xo (final fractional coordinates)
43366    !!----
43367    !!---- Update: February - 2005
43368    !!
43369    Subroutine Cartesian_to_Fractional(Molecule,Cell,NewMolecule)
43370       !---- Arguments ----!
43371       type (Molecule_type), intent(in out)           :: Molecule
43372       type (Crystal_Cell_Type), intent(in)           :: Cell
43373       type (Molecule_type), intent(   out), optional :: NewMolecule
43374
43375       !---- Local Variables ----!
43376       integer                       :: i,na
43377       real(kind=cp)                 :: phi,theta,chi
43378       real(kind=cp), dimension(3)   :: ci,xi
43379       real(kind=cp), dimension(3,3) :: Eu
43380       type (Molecule_type)          :: Newmol
43381
43382       !---- Controls ----!
43383       if (molecule%coor_type /= "C") then
43384          err_molec=.true.
43385          ERR_Molec_Mess="Error in Cartesian_to_Fractional: the input molecule is not in Cartesian coordinates"
43386          return
43387       end if
43388
43389       na=molecule%natoms
43390       if (na <=0) then
43391          err_molec=.true.
43392          ERR_Molec_Mess="Error in Cartesian_to_Fractional: No atoms are defined on molecule variable"
43393          return
43394       end if
43395
43396       if (.not. molecule%in_xtal) then
43397          err_molec=.true.
43398          ERR_Molec_Mess="Error in Cartesian_to_Fractional: the input molecule haven't crystal information"
43399          return
43400       end if
43401
43402       !---- Step 1----!
43403       call init_molecule(newmol,na)
43404       newmol=molecule
43405
43406       !---- Frame after a rotation defined by the matrix M(theta,phi,Chi)
43407       phi   = newmol%orient(1)
43408       theta = newmol%orient(2)
43409       chi   = newmol%orient(3)
43410       if (newmol%is_EulerMat) then
43411          Eu=newmol%Euler
43412       else
43413          call Set_Euler_matrix(newmol%rot_type,phi,theta,chi,Eu)
43414          newmol%Euler=Eu
43415          newmol%is_EulerMat=.true.
43416       end if
43417
43418       do i=1,na
43419          ci=matmul(Eu,newmol%I_coor(:,i))         !Cartesian components in the Crystal Frame
43420          xi=matmul(cell%Orth_Cr_cel,ci)           !Fractional coordinates before translation
43421          newmol%I_coor(:,i) = newmol%xcentre + xi !Final fractional coordinates
43422       end do
43423       newmol%coor_type = "F"
43424
43425       !---- Step 3 ----!
43426       if (present(newmolecule)) then
43427          call Init_molecule(NewMolecule,na)
43428          if (NewMolecule%natoms <=0) then
43429             err_molec=.true.
43430             ERR_Molec_Mess="Error in Cartesian_to_Fractional: The optional variable was not dimensioned!"
43431             return
43432          end if
43433          NewMolecule=newmol
43434       else
43435          Molecule=newmol
43436       end if
43437
43438       return
43439    End Subroutine Cartesian_to_Fractional
43440
43441    !!----
43442    !!---- Subroutine Cartesian_to_Spherical(Molecule,NewMolecule)
43443    !!----    type (Molecule_type), intent(in out)           :: Molecule
43444    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
43445    !!----
43446    !!----    Subroutine to transform the internal coordinates of a
43447    !!----    molecule from cartesian coordinates to  spherical coordinaters.
43448    !!----    If a second argument is present the subroutine creates a new
43449    !!----    molecule (copy of the old one) with spherical coordinates,
43450    !!----    preserving the input molecule in Cartesian Coordinates. Otherwise
43451    !!----    the input molecule is changed on output.
43452    !!----    Control of error is present
43453    !!----
43454    !!---- Update: February - 2005
43455    !!
43456    Subroutine Cartesian_to_Spherical(Molecule,NewMolecule)
43457       !---- Arguments ----!
43458       type (Molecule_type), intent(in out)           :: Molecule
43459       type (Molecule_type), intent(   out), optional :: NewMolecule
43460
43461       !---- Local variables -----!
43462       integer                     :: i,na
43463       real(kind=cp)               :: r, theta, phi
43464       real(kind=cp), dimension(3) :: ri
43465       type (Molecule_type)        :: Newmol
43466
43467       !---- Controls ----!
43468       if (molecule%coor_type /= "C") then
43469          err_molec=.true.
43470          ERR_Molec_Mess="Error in Cartesian_to_Spherical: the input molecule is not in Cartesian coordinates"
43471          return
43472       end if
43473
43474       na= Molecule%natoms
43475       if (na <= 0) then
43476          err_molec=.true.
43477          ERR_Molec_Mess="Error in Cartesian_to_Spherical: No atoms are defined"
43478          return
43479       end if
43480
43481       !---- Start calculations for each atom of the molecule ----!
43482       call init_molecule(newmol,na)
43483       NewMol=Molecule
43484
43485       do i=1,na
43486          ri=Molecule%I_Coor(:,i)
43487          call  Get_Spheric_Coord(ri,r,theta,phi,"D")
43488          NewMol%I_Coor(1,i) = r
43489          NewMol%I_Coor(2,i) = theta
43490          NewMol%I_Coor(3,i) = phi
43491       end do
43492       NewMol%coor_type="S"
43493
43494       if (present(newmolecule)) then
43495          call Init_molecule(NewMolecule,na)
43496          if (NewMolecule%natoms <=0) then
43497             err_molec=.true.
43498             ERR_Molec_Mess="Error in Cartesian_to_Spherical: The optional variable was not dimensioned!"
43499             return
43500          end if
43501          NewMolecule=newmol
43502       else
43503          Molecule=newmol
43504       end if
43505
43506       return
43507    End Subroutine Cartesian_to_Spherical
43508
43509    !!----
43510    !!---- Subroutine Cartesian_to_Zmatrix(Molecule,NewMolecule,Cell, D_min,D_max)
43511    !!----    type (Molecule_type), intent(in out)           :: Molecule
43512    !!----    type (Molecule_type), intent(   out), optional :: NewMolecule
43513    !!----    Type(Crystal_Cell_Type), intent(in),  optional :: Cell
43514    !!----    real(kind=cp),        intent(in    ), optional :: D_min
43515    !!----    real(kind=cp),        intent(in    ), optional :: D_max
43516    !!----
43517    !!----    Subroutine to transform the internal coordinates of a molecule
43518    !!----    from cartesian coordinates to  Z-matrix.
43519    !!----    If a second argument is present the subroutine creates a new
43520    !!----    molecule (copy of the old one) with Z-matrix, preserving
43521    !!----    the input molecule in Cartesian Coordinates. Otherwise the input
43522    !!----    molecule is changed on output.
43523    !!----    The input cartesian coordinates may be defined with respect to another
43524    !!----    internal frame. The final internal frame is that defined for Z-matrices:
43525    !!----    the x-axis is from the first to the second atom and the x-y plane is formed
43526    !!----    by the three first atoms. The Euler matrix and the molecular centre in the
43527    !!----    crystallographic system is changed in consequence.
43528    !!----    Control of error is present
43529    !!----
43530    !!---- Update: February - 2005
43531    !!
43532    Subroutine Cartesian_to_Zmatrix(Molecule,NewMolecule,Cell,D_min,D_max)
43533       !---- Arguments ----!
43534       type (Molecule_type), intent(in out)           :: Molecule
43535       type (Molecule_type), intent(   out), optional :: NewMolecule
43536       Type(Crystal_Cell_Type), intent(in),  optional :: Cell
43537       real(kind=cp),        intent(in    ), optional :: D_min
43538       real(kind=cp),        intent(in    ), optional :: D_max
43539
43540       !---- Local variables -----!
43541       integer                       :: i,na,j,k,n,mode
43542       real(kind=cp)                 :: dist, ang, phi, theta, chi
43543       real(kind=cp), dimension(3)   :: ci,ri,rj,rk,rn,u1,u2,u3
43544       real(kind=cp), dimension(3,3) :: Mat, Eu
43545       type (Molecule_type)          :: Newmol
43546
43547       !---- Controls ----!
43548       if (molecule%coor_type /= "C") then
43549          err_molec=.true.
43550          ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: the input molecule is not in Cartesian coordinates"
43551          return
43552       end if
43553
43554       na= Molecule%natoms
43555       if (na <= 0) then
43556          err_molec=.true.
43557          ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: Not atoms are defined"
43558          return
43559       end if
43560
43561       if (na < 3) then
43562          err_molec=.true.
43563          ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: You need at least three atoms"
43564          return
43565       end if
43566
43567       !---- Call Connectivity if necessary ----!
43568       if (.not. molecule%is_connect) then
43569          mode=0
43570          if (present(d_min)) mode=1
43571          if (present(d_max)) mode=mode + 2
43572          select case (mode)
43573             case (0)
43574                call create_connectivity_cartesian(molecule)
43575             case (1)
43576                call create_connectivity_cartesian(molecule,dmin=d_min)
43577             case (2)
43578                call create_connectivity_cartesian(molecule,dmax=d_max)
43579             case (3)
43580                call create_connectivity_cartesian(molecule,dmin=d_min,dmax=d_max)
43581          end select
43582          if (err_molec) then
43583             ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: the connectivity is wrong"
43584             return
43585          end if
43586          molecule%is_connect=.true.
43587       end if
43588
43589       !---- Start calculations for each atom of the molecule ----!
43590       call init_molecule(newmol,na)
43591       newmol=molecule
43592
43593       !---- First atom is always at origin (Z-matrix) ----!
43594       NewMol%I_Coor(:,1) = 0.0_cp
43595       NewMol%conn(:,1)   = 0
43596
43597       !---- Second atom is always along "x" ----!
43598       ri=molecule%I_coor(:,2)-molecule%I_coor(:,1)
43599       dist=sqrt(dot_product(ri,ri))
43600       NewMol%I_Coor(1,2)   = dist
43601       NewMol%I_Coor(2:3,2) = 0.0_cp
43602       NewMol%conn(2:3,2)   = 0
43603       NewMol%conn(1,2)     = 1
43604
43605       !---- Third atom is always in the "xy" plane ----!
43606       !---- A(i) d_ij  ang_ijk   dang_ijkl  j k l
43607       if (NewMol%conn(1,3) == 1) then
43608          NewMol%conn(2,3) = 2
43609          NewMol%conn(3,3) = 0
43610          ri=molecule%I_coor(:,3)-molecule%I_coor(:,1)
43611          rj=molecule%I_coor(:,2)-molecule%I_coor(:,1)
43612          dist= sqrt(dot_product(ri,ri))
43613          ang = acosd(dot_product(ri,rj)/dist/sqrt(dot_product(rj,rj)))
43614          NewMol%I_coor(1,3) = dist
43615          NewMol%I_coor(2,3) = ang
43616          NewMol%I_coor(3,3) = 0.0_cp
43617       else
43618          NewMol%conn(1,3) = 2
43619          NewMol%conn(2,3) = 1
43620          NewMol%conn(3,3) = 0
43621          ri=molecule%I_coor(:,3)-molecule%I_coor(:,2)
43622          rj=molecule%I_coor(:,1)-molecule%I_coor(:,2)
43623          dist= sqrt(dot_product(ri,ri))
43624          ang = acosd(dot_product(ri,rj)/dist/sqrt(dot_product(rj,rj)))
43625          NewMol%I_coor(1,3) = dist
43626          NewMol%I_coor(2,3) = ang
43627          NewMol%I_coor(3,3) = 0.0_cp
43628       end if
43629
43630       if (Molecule%in_xtal) then    !Modify the Euler matrix, orientation angles and centre
43631          if (Molecule%is_EulerMat) then
43632             Eu=Molecule%Euler
43633          else
43634             phi=Molecule%orient(1)
43635             theta=Molecule%orient(2)
43636             chi=Molecule%orient(3)
43637             Call Set_Euler_matrix(Molecule%rot_type,phi,theta,chi,Eu)
43638          end if
43639          newmol%Euler=Eu
43640          newmol%is_EulerMat=.true.
43641
43642          ri=molecule%I_coor(:,1)
43643          rj=molecule%I_coor(:,2)
43644          rk=molecule%I_coor(:,3)
43645          u1=rj-ri
43646          u1=u1/sqrt(dot_product(u1,u1))
43647          u3=cross_product(u1,rk-ri)
43648          u3=u3/sqrt(dot_product(u3,u3))
43649          u2=cross_product(u3,u1)
43650          Mat(:,1)=u1
43651          Mat(:,2)=u2  !Active matrix needed to get the new Euler matrix
43652          Mat(:,3)=u3
43653
43654          newmol%Euler=matmul(Eu,Mat)  !New Euler Matrix
43655          call Get_PhiTheChi(newmol%Euler,Phi,Theta,Chi,"D")
43656          newmol%orient(1)=  phi
43657          newmol%orient(2)=theta
43658          newmol%orient(3)=  chi
43659
43660          !---- New centre (?) Needs the Cell argument
43661          if (present(Cell)) then
43662             rj=Matmul(Mat,ri)
43663             newmol%xcentre=matmul(Cell%Orth_Cr_cel,rj)+molecule%xcentre
43664          else
43665             if (dot_product(ri,ri) > eps) then
43666                err_molec=.true.
43667                ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: First atom not at the origin => a cell has to be provided "
43668                return
43669             end if
43670          end if
43671       end if
43672
43673       do i=4,na                      !The result of this calculation is independent of the type of
43674          ri = molecule%I_coor(:,i)   !cartesian coordinates => it is not needed to transforn the input Cartesian!
43675          j  = molecule%conn(1,i)     !The connectivity is needed for the Z-matrix description
43676          k  = molecule%conn(2,i)     !If the connectivity is given it is possible to transform to
43677          n  = molecule%conn(3,i)     !Z-matrix if cartesian/spherical coordinates are given.
43678          if ( j == 0 .or. k == 0 .or. n == 0) then
43679             err_molec=.true.
43680             ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: the connectivity is wrong for atom: " &
43681                            //molecule%Atname(i)
43682             return
43683          end if
43684          rj = molecule%I_coor(:,j)
43685          rk = molecule%I_coor(:,k)
43686          rn = molecule%I_coor(:,n)
43687          call get_Z_from_cartesian(ci,ri,rj,rk,rn)
43688          NewMol%I_coor(:,i) = ci
43689       end do
43690       NewMol%coor_type="Z"
43691
43692       if (present(NewMolecule)) then
43693          call Init_molecule(NewMolecule,na)
43694          if (NewMolecule%natoms <=0) then
43695             err_molec=.true.
43696             ERR_Molec_Mess="Error in Cartesian_to_Zmatrix: The optional variable was not dimensioned!"
43697             return
43698          end if
43699          NewMolecule=newmol
43700       else
43701          Molecule=newmol
43702       end if
43703
43704       return
43705    End Subroutine Cartesian_to_Zmatrix
43706
43707    !!--++
43708    !!--++ Subroutine Create_Connectivity_Cartesian(Molecule, Dmin, Dmax)
43709    !!--++    type (Molecule_type),          intent(in out):: Molecule
43710    !!--++    real(kind=cp), optional,       intent(in)    :: Dmin
43711    !!--++    real(kind=cp), optional,       intent(in)    :: Dmax
43712    !!--++
43713    !!--++    (PRIVATE)
43714    !!--++    Subroutine that create the connectivity for the molecule.
43715    !!--++    The coordinates must be in Cartesian system. Control of
43716    !!--++    error is implemented.
43717    !!--++
43718    !!--++ Update: February - 2005
43719    !!
43720    Subroutine Create_Connectivity_Cartesian(Molecule,Dmin,Dmax)
43721       !---- Arguments ----!
43722       type (Molecule_type),          intent(in out):: Molecule
43723       real(kind=cp), optional,       intent(in)    :: Dmin
43724       real(kind=cp), optional,       intent(in)    :: Dmax
43725
43726       !---- Local variables ----!
43727       logical                                                      :: re_order
43728       integer                                                      :: i,j,k,l,m,nc1,nc2,nc3
43729       integer, dimension(molecule%natoms,molecule%natoms)          :: T_Conn
43730       integer, dimension(3,molecule%natoms)                        :: T_N
43731       integer, dimension(molecule%natoms)                          :: T_Ind
43732       real(kind=cp),    dimension(molecule%natoms,molecule%natoms) :: T_Dist
43733       real(kind=cp)                                                :: d_min, d_max
43734       real(kind=cp)                                                :: dist !,ang,tors
43735       type (Molecule_type)                                         :: Newmol
43736
43737
43738       !---- Initialize ----!
43739       d_min=0.6
43740       d_max=3.0
43741       T_Conn=0
43742       T_N   =0
43743       T_Ind =0
43744       T_Dist=0.0
43745       if (present(dmin)) d_min=dmin
43746       if (present(dmax)) d_max=dmax
43747
43748       !---- Controls ----!
43749       if (molecule%coor_type /= "C") then
43750          err_molec=.true.
43751          ERR_Molec_Mess="Error in Connectivity: the input molecule is not in Cartesian coordinates"
43752          return
43753       end if
43754
43755       !---- Creating Tables ----!
43756       do i=1,molecule%natoms
43757          do j=i+1,molecule%natoms
43758             dist=distance(molecule%I_coor(:,i),molecule%I_coor(:,j))
43759             if (dist < d_min .or. dist > d_max) cycle
43760             if (adjustl(molecule%Atsymb(i)) == "H   " .and. &
43761                 adjustl(molecule%Atsymb(j)) == "H   ") cycle
43762             T_Conn(i,j)=i
43763             T_Conn(j,i)=i
43764             T_Dist(i,j)=dist
43765             T_Dist(j,i)=dist
43766          end do
43767       end do
43768
43769       !---- Test for reorder atoms ----!
43770       re_order=.false.
43771
43772       do i=2,molecule%natoms
43773          j=count(T_conn(i,1:i-1) > 0)
43774          if (j==0) re_order=.true.
43775       end do
43776
43777       if (re_order) then
43778          m=1
43779          T_ind(m)=1
43780          do i=1,molecule%natoms
43781             do j=1,molecule%natoms
43782                if (T_Conn(i,j) <= 0) cycle
43783                l=0
43784                do k=1,m
43785                     if (j == T_ind(k)) then
43786                        l=1
43787                        exit
43788                     end if
43789                end do
43790                if (l > 0) cycle
43791                m=m+1
43792                T_ind(m)=j
43793             end do
43794          end do
43795
43796          call init_molecule(newmol,molecule%natoms)
43797          newmol=molecule
43798          do i=2,newmol%natoms
43799             j=T_ind(i)
43800             newmol%AtName(i)=   molecule%AtName(j)
43801             newmol%AtSymb(i)=   molecule%AtSymb(j)
43802             newmol%AtZ(i)=      molecule%AtZ(j)
43803             newmol%Ptr(:,i)=    molecule%Ptr(:,j)
43804             newmol%I_Coor(:,i)= molecule%I_Coor(:,j)
43805             newmol%mI_Coor(:,i)=molecule%mI_Coor(:,j)
43806             newmol%lI_Coor(:,i)=molecule%lI_Coor(:,j)
43807             newmol%biso(i)=     molecule%biso(j)
43808             newmol%mbiso(i)=    molecule%mbiso(j)
43809             newmol%lbiso(i)=    molecule%lbiso(j)
43810             newmol%occ(i)=      molecule%occ(j)
43811             newmol%mocc(i)=     molecule%mocc(j)
43812             newmol%locc(i)=     molecule%locc(j)
43813             newmol%nb(i)=       molecule%nb(j)
43814             newmol%Inb(:,i)=    molecule%Inb(:,j)
43815             newmol%Tb(:,i)=     molecule%Tb(:,j)
43816             newmol%Conn(:,i)=   molecule%Conn(:,j)
43817          end do
43818          molecule=newmol
43819          call init_molecule(newmol,0)
43820
43821          T_Conn=0
43822          T_Dist=0.0
43823          do i=1,molecule%natoms
43824             do j=i+1,molecule%natoms
43825                dist=distance(molecule%I_coor(:,i),molecule%I_coor(:,j))
43826                if (dist < d_min .or. dist > d_max) cycle
43827                if (adjustl(molecule%Atsymb(i)) == "H   " .and. &
43828                    adjustl(molecule%Atsymb(j)) == "H   ") cycle
43829                T_Conn(i,j)=i
43830                T_Conn(j,i)=i
43831                T_Dist(i,j)=dist
43832                T_Dist(j,i)=dist
43833             end do
43834          end do
43835       end if
43836
43837       !---- Connectivity Info ----!
43838       do i=2, molecule%natoms
43839
43840          !---- Distances: Fill N1 ----!
43841          j=minloc(T_Dist(i,1:i-1),dim=1,mask=(T_Dist(i,1:i-1) > 0.0))
43842          T_N(1,i)=j
43843
43844          if (j == 0) then
43845             err_molec=.true.
43846             ERR_Molec_Mess="Error in Connectivity: Some Index are zeros"
43847             return
43848          end if
43849
43850          !---- Angles: Fill N2 ----!
43851          if (i > 2) then
43852             nc1=count((T_Conn(j,1:i-1) > 0 .and. T_Conn(j,1:i-1) /=j),dim=1)
43853             nc2=count((T_Conn(i,1:i-1) > 0 .and. T_Conn(i,1:i-1) /=j),dim=1)
43854             k=0
43855             if (nc1 > 0) then
43856                do
43857                   k=minloc(T_Dist(j,1:i-1),dim=1, mask=(T_Dist(j,1:i-1) > 0.0))
43858                   if (k == j) then
43859                      T_Dist(j,k)=-T_Dist(j,k)
43860                      cycle
43861                   else
43862                      exit
43863                   end if
43864                end do
43865             elseif (nc2 > 0) then
43866                do
43867                   k=minloc(T_Dist(i,1:i-1),dim=1, mask=(T_Dist(i,1:i-1) > 0.0))
43868                   if (k == j) then
43869                      T_Dist(i,k)=-T_Dist(i,k)
43870                      cycle
43871                   else
43872                      exit
43873                   end if
43874                end do
43875             end if
43876             if (k == 0) then
43877                !---- Elegir uno cualquiera ----!
43878                do l=1,i-1
43879                   if (l == j) cycle
43880                   k=l
43881                   exit
43882                end do
43883             end if
43884             T_N(2,i)=k
43885          end if
43886          T_Dist=abs(T_Dist)
43887
43888          !---- Torsion ----!
43889          if (i > 3) then
43890             nc1=count((T_Conn(k,1:i-1) > 0 .and. T_Conn(k,1:i-1) /=j .and. T_Conn(k,1:i-1) /=k),dim=1)
43891             nc2=count((T_Conn(j,1:i-1) > 0 .and. T_Conn(j,1:i-1) /=j .and. T_Conn(j,1:i-1) /=k),dim=1)
43892             nc3=count((T_Conn(i,1:i-1) > 0 .and. T_Conn(i,1:i-1) /=j .and. T_Conn(i,1:i-1) /=k),dim=1)
43893
43894             l=0
43895             if (nc1 > 0) then
43896                do
43897                   l=minloc(T_Dist(k,1:i-1),dim=1, mask=(T_Dist(k,1:i-1) > 0.0))
43898                   if (l == j .or. l == k) then
43899                      T_Dist(k,l)=-T_Dist(k,l)
43900                      cycle
43901                   else
43902                      exit
43903                   end if
43904                end do
43905             elseif (nc2 > 0) then
43906                do
43907                   l=minloc(T_Dist(j,1:i-1),dim=1, mask=(T_Dist(j,1:i-1) > 0.0))
43908                   if (l == j .or. l == k) then
43909                      T_Dist(j,l)=-T_Dist(j,l)
43910                      cycle
43911                   else
43912                      exit
43913                   end if
43914                end do
43915             elseif (nc3 > 0) then
43916                do
43917                   l=minloc(T_Dist(i,1:i-1),dim=1, mask=(T_Dist(i,1:i-1) > 0.0))
43918                   if (l == j .or. l == k) then
43919                      T_Dist(i,l)=-T_Dist(i,l)
43920                      cycle
43921                   else
43922                      exit
43923                   end if
43924                end do
43925             end if
43926             if (l==0) then
43927                !---- Elegir uno cualquiera ----!
43928                do m=1,i-1
43929                   if (m == j .or. m == k) cycle
43930                   l=m
43931                   exit
43932                end do
43933             end if
43934             T_N(3,i)=l
43935          end if
43936          T_Dist=abs(T_Dist)
43937
43938       end do
43939
43940       !---- Final Part ----!
43941       do i=1, molecule%natoms
43942          molecule%Conn(:,i)=T_N(:,i)
43943          select case (i)
43944             case (2)
43945                if (T_N(1,i) == 0) then
43946                   err_molec=.true.
43947                   ERR_Molec_Mess="Error in Connectivity: Some Index are zeros"
43948                end if
43949             case (3)
43950                if (any(T_N(1:2,i) == 0)) then
43951                   err_molec=.true.
43952                   ERR_Molec_Mess="Error in Connectivity: Some Index are zeros"
43953                end if
43954             case (4:)
43955                if (any(T_N(:,i) == 0)) then
43956                   err_molec=.true.
43957                   ERR_Molec_Mess="Error in Connectivity: Some Index are zeros"
43958                end if
43959          end select
43960       end do
43961
43962       return
43963    End Subroutine Create_Connectivity_Cartesian
43964
43965    !!----
43966    !!---- Subroutine Fix_Reference(Molecule, NewMolecule, NAtom_O, NAtom_X, NAtom_XY)
43967    !!----    type (Molecule_type),     intent(in out)           :: Molecule
43968    !!----    type (Molecule_type),     intent(   out), optional :: Newmolecule
43969    !!----    integer,                  intent(in),     optional :: NAtom_O
43970    !!----    integer,                  intent(in),     optional :: NAtom_X
43971    !!----    integer,                  intent(in),     optional :: NAtom_XY
43972    !!----
43973    !!----    Subroutine to order the molecule choosing which atom is the origin,
43974    !!----    which define the X axis and which defines the XY Plane
43975    !!----    If the second argument is present the subroutine creates a new molecule
43976    !!----    preserving the input molecule in Cartesian. Otherwise the input molecule is
43977    !!----    changed on output.
43978    !!----    If Natom_0 is absent, then the first atom on the molecule will be the origin.
43979    !!----    If Natom_X is absent, then the second atom on the molecule will define the X axis.
43980    !!----    If Natom_XY is absent, then the third atom on the molecule will define the XY Plane.
43981    !!----    Control of error is present
43982    !!----
43983    !!---- Update: February - 2005
43984    !!
43985    Subroutine Fix_Reference(Molecule, NewMolecule, NAtom_O, NAtom_X, NAtom_XY)
43986       !---- Arguments ----!
43987       type (Molecule_type),     intent(in out)           :: Molecule
43988       type (Molecule_type),     intent(   out), optional :: Newmolecule
43989       integer,                  intent(in),     optional :: NAtom_O
43990       integer,                  intent(in),     optional :: NAtom_X
43991       integer,                  intent(in),     optional :: NAtom_XY
43992
43993       !---- Local variables ----!
43994       integer                   :: n_or, n_x, n_xy
43995       integer                   :: i
43996       type (Molecule_type)      :: Newmol,SetMol
43997
43998       !---- Initialize ----!
43999       n_or=1
44000       n_x =2
44001       n_xy=3
44002       if (present(natom_O))  n_or=natom_o
44003       if (present(natom_x))  n_x =natom_x
44004       if (present(natom_xy)) n_xy=natom_xy
44005
44006       call Init_Err_Molec()
44007
44008       if (n_x == n_or) then
44009          err_molec=.true.
44010          ERR_Molec_Mess="The atom defining origin and X axis is the same"
44011          return
44012       end if
44013
44014       if (n_xy == n_or .or. n_xy ==n_x) then
44015          err_molec=.true.
44016          ERR_Molec_Mess="The atom defining the Plane XY is equal to the origin or that define the X axis"
44017          return
44018       end if
44019
44020       if (molecule%natoms > 0) call Init_Molecule(Newmol,molecule%natoms)
44021       Newmol=molecule
44022
44023       !---- Sorting the Atom List ----!
44024       call init_molecule(SetMol,1)
44025
44026       !---- Fix Origin ----!
44027       if (n_or /= 1) then
44028          SetMol%AtName(1)    =NewMol%AtName(n_or)
44029          SetMol%AtSymb(1)    =NewMol%AtSymb(n_or)
44030          SetMol%AtZ(1)       =NewMol%AtZ(n_or)
44031          SetMol%Ptr(:,1)     =NewMol%Ptr(:,n_or)
44032          SetMol%I_Coor(:,1)  =NewMol%I_Coor(:,n_or)
44033          SetMol%mI_Coor(:,1) =NewMol%mI_Coor(:,n_or)
44034          SetMol%lI_Coor(:,1) =NewMol%lI_Coor(:,n_or)
44035          SetMol%Biso(1)      =NewMol%Biso(n_or)
44036          SetMol%mbiso(1)     =NewMol%mbiso(n_or)
44037          SetMol%lBiso(1)     =NewMol%lBiso(n_or)
44038          SetMol%Occ(1)       =NewMol%Occ(n_or)
44039          SetMol%mocc(1)      =NewMol%mocc(n_or)
44040          SetMol%lOcc(1)      =NewMol%lOcc(n_or)
44041          SetMol%Nb(1)        =NewMol%Nb(n_or)
44042          SetMol%INb(:,1)     =NewMol%INb(:,n_or)
44043          SetMol%Tb(:,1)      =NewMol%Tb(:,n_or)
44044          SetMol%Conn(:,1)    =NewMol%Conn(:,n_or)
44045
44046          NewMol%AtName(2:n_or)    =NewMol%AtName(1:n_or-1)
44047          NewMol%AtSymb(2:n_or)    =NewMol%AtSymb(1:n_or-1)
44048          NewMol%AtZ(2:n_or)       =NewMol%AtZ(1:n_or-1)
44049          NewMol%Ptr(:,2:n_or)     =NewMol%Ptr(:,1:n_or-1)
44050          NewMol%I_Coor(:,2:n_or)  =NewMol%I_Coor(:,1:n_or-1)
44051          NewMol%mI_Coor(:,2:n_or) =NewMol%mI_Coor(:,1:n_or-1)
44052          NewMol%lI_Coor(:,2:n_or) =NewMol%lI_Coor(:,1:n_or-1)
44053          NewMol%Biso(2:n_or)      =NewMol%Biso(1:n_or-1)
44054          NewMol%mbiso(2:n_or)     =NewMol%mbiso(1:n_or-1)
44055          NewMol%lBiso(2:n_or)     =NewMol%lBiso(1:n_or-1)
44056          NewMol%Occ(2:n_or)       =NewMol%Occ(1:n_or-1)
44057          NewMol%mocc(2:n_or)      =NewMol%mocc(1:n_or-1)
44058          NewMol%lOcc(2:n_or)      =NewMol%lOcc(1:n_or-1)
44059          NewMol%Nb(2:n_or)        =NewMol%Nb(1:n_or-1)
44060          NewMol%INb(:,2:n_or)     =NewMol%INb(:,1:n_or-1)
44061          NewMol%Tb(:,2:n_or)      =NewMol%Tb(:,1:n_or-1)
44062          NewMol%Conn(:,2:n_or)    =NewMol%Conn(:,1:n_or-1)
44063
44064          NewMol%AtName(1)    =SetMol%AtName(1)
44065          NewMol%AtSymb(1)    =SetMol%AtSymb(1)
44066          NewMol%AtZ(1)       =SetMol%AtZ(1)
44067          NewMol%Ptr(:,1)     =SetMol%Ptr(:,1)
44068          NewMol%I_Coor(:,1)  =SetMol%I_Coor(:,1)
44069          NewMol%mI_Coor(:,1) =SetMol%mI_Coor(:,1)
44070          NewMol%lI_Coor(:,1) =SetMol%lI_Coor(:,1)
44071          NewMol%Biso(1)      =SetMol%Biso(1)
44072          NewMol%mbiso(1)     =SetMol%mbiso(1)
44073          NewMol%lBiso(1)     =SetMol%lBiso(1)
44074          NewMol%Occ(1)       =SetMol%Occ(1)
44075          NewMol%mocc(1)      =SetMol%mocc(1)
44076          NewMol%lOcc(1)      =SetMol%lOcc(1)
44077          NewMol%Nb(1)        =SetMol%Nb(1)
44078          NewMol%INb(:,1)     =SetMol%INb(:,1)
44079          NewMol%Tb(:,1)      =SetMol%Tb(:,1)
44080          NewMol%Conn(:,1)    =SetMol%Conn(:,1)
44081
44082          if (Newmol%is_connect) then
44083             do i=1,n_or
44084                if (newmol%conn(1,i) == n_or) then
44085                   newmol%conn(1,i)=1
44086                else if (newmol%conn(1,i) < n_or) then
44087                   newmol%conn(1,i)=newmol%conn(1,i)+1
44088                end if
44089
44090                if (newmol%conn(2,i) == n_or) then
44091                   newmol%conn(2,i)=1
44092                else if (newmol%conn(2,i) < n_or) then
44093                   newmol%conn(2,i)=newmol%conn(2,i)+1
44094                end if
44095
44096                if (newmol%conn(3,i) == n_or) then
44097                   newmol%conn(3,i)=1
44098                else if (newmol%conn(3,i) < n_or) then
44099                   newmol%conn(3,i)=newmol%conn(3,i)+1
44100                end if
44101             end do
44102          end if
44103
44104          if (n_x < n_or) then
44105             n_x=n_x+1
44106          end if
44107          if (n_xy < n_or) then
44108             n_xy=n_xy+1
44109          end if
44110       end if
44111
44112       !---- Fix X Axis ----!
44113       if (n_x /= 2) then
44114
44115          SetMol%AtName(1)    =NewMol%AtName(n_x)
44116          SetMol%AtSymb(1)    =NewMol%AtSymb(n_x)
44117          SetMol%AtZ(1)       =NewMol%AtZ(n_x)
44118          SetMol%Ptr(:,1)     =NewMol%Ptr(:,n_x)
44119          SetMol%I_Coor(:,1)  =NewMol%I_Coor(:,n_x)
44120          SetMol%mI_Coor(:,1) =NewMol%mI_Coor(:,n_x)
44121          SetMol%lI_Coor(:,1) =NewMol%lI_Coor(:,n_x)
44122          SetMol%Biso(1)      =NewMol%Biso(n_x)
44123          SetMol%mbiso(1)     =NewMol%mbiso(n_x)
44124          SetMol%lBiso(1)     =NewMol%lBiso(n_x)
44125          SetMol%Occ(1)       =NewMol%Occ(n_x)
44126          SetMol%mocc(1)      =NewMol%mocc(n_x)
44127          SetMol%lOcc(1)      =NewMol%lOcc(n_x)
44128          SetMol%Nb(1)        =NewMol%Nb(n_x)
44129          SetMol%INb(:,1)     =NewMol%INb(:,n_x)
44130          SetMol%Tb(:,1)      =NewMol%Tb(:,n_x)
44131          SetMol%Conn(:,1)    =NewMol%Conn(:,n_x)
44132
44133          NewMol%AtName(3:n_x)    =NewMol%AtName(2:n_x-1)
44134          NewMol%AtSymb(3:n_x)    =NewMol%AtSymb(2:n_x-1)
44135          NewMol%AtZ(3:n_x)       =NewMol%AtZ(2:n_x-1)
44136          NewMol%Ptr(:,3:n_x)     =NewMol%Ptr(:,2:n_x-1)
44137          NewMol%I_Coor(:,3:n_x)  =NewMol%I_Coor(:,2:n_x-1)
44138          NewMol%mI_Coor(:,3:n_x) =NewMol%mI_Coor(:,2:n_x-1)
44139          NewMol%lI_Coor(:,3:n_x) =NewMol%lI_Coor(:,2:n_x-1)
44140          NewMol%Biso(3:n_x)      =NewMol%Biso(2:n_x-1)
44141          NewMol%mbiso(3:n_x)     =NewMol%mbiso(2:n_x-1)
44142          NewMol%lBiso(3:n_x)     =NewMol%lBiso(2:n_x-1)
44143          NewMol%Occ(3:n_x)       =NewMol%Occ(2:n_x-1)
44144          NewMol%mocc(3:n_x)      =NewMol%mocc(2:n_x-1)
44145          NewMol%lOcc(3:n_x)      =NewMol%lOcc(2:n_x-1)
44146          NewMol%Nb(3:n_x)        =NewMol%Nb(2:n_x-1)
44147          NewMol%INb(:,3:n_x)     =NewMol%INb(:,2:n_x-1)
44148          NewMol%Tb(:,3:n_x)      =NewMol%Tb(:,2:n_x-1)
44149          NewMol%Conn(:,3:n_x)    =NewMol%Conn(:,2:n_x-1)
44150
44151          NewMol%AtName(2)    =SetMol%AtName(1)
44152          NewMol%AtSymb(2)    =SetMol%AtSymb(1)
44153          NewMol%AtZ(2)       =SetMol%AtZ(1)
44154          NewMol%Ptr(:,2)     =SetMol%Ptr(:,1)
44155          NewMol%I_Coor(:,2)  =SetMol%I_Coor(:,1)
44156          NewMol%mI_Coor(:,2) =SetMol%mI_Coor(:,1)
44157          NewMol%lI_Coor(:,2) =SetMol%lI_Coor(:,1)
44158          NewMol%Biso(2)      =SetMol%Biso(1)
44159          NewMol%mbiso(2)     =SetMol%mbiso(1)
44160          NewMol%lBiso(2)     =SetMol%lBiso(1)
44161          NewMol%Occ(2)       =SetMol%Occ(1)
44162          NewMol%mocc(2)      =SetMol%mocc(1)
44163          NewMol%lOcc(2)      =SetMol%lOcc(1)
44164          NewMol%Nb(2)        =SetMol%Nb(1)
44165          NewMol%INb(:,2)     =SetMol%INb(:,1)
44166          NewMol%Tb(:,2)      =SetMol%Tb(:,1)
44167          NewMol%Conn(:,2)    =SetMol%Conn(:,1)
44168
44169          if (Newmol%is_connect) then
44170             do i=1,n_x
44171                if (newmol%conn(1,i) == n_x) then
44172                   newmol%conn(1,i)=2
44173                else if (newmol%conn(1,i) < n_x .and. newmol%conn(1,i) > 1) then
44174                   newmol%conn(1,i)=newmol%conn(1,i)+1
44175                end if
44176
44177                if (newmol%conn(2,i) == n_x) then
44178                   newmol%conn(2,i)=2
44179                else if (newmol%conn(2,i) < n_x .and. newmol%conn(2,i) > 1) then
44180                   newmol%conn(2,i)=newmol%conn(2,i)+1
44181                end if
44182
44183                if (newmol%conn(3,i) == n_x) then
44184                   newmol%conn(3,i)=2
44185                else if (newmol%conn(3,i) < n_x .and. newmol%conn(3,i) > 1) then
44186                   newmol%conn(3,i)=newmol%conn(3,i)+1
44187                end if
44188             end do
44189          end if
44190          if (n_xy < n_x) then
44191             n_xy=n_xy+1
44192          end if
44193       end if
44194
44195       !---- Fix XY Plane ----!
44196       if (n_xy /= 3) then
44197
44198          SetMol%AtName(1)    =NewMol%AtName(n_xy)
44199          SetMol%AtSymb(1)    =NewMol%AtSymb(n_xy)
44200          SetMol%AtZ(1)       =NewMol%AtZ(n_xy)
44201          SetMol%Ptr(:,1)     =NewMol%Ptr(:,n_xy)
44202          SetMol%I_Coor(:,1)  =NewMol%I_Coor(:,n_xy)
44203          SetMol%mI_Coor(:,1) =NewMol%mI_Coor(:,n_xy)
44204          SetMol%lI_Coor(:,1) =NewMol%lI_Coor(:,n_xy)
44205          SetMol%Biso(1)      =NewMol%Biso(n_xy)
44206          SetMol%mbiso(1)     =NewMol%mbiso(n_xy)
44207          SetMol%lBiso(1)     =NewMol%lBiso(n_xy)
44208          SetMol%Occ(1)       =NewMol%Occ(n_xy)
44209          SetMol%mocc(1)      =NewMol%mocc(n_xy)
44210          SetMol%lOcc(1)      =NewMol%lOcc(n_xy)
44211          SetMol%Nb(1)        =NewMol%Nb(n_xy)
44212          SetMol%INb(:,1)     =NewMol%INb(:,n_xy)
44213          SetMol%Tb(:,1)      =NewMol%Tb(:,n_xy)
44214          SetMol%Conn(:,1)    =NewMol%Conn(:,n_xy)
44215
44216          NewMol%AtName(4:n_xy)    =NewMol%AtName(3:n_xy-1)
44217          NewMol%AtSymb(4:n_xy)    =NewMol%AtSymb(3:n_xy-1)
44218          NewMol%AtZ(4:n_xy)       =NewMol%AtZ(3:n_xy-1)
44219          NewMol%Ptr(:,4:n_xy)     =NewMol%Ptr(:,3:n_xy-1)
44220          NewMol%I_Coor(:,4:n_xy)  =NewMol%I_Coor(:,3:n_xy-1)
44221          NewMol%mI_Coor(:,4:n_xy) =NewMol%mI_Coor(:,3:n_xy-1)
44222          NewMol%lI_Coor(:,4:n_xy) =NewMol%lI_Coor(:,3:n_xy-1)
44223          NewMol%Biso(4:n_xy)      =NewMol%Biso(3:n_xy-1)
44224          NewMol%mbiso(4:n_xy)     =NewMol%mbiso(3:n_xy-1)
44225          NewMol%lBiso(4:n_xy)     =NewMol%lBiso(3:n_xy-1)
44226          NewMol%Occ(4:n_xy)       =NewMol%Occ(3:n_xy-1)
44227          NewMol%mocc(4:n_xy)      =NewMol%mocc(3:n_xy-1)
44228          NewMol%lOcc(4:n_xy)      =NewMol%lOcc(3:n_xy-1)
44229          NewMol%Nb(4:n_xy)        =NewMol%Nb(3:n_xy-1)
44230          NewMol%INb(:,4:n_xy)     =NewMol%INb(:,3:n_xy-1)
44231          NewMol%Tb(:,4:n_xy)      =NewMol%Tb(:,3:n_xy-1)
44232          NewMol%Conn(:,4:n_xy)    =NewMol%Conn(:,3:n_xy-1)
44233
44234          NewMol%AtName(3)    =SetMol%AtName(1)
44235          NewMol%AtSymb(3)    =SetMol%AtSymb(1)
44236          NewMol%AtZ(3)       =SetMol%AtZ(1)
44237          NewMol%Ptr(:,3)     =SetMol%Ptr(:,1)
44238          NewMol%I_Coor(:,3)  =SetMol%I_Coor(:,1)
44239          NewMol%mI_Coor(:,3) =SetMol%mI_Coor(:,1)
44240          NewMol%lI_Coor(:,3) =SetMol%lI_Coor(:,1)
44241          NewMol%Biso(3)      =SetMol%Biso(1)
44242          NewMol%mbiso(3)     =SetMol%mbiso(1)
44243          NewMol%lBiso(3)     =SetMol%lBiso(1)
44244          NewMol%Occ(3)       =SetMol%Occ(1)
44245          NewMol%mocc(3)      =SetMol%mocc(1)
44246          NewMol%lOcc(3)      =SetMol%lOcc(1)
44247          NewMol%Nb(3)        =SetMol%Nb(1)
44248          NewMol%INb(:,3)     =SetMol%INb(:,1)
44249          NewMol%Tb(:,3)      =SetMol%Tb(:,1)
44250          NewMol%Conn(:,3)    =SetMol%Conn(:,1)
44251
44252          if (Newmol%is_connect) then
44253             do i=1,n_xy
44254                if (newmol%conn(1,i) == n_xy) then
44255                   newmol%conn(1,i)=3
44256                else if (newmol%conn(1,i) < n_xy .and. newmol%conn(1,i) > 2) then
44257                   newmol%conn(1,i)=newmol%conn(1,i)+1
44258                end if
44259
44260                if (newmol%conn(2,i) == n_xy) then
44261                   newmol%conn(2,i)=3
44262                else if (newmol%conn(2,i) < n_xy .and. newmol%conn(2,i) > 2) then
44263                   newmol%conn(2,i)=newmol%conn(2,i)+1
44264                end if
44265
44266                if (newmol%conn(3,i) == n_xy) then
44267                   newmol%conn(3,i)=3
44268                else if (newmol%conn(3,i) < n_xy .and. newmol%conn(3,i) > 2) then
44269                   newmol%conn(3,i)=newmol%conn(3,i)+1
44270                end if
44271             end do
44272          end if
44273       end if
44274
44275       if (present(Newmolecule)) then
44276          call Init_molecule(NewMolecule,Newmol%natoms)
44277          if (NewMolecule%natoms <=0) then
44278             err_molec=.true.
44279             ERR_Molec_Mess="Error in Fix_Reference: The optional variable was not dimensioned!"
44280             return
44281          end if
44282          Newmolecule=Newmol
44283       else
44284          Molecule=Newmol
44285       end if
44286
44287       return
44288    End Subroutine Fix_Reference
44289
44290    !!----
44291    !!---- Subroutine Fix_Orient_Cartesian(Molecule, NewMolecule, NAtom_O, NAtom_X, NAtom_XY,Mat)
44292    !!----    type (Molecule_type),     intent(in out)           :: Molecule
44293    !!----    type (Molecule_type),     intent(   out), optional :: Newmolecule
44294    !!----    integer,                  intent(in),     optional :: NAtom_O
44295    !!----    integer,                  intent(in),     optional :: NAtom_X
44296    !!----    integer,                  intent(in),     optional :: NAtom_XY
44297    !!----    real(kind=cp),dimension(3,3),intent(out), optional :: Mat
44298    !!----
44299    !!----    Subroutine to transform the Cartesian coordinates of the molecule choosing
44300    !!----    which atom is the origin, which define the X axis and which defines the XY Plane
44301    !!----    If the second argument is present the subroutine creates a new molecule
44302    !!----    preserving the input molecule in Cartesian. Otherwise the input molecule is
44303    !!----    changed on output.
44304    !!----    If Natom_0 is absent, then the first atom on the molecule will be the origin.
44305    !!----    If Natom_X is absent, then the second atom on the molecule will define the X axis.
44306    !!----    If Natom_XY is absent, then the third atom on the molecule will define the XY Plane.
44307    !!----    The optional output matrix Mat is the active rotation matrix passing from the old
44308    !!----    Cartesian frame to the new one. The transpose matrix has served to transform the
44309    !!----    original Cartesian coordinates.
44310    !!----    Control of error is present
44311    !!----
44312    !!---- Update: February - 2005
44313    !!
44314    Subroutine Fix_Orient_Cartesian(Molecule, NewMolecule, NAtom_O, NAtom_X, NAtom_XY,Mat)
44315       !---- Arguments ----!
44316       type (Molecule_type),     intent(in out)           :: Molecule
44317       type (Molecule_type),     intent(   out), optional :: Newmolecule
44318       integer,                  intent(in),     optional :: NAtom_O
44319       integer,                  intent(in),     optional :: NAtom_X
44320       integer,                  intent(in),     optional :: NAtom_XY
44321       real(kind=cp),dimension(3,3),intent(out), optional :: Mat
44322
44323       !---- Local variables ----!
44324       integer                       :: n_or, n_x, n_xy
44325       integer                       :: i
44326       real(kind=cp),dimension(3)    :: u1,u2,u3
44327       real(kind=cp),dimension(3,3)  :: R
44328       type (Molecule_type)          :: Newmol
44329
44330       n_or=1
44331       n_x =2
44332       n_xy=3
44333       if (present(natom_O))  n_or=natom_o
44334       if (present(natom_x))  n_x =natom_x
44335       if (present(natom_xy)) n_xy=natom_xy
44336
44337       if (molecule%natoms > 0) call Init_Molecule(Newmol,molecule%natoms)
44338       call Fix_Reference(Molecule,Newmol,n_or,n_x,n_xy)
44339       if (err_molec) return
44340
44341       !---- Traslation the Origin ----!
44342       do i=2,Newmol%natoms
44343          newmol%I_coor(:,i)=newmol%I_coor(:,i)-newmol%I_coor(:,1)
44344       end do
44345       newmol%I_coor(:,1)=0.0
44346
44347       u1=Newmol%I_coor(:,2)
44348       u1=u1/sqrt(dot_product(u1,u1))
44349       u2=Newmol%I_coor(:,3)
44350       u3=cross_product(u1,u2)
44351       u3=u3/sqrt(dot_product(u3,u3))
44352       u2=cross_product(u3,u1)
44353       R(1,:)=u1
44354       R(2,:)=u2  !Passive matrix needed to get the new coordinates
44355       R(3,:)=u3  !The active matrix can be output in the optional argument
44356       if (present(Mat)) Mat=transpose(R)
44357
44358       do i=2,Newmol%natoms
44359          newmol%I_coor(:,i)=matmul(R,newmol%I_coor(:,i))
44360       end do
44361
44362       if (present(Newmolecule)) then
44363          if (NewMol%natoms <=0) then
44364             err_molec=.true.
44365             ERR_Molec_Mess="Error in Fix_Orient_Cartesian: The optional variable was not dimensioned!"
44366             return
44367          end if
44368          Newmolecule=Newmol
44369       else
44370          Molecule=Newmol
44371       end if
44372
44373       return
44374    End Subroutine Fix_Orient_Cartesian
44375
44376    !!----
44377    !!---- Subroutine Empiric_Formula(Atm/Molcrys/Molecule,Formula,Form_Weight)
44378    !!----    type(Atom_List_Type),          intent(in)  :: Atm
44379    !!----    or
44380    !!----    type(molecular_crystal_type),  intent(in)  :: Molcrys
44381    !!----    or
44382    !!----    type(molecule_type),           intent(in)  :: Molecule
44383    !!----    character(len=*),              intent(out) :: Formula
44384    !!----    real(kind=cp), optional,       intent(out) :: Form_Weight
44385    !!----
44386    !!----    Obtain the Empiric Formula from Atm/Molcrys/Molecule variable
44387    !!----
44388    !!---- Update: February - 2005
44389    !!
44390
44391    !!--++
44392    !!--++ Subroutine Empiric_Formula_FAtom(Atm,Formula,Form_Weight)
44393    !!--++    type(Atom_List_Type),    intent(in)  :: Atm
44394    !!--++    character(len=*),        intent(out) :: Formula
44395    !!--++    real(kind=cp), optional, intent(out) :: Form_Weight
44396    !!--++
44397    !!--++    (OVERLOADED)
44398    !!--++    Obtain the Empiric Formula from Atm variable
44399    !!--++
44400    !!--++ Update: February - 2005
44401    !!
44402    Subroutine Empiric_Formula_FAtom(Atm,Formula,Form_Weight)
44403       !---- Arguments ----!
44404       type(Atom_List_Type),     intent(in)  :: Atm
44405       character(len=*),         intent(out) :: Formula
44406       real(kind=cp), optional,  intent(out) :: Form_Weight
44407
44408       !---- Local variables ----!
44409       character(len=2)                  :: car
44410       character(len=5)                  :: numcar
44411       integer                           :: i,j
44412       integer, dimension(Num_Chem_Info) :: N_PT
44413       real(kind=cp)                     :: weight
44414
44415       !---- Init ----!
44416       N_PT=0
44417       weight=0.0
44418
44419       Formula=" "
44420       if (Atm%natoms <= 0) then
44421          if (present(Form_weight)) Form_weight=0.0
44422          return
44423       end if
44424
44425       !---- Set Information Table ----!
44426       call Set_Chem_Info()
44427
44428       do i=1,atm%natoms
44429          car=atm%atom(i)%chemsymb
44430          car=u_case(car)
44431          do j=1,Num_Chem_Info
44432             if (car == Chem_Info(j)%Symb) then
44433                n_pt(j)=n_pt(j)+1
44434                exit
44435             end if
44436          end do
44437       end do
44438
44439       if (all (n_pt ==0)) then
44440          if (present(Form_weight)) Form_weight=0.0
44441          call Remove_Chem_Info()
44442          return
44443       end if
44444
44445       do i=1,Num_Chem_Info
44446          if (n_pt(i) == 0) cycle
44447          car=Chem_Info(i)%Symb
44448          car(2:2)=l_case(car(2:2))
44449          write(unit=numcar,fmt="(i5)") n_pt(i)
44450          Formula=trim(Formula)//trim(car)//adjustl(numcar)
44451          weight=weight+n_pt(i)*Chem_Info(i)%atwe
44452       end do
44453
44454       call Remove_Chem_Info()
44455
44456       if (present(Form_weight)) Form_weight=weight
44457
44458       return
44459    End Subroutine Empiric_Formula_FAtom
44460
44461    !!--++
44462    !!--++ Subroutine Empiric_Formula_Molcrys(Molcrys,Formula,Form_Weight)
44463    !!--++    type(molecular_crystal_type), intent(in)  :: Molcrys
44464    !!--++    character(len=*),             intent(out) :: Formula
44465    !!--++    real(kind=cp), optional,      intent(out) :: Form_Weight
44466    !!--++
44467    !!--++    (Overloaded)
44468    !!--++    Obtain the Empiric Formula from Molecule variable and
44469    !!--++    the Weight is the variable is present.
44470    !!--++
44471    !!--++ Update: February - 2005
44472    !!
44473    Subroutine Empiric_Formula_Molcrys(Molcrys,Formula,Form_Weight)
44474       !---- Arguments ----!
44475       type(molecular_crystal_type), intent(in)  :: Molcrys
44476       character(len=*),             intent(out) :: Formula
44477       real(kind=cp), optional,      intent(out) :: Form_Weight
44478
44479       !---- Local variables ----!
44480       character(len=2)                  :: car
44481       character(len=5)                  :: numcar
44482       integer                           :: i,j,k
44483       integer, dimension(Num_Chem_Info) :: N_PT
44484       real(kind=cp)                     :: weight
44485
44486
44487       !---- Init ----!
44488       N_PT=0
44489       weight=0.0
44490
44491       Formula=" "
44492
44493       if (molcrys%n_free <= 0 .and. molcrys%n_mol <=0) then
44494          if (present(Form_weight)) Form_weight=0.0
44495          return
44496       end if
44497
44498       !---- Set Information Table ----!
44499       call Set_Chem_Info()
44500
44501       do i=1,molcrys%n_free
44502          car=molcrys%atm(i)%chemsymb
44503          car=u_case(car)
44504          do j=1,Num_Chem_Info
44505             if (car == Chem_Info(j)%Symb) then
44506                n_pt(j)=n_pt(j)+1
44507                exit
44508             end if
44509          end do
44510       end do
44511
44512       do k=1,molcrys%n_mol
44513          do i=1,molcrys%mol(k)%natoms
44514                 car=molcrys%mol(k)%atsymb(i)
44515             car=u_case(car)
44516             do j=1,Num_Chem_Info
44517                if (car == Chem_Info(j)%Symb) then
44518                   n_pt(j)=n_pt(j)+1
44519                   exit
44520                end if
44521             end do
44522          end do
44523       end do
44524
44525       if (all (n_pt ==0)) then
44526          if (present(Form_weight)) Form_weight=0.0
44527          call Remove_Chem_Info()
44528          return
44529       end if
44530
44531       do i=1,Num_Chem_Info
44532          if (n_pt(i) == 0) cycle
44533          car=Chem_Info(i)%Symb
44534          car(2:2)=l_case(car(2:2))
44535          write(unit=numcar,fmt="(i5)") n_pt(i)
44536          Formula=trim(Formula)//trim(car)//adjustl(numcar)
44537          weight=weight+n_pt(i)*Chem_Info(i)%atwe
44538       end do
44539
44540       call Remove_Chem_Info()
44541
44542       if (present(Form_weight)) Form_weight=weight
44543
44544       return
44545    End Subroutine Empiric_Formula_Molcrys
44546
44547    !!--++
44548    !!--++ Subroutine Empiric_Formula_Molec(Molecule,Formula,Form_Weight)
44549    !!--++    type(molecule_type),     intent(in)  :: Molecule
44550    !!--++    character(len=*),        intent(out) :: Formula
44551    !!--++    real(kind=cp), optional, intent(out) :: Form_Weight
44552    !!--++
44553    !!--++    (Overloaded)
44554    !!--++    Obtain the Empiric Formula from Molecule variable and
44555    !!--++    the Weight is the variable is present.
44556    !!--++
44557    !!--++ Update: February - 2005
44558    !!
44559    Subroutine Empiric_Formula_Molec(Molecule,Formula,Form_Weight)
44560       !---- Arguments ----!
44561       type(molecule_type),      intent(in)  :: Molecule
44562       character(len=*),         intent(out) :: Formula
44563       real(kind=cp), optional,  intent(out) :: Form_Weight
44564
44565       !---- Local variables ----!
44566       character(len=2)                  :: car
44567       character(len=5)                  :: numcar
44568       integer                           :: i,j
44569       integer, dimension(Num_Chem_Info) :: N_PT
44570       real(kind=cp)                     :: weight
44571
44572       !---- Init ----!
44573       N_PT=0
44574       weight=0.0
44575
44576       Formula=" "
44577       if (molecule%natoms <= 0) then
44578          if (present(Form_weight)) Form_weight=0.0
44579          return
44580       end if
44581
44582       !---- Set Information Table ----!
44583       call Set_Chem_Info()
44584
44585       do i=1,molecule%natoms
44586          call Get_ChemSymb(molecule%atsymb(i),car)
44587          car=u_case(car)
44588          do j=1,Num_Chem_Info
44589             if (car == Chem_Info(j)%Symb) then
44590                n_pt(j)=n_pt(j)+1
44591                exit
44592             end if
44593          end do
44594       end do
44595
44596       if (all (n_pt ==0)) then
44597          if (present(Form_weight)) Form_weight=0.0
44598          call Remove_Chem_Info()
44599          return
44600       end if
44601
44602       do i=1,Num_Chem_Info
44603          if (n_pt(i) == 0) cycle
44604          car=Chem_Info(i)%Symb
44605          car(2:2)=l_case(car(2:2))
44606          write(unit=numcar,fmt="(i5)") n_pt(i)
44607          Formula=trim(Formula)//trim(car)//adjustl(numcar)
44608          weight=weight+n_pt(i)*Chem_Info(i)%atwe
44609       end do
44610
44611       call Remove_Chem_Info()
44612
44613       if (present(Form_weight)) Form_weight=weight
44614
44615       return
44616    End Subroutine Empiric_Formula_Molec
44617
44618    !!----
44619    !!---- Subroutine Fractional_to_Cartesian(Molecule,Cell,NewMolecule)
44620    !!----    type (Molecule_type),     intent(in out)           :: Molecule
44621    !!----    type (Crystal_Cell_Type), intent(in    )           :: Cell
44622    !!----    type (Molecule_type),     intent(   out), optional :: Newmolecule
44623    !!----
44624    !!----    Subroutine to transform the fractional coordinates to cartesian internal
44625    !!----    coordinates of a molecule.
44626    !!----    If Newmolecule is present the subroutine creates a new molecule
44627    !!----    (copy of the old one) with cartesian coordinates, preserving
44628    !!----    the input molecule in fractional. Otherwise the input molecule is
44629    !!----    changed on output.
44630    !!----    Control of error is present
44631    !!----
44632    !!---- Update: February - 2005
44633    !!
44634    Subroutine Fractional_to_Cartesian(Molecule,Cell,NewMolecule)
44635       !---- Arguments ----!
44636       type (Molecule_type),     intent(in out)           :: Molecule
44637       type (Crystal_Cell_Type), intent(in    )           :: Cell
44638       type (Molecule_type),     intent(   out), optional :: NewMolecule
44639
44640       !---- Local variables -----!
44641       integer                       :: i, na
44642       real(kind=cp)                 :: phi,theta,chi
44643       real(kind=cp), dimension(3)   :: ci,xi
44644       real(kind=cp), dimension(3,3) :: Eu
44645
44646       type (Molecule_type)          :: Newmol
44647
44648       !---- Controls ----!
44649       if (molecule%coor_type /= "F") then
44650          err_molec=.true.
44651          ERR_Molec_Mess="Error in Fractional_to_Cartesian: the input molecule is not in fractional coordinates"
44652          return
44653       end if
44654
44655       na= Molecule%natoms
44656       if (na <= 0) then
44657          err_molec=.true.
44658          ERR_Molec_Mess="Error in Fractional_to_Cartesian: No atoms are defined"
44659          return
44660       end if
44661
44662       call Init_molecule(NewMol,na)
44663       NewMol=Molecule
44664
44665       if (molecule%in_xtal) then
44666          if (newmol%is_EulerMat) then
44667             Eu=newmol%Euler
44668          else
44669             phi=newmol%orient(1)
44670             theta=newmol%orient(2)
44671             chi=newmol%orient(3)
44672             Call Set_Euler_matrix(newmol%rot_type,phi,theta,chi,Eu)
44673             newmol%Euler=Eu
44674             newmol%is_EulerMat=.true.
44675          end if
44676
44677          !---- Newmol contains fractional coordinates ----!
44678          do i=1,newmol%natoms
44679             xi=newmol%I_coor(:,i) - newmol%xcentre !Fractional coordinates after removing translation
44680             ci=matmul(cell%Cr_Orth_cel,xi)       !Cartesian components in the Crystal Frame
44681             newmol%I_coor(1:3,i) = matmul(ci,Eu)   !Final Cartesian internal coordinates (use passive matrix!)
44682          end do
44683       else
44684          do i=1,newmol%natoms
44685             newmol%I_coor(:,i)=matmul(cell%cr_orth_cel,newmol%I_coor(:,i))
44686          end do
44687          call Fix_Orient_Cartesian(newmol)  ! Select the internal frame as needed for Z-matrices
44688       end if
44689       newmol%coor_type = "C"
44690
44691       if (present(NewMolecule)) then
44692          call Init_molecule(NewMolecule,Newmol%natoms)
44693          if (NewMolecule%natoms <=0) then
44694             err_molec=.true.
44695             ERR_Molec_Mess="Error in Fractional to Cartesian: The optional variable was not dimensioned!"
44696             return
44697          end if
44698          NewMolecule=newmol
44699       else
44700          Molecule=newmol
44701       end if
44702
44703       return
44704    End Subroutine Fractional_to_Cartesian
44705
44706    !!----
44707    !!---- Subroutine Fractional_to_Spherical(Molecule,Cell,NewMolecule)
44708    !!----    type (Molecule_type), intent(in out)           :: Molecule
44709    !!----    type (Crystal_Cell_Type), intent(in)           :: Cell
44710    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
44711    !!----
44712    !!----    Subroutine to transform the internal coordinates of a
44713    !!----    molecule from Fractional coordinates to  Spherical coordinaters.
44714    !!----    If a third argument is present the subroutine creates a new
44715    !!----    molecule (copy of the old one) with Spherical coordinates,
44716    !!----    preserving the input molecule in Fractional Coordinates. Otherwise
44717    !!----    the input molecule is changed on output.
44718    !!----    Control of error is present
44719    !!----
44720    !!---- Update: February - 2005
44721    !!
44722    Subroutine Fractional_to_Spherical(Molecule, Cell, NewMolecule)
44723       !---- Arguments ----!
44724       type (Molecule_type), intent(in out)           :: Molecule
44725       type (Crystal_Cell_Type), intent(in)           :: Cell
44726       type (Molecule_type), intent(   out), optional :: NewMolecule
44727
44728       !---- Local Variables ----!
44729       integer                     :: na
44730       type (Molecule_type)        :: Newmol
44731
44732       !---- Controls ----!
44733       if (molecule%coor_type /= "F") then
44734          err_molec=.true.
44735          ERR_Molec_Mess="Error in Fractional_to_Spherical: the input molecule is not in Fractional coordinates"
44736          return
44737       end if
44738
44739       na= Molecule%natoms
44740       if (na <= 0) then
44741          err_molec=.true.
44742          ERR_Molec_Mess="Error in Fractional_to_Spherical: No atoms are defined"
44743          return
44744       end if
44745
44746       !---- Step 1----!
44747       call init_molecule(NewMol,na)
44748       NewMol= Molecule
44749       call Fractional_to_Cartesian(NewMol,Cell)
44750       if (err_molec) then
44751          ERR_Molec_Mess="Error in Fractional_to_Spherical: Intermediate procedure fail (I)!"
44752          return
44753       end if
44754
44755       !---- Step 2 ----!
44756       call Cartesian_to_Spherical(NewMol)
44757       if (err_molec) then
44758          ERR_Molec_Mess="Error in Fractional_to_Spherical: Intermediate procedure fail (II)!"
44759          return
44760       end if
44761
44762       !---- Step 3 ----!
44763       if (present(newmolecule)) then
44764          call Init_molecule(NewMolecule,Newmol%natoms)
44765          if (NewMolecule%natoms <=0) then
44766             err_molec=.true.
44767             ERR_Molec_Mess="Error in Fractional to Spherical: The optional variable was not dimensioned!"
44768             return
44769          end if
44770          NewMolecule=newmol
44771       else
44772          Molecule=newmol
44773       end if
44774
44775       return
44776    End Subroutine Fractional_to_Spherical
44777
44778    !!----
44779    !!---- Subroutine Fractional_to_Zmatrix(Molecule,Cell,NewMolecule)
44780    !!----    type (Molecule_type), intent(in out)           :: Molecule
44781    !!----    type (Crystal_Cell_Type), intent(in)           :: Cell
44782    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
44783    !!----
44784    !!----    Subroutine to transform the internal coordinates of a
44785    !!----    molecule from Fractional coordinates to  Zmatrix coordinaters.
44786    !!----    If a second argument is present the subroutine creates a new
44787    !!----    molecule (copy of the old one) with Zmatrix coordinates,
44788    !!----    preserving the input molecule in Fractional Coordinates. Otherwise
44789    !!----    the input molecule is changed on output.
44790    !!----    Control of error is present
44791    !!----
44792    !!---- Update: February - 2005
44793    !!
44794    Subroutine Fractional_to_Zmatrix(Molecule,Cell,NewMolecule)
44795       !---- Arguments ----!
44796       type (Molecule_type), intent(in out)           :: Molecule
44797       type (Crystal_Cell_Type), intent(in)           :: Cell
44798       type (Molecule_type), intent(   out), optional :: NewMolecule
44799
44800       !---- Local Variables ----!
44801       integer                     :: na
44802       type (Molecule_type)        :: Newmol
44803
44804       !---- Controls ----!
44805       if (molecule%coor_type /= "F") then
44806          err_molec=.true.
44807          ERR_Molec_Mess="Error in Fractional_to_Zmatrix: the input molecule is not in Fractional coordinates"
44808          return
44809       end if
44810
44811       na= Molecule%natoms
44812       if (na <= 0) then
44813          err_molec=.true.
44814          ERR_Molec_Mess="Error in Fractional_to_Spherical: No atoms are defined"
44815          return
44816       end if
44817
44818       !---- Step 1----!
44819       call Init_Molecule(NewMol,na)
44820       NewMol=Molecule
44821       call Fractional_to_Cartesian(NewMol,Cell)
44822       if (err_molec) then
44823          ERR_Molec_Mess="Error in Fractional_to_Zmatrix: Intermediate procedure fail (I)!"
44824          return
44825       end if
44826
44827       !---- Step 2 ----!
44828       call Cartesian_to_Zmatrix(NewMol, Cell=Cell)  !The cell is needed to eventually take into account
44829       if (err_molec) then                           !a different Cartesian frame on the input molecule
44830          ERR_Molec_Mess="Error in Fractional_to_Zmatrix: Intermediate procedure fail (II)!"
44831          return
44832       end if
44833
44834       !---- Step 3 ----!
44835       if (present(newmolecule)) then
44836          call Init_molecule(NewMolecule,na)
44837          if (NewMolecule%natoms <=0) then
44838             err_molec=.true.
44839             ERR_Molec_Mess="Error in Fractional to ZMatrix: The optional variable was not dimensioned!"
44840             return
44841          end if
44842          NewMolecule=newmol
44843       else
44844          Molecule=newmol
44845       end if
44846
44847       return
44848    End Subroutine Fractional_to_Zmatrix
44849
44850    !!--++
44851    !!--++ Subroutine Get_Cartesian_from_Z(ci,ri,rj,rk,rn)
44852    !!--++    real, dimension(3), intent ( in) :: ci,rj,rj,rn
44853    !!--++    real, dimension(3), intent (out) :: ri
44854    !!--++
44855    !!--++    Subroutine to calculate the cartesian coordinates of an atom (i)
44856    !!--++    when its distance (dij=ci(1)) to another atom (j), the angle (aijk=ci(2))
44857    !!--++    spanned with another atom (k) centred at (j), the torsion angle
44858    !!--++    (bijkn=ci(3)) with a fourth atom (n) and the coordinates of
44859    !!--++    the three atoms (jkn), rj,rk,rn are all given.
44860    !!--++
44861    !!--<<    The algorithm used to determine the Cartesian coordinates of atom (i) is the
44862    !!--++    following:
44863    !!--++       - Select a local Cartesian frame with (j) at origin, x-axis along (jk),
44864    !!--++         z-axis perpendicular to the plane (jkn), y-axis right-handled frame
44865    !!--++            e1 = rjk/djk, e2 = e3 x e1,  e3= rjk x rkn / djk/dkn
44866    !!--++       - The above system determine a matrix M = (e1,e2,e3), with components ei in columns
44867    !!--++         that serves to transform interatomic vector components back to the original system.
44868    !!--++       - In the above system the coordinates of atom (i) is given by
44869    !!--++            ri = rj + M ui
44870    !!--++
44871    !!--++         where
44872    !!--++            ui = d ( cos(aijk), cos(bijkn) sin(aijk), sqrt(1 - cos(aijk)^2 -(cos(bijkn) sin(aijk))^2))
44873    !!-->>
44874    !!--++
44875    !!--++ Update: February - 2005
44876    !!
44877    Subroutine Get_Cartesian_from_Z(ci,ri,rj,rk,rn)
44878       !---- Arguments ----!
44879       real(kind=cp), dimension(3), intent ( in) :: ci,rj,rk,rn
44880       real(kind=cp), dimension(3), intent (out) :: ri
44881
44882       !--- Local variables ---!
44883       real(kind=cp)                 :: ca,cb,sa
44884       real(kind=cp), dimension(3)   :: r,e1,e2,e3
44885       real(kind=cp), dimension(3,3) :: M
44886
44887       ca = cosd(ci(2))                  ! cos(aijk)
44888       sa = sqrt(abs(1.0_cp - ca*ca))    ! sin(aijk)
44889       cb = cosd(ci(3))                  ! cos(bijkn)
44890       r(1) = ci(1) * ca                 ! Coordinates in the local system
44891       r(2) = ci(1)*cb*sa
44892       r(3) = ci(1)*sqrt(abs(1.0_cp - ca*ca - sa*sa*cb*cb )) *sign(1.0_cp,ci(3))
44893
44894       e1  = rk - rj
44895       e1  = e1/sqrt(dot_product(e1,e1))
44896       e3  = cross_product( rk - rj, rn - rk)
44897       e3  = e3/sqrt(dot_product(e3,e3))
44898       e2  = cross_product( e3, e1)
44899       M(:,1) = e1
44900       M(:,2) = e2
44901       M(:,3) = e3
44902
44903       ri = rj + matmul(M,r)
44904
44905       return
44906    End Subroutine Get_Cartesian_from_Z
44907
44908
44909    !!--++
44910    !!--++ Subroutine Get_Z_from_Cartesian(ci,ri,rj,rk,rn)
44911    !!--++    real, dimension(3), intent ( in) :: ri,rj,rj,rn
44912    !!--++    real, dimension(3), intent (out) :: ci
44913    !!--++
44914    !!--++     Subroutine to calculate the distance of an atom (i)
44915    !!--++     (dij=ci(1)) to another atom (j), the angle (aijk=ci(2))
44916    !!--++     spanned with another atom (k) centred at (j) and  the torsion angle
44917    !!--++     (bijkn=ci(3)) with a fourth atom (n) when the cartesian coordinates are given
44918    !!--++
44919    !!--++ Update: February - 2005
44920    !!
44921    Subroutine Get_Z_from_Cartesian(ci,ri,rj,rk,rn)
44922       !---- Arguments ----!
44923       real(kind=cp), dimension(3), intent ( in) :: ri,rj,rk,rn
44924       real(kind=cp), dimension(3), intent (out) :: ci
44925
44926       !--- Local variables ---!
44927       real(kind=cp)                 :: dji,djk
44928       real(kind=cp), dimension(3)   :: rji,rjk
44929
44930       rji = ri-rj
44931       ci(1) = sqrt(dot_product(rji,rji))
44932       rjk = rk-rj
44933       dji = ci(1)
44934       djk = sqrt(dot_product(rjk,rjk))
44935       ci(2) = acosd( dot_product(rji,rjk)/dji/djk)
44936       ci(3) = angle_dihedral(ri,rj,rk,rn)
44937       if (abs(ci(3)+180.00) <= 0.001) ci(3)=180.0
44938
44939       return
44940    End Subroutine Get_Z_from_Cartesian
44941
44942    !!----
44943    !!---- Subroutine Init_Err_Molec()
44944    !!----
44945    !!----    Initialize Flags of Errors in this module
44946    !!----
44947    !!---- Update: February - 2005
44948    !!
44949    Subroutine Init_Err_Molec()
44950
44951       err_molec=.false.
44952       ERR_Molec_Mess=" "
44953
44954       return
44955    End Subroutine Init_Err_Molec
44956
44957    !!----
44958    !!---- Subroutine Init_Molecule(Molecule,Natm)
44959    !!----    type(Molecule_Type), intent(out) :: Molecule
44960    !!----    integer, optional,   intent(in)  :: Natm
44961    !!----
44962    !!----    Initialize the Variable Molecule
44963    !!----
44964    !!---- Update: February - 2005
44965    !!
44966    Subroutine Init_Molecule(Molecule,Natm)
44967       !---- Argument ----!
44968       type(Molecule_Type), intent(out) :: Molecule
44969       integer, optional,   intent(in)  :: Natm
44970
44971       molecule%name_mol   =" "
44972       molecule%natoms     =0
44973
44974       molecule%in_xtal    = .false.
44975       molecule%is_eulerMat= .false.
44976       molecule%is_connect = .false.
44977       molecule%rot_type   =" "
44978       molecule%coor_type  =" "
44979       molecule%therm_type =" "
44980
44981       molecule%xcentre    =0.0
44982       molecule%mxcentre   =0.0
44983       molecule%lxcentre   =0
44984
44985       molecule%orient     =0.0
44986       molecule%mOrient    =0.0
44987       molecule%lorient    =0
44988
44989       molecule%t_tls      =0.0
44990       molecule%mT_TLS     =0.0
44991       molecule%lt_tls     =0
44992
44993       molecule%l_tls      =0.0
44994       molecule%mL_TLS     =0.0
44995       molecule%ll_tls     =0
44996
44997       molecule%s_tls      =0.0
44998       molecule%mS_TLS     =0.0
44999       molecule%ls_tls     =0
45000
45001       molecule%euler      =0.0
45002
45003       if (allocated(molecule%AtName))  deallocate(molecule%AtName)
45004       if (allocated(molecule%AtSymb))  deallocate(molecule%AtSymb)
45005       if (allocated(molecule%AtZ))     deallocate(molecule%AtZ)
45006       if (allocated(molecule%Ptr))     deallocate(molecule%Ptr)
45007       if (allocated(molecule%I_Coor))  deallocate(molecule%I_Coor)
45008       if (allocated(molecule%mI_Coor)) deallocate(molecule%mI_Coor)
45009       if (allocated(molecule%lI_Coor)) deallocate(molecule%lI_Coor)
45010       if (allocated(molecule%Biso))    deallocate(molecule%Biso)
45011       if (allocated(molecule%mbiso))   deallocate(molecule%mbiso)
45012       if (allocated(molecule%lBiso))   deallocate(molecule%lBiso)
45013       if (allocated(molecule%Occ))     deallocate(molecule%Occ)
45014       if (allocated(molecule%mocc))    deallocate(molecule%mocc)
45015       if (allocated(molecule%lOcc))    deallocate(molecule%lOcc)
45016       if (allocated(molecule%Nb))      deallocate(molecule%Nb)
45017       if (allocated(molecule%INb))     deallocate(molecule%INb)
45018       if (allocated(molecule%Tb))      deallocate(molecule%Tb)
45019       if (allocated(molecule%Conn))    deallocate(molecule%Conn)
45020
45021       if (present(natm)) then
45022          if (natm > 0) then
45023             molecule%natoms=natm
45024
45025             allocate(molecule%AtName(natm))
45026             allocate(molecule%AtSymb(natm))
45027             allocate(molecule%AtZ(natm))
45028             allocate(molecule%Ptr(2,natm))
45029             allocate(molecule%I_Coor(3,natm))
45030             allocate(molecule%mI_Coor(3,natm))
45031             allocate(molecule%lI_Coor(3,natm))
45032             allocate(molecule%Biso(natm))
45033             allocate(molecule%mbiso(natm))
45034             allocate(molecule%lBiso(natm))
45035             allocate(molecule%Occ(natm))
45036             allocate(molecule%mocc(natm))
45037             allocate(molecule%lOcc(natm))
45038             allocate(molecule%Nb(natm))
45039             allocate(molecule%INb(10,natm))
45040             allocate(molecule%Tb(10,natm))
45041             allocate(molecule%Conn(3,natm))
45042
45043             molecule%AtName  =" "
45044             molecule%AtSymb  =" "
45045             molecule%AtZ     =0
45046             molecule%Ptr     =0
45047             molecule%I_Coor  =0.0
45048             molecule%mI_Coor =0.0
45049             molecule%lI_Coor =0
45050             molecule%Biso    =0.0
45051             molecule%mbiso   =0.0
45052             molecule%lBiso   =0
45053             molecule%Occ     =0.0
45054             molecule%mocc    =0.0
45055             molecule%lOcc    =0
45056             molecule%Nb      =0
45057             molecule%INb     =0
45058             molecule%Tb      =0
45059             molecule%Conn    =0
45060
45061
45062          end if
45063       end if
45064
45065       return
45066    End Subroutine Init_Molecule
45067    !!----
45068    !!---- Subroutine Init_Molecule(Molx,Natm,Nmol)
45069    !!----    type(Molecular_Crystal_Type), intent(out) :: Molx
45070    !!----    integer, optional,            intent(in)  :: Natm
45071    !!----    integer, optional,            intent(in)  :: Nmol
45072    !!----
45073    !!----    Initialization for Molecular Crystal
45074    !!----
45075    !!---- Update: October - 2014
45076    !!
45077    Subroutine Init_Mol_Crys(Molx,Natm,Nmol)
45078        !---- Argument ----!
45079        type(Molecular_Crystal_Type), intent(out) :: Molx
45080        integer, optional,            intent(in)  :: Natm
45081        integer, optional,            intent(in)  :: Nmol
45082
45083        integer :: i
45084
45085        molx%N_Free    = 0
45086        molx%N_Mol     = 0
45087        molx%N_Species = 0
45088        molx%Npat      = 0
45089
45090        if (allocated(molx%atm))  deallocate(molx%atm)
45091        if (allocated(molx%mol))  deallocate(molx%mol)
45092
45093        if (present(nmol) .and. nmol > 0) then
45094            molx%N_Mol = nmol
45095            allocate(molx%mol(nmol))
45096            do i=1,nmol
45097                call init_molecule(molx%mol(i))
45098            end do
45099        end if
45100
45101        if (present(natm) .and. natm > 0) then
45102            molx%N_Free = natm
45103            allocate (molx%atm(natm))
45104            do i=1,natm
45105                call init_atom_type(molx%atm(i))
45106            end do
45107        end if
45108        return
45109    End Subroutine Init_Mol_Crys
45110    !!----
45111    !!---- Subroutine Molcrys_to_AtomList(Molcrys,Atm)
45112    !!----    type (Molecular_Crystal_Type), intent(in)  :: Molec
45113    !!----    type (Atom_List_Type),         intent(out) :: Atm
45114    !!----
45115    !!---- Subroutine to pass all information from Molecular_Crystal_Type
45116    !!---- to Atom_List_Type
45117    !!----
45118    !!---- Update: April - 2005
45119    !!
45120    Subroutine Molcrys_to_AtomList(Molcrys,Atm)
45121       !---- Arguments ----!
45122       type (Molecular_Crystal_Type), intent(in)  :: Molcrys
45123       type (Atom_List_Type),         intent(out) :: Atm
45124
45125       !---- Local variables ----!
45126       integer               :: i, n
45127       integer               :: Nat, NaF, NMol
45128       type (Atom_List_Type) :: A
45129
45130       !---- Number of Atoms ----!
45131       NaF=molcrys%n_free
45132       NMol=molcrys%n_mol
45133       if (NMol > 0) then
45134          Nat=NaF+sum(molcrys%mol(1:NMol)%natoms)
45135       else
45136          Nat=NaF
45137       end if
45138       if (Nat <= 0) return
45139
45140       !---- Allocating Atom_List_Type ----!
45141       call allocate_atom_list(Nat,Atm)
45142
45143       !---- Fill information from Free atoms Part ----!
45144       if (naF > 0) Atm%Atom(1:NaF)=molcrys%atm(1:NaF)
45145
45146       !---- Fill information from Molecules Part ----!
45147       n=naF
45148       do i=1,NMol
45149          if (molcrys%mol(i)%natoms <= 0) cycle
45150          if (.not. molcrys%mol(i)%in_xtal) cycle
45151          call molec_to_AtomList(molcrys%mol(i),A,"F",molcrys%cell)
45152          if (err_molec) return
45153          if (A%natoms <= 0) cycle
45154          Atm%Atom(n+1:n+A%natoms)=A%Atom(1:A%natoms)
45155          n=n+A%natoms
45156          call deallocate_atom_list(A)
45157       end do
45158
45159       return
45160    End Subroutine Molcrys_to_AtomList
45161
45162    !!----
45163    !!---- Subroutine Molec_to_AtomList(Molec,Atm, Coor_Type, Cell)
45164    !!----    type (Molecule_Type),               intent(in)  :: Molec
45165    !!----    type (Atom_List_Type),              intent(out) :: Atm
45166    !!----    character(len=*),         optional, intent(in)  :: Coor_type
45167    !!----    type (Crystal_Cell_type), optional, intent(in)  :: Cell
45168    !!----
45169    !!---- Subroutine to pass all information from Molecule_Type
45170    !!---- to Atom_List_Type. Coor_type determine the type of
45171    !!---- cordinates parameter in output. In general Cell if
45172    !!---- necessary to obtain on Output fractional coordinates or
45173    !!---- special case for ZMatrix.
45174    !!----
45175    !!---- Update: April - 2005
45176    !!
45177    Subroutine Molec_to_AtomList(Molec, Atm, Coor_Type, Cell)
45178       !---- Arguments ----!
45179       type (Molecule_Type),               intent(in)     :: Molec
45180       type (Atom_List_Type),              intent(out)    :: Atm
45181       character(len=*),         optional, intent(in)     :: Coor_type
45182       type (Crystal_Cell_type), optional, intent(in)     :: Cell
45183
45184       !---- Local Variables ----!
45185       character(len=1)      :: car
45186       integer               :: i,nat
45187       type (Molecule_Type)  :: newmol
45188
45189       !---- Number of Atoms ----!
45190       Nat=molec%natoms
45191       Atm%natoms=0
45192       if (Nat <= 0) return
45193
45194       car="F"
45195       if (present(coor_type)) car=adjustl(coor_type)
45196       call init_molecule(newmol,nat)
45197
45198       newmol=molec
45199
45200       select case (car)
45201          case ("C")
45202             select case (molec%coor_type)
45203                case ("C")
45204
45205                case ("F")
45206                   if (present(cell)) then
45207                      call Fractional_to_Cartesian(newmol,cell)
45208                      if (err_molec) then
45209                         call init_molecule(newmol)
45210                         return
45211                      end if
45212                   else
45213                      err_molec=.true.
45214                      ERR_Molec_Mess="You need the Cell_Type on this routine"
45215                      call init_molecule(newmol)
45216                      return
45217                   end if
45218
45219                case ("S")
45220                   call Spherical_to_Cartesian(newmol)
45221                   if (err_molec) then
45222                      call init_molecule(newmol)
45223                      return
45224                   end if
45225
45226                case ("Z")
45227                   call ZMatrix_to_Cartesian(newmol)
45228                   if (err_molec) then
45229                      call init_molecule(newmol)
45230                      return
45231                   end if
45232
45233             end select
45234
45235          case ("F")
45236             select case (molec%coor_type)
45237                case ("C")
45238                   if ( present(cell)) then
45239                      call Cartesian_to_Fractional(newmol,cell)
45240                      if (err_molec) then
45241                         call init_molecule(newmol)
45242                         return
45243                      end if
45244                   else
45245                      err_molec=.true.
45246                      ERR_Molec_Mess="You need the Cell_Type on this routine"
45247                      call init_molecule(newmol)
45248                      return
45249                   end if
45250
45251                case ("F")
45252
45253                case ("S")
45254                   if (present(cell)) then
45255                      call Spherical_to_Fractional(newmol,cell)
45256                      if (err_molec) then
45257                         call init_molecule(newmol)
45258                         return
45259                      end if
45260                   else
45261                      err_molec=.true.
45262                      ERR_Molec_Mess="You need the Cell_Type on this routine"
45263                      call init_molecule(newmol)
45264                      return
45265                   end if
45266
45267                case ("Z")
45268                   if (present(cell)) then
45269                      call ZMatrix_to_Fractional(newmol,cell)
45270                      if (err_molec) then
45271                         call init_molecule(newmol)
45272                         return
45273                      end if
45274                   else
45275                      err_molec=.true.
45276                      ERR_Molec_Mess="You need the Cell_Type on this routine"
45277                      call init_molecule(newmol)
45278                      return
45279                   end if
45280             end select
45281
45282          case ("S")
45283             select case (molec%coor_type)
45284                case ("C")
45285                   call Cartesian_to_Spherical(newmol)
45286                   if (err_molec) then
45287                      call init_molecule(newmol)
45288                      return
45289                   end if
45290
45291                case ("F")
45292                   if (present(cell)) then
45293                      call Fractional_to_Spherical(newmol,cell)
45294                      if (err_molec) then
45295                         call init_molecule(newmol)
45296                         return
45297                      end if
45298                   else
45299                      err_molec=.true.
45300                      ERR_Molec_Mess="You need the Cell_Type on this routine"
45301                      call init_molecule(newmol)
45302                      return
45303                   end if
45304
45305                case ("S")
45306
45307                case ("Z")
45308                   call ZMatrix_to_Spherical(newmol)
45309                   if (err_molec) then
45310                      call init_molecule(newmol)
45311                      return
45312                   end if
45313
45314             end select
45315
45316          case ("Z")
45317             select case (molec%coor_type)
45318                case ("C")
45319                   if (present(cell)) then
45320                      call Cartesian_to_ZMatrix(newmol,cell=cell)
45321                   else
45322                      call Cartesian_to_ZMatrix(newmol)
45323                   end if
45324                   if (err_molec) then
45325                      call init_molecule(newmol)
45326                      return
45327                   end if
45328
45329                case ("F")
45330                   if (present(cell)) then
45331                      call Fractional_to_ZMatrix(newmol,cell)
45332                      if (err_molec) then
45333                         call init_molecule(newmol)
45334                         return
45335                      end if
45336                   else
45337                      err_molec=.true.
45338                      ERR_Molec_Mess="You need the Cell_Type on this routine"
45339                      call init_molecule(newmol)
45340                      return
45341                   end if
45342
45343                case ("S")
45344                   if (present(cell)) then
45345                      call Spherical_to_ZMatrix(newmol,cell=cell)
45346                   else
45347                      call Spherical_to_ZMatrix(newmol)
45348                   end if
45349                   if (err_molec) then
45350                      call init_molecule(newmol)
45351                      return
45352                   end if
45353
45354                case ("Z")
45355             end select
45356
45357       end select
45358
45359       !---- Allocating Atom_List_Type ----!
45360       call allocate_atom_list(Nat,Atm)
45361
45362       !---- Passing Information ----!
45363       Atm%Atom(1:Nat)%Lab      =Newmol%AtName(1:Nat)
45364       Atm%Atom(1:Nat)%SfacSymb =Newmol%AtSymb(1:Nat)
45365       Atm%Atom(1:Nat)%Active   =.true.
45366       Atm%Atom(1:Nat)%Z        =Newmol%AtZ(1:Nat)
45367       Atm%Atom(1:Nat)%Mult     =1
45368       !Atm%Atom(1:Nat)%X        =Newmol%I_Coor(:,1:Nat)
45369       !Atm%Atom(1:Nat)%X_Std    =0.0
45370       !Atm%Atom(1:Nat)%MX       =Newmol%mI_Coor(:,1:Nat)
45371       !Atm%Atom(1:Nat)%LX       =Newmol%lI_Coor(:,1:Nat)
45372       Atm%Atom(1:Nat)%Occ      =Newmol%Occ(1:Nat)
45373       Atm%Atom(1:Nat)%Occ_Std  =0.0
45374       Atm%Atom(1:Nat)%MOcc     =Newmol%mOcc(1:Nat)
45375       Atm%Atom(1:Nat)%LOcc     =Newmol%lOcc(1:Nat)
45376       Atm%Atom(1:Nat)%Biso     =Newmol%biso(1:Nat)
45377       Atm%Atom(1:Nat)%Biso_std =0.0
45378       Atm%Atom(1:Nat)%MBiso    =Newmol%mbiso(1:Nat)
45379       Atm%Atom(1:Nat)%LBiso    =Newmol%lbiso(1:Nat)
45380       Atm%Atom(1:Nat)%Utype    ="none"
45381       Atm%Atom(1:Nat)%ThType   ="isotr"
45382       !Atm%Atom(1:Nat)%U        =0.0
45383       !Atm%Atom(1:Nat)%U_std    =0.0
45384       Atm%Atom(1:Nat)%Ueq      =0.0
45385       !Atm%Atom(1:Nat)%MU       =0.0
45386       !Atm%Atom(1:Nat)%LU       =0
45387       Atm%Atom(1:Nat)%Charge   =0.0
45388       Atm%Atom(1:Nat)%Moment   =0.0
45389       !Atm%Atom(1:Nat)%Ind      =0
45390       Atm%Atom(1:Nat)%NVar     =0
45391       !Atm%Atom(1:Nat)%VarF     =0.0
45392
45393       do i=1,Nat
45394          call Get_ChemSymb(Atm%Atom(i)%SfacSymb, Atm%Atom(i)%ChemSymb)
45395          Atm%Atom(i)%X=Newmol%I_Coor(:,i)
45396          Atm%Atom(i)%X_Std=0.0
45397          Atm%Atom(i)%mX=Newmol%mI_Coor(:,i)
45398          Atm%Atom(i)%lX=Newmol%lI_Coor(:,i)
45399          Atm%Atom(i)%U    =0.0
45400          Atm%Atom(i)%U_Std=0.0
45401          Atm%Atom(i)%mU   =0.0
45402          Atm%Atom(i)%lU   =0
45403          Atm%Atom(i)%Ind  =0
45404          Atm%Atom(i)%VarF =0.0
45405       end do
45406
45407       call init_molecule(newmol)
45408
45409       return
45410    End Subroutine Molec_to_AtomList
45411
45412    !!----
45413    !!---- Subroutine Read_Free_Atoms(Lun,AtmF,N)
45414    !!----    integer,                       intent(in)   :: Lun        ! Logical unit to be rad
45415    !!----    type(Atom_Type), dimension(:), intent(out)  :: AtmF       ! Free atoms
45416    !!----    integer,                       intent(out)  :: N          ! Free atoms read
45417    !!----
45418    !!--<<    Subroutine to read a set of Free Atoms from a file.
45419    !!----    The format is:
45420    !!----        ATOMS N_Atoms
45421    !!----
45422    !!----    Internal Coordinates for Atoms (N_Atoms Lines)
45423    !!----        Atom_Name(6)  Atom_Specie(4)  Coordinates(3)  Biso  Occ [VARY]
45424    !!----
45425    !!----    if VARY is present as last option on the Internal Coordinates line,
45426    !!----    then an extra line is read
45427    !!----        Codes_Coordinates(3)   Code_BIso  Code_Occ
45428    !!-->>
45429    !!----
45430    !!----    Control of error is present
45431    !!----
45432    !!---- Update: February - 2005
45433    !!
45434    Subroutine Read_Free_Atoms(Lun, AtmF, N)
45435       !---- Arguments ----!
45436       integer,                       intent(in)   :: Lun    ! Logical unit to be rad
45437       type(Atom_Type), dimension(:), intent(out)  :: AtmF   ! Free atoms
45438       integer,                       intent(out)  :: N      ! Free atoms read
45439
45440       !---- Local Variables ----!
45441       character(len=80)           :: line
45442       character(len=6)            :: label
45443       character(len=4)            :: var,symb
45444       integer                     :: i,ier,nlong,iv
45445       integer,       dimension(5) :: ivet
45446       real(kind=cp), dimension(5) :: vet
45447
45448       call Init_Err_Molec()
45449       N=0
45450       do
45451          read(unit=lun,fmt="(a)",iostat=ier) line
45452          if (ier == 0) then
45453             line=adjustl(line)
45454             if (u_case(line(1:4)) /= "ATOM") cycle
45455          else
45456             err_molec=.true.
45457             ERR_Molec_Mess="Atoms Information not found in file! "
45458             return
45459          end if
45460
45461          call cutst(line,nlong)
45462          call getnum(line,vet,ivet,iv)
45463          if (iv /= 1) then
45464             err_molec=.true.
45465             ERR_Molec_Mess="Number of Free atoms not found in file! "
45466             return
45467          end if
45468          N=ivet(1)
45469          exit
45470       end do
45471
45472       do i=1,N
45473          read(unit=lun,fmt="(a)",iostat=ier) line
45474          if (ier /=0) then
45475             err_molec=.true.
45476             ERR_Molec_Mess="Free atoms Information was incomplete "
45477             return
45478          end if
45479          call cutst(line,nlong,label)
45480          call cutst(line,nlong,symb)
45481
45482          line=u_case(line)
45483          var=" "
45484          iv=index(line,"VARY")
45485          if (iv /= 0) then
45486             line=line(1:iv-1)
45487             var="VARY"
45488          end if
45489
45490          call getnum(line,vet,ivet,iv)
45491          select case (iv)
45492             case (:2)
45493                vet(1:3)=0.0
45494                vet(4)=0.0
45495                vet(5)=1.0
45496             case (3)
45497                vet(4)=0.0
45498                vet(5)=1.0
45499             case (4)
45500                vet(5)=1.0
45501          end select
45502          AtmF(i)%Lab =label
45503          AtmF(i)%ChemSymb=symb
45504          AtmF(i)%x=vet(1:3)
45505          AtmF(i)%biso=vet(4)
45506          AtmF(i)%occ =vet(5)
45507
45508          if (var == "VARY") then
45509             do
45510                read(unit=lun,fmt="(a)", iostat=ier) line
45511                if (ier /= 0) then
45512                   err_molec=.true.
45513                   ERR_Molec_Mess="Error reading the refinement codes of free atoms "
45514                   return
45515                end if
45516                line=adjustl(line)
45517                if (line(1:1) =="!") cycle
45518                exit
45519             end do
45520
45521             call getnum(line,vet,ivet,iv)
45522             select case (iv)
45523                case (3)
45524                   AtmF(i)%mx =vet(1:3)
45525
45526                case (5)
45527                   AtmF(i)%mx    =vet(1:3)
45528                   AtmF(i)%mbiso =vet(4)
45529                   AtmF(i)%mocc  =vet(5)
45530
45531                case default
45532                   err_molec=.true.
45533                   ERR_Molec_Mess="Error reading the refinement codes of free atoms  "
45534                   return
45535             end select
45536          end if
45537
45538       end do
45539
45540       return
45541    End Subroutine Read_Free_Atoms
45542
45543    !!----
45544    !!---- Subroutine Read_Molecule(Lun,Molecule) or (File_Dat, N_Ini, N_End, Molecule)
45545    !!----    integer,              intent( in)           :: Lun         !  In -> Logical unit to be read
45546    !!----    or
45547    !!----    character(len=*), dimension(:), intent(in)  :: File_Dat
45548    !!----    integer,                        intent(in)  :: N_Ini
45549    !!----    integer,                        intent(in)  :: N_End
45550    !!----    and
45551    !!----    type (Molecule_type),           intent(out) :: Molecule    ! Out -> Molecule
45552    !!----
45553    !!--<<    Subroutine to read a molecule from a file
45554    !!----    The format is:
45555    !!----        MOLE[X] N_Atoms Molecule_Name Coordinates_Type
45556    !!----
45557    !!----    where:
45558    !!----        N_atoms             Number of atoms in the molecule definition
45559    !!----        Molecule_Name       Name for the molecule
45560    !!----        Coordinates_Type    C: Cartesian coordinates
45561    !!----                            F: Fractional coordinates
45562    !!----                            S: Spherical coordinates
45563    !!----                            Z: Z-Matrix coordinates
45564    !!----
45565    !!----    If keyword MOLEX is present, then the next line will be read (6 reals, 2 characters)
45566    !!----        Molecule_Centre(3), Molecule_Orient(3), Rotational_Angle Type(1), Thermal_Factor Type(1)
45567    !!----
45568    !!----    where:
45569    !!----        Molecule_Centre     Coordinate of Center of Molecule
45570    !!----        Molecule_Orient     Angles orientation
45571    !!----        Rotational Angle    E: Conventional Euler angles (alpha, beta, gamma)
45572    !!----                            P: Polar Euler angles (Phi, theta, Chi) (default)
45573    !!----        Thermal Factor    ISO: No collective motion
45574    !!----                          TLS: Traslational + Librational + Correlation
45575    !!----                           TL: Traslational + Librational
45576    !!----                            T: Traslational
45577    !!----
45578    !!----        According to Thermal Factors, next lines will be read
45579    !!----                          [T]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
45580    !!----
45581    !!----                         [TL]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
45582    !!----                               6 Thermal Factors (Line3) + 6 Codes Thermal Factors (Line4)
45583    !!----
45584    !!----                        [TLS]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
45585    !!----                               6 Thermal Factors (Line3) + 6 Codes Thermal Factors (Line4)
45586    !!----                               9 Thermal Factors (Line5) + 9 Codes Thermal Factors (Line6)
45587    !!----
45588    !!----    Internal Coordinates for Atoms (N_Atoms Lines)
45589    !!----        Atom_Name(6)  Atom_Specie(4)  Coordinates(3)  N1  N2  N3  Biso  Occ [VARY]
45590    !!----
45591    !!----    if VARY is present as last option on the Internal Coordinates line,
45592    !!----    then an extra line is read
45593    !!----        Codes_Coordinates(3)   Code_BIso  Code_Occ
45594    !!-->>
45595    !!----    Control of error is present
45596    !!----
45597    !!---- Update: February - 2005
45598    !!
45599
45600    !!--++
45601    !!--++ Subroutine Read_Molecule_in_File(Lun,Molecule)
45602    !!--++    integer,              intent( in)                  :: Lun         !  In -> Logical unit to be read
45603    !!--++    type (Molecule_type), intent(out)                  :: Molecule    ! Out -> Molecule
45604    !!--++
45605    !!--++    (Overloaded)
45606    !!--++    Subroutine to read a molecule from a file.
45607    !!--++    The format is:
45608    !!--++        MOLE[X] N_Atoms Molecule_Name Coordinates_Type
45609    !!--++
45610    !!--++    where:
45611    !!--++        N_atoms             Number of atoms in the molecule definition
45612    !!--++        Molecule_Name       Name for the molecule
45613    !!--++        Coordinates_Type    C: Cartesian coordinates
45614    !!--++                            F: Fractional coordinates
45615    !!--++                            S: Spherical coordinates
45616    !!--++                            Z: Z-Matrix coordinates
45617    !!--++
45618    !!--++    If keyword MOLEX is present, then the next line will be read (6 reals, 2 characters)
45619    !!--++        Molecule_Centre(3), Molecule_Orient(3), Rotational_Angle Type(1), Thermal_Factor Type(1)
45620    !!--++
45621    !!--++    where:
45622    !!--++        Molecule_Centre     Coordinate of Center of Molecule
45623    !!--++        Molecule_Orient     Angles orientation
45624    !!--++        Rotational Angle    E: Conventional Euler angles (alpha, beta, gamma)
45625    !!--++                            P: Polar Euler angles (Phi, theta, Chi) (default)
45626    !!--++        Thermal Factor    ISO: No collective motion
45627    !!--++                          TLS: Traslational + Librational + Correlation
45628    !!--++                           TL: Traslational + Librational
45629    !!--++                            T: Traslational
45630    !!--++
45631    !!--++        According to Thermal Factors, next lines will be read
45632    !!--++                          [T]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
45633    !!--++
45634    !!--++                         [TL]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
45635    !!--++                               6 Thermal Factors (Line3) + 6 Codes Thermal Factors (Line4)
45636    !!--++
45637    !!--++                        [TLS]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
45638    !!--++                               6 Thermal Factors (Line3) + 6 Codes Thermal Factors (Line4)
45639    !!--++                               9 Thermal Factors (Line5) + 9 Codes Thermal Factors (Line6)
45640    !!--++
45641    !!--++    Internal Coordinates for Atoms (N_Atoms Lines)
45642    !!--++        Atom_Name(6)  Atom_Specie(4)  Coordinates(3)  N1  N2  N3  Biso  Occ [VARY]
45643    !!--++
45644    !!--++    if VARY is present as last option on the Internal Coordinates line,
45645    !!--++    then an extra line is read
45646    !!--++        Codes_Coordinates(3)   Code_BIso  Code_Occ
45647    !!--++
45648    !!--++    Control of error is present
45649    !!--++
45650    !!--++ Update: February - 2005
45651    !!
45652    Subroutine Read_Molecule_in_File(Lun,Molecule)
45653       !---- Arguments ----!
45654       integer,              intent(in    ) :: lun
45655       type (Molecule_type), intent(   out) :: Molecule
45656
45657       !---- Local variables -----!
45658       character(len=150)              :: line
45659       character(len=20),dimension(10) :: dire
45660       character(len=4)                :: var
45661       integer                         :: i,j,ic,npos,na,ier
45662       integer,dimension(10)           :: ivet
45663       real(kind=cp), dimension(10)    :: vet
45664       real(kind=cp),dimension(3,3)    :: Eu
45665       logical                         :: in_xtal,mol_found
45666
45667       in_xtal=.false.
45668       mol_found =.false.
45669       call Init_Err_Molec()
45670
45671       do
45672          read(unit=lun,fmt="(a)", iostat=ier) line
45673          if (ier == 0) then
45674             line=adjustl(line)
45675             if (u_case(line(1:4)) /= "MOLE") cycle
45676          else
45677             if(.not. mol_found) then
45678              err_molec=.true.
45679              ERR_Molec_Mess="Molecule not found in file! "
45680             end if
45681             return
45682          end if
45683
45684          mol_found =.true.
45685          if (u_case(line(1:5)) == "MOLEX") in_xtal=.true.
45686          i=index(line,"!")
45687          if( i /= 0 ) line=line(1:i-1)
45688
45689          !---- Coordinates format ----!
45690          call getword(line,dire,ic)
45691          if (ic /= 4) then
45692             err_molec=.true.
45693             ERR_Molec_Mess="Instruction: MOLE[X] N_Atoms Molecule_Name Coordinates_Type, not found in file! "
45694             return
45695          end if
45696
45697          !---- Name and Number of Atoms in the molecule ----!
45698          read(unit=dire(2),fmt=*,iostat=ier) na
45699          if (na > 0) then
45700             call init_molecule(molecule,na)
45701             Molecule%Name_mol =dire(3)
45702          else
45703             err_molec=.true.
45704             ERR_Molec_Mess="Error reading the number of atoms in a molecule: "//trim(line)
45705             return
45706          end if
45707
45708          select case (dire(4)(1:1)) ! Coordinates_Type [C,S,F,Z]
45709             case ("C","c")
45710                molecule%coor_type="C"
45711             case ("F","f")
45712                molecule%coor_type="F"
45713             case ("S","s")
45714                molecule%coor_type="S"
45715             case ("Z","z")
45716                molecule%coor_type="Z"
45717             case default
45718                err_molec=.true.
45719                ERR_Molec_Mess="Coordinates Type for Molecule Unknown! "
45720                return
45721          end select ! dire
45722          exit !The molecule has been found
45723       end do
45724
45725       !---- Initialize the crystal part of the molecule
45726       Molecule%xcentre    = 0.0_cp
45727       Molecule%orient     = 0.0_cp
45728       Molecule%therm_type = "   "
45729       Molecule%T_TLS      = 0.0_cp
45730       Molecule%L_TLS      = 0.0_cp
45731       Molecule%S_TLS      = 0.0_cp
45732       Molecule%in_xtal    = .false.
45733       Molecule%is_EulerMat=.false.
45734
45735       if (in_xtal) then
45736          !---- Read the global coordinates of the centre of molecule and orientational angles
45737          do
45738             read(unit=lun,fmt="(a)", iostat=ier) line
45739             if (ier /= 0) then
45740                err_molec=.true.
45741                ERR_Molec_Mess="Error reading Molecule information! "
45742                return
45743             end if
45744             line=adjustl(line)
45745             if (line(1:1) =="!") cycle
45746             exit
45747          end do
45748
45749          i=index(line,"!")
45750          if( i /= 0 ) line=line(1:i-1)
45751
45752          call getword(line,dire,ic)
45753          if (ic /= 8) then
45754             err_molec=.true.
45755             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
45756             return
45757          end if
45758
45759          line=trim(dire(1))//"   "//trim(dire(2))//"   "//trim(dire(3))
45760          call getnum(line,vet,ivet,ic)
45761          if (ic /= 3) then
45762             err_molec=.true.
45763             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
45764             return
45765          end if
45766          Molecule%xcentre=vet(1:3)
45767
45768          line=trim(dire(4))//"   "//trim(dire(5))//"   "//trim(dire(6))
45769          call getnum(line,vet,ivet,ic)
45770          if (ic /= 3) then
45771             err_molec=.true.
45772             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
45773             return
45774          end if
45775          Molecule%orient=vet(1:3)
45776
45777          Molecule%rot_type=adjustl(u_case(dire(7)))
45778          Molecule%therm_type=adjustl(u_case(dire(8)))
45779
45780          do
45781             read(unit=lun,fmt="(a)", iostat=ier) line
45782             if (ier /= 0) then
45783                err_molec=.true.
45784                ERR_Molec_Mess="Error reading Molecule information! "
45785                return
45786             end if
45787             line=adjustl(line)
45788             if (line(1:1) =="!") cycle
45789             exit
45790          end do
45791          i=index(line,"!")
45792          if( i /= 0 ) line=line(1:i-1)
45793
45794          call getnum(line,vet,ivet,ic)
45795          if (ic /= 6) then
45796             err_molec=.true.
45797             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
45798             return
45799          end if
45800          Molecule%mxcentre=vet(1:3)
45801          Molecule%mOrient =vet(4:6)
45802
45803          Molecule%in_xtal = .true.
45804
45805          !---- Set the Euler Matrix
45806          if (Molecule%rot_type /= "E") Molecule%rot_type="P"
45807
45808          call Set_euler_matrix(Molecule%rot_type,  &
45809                                Molecule%orient(1),Molecule%orient(2),Molecule%orient(3),Eu)
45810                                !    Phi/alpha          Theta/beta          Chi/gamma
45811          Molecule%Euler=Eu
45812          Molecule%is_EulerMat=.true.
45813
45814          !---- Read the THERMAL PARAMETERS
45815          if (Molecule%therm_type(1:1) == "T") then
45816             do
45817                read(unit=lun,fmt="(a)", iostat=ier) line
45818                if (ier /= 0) then
45819                   err_molec=.true.
45820                   ERR_Molec_Mess="Error reading Molecule information! "
45821                   return
45822                end if
45823                line=adjustl(line)
45824                if (line(1:1) =="!") cycle
45825                exit
45826             end do
45827             i=index(line,"!")
45828             if( i /= 0 ) line=line(1:i-1)
45829
45830             call getnum(line,vet,ivet,ic)
45831             if (ic /= 6) then
45832                err_molec=.true.
45833                ERR_Molec_Mess="Error reading the tensor T of the molecule: "//trim(Molecule%Name_mol)
45834                return
45835             end if
45836             Molecule%T_TLS=vet(1:6)
45837
45838             do
45839                read(unit=lun,fmt="(a)", iostat=ier) line
45840                if (ier /= 0) then
45841                   err_molec=.true.
45842                   ERR_Molec_Mess="Error reading Molecule information! "
45843                   return
45844                end if
45845                line=adjustl(line)
45846                if (line(1:1) =="!") cycle
45847                exit
45848             end do
45849             i=index(line,"!")
45850             if( i /= 0 ) line=line(1:i-1)
45851
45852             call getnum(line,vet,ivet,ic)
45853             if (ic /= 6) then
45854                err_molec=.true.
45855                ERR_Molec_Mess="Error reading the codes of tensor T of the molecule: "//trim(Molecule%Name_mol)
45856                return
45857             end if
45858             Molecule%mT_TLS=vet(1:6)
45859          end if
45860
45861          if (Molecule%therm_type(2:2) == "L") then
45862             do
45863                read(unit=lun,fmt="(a)", iostat=ier) line
45864                if (ier /= 0) then
45865                   err_molec=.true.
45866                   ERR_Molec_Mess="Error reading Molecule information! "
45867                   return
45868                end if
45869                line=adjustl(line)
45870                if (line(1:1) =="!") cycle
45871                exit
45872             end do
45873             i=index(line,"!")
45874             if( i /= 0 ) line=line(1:i-1)
45875
45876             call getnum(line,vet,ivet,ic)
45877             if (ic /= 6) then
45878                err_molec=.true.
45879                ERR_Molec_Mess="Error reading the tensor L of the molecule: "//trim(Molecule%Name_mol)
45880                return
45881             end if
45882             Molecule%L_TLS=vet(1:6)
45883
45884             do
45885                read(unit=lun,fmt="(a)", iostat=ier) line
45886                if (ier /= 0) then
45887                   err_molec=.true.
45888                   ERR_Molec_Mess="Error reading Molecule information! "
45889                   return
45890                end if
45891                line=adjustl(line)
45892                if (line(1:1) =="!") cycle
45893                exit
45894             end do
45895             i=index(line,"!")
45896             if( i /= 0 ) line=line(1:i-1)
45897
45898             call getnum(line,vet,ivet,ic)
45899             if (ic /= 6) then
45900                err_molec=.true.
45901                ERR_Molec_Mess="Error reading the codes of the tensor L of the molecule: "//trim(Molecule%Name_mol)
45902                return
45903             end if
45904             Molecule%mL_TLS=vet(1:6)
45905          end if
45906
45907          if (Molecule%therm_type(3:3) == "S") then
45908             do
45909                read(unit=lun,fmt="(a)", iostat=ier) line
45910                if (ier /= 0) then
45911                   err_molec=.true.
45912                   ERR_Molec_Mess="Error reading Molecule information! "
45913                   return
45914                end if
45915                line=adjustl(line)
45916                if (line(1:1) =="!") cycle
45917                exit
45918             end do
45919             i=index(line,"!")
45920             if( i /= 0 ) line=line(1:i-1)
45921
45922             call getnum(line,vet,ivet,ic)
45923             if (ic /= 9) then
45924                err_molec=.true.
45925                ERR_Molec_Mess="Error reading the tensor S of the molecule: "//trim(Molecule%Name_mol)
45926                return
45927             end if
45928             Molecule%S_TLS(1,:)=vet(1:3)
45929             Molecule%S_TLS(2,:)=vet(4:6)
45930             Molecule%S_TLS(3,:)=vet(7:9)
45931
45932             do
45933                read(unit=lun,fmt="(a)", iostat=ier) line
45934                if (ier /= 0) then
45935                   err_molec=.true.
45936                   ERR_Molec_Mess="Error reading Molecule information! "
45937                   return
45938                end if
45939                line=adjustl(line)
45940                if (line(1:1) =="!") cycle
45941                exit
45942             end do
45943             i=index(line,"!")
45944             if( i /= 0 ) line=line(1:i-1)
45945
45946             call getnum(line,vet,ivet,ic)
45947             if (ic /= 9) then
45948                err_molec=.true.
45949                ERR_Molec_Mess="Error reading the code of tensor S of the molecule: "//trim(Molecule%Name_mol)
45950                return
45951             end if
45952             Molecule%mS_TLS(1,:)=vet(1:3)
45953             Molecule%mS_TLS(2,:)=vet(4:6)
45954             Molecule%mS_TLS(3,:)=vet(7:9)
45955          end if
45956
45957       end if  !(in_xtal)
45958
45959       !---- Read the internal coordinates of the atoms in the molecule
45960       !---- Read the Z-matrix/Cartesian/spherical/Fractional coordinates of the molecule
45961       molecule%is_connect=.true.
45962       do i=1,na
45963          do
45964             read(unit=lun,fmt="(a)", iostat=ier) line
45965             if (ier /= 0) then
45966                err_molec=.true.
45967                ERR_Molec_Mess="Error reading Molecule information! "
45968                return
45969             end if
45970             line=adjustl(line)
45971             if (line(1:1) =="!") cycle
45972             exit
45973          end do
45974          j=index(line,"!")
45975          if( j /= 0 ) line=line(1:j-1)
45976
45977          !---- Atom Name ---!
45978          call Cutst(line,ic,Molecule%Atname(i))
45979
45980          !---- Atom specie ----!
45981          call Cutst(line,ic,Molecule%Atsymb(i))
45982
45983          !---- Passing Codes? ----!
45984          call getword(line,dire,ic)
45985          var=adjustl(dire(ic))
45986          var=u_case(var)
45987          if (var == "VARY") then
45988             ic=len_trim(line)
45989             npos=index(line(1:ic)," ",back=.true.)
45990             if (npos <=0) then
45991                err_molec=.true.
45992                ERR_Molec_Mess="Error reading Molecule information (II)! "
45993                return
45994             end if
45995             line=line(1:npos)
45996          end if
45997
45998          !---- Rest of Information ----!
45999          vet =0.0
46000          ivet=0
46001          call getnum(line,vet,ivet,ic)
46002          select case (ic)
46003             case (0)
46004                Molecule%I_Coor(:,i)=0.0
46005                Molecule%Conn(:,i)  =0
46006                Molecule%Biso(i)    =0.5
46007                Molecule%Occ(i)     =1.0
46008             case (1)
46009                Molecule%I_Coor(1,i)  =vet(1)
46010                Molecule%I_Coor(2:3,i)=0.0
46011                Molecule%conn(:,i)    =0
46012                Molecule%biso(i)      =0.5
46013                Molecule%Occ(i)       =1.0
46014
46015             case (2)
46016                Molecule%I_Coor(1:2,i)=vet(1:2)
46017                Molecule%I_Coor(3,i)  =0.0
46018                Molecule%conn(:,i)    =0
46019                Molecule%biso(i)      =0.5
46020                Molecule%Occ(i)       =1.0
46021
46022             case (3)
46023                Molecule%I_Coor(:,i)  =vet(1:3)
46024                Molecule%conn(:,i)    =0
46025                Molecule%biso(i)      =0.5
46026                Molecule%Occ(i)       =1.0
46027
46028             case (4)
46029                Molecule%I_Coor(:,i)  =vet(1:3)
46030                Molecule%conn(1,i)    =ivet(4)
46031                Molecule%conn(2:3,i)  =0
46032                Molecule%biso(i)      =0.5
46033                Molecule%Occ(i)       =1.0
46034
46035             case (5)
46036                Molecule%I_Coor(:,i)  =vet(1:3)
46037                Molecule%conn(1:2,i)  =ivet(4:5)
46038                Molecule%conn(3,i)    =0
46039                Molecule%biso(i)      =0.5
46040                Molecule%Occ(i)       =1.0
46041
46042             case (6)
46043                Molecule%I_Coor(:,i)  =vet(1:3)
46044                Molecule%conn(:,i)    =ivet(4:6)
46045                Molecule%biso(i)      =0.5
46046                Molecule%Occ(i)       =1.0
46047
46048             case (7)
46049                Molecule%I_Coor(:,i)  =vet(1:3)
46050                Molecule%conn(:,i)    =ivet(4:6)
46051                Molecule%biso(i)      =vet(7)
46052                Molecule%Occ(i)       =1.0
46053
46054             case (8)
46055                Molecule%I_Coor(:,i)  =vet(1:3)
46056                Molecule%conn(:,i)    =ivet(4:6)
46057                Molecule%biso(i)      =vet(7)
46058                Molecule%Occ(i)       =vet(8)
46059
46060             case default
46061                err_molec=.true.
46062                ERR_Molec_Mess="Error reading the atoms in the molecule: "//trim(Molecule%Name_mol)
46063                return
46064
46065          end select ! ic
46066
46067          if (Molecule%coor_type == "Z") then
46068
46069             if (i == 2 .and. (ivet(4) ==0 .and. ivet(5) ==0 .and. ivet(6) ==0)) then
46070                Molecule%conn(1,i)=1
46071             end if
46072             if(Molecule%I_Coor(3,i) > 180.0) Molecule%I_Coor(3,i) = Molecule%I_Coor(3,i) -360.0
46073             if(Molecule%I_Coor(3,i) <-180.0) Molecule%I_Coor(3,i) = Molecule%I_Coor(3,i) +360.0
46074
46075             if (ivet(4) >= i .or. ivet(5) >= i .or. ivet(6) >= i )                err_molec=.true.
46076             if (i == 3 .and. (ivet(4) == 0 .or. ivet(5) == 0))                    err_molec=.true.
46077             if (i > 3 .and. (ivet(4) == 0 .or. ivet(5) == 0 .or. ivet(6) == 0))   err_molec=.true.
46078             if (err_molec) then
46079                ERR_Molec_Mess = "The Z-matrix connectivity is wrong: "//trim(line)
46080                return
46081             end if
46082          else
46083             if (ivet(4) >= i .or. ivet(5) >= i .or. ivet(6) >= i )               molecule%is_connect=.false.
46084             if (i == 3 .and. (ivet(4) == 0 .or. ivet(5) == 0))                   molecule%is_connect=.false.
46085             if (i > 3 .and. (ivet(4) == 0 .or. ivet(5) == 0 .or. ivet(6) == 0))  molecule%is_connect=.false.
46086          end if
46087
46088          Molecule%mI_Coor(:,i)=0.0
46089          Molecule%mbiso(i)  =0.0
46090          Molecule%mocc(i)   =0.0
46091
46092          if (var == "VARY") then
46093             do
46094                read(unit=lun,fmt="(a)", iostat=ier) line
46095                if (ier /= 0) then
46096                   err_molec=.true.
46097                   ERR_Molec_Mess="Error reading the refinement codes of atoms in the molecule: "//trim(Molecule%Name_mol)
46098                   return
46099                end if
46100                line=adjustl(line)
46101                if (line(1:1) =="!") cycle
46102                exit
46103             end do
46104             j=index(line,"!")
46105             if( j /= 0 ) line=line(1:j-1)
46106
46107             call getnum(line,vet,ivet,ic)
46108             select case (ic)
46109                case (3)
46110                   Molecule%mI_Coor(:,i)=vet(1:3)
46111
46112                case (5)
46113                   Molecule%mI_Coor(:,i)=vet(1:3)
46114                   Molecule%mbiso(i)  =vet(4)
46115                   Molecule%mocc(i)   =vet(5)
46116
46117                case default
46118                   err_molec=.true.
46119                   ERR_Molec_Mess="Error reading the refinement codes of atoms in the molecule: "//trim(Molecule%Name_mol)
46120                   return
46121             end select
46122          end if
46123
46124       end do
46125
46126       return
46127    End Subroutine Read_Molecule_in_File
46128
46129    !!--++
46130    !!--++ Subroutine Read_Molecule_in_Var(File_Dat, N_Ini, N_End, Molecule)
46131    !!--++    character(len=*), dimension(:), intent(in)  :: File_Dat
46132    !!--++    integer,                        intent(in)  :: N_Ini
46133    !!--++    integer,                        intent(in)  :: N_End
46134    !!--++    type (Molecule_type),           intent(out) :: Molecule    ! Out -> Molecule
46135    !!--++
46136    !!--++    (Overloaded)
46137    !!--++    Subroutine to read a molecule from a file.
46138    !!--++    The format is:
46139    !!--++        MOLE[X] N_Atoms Molecule_Name Coordinates_Type
46140    !!--++
46141    !!--++    where:
46142    !!--++        N_atoms             Number of atoms in the molecule definition
46143    !!--++        Molecule_Name       Name for the molecule
46144    !!--++        Coordinates_Type    C: Cartesian coordinates
46145    !!--++                            F: Fractional coordinates
46146    !!--++                            S: Spherical coordinates
46147    !!--++                            Z: Z-Matrix coordinates
46148    !!--++
46149    !!--++    If keyword MOLEX is present, then the next line will be read (6 reals, 2 characters)
46150    !!--++        Molecule_Centre(3), Molecule_Orient(3), Rotational_Angle Type(1), Thermal_Factor Type(1)
46151    !!--++
46152    !!--++    where:
46153    !!--++        Molecule_Centre     Coordinate of Center of Molecule
46154    !!--++        Molecule_Orient     Angles orientation
46155    !!--++        Rotational Angle    E: Conventional Euler angles (alpha, beta, gamma)
46156    !!--++                            P: Polar Euler angles (Phi, theta, Chi) (default)
46157    !!--++        Thermal Factor    ISO: No collective motion
46158    !!--++                          TLS: Traslational + Librational + Correlation
46159    !!--++                           TL: Traslational + Librational
46160    !!--++                            T: Traslational
46161    !!--++
46162    !!--++        According to Thermal Factors, next lines will be read
46163    !!--++                          [T]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
46164    !!--++
46165    !!--++                         [TL]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
46166    !!--++                               6 Thermal Factors (Line3) + 6 Codes Thermal Factors (Line4)
46167    !!--++
46168    !!--++                        [TLS]: 6 Thermal Factors (Line1) + 6 Codes Thermal Factors (Line2)
46169    !!--++                               6 Thermal Factors (Line3) + 6 Codes Thermal Factors (Line4)
46170    !!--++                               9 Thermal Factors (Line5) + 9 Codes Thermal Factors (Line6)
46171    !!--++
46172    !!--++    Internal Coordinates for Atoms (N_Atoms Lines)
46173    !!--++        Atom_Name(6)  Atom_Specie(4)  Coordinates(3)  N1  N2  N3  Biso  Occ [VARY]
46174    !!--++
46175    !!--++    if VARY is present as last option on the Internal Coordinates line,
46176    !!--++    then an extra line is read
46177    !!--++        Codes_Coordinates(3)   Code_BIso  Code_Occ
46178    !!--++
46179    !!--++    Control of error is present
46180    !!--++
46181    !!--++ Update: February - 2005
46182    !!
46183    Subroutine Read_Molecule_in_Var(File_dat,n_ini,n_end,Molecule)
46184       !---- Arguments ----!
46185       character(len=*), dimension(:), intent(in)      :: File_Dat
46186       integer,                        intent(in out)  :: N_Ini
46187       integer,                        intent(in)      :: N_End
46188       type (Molecule_type),           intent(out)     :: Molecule
46189
46190       !---- Local variables -----!
46191       character(len=150)              :: line
46192       character(len=20),dimension(10) :: dire
46193       character(len=4)                :: var
46194       integer                         :: i,j,ic,npos,na,ier
46195       integer,dimension(10)           :: ivet
46196       real(kind=cp), dimension(10)    :: vet
46197       real(kind=cp),dimension(3,3)    :: Eu
46198       logical                         :: in_xtal
46199
46200       in_xtal=.false.
46201       call Init_Err_Molec()
46202
46203       n_ini=n_ini-1
46204
46205       do
46206          n_ini=n_ini+1
46207          if (n_ini > n_end) then
46208             err_molec=.true.
46209             ERR_Molec_Mess="Not found Molecule"
46210             return
46211          end if
46212          line=adjustl(file_dat(n_ini))
46213          if (u_case(line(1:4)) /= "MOLE") cycle
46214
46215          if (u_case(line(1:5)) == "MOLEX") in_xtal=.true.
46216          i=index(line,"!")
46217          if( i /= 0 ) line=line(1:i-1)
46218
46219          !---- Coordinates format ----!
46220          call getword(line,dire,ic)
46221          if (ic /= 4) then
46222             err_molec=.true.
46223             ERR_Molec_Mess="Instruction: MOLE[X] N_Atoms Molecule_Name Coordinates_Type, not found! "
46224             return
46225          end if
46226
46227          !---- Name and Number of Atoms in the molecule ----!
46228          read(unit=dire(2),fmt=*,iostat=ier) na
46229          if(ier /= 0) then
46230             err_molec=.true.
46231             ERR_Molec_Mess="Error reading the number of atoms in a molecule: "//trim(line)
46232             return
46233          else
46234             if (na > 0) then
46235                call init_molecule(molecule,na)
46236                Molecule%Name_mol =dire(3)
46237             else
46238                err_molec=.true.
46239                ERR_Molec_Mess="Error reading the number of atoms in a molecule: "//trim(line)
46240                return
46241             end if
46242          end if
46243
46244          select case (dire(4)(1:1)) ! Coordinates_Type [C,S,F,Z]
46245             case ("C","c")
46246                molecule%coor_type="C"
46247             case ("F","f")
46248                molecule%coor_type="F"
46249             case ("S","s")
46250                molecule%coor_type="S"
46251             case ("Z","z")
46252                molecule%coor_type="Z"
46253             case default
46254                err_molec=.true.
46255                ERR_Molec_Mess="Coordinates Type for Molecule Unknown! "
46256                return
46257          end select ! dire
46258
46259          exit !The molecule has been found
46260
46261       end do
46262
46263       !---- Initialize the crystal part of the molecule
46264       Molecule%xcentre    = 0.0_cp
46265       Molecule%orient     = 0.0_cp
46266       Molecule%therm_type = "   "
46267       Molecule%T_TLS      = 0.0_cp
46268       Molecule%L_TLS      = 0.0_cp
46269       Molecule%S_TLS      = 0.0_cp
46270       Molecule%in_xtal    = .false.
46271       Molecule%is_EulerMat=.false.
46272
46273       if (in_xtal) then
46274          !---- Read the global coordinates of the centre of molecule and orientational angles
46275          do
46276             n_ini=n_ini+1
46277             if (n_ini > n_end) then
46278                err_molec=.true.
46279                ERR_Molec_Mess="Error reading Molecule information! "
46280                return
46281             end if
46282             line=adjustl(file_dat(n_ini))
46283             if (line(1:1) =="!") cycle
46284             exit
46285          end do
46286
46287          i=index(line,"!")
46288          if( i /= 0 ) line=line(1:i-1)
46289
46290          call getword(line,dire,ic)
46291          if (ic /= 8) then
46292             err_molec=.true.
46293             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
46294             return
46295          end if
46296
46297          line=trim(dire(1))//"   "//trim(dire(2))//"   "//trim(dire(3))
46298          call getnum(line,vet,ivet,ic)
46299          if (ic /= 3) then
46300             err_molec=.true.
46301             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
46302             return
46303          end if
46304          Molecule%xcentre=vet(1:3)
46305
46306          line=trim(dire(4))//"   "//trim(dire(5))//"   "//trim(dire(6))
46307          call getnum(line,vet,ivet,ic)
46308          if (ic /= 3) then
46309             err_molec=.true.
46310             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
46311             return
46312          end if
46313          Molecule%orient=vet(1:3)
46314
46315          Molecule%rot_type=adjustl(u_case(dire(7)))
46316          Molecule%therm_type=adjustl(u_case(dire(8)))
46317
46318          do
46319             n_ini=n_ini+1
46320             if (n_ini > n_end) then
46321                err_molec=.true.
46322                ERR_Molec_Mess="Error reading Molecule information! "
46323                return
46324             end if
46325             line=adjustl(file_dat(n_ini))
46326             if (line(1:1) =="!") cycle
46327             exit
46328          end do
46329          i=index(line,"!")
46330          if( i /= 0 ) line=line(1:i-1)
46331
46332          call getnum(line,vet,ivet,ic)
46333          if (ic /= 6) then
46334             err_molec=.true.
46335             ERR_Molec_Mess="Error reading the position and angles of the molecule: "//trim(Molecule%Name_mol)
46336             return
46337          end if
46338          Molecule%mxcentre=vet(1:3)
46339          Molecule%mOrient =vet(4:6)
46340
46341          Molecule%in_xtal = .true.
46342
46343          !---- Set the Euler Matrix
46344          if (Molecule%rot_type /= "E") Molecule%rot_type="P"
46345
46346          call Set_euler_matrix(Molecule%rot_type,  &
46347                                Molecule%orient(1),Molecule%orient(2),Molecule%orient(3),Eu)
46348                                !    Phi/alpha          Theta/beta          Chi/gamma
46349          Molecule%Euler=Eu
46350          Molecule%is_EulerMat=.true.
46351
46352          !---- Read the THERMAL PARAMETERS
46353          if (Molecule%therm_type(1:1) == "T") then
46354             do
46355                n_ini=n_ini+1
46356                if (n_ini > n_end) then
46357                   err_molec=.true.
46358                   ERR_Molec_Mess="Error reading Molecule information! "
46359                   return
46360                end if
46361                line=adjustl(file_dat(n_ini))
46362                if (line(1:1) =="!") cycle
46363                exit
46364             end do
46365             i=index(line,"!")
46366             if( i /= 0 ) line=line(1:i-1)
46367
46368             call getnum(line,vet,ivet,ic)
46369             if (ic /= 6) then
46370                err_molec=.true.
46371                ERR_Molec_Mess="Error reading the tensor T of the molecule: "//trim(Molecule%Name_mol)
46372                return
46373             end if
46374             Molecule%T_TLS=vet(1:6)
46375
46376             do
46377                n_ini=n_ini+1
46378                if (n_ini > n_end) then
46379                   err_molec=.true.
46380                   ERR_Molec_Mess="Error reading Molecule information! "
46381                   return
46382                end if
46383                line=adjustl(file_dat(n_ini))
46384                if (line(1:1) =="!") cycle
46385                exit
46386             end do
46387             i=index(line,"!")
46388             if( i /= 0 ) line=line(1:i-1)
46389
46390             call getnum(line,vet,ivet,ic)
46391             if (ic /= 6) then
46392                err_molec=.true.
46393                ERR_Molec_Mess="Error reading the codes of tensor T of the molecule: "//trim(Molecule%Name_mol)
46394                return
46395             end if
46396             Molecule%mT_TLS=vet(1:6)
46397          end if
46398
46399          if (Molecule%therm_type(2:2) == "L") then
46400             do
46401                n_ini=n_ini+1
46402                if (n_ini > n_end) then
46403                   err_molec=.true.
46404                   ERR_Molec_Mess="Error reading Molecule information! "
46405                   return
46406                end if
46407                line=adjustl(file_dat(n_ini))
46408                if (line(1:1) =="!") cycle
46409                exit
46410             end do
46411             i=index(line,"!")
46412             if( i /= 0 ) line=line(1:i-1)
46413
46414             call getnum(line,vet,ivet,ic)
46415             if (ic /= 6) then
46416                err_molec=.true.
46417                ERR_Molec_Mess="Error reading the tensor L of the molecule: "//trim(Molecule%Name_mol)
46418                return
46419             end if
46420             Molecule%L_TLS=vet(1:6)
46421
46422             do
46423                n_ini=n_ini+1
46424                if (n_ini > n_end) then
46425                   err_molec=.true.
46426                   ERR_Molec_Mess="Error reading Molecule information! "
46427                   return
46428                end if
46429                line=adjustl(file_dat(n_ini))
46430                if (line(1:1) =="!") cycle
46431                exit
46432             end do
46433             i=index(line,"!")
46434             if( i /= 0 ) line=line(1:i-1)
46435
46436             call getnum(line,vet,ivet,ic)
46437             if (ic /= 6) then
46438                err_molec=.true.
46439                ERR_Molec_Mess="Error reading the codes of the tensor L of the molecule: "//trim(Molecule%Name_mol)
46440                return
46441             end if
46442             Molecule%mL_TLS=vet(1:6)
46443          end if
46444
46445          if (Molecule%therm_type(3:3) == "S") then
46446             do
46447                n_ini=n_ini+1
46448                if (n_ini > n_end) then
46449                   err_molec=.true.
46450                   ERR_Molec_Mess="Error reading Molecule information! "
46451                   return
46452                end if
46453                line=adjustl(file_dat(n_ini))
46454                if (line(1:1) =="!") cycle
46455                exit
46456             end do
46457             i=index(line,"!")
46458             if( i /= 0 ) line=line(1:i-1)
46459
46460             call getnum(line,vet,ivet,ic)
46461             if (ic /= 9) then
46462                err_molec=.true.
46463                ERR_Molec_Mess="Error reading the tensor S of the molecule: "//trim(Molecule%Name_mol)
46464                return
46465             end if
46466             Molecule%S_TLS(1,:)=vet(1:3)
46467             Molecule%S_TLS(2,:)=vet(4:6)
46468             Molecule%S_TLS(3,:)=vet(7:9)
46469
46470             do
46471                n_ini=n_ini+1
46472                if (n_ini > n_end) then
46473                   err_molec=.true.
46474                   ERR_Molec_Mess="Error reading Molecule information! "
46475                   return
46476                end if
46477                line=adjustl(file_dat(n_ini))
46478                if (line(1:1) =="!") cycle
46479                exit
46480             end do
46481             i=index(line,"!")
46482             if( i /= 0 ) line=line(1:i-1)
46483
46484             call getnum(line,vet,ivet,ic)
46485             if (ic /= 9) then
46486                err_molec=.true.
46487                ERR_Molec_Mess="Error reading the code of tensor S of the molecule: "//trim(Molecule%Name_mol)
46488                return
46489             end if
46490             Molecule%mS_TLS(1,:)=vet(1:3)
46491             Molecule%mS_TLS(2,:)=vet(4:6)
46492             Molecule%mS_TLS(3,:)=vet(7:9)
46493          end if
46494
46495       end if  !(in_xtal)
46496
46497       !---- Read the internal coordinates of the atoms in the molecule
46498       !---- Read the Z-matrix/Cartesian/spherical/Fractional coordinates of the molecule
46499       molecule%is_connect=.true.
46500       do i=1,na
46501          do
46502             n_ini=n_ini+1
46503             if (n_ini > n_end) then
46504                err_molec=.true.
46505                ERR_Molec_Mess="Error reading Molecule information! "
46506                return
46507             end if
46508             line=adjustl(file_dat(n_ini))
46509             if (line(1:1) =="!") cycle
46510             exit
46511          end do
46512          j=index(line,"!")
46513          if( j /= 0 ) line=line(1:j-1)
46514
46515          !---- Atom Name ---!
46516          call Cutst(line,ic,Molecule%Atname(i))
46517
46518          !---- Atom specie ----!
46519          call Cutst(line,ic,Molecule%Atsymb(i))
46520
46521          !---- Passing Codes? ----!
46522          call getword(line,dire,ic)
46523          var=adjustl(dire(ic))
46524          var=u_case(var)
46525          if (var == "VARY") then
46526             ic=len_trim(line)
46527             npos=index(line(1:ic)," ",back=.true.)
46528             if (npos <=0) then
46529                err_molec=.true.
46530                ERR_Molec_Mess="Error reading Molecule information (II)! "
46531                return
46532             end if
46533             line=line(1:npos)
46534          end if
46535
46536          !---- Rest of Information ----!
46537          vet =0.0
46538          ivet=0
46539          call getnum(line,vet,ivet,ic)
46540          select case (ic)
46541             case (0)
46542                Molecule%I_Coor(:,i)=0.0
46543                Molecule%Conn(:,i)  =0
46544                Molecule%Biso(i)    =0.5
46545                Molecule%Occ(i)     =1.0
46546             case (1)
46547                Molecule%I_Coor(1,i)  =vet(1)
46548                Molecule%I_Coor(2:3,i)=0.0
46549                Molecule%conn(:,i)    =0
46550                Molecule%biso(i)      =0.5
46551                Molecule%Occ(i)       =1.0
46552
46553             case (2)
46554                Molecule%I_Coor(1:2,i)=vet(1:2)
46555                Molecule%I_Coor(3,i)  =0.0
46556                Molecule%conn(:,i)    =0
46557                Molecule%biso(i)      =0.5
46558                Molecule%Occ(i)       =1.0
46559
46560             case (3)
46561                Molecule%I_Coor(:,i)  =vet(1:3)
46562                Molecule%conn(:,i)    =0
46563                Molecule%biso(i)      =0.5
46564                Molecule%Occ(i)       =1.0
46565
46566             case (4)
46567                Molecule%I_Coor(:,i)  =vet(1:3)
46568                Molecule%conn(1,i)    =ivet(4)
46569                Molecule%conn(2:3,i)  =0
46570                Molecule%biso(i)      =0.5
46571                Molecule%Occ(i)       =1.0
46572
46573             case (5)
46574                Molecule%I_Coor(:,i)  =vet(1:3)
46575                Molecule%conn(1:2,i)  =ivet(4:5)
46576                Molecule%conn(3,i)    =0
46577                Molecule%biso(i)      =0.5
46578                Molecule%Occ(i)       =1.0
46579
46580             case (6)
46581                Molecule%I_Coor(:,i)  =vet(1:3)
46582                Molecule%conn(:,i)    =ivet(4:6)
46583                Molecule%biso(i)      =0.5
46584                Molecule%Occ(i)       =1.0
46585
46586             case (7)
46587                Molecule%I_Coor(:,i)  =vet(1:3)
46588                Molecule%conn(:,i)    =ivet(4:6)
46589                Molecule%biso(i)      =vet(7)
46590                Molecule%Occ(i)       =1.0
46591
46592             case (8)
46593                Molecule%I_Coor(:,i)  =vet(1:3)
46594                Molecule%conn(:,i)    =ivet(4:6)
46595                Molecule%biso(i)      =vet(7)
46596                Molecule%Occ(i)       =vet(8)
46597
46598             case default
46599                err_molec=.true.
46600                ERR_Molec_Mess="Error reading the atoms in the molecule: "//trim(Molecule%Name_mol)
46601                return
46602
46603          end select ! ic
46604
46605          if (Molecule%coor_type == "Z") then
46606
46607             if (i == 2 .and. (ivet(4) ==0 .and. ivet(5) ==0 .and. ivet(6) ==0)) then
46608                Molecule%conn(1,i)=1
46609             end if
46610
46611             if (ivet(4) >= i .or. ivet(5) >= i .or. ivet(6) >= i )                err_molec=.true.
46612             if (i == 3 .and. (ivet(4) == 0 .or. ivet(5) == 0))                    err_molec=.true.
46613             if (i > 3 .and. (ivet(4) == 0 .or. ivet(5) == 0 .or. ivet(6) == 0))   err_molec=.true.
46614             if (err_molec) then
46615                ERR_Molec_Mess = "The Z-matrix connectivity is wrong: "//trim(line)
46616                return
46617             end if
46618          else
46619             if (ivet(4) >= i .or. ivet(5) >= i .or. ivet(6) >= i )               molecule%is_connect=.false.
46620             if (i == 3 .and. (ivet(4) == 0 .or. ivet(5) == 0))                   molecule%is_connect=.false.
46621             if (i > 3 .and. (ivet(4) == 0 .or. ivet(5) == 0 .or. ivet(6) == 0))  molecule%is_connect=.false.
46622          end if
46623
46624          Molecule%mI_Coor(:,i)=0.0
46625          Molecule%mbiso(i)  =0.0
46626          Molecule%mocc(i)   =0.0
46627
46628          if (var == "VARY") then
46629             do
46630                n_ini=n_ini+1
46631                if (n_ini > n_end) then
46632                   err_molec=.true.
46633                   ERR_Molec_Mess="Error reading the refinement codes of atoms in the molecule: "//trim(Molecule%Name_mol)
46634                   return
46635                end if
46636                line=adjustl(file_dat(n_ini))
46637                if (line(1:1) =="!") cycle
46638                exit
46639             end do
46640             j=index(line,"!")
46641             if( j /= 0 ) line=line(1:j-1)
46642
46643             call getnum(line,vet,ivet,ic)
46644             select case (ic)
46645                case (3)
46646                   Molecule%mI_Coor(:,i)=vet(1:3)
46647
46648                case (5)
46649                   Molecule%mI_Coor(:,i)=vet(1:3)
46650                   Molecule%mbiso(i)  =vet(4)
46651                   Molecule%mocc(i)   =vet(5)
46652
46653                case default
46654                   err_molec=.true.
46655                   ERR_Molec_Mess="Error reading the refinement codes of atoms in the molecule: "//trim(Molecule%Name_mol)
46656                   return
46657             end select
46658          end if
46659
46660       end do
46661
46662       return
46663    End Subroutine Read_Molecule_in_Var
46664
46665    !!----
46666    !!---- Subroutine Set_Euler_Matrix(Rt,Phi,Theta,Chi,Eu)
46667    !!----    character(len=*),              intent ( in) :: Rt
46668    !!----    real(kind=cp),                 intent ( in) :: Phi,Theta,Chi
46669    !!----    real(kind=cp), dimension(3,3), intent (out) :: Eu
46670    !!----
46671    !!----    Subroutine to obtain the Euler active matrix to transform a point
46672    !!----    to another point. For instance the internal coordinates of a molecule
46673    !!----    can be transformed to absolute positions using columns vectors.
46674    !!----    If the Cartesian coordinates of an atom in the molecular frame is the
46675    !!----    column vector  Xm, the cartesian coordinates in the crystal frame X
46676    !!----    are obtained from:  X = Eu Xm
46677    !!----    The internal coordinates of a point are obtained from Xm = EuT X.
46678    !!----    The character variable "rt" indicates the type of Euler angles provided.
46679    !!----    If rt="E", the angles PHI,THETA,CHI correspond to the conventional
46680    !!----    Euler angles ALPHA, BETA, GAMMA. Otherwise, they correspond to the
46681    !!----    2nd setting, allowing to interpret PHI and THETA as the polar angles of
46682    !!----    the molecular frame Zm-axis, and CHI a rotation around Zm.
46683    !!----
46684    !!----   Update: February - 2005
46685    !!
46686    Subroutine Set_Euler_Matrix(Rt,Phi,Theta,Chi,Eu)
46687       !---- Arguments ----!
46688       character(len=*),              intent ( in) :: Rt
46689       real(kind=cp),                 intent ( in) :: Phi,Theta,Chi
46690       real(kind=cp), dimension(3,3), intent (out) :: Eu
46691
46692       !---- Local Variables ----!
46693       real(kind=cp) :: PH,TH,CH
46694
46695       TH=THETA
46696       if (rt(1:1) == "E") then
46697          PH=PHI+90.0_cp
46698          CH=CHI-90.0_cp
46699       else
46700          PH=PHI
46701          CH=CHI
46702       end if
46703       Eu(1,1) =  cosd(PH)* cosd(TH)* cosd(CH) - sind(PH)* sind(CH)
46704       Eu(1,2) = -cosd(PH)* cosd(TH)* sind(CH) - sind(PH)* cosd(CH)
46705       Eu(1,3) =  cosd(PH)* sind(TH)
46706       Eu(2,1) =  sind(PH)* cosd(TH)* cosd(CH) + cosd(PH)* sind(CH)
46707       Eu(2,2) = -sind(PH)* cosd(TH)* sind(CH) + cosd(PH)* cosd(CH)
46708       Eu(2,3) =  sind(PH)* sind(TH)
46709       Eu(3,1) = -cosd(CH)* sind(TH)
46710       Eu(3,2) =  sind(CH)* sind(TH)
46711       Eu(3,3) =            cosd(TH)
46712
46713       return
46714    End Subroutine Set_Euler_Matrix
46715
46716    !!----
46717    !!---- Subroutine Spherical_to_Cartesian(Molecule,NewMolecule)
46718    !!----    type (Molecule_type), intent(in out)           :: Molecule
46719    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
46720    !!----
46721    !!----    Subroutine to transform the internal coordinates of a molecule from Spherical
46722    !!----    coordinates to  cartesian coordinaters.
46723    !!----    If a second argument is present the subroutine creates a new molecule
46724    !!----    (copy of the old one) with spherical coordinates, preserving
46725    !!----    the input molecule in Cartesian Coordinates. Otherwise the input
46726    !!----    molecule is changed on output.
46727    !!----    Control of error is present
46728    !!----
46729    !!---- Update: February - 2005
46730    !!
46731    Subroutine Spherical_to_Cartesian(Molecule,NewMolecule)
46732       !---- Arguments ----!
46733       type (Molecule_type), intent(in out)           :: Molecule
46734       type (Molecule_type), intent(   out), optional :: Newmolecule
46735
46736       !---- Local variables -----!
46737       integer                     :: i,na
46738       real(kind=cp)               :: r, theta, phi
46739
46740       type (Molecule_type)        :: Newmol
46741
46742       !---- Controls ----!
46743       if (molecule%coor_type /= "S") then
46744          err_molec=.true.
46745          ERR_Molec_Mess="Error in Spherical_to_Cartesian: the input molecule is not in Spherical coordinates"
46746          return
46747       end if
46748
46749       na= Molecule%natoms
46750       if (na <= 0) then
46751          err_molec=.true.
46752          ERR_Molec_Mess="Error in Spherical_to_Cartesian: No atoms are defined"
46753          return
46754       end if
46755
46756       call init_molecule(newmol,na)
46757       NewMol=Molecule
46758
46759       !---- Start calculations for each atom of the molecule ----!
46760       do i=1,na
46761          r     = Molecule%I_coor(1,i)
46762          theta = Molecule%I_coor(2,i)
46763          phi   = Molecule%I_coor(3,i)
46764          NewMol%I_coor(1,i) = r*sind(theta)*cosd(phi)
46765          NewMol%I_coor(2,i) = r*sind(theta)*sind(phi)
46766          NewMol%I_coor(3,i) = r*cosd(theta)
46767       end do
46768       NewMol%coor_type="C"
46769
46770       if (present(NewMolecule)) then
46771          call Init_molecule(NewMolecule,Newmol%natoms)
46772          if (NewMolecule%natoms <=0) then
46773             err_molec=.true.
46774             ERR_Molec_Mess="Error in Spherical to Cartesian: The optional variable was not dimensioned!"
46775             return
46776          end if
46777          NewMolecule=newmol
46778       else
46779          Molecule=newmol
46780       end if
46781
46782       return
46783    End Subroutine Spherical_to_Cartesian
46784
46785    !!----
46786    !!---- Subroutine Spherical_to_Fractional(Molecule,Cell,NewMolecule)
46787    !!----    type (Molecule_type), intent(in out)           :: Molecule
46788    !!----    type (Crystal_Cell_Type), intent(in)           :: Cell
46789    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
46790    !!----
46791    !!----    Subroutine to transform the internal coordinates of a
46792    !!----    molecule from Spherical coordinates to  Fractional coordinaters.
46793    !!----    If a second argument is present the subroutine creates a new
46794    !!----    molecule (copy of the old one) with Fractional coordinates,
46795    !!----    preserving the input molecule in Spherical Coordinates. Otherwise
46796    !!----    the input molecule is changed on output.
46797    !!----    Control of error is present
46798    !!----
46799    !!---- Update: February - 2005
46800    !!
46801    Subroutine Spherical_to_Fractional(Molecule, Cell, NewMolecule)
46802       !---- Arguments ----!
46803       type (Molecule_type), intent(in out)           :: Molecule
46804       type (Crystal_Cell_Type), intent(in)           :: Cell
46805       type (Molecule_type), intent(   out), optional :: NewMolecule
46806
46807       !---- Local Variables ----!
46808       integer                     :: na
46809       type (Molecule_type)        :: Newmol
46810
46811       !---- Controls ----!
46812       if (molecule%coor_type /= "S") then
46813          err_molec=.true.
46814          ERR_Molec_Mess="Error in Spherical_to_Fractional: the input molecule is not in Spherical coordinates"
46815          return
46816       end if
46817
46818       na= Molecule%natoms
46819       if (na <= 0) then
46820          err_molec=.true.
46821          ERR_Molec_Mess="Error in Spherical_to_Fractional: No atoms are defined"
46822          return
46823       end if
46824
46825       !---- Step 1----!
46826       call init_molecule(newmol,na)
46827       newmol=Molecule
46828       call Spherical_to_Cartesian(NewMol)
46829       if (err_molec) then
46830          ERR_Molec_Mess="Error in Spherical_to_Fractional: Intermediate procedure fail (I)!"
46831          return
46832       end if
46833
46834       !---- Step 2 ----!
46835       call Cartesian_to_Fractional(NewMol,Cell)
46836       if (err_molec) then
46837          ERR_Molec_Mess="Error in Spherical_to_Fractional: Intermediate procedure fail (II)!"
46838          return
46839       end if
46840
46841       !---- Step 3 ----!
46842       if (present(newmolecule)) then
46843          call Init_molecule(NewMolecule,na)
46844          if (NewMolecule%natoms <=0) then
46845             err_molec=.true.
46846             ERR_Molec_Mess="Error in Spherical to Fractional: The optional variable was not dimensioned!"
46847             return
46848          end if
46849          NewMolecule=newmol
46850       else
46851          Molecule=newmol
46852       end if
46853
46854       return
46855    End Subroutine Spherical_to_Fractional
46856
46857    !!----
46858    !!---- Subroutine Spherical_to_Zmatrix(Molecule,NewMolecule,Cell)
46859    !!----    type (Molecule_type), intent(in out)           :: Molecule
46860    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
46861    !!----    Type(Crystal_Cell_Type), intent(in),  optional :: Cell
46862    !!----
46863    !!----    Subroutine to transform the internal coordinates of a
46864    !!----    molecule from Spherical coordinates to  Zmatrix coordinaters.
46865    !!----    If a second argument is present the subroutine creates a new
46866    !!----    molecule (copy of the old one) with Zmatrix coordinates,
46867    !!----    preserving the input molecule in Spherical Coordinates. Otherwise
46868    !!----    the input molecule is changed on output.
46869    !!----    Control of error is present
46870    !!----
46871    !!---- Update: February - 2005
46872    !!
46873    Subroutine Spherical_to_Zmatrix(Molecule, NewMolecule,Cell)
46874       !---- Arguments ----!
46875       type (Molecule_type), intent(in out)           :: Molecule
46876       type (Molecule_type), intent(   out), optional :: NewMolecule
46877       Type(Crystal_Cell_Type), intent(in),  optional :: Cell
46878
46879       !---- Local Variables ----!
46880       integer                     :: na
46881       type (Molecule_type)        :: Newmol
46882
46883       !---- Controls ----!
46884       if (molecule%coor_type /= "S") then
46885          err_molec=.true.
46886          ERR_Molec_Mess="Error in Spherical_to_ZMatrix: the input molecule is not in Spherical coordinates"
46887          return
46888       end if
46889
46890       na= Molecule%natoms
46891       if (na <= 0) then
46892          err_molec=.true.
46893          ERR_Molec_Mess="Error in Spherical_to_ZMatrix: No atoms are defined"
46894          return
46895       end if
46896
46897       !---- Step 1----!
46898       call init_molecule(newmol,na)
46899       newmol= Molecule
46900       call Spherical_to_Cartesian(NewMol)
46901       if (err_molec) then
46902          ERR_Molec_Mess="Error in Spherical_to_Zmatrix: Intermediate procedure fail (I)!"
46903          return
46904       end if
46905
46906       !---- Step 2 ----!
46907       if(present(Cell)) then
46908          call Cartesian_to_Zmatrix(NewMol,Cell=Cell)
46909       else
46910          call Cartesian_to_Zmatrix(NewMol)
46911       end if
46912       if (err_molec) then
46913          ERR_Molec_Mess="Error in Spherical_to_Zmatrix: Intermediate procedure fail (II)!"
46914          return
46915      end if
46916
46917       !---- Step 3 ----!
46918       if (present(newmolecule)) then
46919          call Init_molecule(NewMolecule,na)
46920          if (NewMolecule%natoms <=0) then
46921             err_molec=.true.
46922             ERR_Molec_Mess="Error in Spherical to ZMatrix: The optional variable was not dimensioned!"
46923             return
46924          end if
46925          NewMolecule=newmol
46926       else
46927          Molecule=newmol
46928       end if
46929
46930       return
46931    End Subroutine Spherical_to_Zmatrix
46932
46933    !!----
46934    !!---- Subroutine Write_Free_Atoms(AtmF,N,Lun)
46935    !!----    type (Atom_type), dimension(:), intent(in) :: AtmF
46936    !!----    integer,                        intent(in) :: N
46937    !!----    integer, optional,              intent(in) :: Lun
46938    !!----
46939    !!----    Write information about Free Atoms for Molecular Crystal
46940    !!----
46941    !!---- Update: February - 2005
46942    !!
46943    Subroutine Write_Free_Atoms(AtmF,N,Lun)
46944       !---- Arguments ----!
46945       type (Atom_type), dimension(:), intent(in) :: AtmF
46946       integer,                        intent(in) :: N
46947       integer, optional,              intent(in) :: Lun
46948
46949       !---- Local Variables ----!
46950       integer :: i,uni
46951
46952       uni=6
46953       if (present(lun)) uni=lun
46954
46955       write(unit=uni,fmt="(a)")     " "
46956       write(unit=uni,fmt="(a,i4)")  " => Number of Free Atoms: ",N
46957       write(unit=uni,fmt="(a)")     " "
46958       write (unit=uni,fmt="(T5,a)") " Atom      Chem        x/a        y/b        z/c       Occ     Biso"
46959       write (unit=uni,fmt="(T5,a)") "===================================================================="
46960       do i=1,N
46961          write(unit=uni,fmt="(T5,a,T16,a,T21,5f11.4)") atmF(i)%Lab,atmF(i)%chemsymb,atmF(i)%x,atmF(i)%occ,atmF(i)%biso
46962       end do
46963
46964       return
46965    End Subroutine Write_Free_Atoms
46966
46967    !!----
46968    !!---- Subroutine Write_Molecular_Crystal(MolCrys,Lun)
46969    !!----    type (Molecular_Crystal_type), intent(in) :: MolCrys
46970    !!----    integer, optional,             intent(in) :: Lun
46971    !!----
46972    !!----    Write information about Molecular Crystal
46973    !!----
46974    !!---- Update: February - 2005
46975    !!
46976    Subroutine Write_Molecular_Crystal(MolCrys,Lun)
46977       !---- Arguments ----!
46978       type(Molecular_Crystal_Type), intent(in) :: MolCrys
46979       integer, optional,            Intent(in) :: Lun
46980
46981       !---- Local Variables ----!
46982       integer :: i,uni
46983
46984       uni=6
46985       if (present(lun)) uni=lun
46986
46987       write(unit=uni,fmt="(/,/,a)") "      Molecular Crystal Information  "
46988       write(unit=uni,fmt="(a)")     "      ----------------------------- "
46989
46990       write(unit=uni,fmt="(a)")     " "
46991       call Write_Crystal_Cell(MolCrys%Cell,uni)
46992       write(unit=uni,fmt="(a)")     " "
46993
46994       write(unit=uni,fmt="(a)")     " "
46995       call Write_SpaceGroup(MolCrys%SPG,uni)
46996       write(unit=uni,fmt="(a)")     " "
46997
46998       if (MolCrys%N_Free > 0) then
46999          write(unit=uni,fmt="(a)")     " "
47000          call Write_Free_Atoms(MolCrys%Atm,MolCrys%N_Free,uni)
47001          write(unit=uni,fmt="(a)")     " "
47002       end if
47003
47004       if (MolCrys%N_Mol > 0) then
47005          do i=1,MolCrys%N_Mol
47006             write(unit=uni,fmt="(a)")     " "
47007             call Write_Molecule(MolCrys%Mol(i),uni)
47008             write(unit=uni,fmt="(a)")     " "
47009          end do
47010       end if
47011
47012       return
47013    End Subroutine Write_Molecular_Crystal
47014
47015    !!----
47016    !!---- Subroutine Write_Molecule(Molecule,Lun)
47017    !!----    type (Molecule_type), intent(in)           :: Molecule
47018    !!----    integer,              intent(in), optional :: Lun
47019    !!----
47020    !!----    Write information about molecule
47021    !!----
47022    !!---- Update: February - 2005
47023    !!
47024    Subroutine Write_Molecule(Molecule,Lun)
47025       !---- Arguments ----!
47026       type (Molecule_type), intent(in):: Molecule
47027       integer,optional,     intent(in):: Lun
47028
47029       !---- Local variables -----!
47030       integer            :: i,uni,j
47031       character(len=4)   :: var
47032       real(kind=cp), dimension(3  ) :: geom_cent
47033
47034       uni=6
47035       if (present(lun)) uni=lun
47036
47037       write(unit=uni,fmt="(/,/,a,a)")    " =>  MOLECULE of name :  ",trim(Molecule%Name_mol)
47038       select case (molecule%coor_type)
47039          case ("C","c")
47040             write(unit=uni,fmt="(a)")     "            Type of Molecular description: CARTESIAN COORDINATES"
47041          case ("F","f")
47042             write(unit=uni,fmt="(a)")     "            Type of Molecular description: FRACTIONAL COORDINATES"
47043          case ("S","s")
47044             write(unit=uni,fmt="(a)")     "            Type of Molecular description: SPHERICAL COORDINATES"
47045          case ("Z","z")
47046             write(unit=uni,fmt="(a)")     "            Type of Molecular description: Z-MATRIX"
47047          case default
47048             write(unit=uni,fmt="(a)")     "            Type of Molecular description: UNKNOWN "
47049       end select ! molecule%coor_type
47050
47051       write(unit=uni,fmt="(a,i3)")     "                          Number of atoms: ",  Molecule%natoms
47052       if (Molecule%in_xtal) then
47053          write(unit=uni,fmt="(a,3f11.5)")   "         Fractional coordinates of centre: ",  Molecule%xcentre
47054          write(unit=uni,fmt="(a,3f11.5)")   "                         Refinement codes: ",  Molecule%mxcentre
47055
47056          if (Molecule%rot_type == "E") then
47057             write(unit=uni,fmt="(a,3f11.5,a,3f9.5,a)") &
47058                                 "   Orientation EULER angles (alp,bet,gam): ",  Molecule%orient,&
47059                                 " (radians:", Molecule%orient*to_rad,")"
47060          else
47061             write(unit=uni,fmt="(a,3f11.5,a,3f9.5,a)") &
47062                                 "   Orientation POLAR angles (PHI,THE,CHI): ",  Molecule%orient,&
47063                                 " (radians:", Molecule%orient*to_rad,")"
47064          end if
47065          write(unit=uni,fmt="(a,3f11.5)") "                         Refinement codes: ",  Molecule%mOrient
47066
47067          if (Molecule%therm_type(1:1) == "T") then
47068             write(unit=uni,fmt="(a,6f11.5)")"       T-tensor (T11,T22,T33,T12,T13,T23): ", Molecule%T_TLS
47069             write(unit=uni,fmt="(a,6f11.5)")"                         Refinement codes: ", Molecule%mT_TLS
47070          end if
47071
47072          if (Molecule%therm_type(2:2) == "L") then
47073             write(unit=uni,fmt="(a,6f11.5)")"       L-tensor (L11,L22,L33,L12,L13,L23): ", Molecule%L_TLS
47074             write(unit=uni,fmt="(a,6f11.5)")"                         Refinement codes: ", Molecule%mL_TLS
47075          end if
47076
47077          if (Molecule%therm_type(3:3) == "S") then
47078             write(unit=uni,fmt="(a,3f11.5,tr5,3f11.5)")"       S-tensor             (S11,S12,S13): ", &
47079                                              Molecule%S_TLS(1,:), Molecule%mS_TLS(1,:)
47080             write(unit=uni,fmt="(a,3f11.5,tr5,3f11.5)")"     + Refinement codes     (S21,S22,S23): ", &
47081                                              Molecule%S_TLS(2,:), Molecule%mS_TLS(2,:)
47082             write(unit=uni,fmt="(a,3f11.5,tr5,3f11.5)")"                            (S31,S32,S33): ", &
47083                                              Molecule%S_TLS(3,:), Molecule%mS_TLS(3,:)
47084          end if
47085
47086          select case (Molecule%coor_type)
47087             case ("C","c")
47088                write(unit=uni,fmt="(t29,a)")"Atom    Type        XC          YC          ZC    N1  N2  N3      Biso        Occ "
47089             case ("F","f")
47090                write(unit=uni,fmt="(t29,a)")"Atom    Type        X           Y           Z     N1  N2  N3      Biso        Occ "
47091             case ("S","s")
47092                write(unit=uni,fmt="(t29,a)")"Atom    Type    distance      Theta       Phi     N1  N2  N3      Biso        Occ "
47093             case ("Z","z")
47094                write(unit=uni,fmt="(t29,a)")"Atom    Type    distance  Bond-Angle Torsion-Ang  N1  N2  N3      Biso        Occ "
47095             case default
47096                write(unit=uni,fmt="(t29,a)")"Atom    Type      Coor1       Coor2       Coor3   N1  N2  N3      Biso        Occ "
47097          end select ! Molecule%coor_type
47098
47099       else  !(Molecule%in_xtal)
47100
47101          select case (Molecule%coor_type)
47102             case ("C","c")
47103                write(unit=uni,fmt="(t29,a)")"Atom    Type        XC          YC          ZC    N1  N2  N3 "
47104             case ("F","f")
47105                write(unit=uni,fmt="(t29,a)")"Atom    Type        X           Y           Z     N1  N2  N3 "
47106             case ("S","s")
47107                write(unit=uni,fmt="(t29,a)")"Atom    Type    distance      Theta       Phi     N1  N2  N3 "
47108             case ("Z","z")
47109                write(unit=uni,fmt="(t29,a)")"Atom    Type    distance  Bond-Angle Torsion-Ang  N1  N2  N3 "
47110             case default
47111                write(unit=uni,fmt="(t29,a)")"Atom    Type      Coor1       Coor2       Coor3   N1  N2  N3 "
47112          end select ! Molecule%coor_type
47113
47114       end if  !(Molecule%in_xtal)
47115
47116          geom_cent=0.0_cp
47117
47118          if (Molecule%in_xtal ) then
47119             do i=1,Molecule%natoms
47120                  if(Molecule%AtSymb(i) /= "ZE") geom_cent=geom_cent + Molecule%I_Coor(:,i)
47121                  write(unit=uni,fmt="(t29,a,tr2,a,3f12.5,3i4,2f12.5)")  &
47122                       Molecule%AtName(i), Molecule%AtSymb(i),Molecule%I_Coor(:,i),  &
47123                       Molecule%Conn(:,i), Molecule%Biso(i),  Molecule%Occ(i)
47124                  var="    "
47125                  do j=1,3
47126                     if (abs(Molecule%mI_Coor(j,i)) > eps) var="VARY"
47127                  end do
47128                  if (abs(Molecule%mbiso(i)) > eps)      var="VARY"
47129                  if (abs(Molecule%mocc(i))  > eps)      var="VARY"
47130                  if (var == "VARY") then
47131                     write(unit=uni,fmt="(t41,3f12.5,tr12,2f12.5)")  Molecule%mI_Coor(:,i), &
47132                          Molecule%mbiso(i),Molecule%mocc(i)
47133                  end if
47134             end do
47135          else
47136             do i=1,Molecule%natoms
47137                  if(Molecule%AtSymb(i) /= "DU") geom_cent=geom_cent + Molecule%I_Coor(:,i)
47138                  write(unit=uni,fmt="(t29,a,tr2,a,3f12.5,3i4       )")  &
47139                  Molecule%Atname(i), Molecule%Atsymb(i), Molecule%I_coor(:,i),  &
47140                  Molecule%conn(:,i)
47141             end do
47142          end if
47143
47144       if(      molecule%coor_type == "C" .or. molecule%coor_type == "c" &
47145           .or. molecule%coor_type == "F" .or. molecule%coor_type == "f") then
47146           geom_cent=geom_cent/real(Molecule%natoms)
47147           write(unit=uni,fmt="(//,a,3F10.5)")  "  => Geometrical centre of molecule ( "//trim(Molecule%Name_mol)//" ):", geom_cent
47148       end if
47149
47150       write(unit=uni,fmt="(/,a)")              "  => Euler Matrix of molecule ( "//trim(Molecule%Name_mol)//" ):"
47151       do i=1,3
47152          write(unit=uni,fmt="(t29,3f10.5)")  Molecule%Euler(i,:)
47153       end do
47154
47155       return
47156    End Subroutine Write_Molecule
47157
47158    !!----
47159    !!---- Subroutine Zmatrix_to_Cartesian(Molecule,NewMolecule)
47160    !!----    type (Molecule_type), intent(in out)           :: Molecule
47161    !!----    type (Molecule_type), intent(   out), optional :: NewMolecule
47162    !!----
47163    !!----    Subroutine to transform the internal coordinates of a molecule from
47164    !!----    Z-matrix to cartesian coordinates.
47165    !!----    If a second argument is present the subroutine creates a new molecule
47166    !!----    (copy of the old one) with cartesian coordinates, preserving
47167    !!----    the input molecule. Otherwise the input molecule is changed on output.
47168    !!----    Control of error is present
47169    !!----
47170    !!---- Update: February - 2005
47171    !!
47172    Subroutine Zmatrix_to_Cartesian(Molecule,NewMolecule)
47173       !---- Arguments ----!
47174       type (Molecule_type), intent(in out)           :: Molecule
47175       type (Molecule_type), intent(   out), optional :: NewMolecule
47176
47177       !---- Local variables -----!
47178       integer                     :: i,na,j,k,n
47179       real(kind=cp)               :: dist, ang
47180       real(kind=cp), dimension(3) :: ci,ri,rj,rk,rn
47181
47182       type (Molecule_type)        :: Newmol
47183
47184       !---- Controls ----!
47185       if (molecule%coor_type /= "Z") then
47186          err_molec=.true.
47187          ERR_Molec_Mess="Error in Zmatrix_to_Cartesian: the input molecule is not a Z-matrix"
47188          return
47189       end if
47190
47191       na= Molecule%natoms
47192       if (na <= 0) then
47193          err_molec=.true.
47194          ERR_Molec_Mess="Error in Zmatrix_to_Cartesian: Not atoms are defined"
47195          return
47196       end if
47197
47198       call init_molecule(newmol,na)
47199       NewMol=Molecule
47200
47201       !---- Start calculations for each atom of the molecule ----!
47202
47203       !---- First atom is always at origin (Z-matrix)
47204       NewMol%I_coor(:,1) = 0.0_cp
47205       NewMol%conn(:,1) = 0
47206
47207       !---- Second atom is always along "x"
47208       NewMol%I_coor(2:3,2) = 0.0
47209       NewMol%conn(2:3,2) = 0
47210       NewMol%conn(1,2)   = 1
47211
47212       !--- Third atom is always in the "xy" plane       !A(i) d_ij  ang_ijk   dang_ijkl  j k l
47213       if (NewMol%conn(1,3) == 1) then
47214          NewMol%conn(2,3) = 2
47215          NewMol%conn(3,3) = 0
47216          dist= NewMol%I_coor(1,3)
47217          ang = NewMol%I_coor(2,3)
47218          NewMol%I_coor(1,3) = dist * cosd(ang)
47219          NewMol%I_coor(2,3) = dist * sind(ang)
47220          NewMol%I_coor(3,3) = 0.0_cp
47221       else
47222          NewMol%conn(1,3) = 2
47223          NewMol%conn(2,3) = 1
47224          NewMol%conn(3,3) = 0
47225          dist= NewMol%I_coor(1,3)
47226          ang = NewMol%I_coor(2,3)
47227          NewMol%I_coor(1,3) = dist * cosd(180.0_cp-ang) +  NewMol%I_coor(1,2)
47228          NewMol%I_coor(2,3) = dist * sind(180.0_cp-ang)
47229          NewMol%I_coor(3,3) = 0.0_cp
47230       end if
47231
47232       do i=4,na
47233          ci(:) = NewMol%I_coor(:,i)
47234          j     = NewMol%conn(1,i)         !The connectivity is needed for the Z-matrix description
47235          k     = NewMol%conn(2,i)         !If the connectivity is given it is possible to transform to
47236          n     = NewMol%conn(3,i)         !Z-matrix if cartesian/spherical coordinates are given.
47237          if (j == 0 .or. k == 0 .or. n == 0) cycle
47238          rj(:) = NewMol%I_coor(:,j)
47239          rk(:) = NewMol%I_coor(:,k)
47240          rn(:) = NewMol%I_coor(:,n)
47241          call get_cartesian_from_Z(ci,ri,rj,rk,rn)
47242          NewMol%I_coor(:,i) = ri
47243       end do
47244       NewMol%coor_type="C"
47245
47246       if (present(NewMolecule)) then
47247          call Init_molecule(NewMolecule,na)
47248          if (NewMolecule%natoms <=0) then
47249             err_molec=.true.
47250             ERR_Molec_Mess="Error in ZMatrix to Cartesian: The optional variable was not dimensioned!"
47251             return
47252          end if
47253          NewMolecule=newmol
47254       else
47255          Molecule=newmol
47256       end if
47257
47258       return
47259    End Subroutine Zmatrix_to_Cartesian
47260
47261    !!----
47262    !!---- Subroutine Zmatrix_to_Fractional(Molecule,Cell,NewMolecule)
47263    !!----    type (Molecule_type),     intent(in out)           :: Molecule
47264    !!----    type (Crystal_Cell_Type), intent(in    )           :: Cell
47265    !!----    type (Molecule_type),     intent(   out), optional :: NewMolecule
47266    !!----
47267    !!----    Subroutine to transform the internal coordinates of a molecule from
47268    !!----    Z-matrix to fractional coordinates.
47269    !!----    If a third argument is present the subroutine creates a new molecule
47270    !!----    (copy of the old one) with fractional coordinates, preserving
47271    !!----    the input molecule in Z-matrix. Otherwise the input molecule is changed on output.
47272    !!----    Control of error is present
47273    !!----
47274    !!---- Update: February - 2005
47275    !!
47276    Subroutine Zmatrix_to_Fractional(Molecule,Cell,NewMolecule)
47277       !---- Arguments ----!
47278       type (Molecule_type),     intent(in out)           :: Molecule
47279       type (Crystal_Cell_Type), intent(in    )           :: Cell
47280       type (Molecule_type),     intent(   out), optional :: NewMolecule
47281
47282       !---- Local variables -----!
47283       integer                       :: na
47284       type (Molecule_type)          :: Newmol
47285
47286       !---- Controls ----!
47287       if (molecule%coor_type /= "Z") then
47288          err_molec=.true.
47289          ERR_Molec_Mess="Error in Zmatrix_to_Fractional: the input molecule is not in Zmatrix coordinates"
47290          return
47291       end if
47292
47293       na=molecule%natoms
47294       if (na <= 0) then
47295          err_molec=.true.
47296          ERR_Molec_Mess="Error in Zmatrix_to_Fractional: No atoms found"
47297          return
47298       end if
47299
47300       call init_molecule(newmol,na)
47301       newmol= molecule
47302       call Zmatrix_to_Cartesian(newmol)
47303       call Cartesian_to_Fractional(newmol,cell)
47304
47305       if (present(NewMolecule)) then
47306          call Init_molecule(NewMolecule,Newmol%natoms)
47307          if (NewMolecule%natoms <=0) then
47308             err_molec=.true.
47309             ERR_Molec_Mess="Error in ZMatrix_to_Fractional: The optional variable was not dimensioned!"
47310             return
47311          end if
47312          NewMolecule=newmol
47313       else
47314          Molecule=newmol
47315       end if
47316
47317       return
47318    End Subroutine Zmatrix_to_Fractional
47319
47320    !!----
47321    !!---- Subroutine Zmatrix_to_Spherical(Molecule,NewMolecule)
47322    !!----    type (Molecule_type), intent(in out)           :: Molecule
47323    !!----    type (Molecule_type), intent(   out), optional :: Newmolecule
47324    !!----
47325    !!----    Subroutine to transform the internal coordinates of a
47326    !!----    molecule from Zmatrix coordinates to  Spherical coordinaters.
47327    !!----    If a second argument is present the subroutine creates a new
47328    !!----    molecule (copy of the old one) with Spherical coordinates,
47329    !!----    preserving the input molecule in Zmatrix Coordinates. Otherwise
47330    !!----    the input molecule is changed on output.
47331    !!----    Control of error is present
47332    !!----
47333    !!---- Update: February - 2005
47334    !!
47335    Subroutine Zmatrix_to_Spherical(Molecule, NewMolecule)
47336       !---- Arguments ----!
47337       type (Molecule_type), intent(in out)           :: Molecule
47338       type (Molecule_type), intent(   out), optional :: NewMolecule
47339
47340       !---- Local Variables ----!
47341       integer                     :: na
47342       type (Molecule_type)        :: Newmol
47343
47344       !---- Controls ----!
47345       if (molecule%coor_type /= "Z") then
47346          err_molec=.true.
47347          ERR_Molec_Mess="Error in Zmatrix_to_Spherical: the input molecule is not in Zmatrix coordinates"
47348          return
47349       end if
47350
47351       na=molecule%natoms
47352       if (na <= 0) then
47353          err_molec=.true.
47354          ERR_Molec_Mess="Error in Zmatrix_to_Fractional: No atoms found"
47355          return
47356       end if
47357
47358       !---- Step 1----!
47359       call init_Molecule(newmol,na)
47360       newmol=Molecule
47361       call Zmatrix_to_Cartesian(NewMol)
47362       if (err_molec) then
47363          ERR_Molec_Mess="Error in Zmatrix_to_Spherical: Intermediate procedure fail (I)!"
47364          return
47365       end if
47366
47367       !---- Step 2 ----!
47368       call Cartesian_to_Spherical(NewMol)
47369       if (err_molec) then
47370          ERR_Molec_Mess="Error in Zmatrix_to_Spherical: Intermediate procedure fail (II)!"
47371          return
47372       end if
47373
47374       !---- Step 3 ----!
47375       if (present(newmolecule)) then
47376          call Init_molecule(NewMolecule,na)
47377          if (NewMolecule%natoms <=0) then
47378             err_molec=.true.
47379             ERR_Molec_Mess="Error in ZMatrix to Spherical: The optional variable was not dimensioned!"
47380             return
47381          end if
47382          NewMolecule=newmol
47383       else
47384          Molecule=newmol
47385       end if
47386
47387       return
47388    End Subroutine Zmatrix_to_Spherical
47389
47390 End Module CFML_Molecular_Crystals
47391!!-------------------------------------------------------
47392!!---- Crystallographic Fortran Modules Library (CrysFML)
47393!!-------------------------------------------------------
47394!!---- The CrysFML project is distributed under LGPL. In agreement with the
47395!!---- Intergovernmental Convention of the ILL, this software cannot be used
47396!!---- in military applications.
47397!!----
47398!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
47399!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
47400!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
47401!!----
47402!!---- Authors: Juan Rodriguez-Carvajal (ILL)
47403!!----          Javier Gonzalez-Platas  (ULL)
47404!!----
47405!!---- Contributors: Laurent Chapon     (ILL)
47406!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
47407!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
47408!!----               Tierry Roisnel     (CDIFX,Rennes France)
47409!!----               Eric Pellegrini    (ILL)
47410!!----
47411!!---- This library is free software; you can redistribute it and/or
47412!!---- modify it under the terms of the GNU Lesser General Public
47413!!---- License as published by the Free Software Foundation; either
47414!!---- version 3.0 of the License, or (at your option) any later version.
47415!!----
47416!!---- This library is distributed in the hope that it will be useful,
47417!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
47418!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
47419!!---- Lesser General Public License for more details.
47420!!----
47421!!---- You should have received a copy of the GNU Lesser General Public
47422!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
47423!!----
47424!!----
47425!!---- MODULE: CFML_IO_Formats
47426!!----   INFO: Creation/Conversion for several formats
47427!!----
47428!!---- HISTORY
47429!!----    Update: 07/03/2011
47430!!----
47431!!----
47432!!---- DEPENDENCIES
47433!!----
47434!!---- VARIABLES
47435!!----    ERR_FORM
47436!!----    ERR_FORM_MESS
47437!!----    INTERVAL_TYPE
47438!!----    JOB_INFO_TYPE
47439!!----
47440!!---- PROCEDURES
47441!!----    Functions:
47442!!----
47443!!----    Subroutines:
47444!!----       FILE_TO_FILELIST
47445!!----       GET_JOB_INFO
47446!!----       GET_PHASES_FILE
47447!!--++       GET_NPHASES_CIFFILE
47448!!--++       GET_NPHASES_PCRFILE
47449!!----       INIT_ERR_FORM
47450!!----       READ_ATOM
47451!!----       READ_CELL
47452!!----       READ_CIF_ATOM
47453!!----       READ_CIF_CELL
47454!!----       READ_CIF_CHEMICALNAME
47455!!----       READ_CIF_CONT
47456!!----       READ_CIF_HALL
47457!!----       READ_CIF_HM
47458!!----       READ_CIF_LAMBDA
47459!!----       READ_CIF_SYMM
47460!!----       READ_CIF_TITLE
47461!!----       READ_CIF_Z
47462!!----       READ_FILE_ATOM
47463!!--++       READ_FILE_ATOMLIST             [Overloaded]
47464!!--++       READ_FILE_POINTLIST            [Overloaded]
47465!!----       READ_FILE_CELL
47466!!--++       READ_FILE_CELLc                [Overloaded]
47467!!--++       READ_FILE_CELLt                [Overloaded]
47468!!----       READ_FILE_LAMBDA
47469!!----       READ_FILE_RNGSINTL
47470!!----       READ_FILE_SPG
47471!!----       READ_FILE_TRANSF
47472!!----       READ_SHX_ATOM
47473!!----       READ_SHX_CELL
47474!!----       READ_SHX_CONT
47475!!----       READ_SHX_FVAR
47476!!----       READ_SHX_LATT
47477!!----       READ_SHX_SYMM
47478!!----       READ_SHX_TITL
47479!!----       READ_UVALS
47480!!--++       READN_SET_XTAL_CFL             [Private]
47481!!--++       READN_SET_XTAL_CFL_MOLEC       [Private]
47482!!--++       READN_SET_XTAL_CIF             [Private]
47483!!--++       READN_SET_XTAL_PCR             [Private]
47484!!--++       READN_SET_XTAL_SHX             [Private]
47485!!----       READN_SET_XTAL_STRUCTURE
47486!!--++       READN_SET_XTAL_STRUCTURE_MOLCR [Overloaded]
47487!!--++       READN_SET_XTAL_STRUCTURE_SPLIT [Overloaded]
47488!!----       WRITE_CIF_POWDER_PROFILE
47489!!----       WRITE_CIF_TEMPLATE
47490!!----       WRITE_SHX_TEMPLATE
47491!!----
47492!!
47493 Module CFML_IO_Formats
47494
47495    !---- Use modules ----!
47496    Use CFML_GlobalDeps,                only: cp,sp,pi,eps
47497    Use CFML_Math_General,              only: sind
47498    Use CFML_String_Utilities
47499    Use CFML_Crystal_Metrics,           only: Crystal_Cell_Type, Set_Crystal_Cell, Convert_U_Betas, &
47500                                              Convert_B_Betas, U_Equiv, Convert_Betas_U
47501    Use CFML_Crystallographic_Symmetry, only: Space_Group_Type, Set_SpaceGroup, Get_Multip_Pos
47502    Use CFML_Atom_TypeDef,              only: Atom_Type, Init_Atom_Type,atom_list_type,         &
47503                                              Allocate_atom_list, Deallocate_atom_list
47504    Use CFML_Molecular_Crystals,        only: Err_Molec, Err_Molec_Mess,Molecular_Crystal_Type, &
47505                                              Read_Molecule, Set_Euler_Matrix, Write_Molecule
47506    Use CFML_Geometry_Calc,             only: Point_List_Type, Get_Euler_from_Fract
47507
47508    !---- Variables ----!
47509    implicit none
47510
47511    private
47512
47513
47514    !---- List of public functions ----!
47515
47516    !---- List of public subroutines ----!
47517    public :: Init_Err_Form, Read_Atom, Read_Cell, Read_Cif_Atom, Read_Cif_Cell,                 &
47518              Read_Cif_Cont, Read_Cif_Hall, Read_Cif_Hm, Read_Cif_Lambda, Read_Cif_Symm,         &
47519              Read_Cif_Title, Read_Cif_Z, Read_File_Atom, Read_File_Spg, Read_Cif_ChemicalName,  &
47520              Read_File_Transf, Read_Shx_Atom, Read_Shx_Cell, Read_Shx_Cont, Read_Shx_Fvar,      &
47521              Read_Shx_Latt, Read_Shx_Symm, Read_Shx_Titl, Read_Uvals, Write_Cif_Powder_Profile, &
47522              Write_Cif_Template, Write_Shx_Template, Read_File_rngSINTL, Read_File_Lambda,      &
47523              Get_job_info, File_To_FileList, Get_Phases_File
47524
47525    !---- List of public overloaded procedures: subroutines ----!
47526    public :: Read_File_Cell, Readn_Set_Xtal_Structure, Write_Atoms_CFL, Write_CFL
47527
47528    !---- List of private functions ----!
47529
47530    !---- List of private subroutines ----!
47531    private:: Read_File_Cellc, Read_File_Cellt, Read_File_Atomlist,Read_File_Pointlist,               &
47532              Readn_Set_Xtal_CFL, Readn_Set_Xtal_CIF, Readn_Set_Xtal_PCR,Readn_Set_Xtal_SHX,          &
47533              Readn_Set_Xtal_CFL_Molec, Readn_Set_Xtal_Structure_Split,                               &
47534              Readn_Set_Xtal_Structure_Molcr, Get_NPhases_CIFFile,Get_NPHases_PCRFile,                &
47535              Write_CFL_Molcrys, Write_CFL_Atom_List_Type, Write_Atoms_CFL_ATM, Write_Atoms_CFL_MOLX, &
47536              Write_Atoms_CFL_MOLX_orig
47537
47538    !---- Definitions ----!
47539
47540
47541    !!----
47542    !!---- ERR_FORM
47543    !!----    logical, public :: err_form
47544    !!----
47545    !!----    Logical Variable indicating an error in CFML_IO_Formats
47546    !!----
47547    !!---- Update: February - 2005
47548    !!
47549    logical, public :: err_form
47550
47551    !!----
47552    !!---- ERR_FORM_MESS
47553    !!----    character(len=150), public :: ERR_Form_Mess
47554    !!----
47555    !!----    String containing information about the last error
47556    !!----
47557    !!---- Update: February - 2005
47558    !!
47559    character(len=150),       public  :: ERR_Form_Mess
47560
47561    !!----
47562    !!---- EPSS
47563    !!----    real(kind=cp), parameter, private :: epss=1.0e-5_cp
47564    !!----
47565    !!----    Private small real number for floating point comparisons
47566    !!----
47567    !!---- Update: February - 2011
47568    !!
47569    real(kind=cp), parameter, private :: epss=1.0e-5_cp
47570
47571    !!----
47572    !!---- TYPE :: INTERVAL_TYPE
47573    !!--..
47574    !!---- Type, public :: interval_type
47575    !!----    real(kind=cp) :: mina  !low limit
47576    !!----    real(kind=cp) :: maxb  !high limit
47577    !!---- End Type interval_type
47578    !!----
47579    !!---- Update: February - 2005
47580    !!
47581    Type, public :: interval_type
47582       real(kind=cp) :: mina  !low limit
47583       real(kind=cp) :: maxb  !high limit
47584    End Type interval_type
47585
47586    !!----
47587    !!---- TYPE :: JOB_INFO_TYPE
47588    !!--..
47589    !!---- Type, public :: Job_Info_type
47590    !!----    character(len=120)                            :: Title          ! Title
47591    !!----    integer                                       :: Num_Phases     ! Number of phases
47592    !!----    integer                                       :: Num_Patterns   ! Number of patterns
47593    !!----    integer                                       :: Num_cmd        ! Number of command lines
47594    !!----    character(len=16),  dimension(:), allocatable :: Patt_typ       ! Type of Pattern
47595    !!----    character(len=128), dimension(:), allocatable :: Phas_nam       ! Name of phases
47596    !!----    character(len=128), dimension(:), allocatable :: cmd            ! Command lines: text for actions
47597    !!----    type(interval_type),dimension(:), allocatable :: range_stl      ! Range in sinTheta/Lambda
47598    !!----    type(interval_type),dimension(:), allocatable :: range_q        ! Range in 4pi*sinTheta/Lambda
47599    !!----    type(interval_type),dimension(:), allocatable :: range_d        ! Range in d-spacing
47600    !!----    type(interval_type),dimension(:), allocatable :: range_2theta   ! Range in 2theta-spacing
47601    !!----    type(interval_type),dimension(:), allocatable :: range_Energy   ! Range in Energy
47602    !!----    type(interval_type),dimension(:), allocatable :: range_tof      ! Range in Time of Flight
47603    !!----    type(interval_type),dimension(:), allocatable :: Lambda         ! Lambda
47604    !!----    real(kind=cp)      ,dimension(:), allocatable :: ratio          ! ratio lambda2/lambda1
47605    !!----    real(kind=cp)      ,dimension(:), allocatable :: dtt1,dtt2      ! d-to-TOF coefficients
47606    !!---- End Type Job_Info_type
47607    !!----
47608    !!---- Update: February - 2005
47609    !!
47610    Type, public :: Job_Info_type
47611       character(len=120)                            :: Title
47612       integer                                       :: Num_Phases
47613       integer                                       :: Num_Patterns
47614       integer                                       :: Num_cmd
47615       character(len=16),  dimension(:), allocatable :: Patt_typ
47616       character(len=128), dimension(:), allocatable :: Phas_nam
47617       character(len=128), dimension(:), allocatable :: cmd
47618       type(interval_type),dimension(:), allocatable :: range_stl
47619       type(interval_type),dimension(:), allocatable :: range_q
47620       type(interval_type),dimension(:), allocatable :: range_d
47621       type(interval_type),dimension(:), allocatable :: range_2theta
47622       type(interval_type),dimension(:), allocatable :: range_Energy
47623       type(interval_type),dimension(:), allocatable :: range_tof
47624       type(interval_type),dimension(:), allocatable :: Lambda
47625       real(kind=cp)      ,dimension(:), allocatable :: ratio
47626       real(kind=cp)      ,dimension(:), allocatable :: dtt1,dtt2
47627    End Type Job_Info_type
47628
47629    !!----
47630    !!---- TYPE :: FILE_LIST_TYPE
47631    !!--..
47632    !!---- Type,public :: File_List_Type
47633    !!----    integer                                       :: nlines ! Number of lines in the file
47634    !!----    character(len=256), allocatable, dimension(:) :: line   ! Content of the lines
47635    !!---- End Type file_list_type
47636    !!----
47637    !!---- Updated: February - 2005, November 2012
47638    !!
47639    Type,public :: File_List_Type
47640       integer                                       :: nlines
47641       character(len=256), allocatable, dimension(:) :: line
47642    End Type File_List_Type
47643
47644
47645    !---- Interfaces - Overloaded procedures--!
47646    Interface  Read_File_Cell
47647       Module Procedure Read_File_Cellc  !Last Output Argument Vector Of Six Component With The Cell Parameters
47648       Module Procedure Read_File_Cellt  !Last output argument object of type Crystal_cell_type
47649    End interface
47650
47651    Interface Read_File_Atom
47652       Module Procedure Read_File_Atomlist   !Last Output Argument of type Atom_list_type
47653       Module Procedure Read_File_Pointlist  !Last output argument of type Point_list_type
47654    End Interface
47655
47656    Interface Readn_Set_Xtal_Structure
47657       Module Procedure Readn_Set_Xtal_Structure_Molcr ! For Molecular Crystal Type
47658       Module Procedure Readn_Set_Xtal_Structure_Split ! For Cell, Spg, A types
47659    End Interface
47660
47661    Interface Write_CFL
47662       Module Procedure Write_CFL_Molcrys        ! For Molecular Crystal Type
47663       Module Procedure Write_CFL_Atom_List_Type ! For Cell, Spg, A Types
47664    End Interface
47665
47666    Interface Write_Atoms_CFL
47667       Module Procedure Write_Atoms_CFL_MOLX ! For Molecular Crystal Type
47668       Module Procedure Write_Atoms_CFL_ATM  ! For Cell, Spg, A Types
47669    End Interface
47670
47671 Contains
47672
47673    !---- Functions ----!
47674
47675    !---- Subroutines ----!
47676
47677    !!----
47678    !!---- Subroutine File_To_FileList(File_dat,File_list)
47679    !!----   character(len=*),     intent( in) :: file_dat  !Input data file
47680    !!----   type(file_list_type), intent(out) :: file_list !File list structure
47681    !!----
47682    !!----    Charge an external file to an object of File_List_Type.
47683    !!----
47684    !!---- Update: August - 2008
47685    !!
47686    Subroutine File_To_FileList(File_dat,File_list)
47687       !---- Arguments ----!
47688       character(len=*),      intent( in) :: file_dat
47689       type(file_list_type),  intent(out) :: file_list
47690
47691       !---- Local Variables ----!
47692       integer                           :: nlines
47693
47694       !---- Number of Lines in the input file ----!
47695       call Number_Lines(trim(File_dat), nlines)
47696
47697       if (nlines==0) then
47698          err_form=.true.
47699          ERR_Form_Mess="The file "//trim(File_dat)//" contains nothing"
47700          return
47701       else
47702          file_list%nlines=nlines
47703          if (allocated(file_list%line)) deallocate(file_list%line)
47704          allocate(file_list%line(nlines))
47705          call reading_Lines(trim(File_dat),nlines,file_list%line)
47706       end if
47707
47708       return
47709    End Subroutine File_To_FileList
47710
47711    !!----
47712    !!---- Subroutine Get_Job_Info(file_dat,i_ini,i_end,Job_info)
47713    !!----   character(len=*), dimension(:), intent( in) :: file_dat     !Lines of text (content of a file)
47714    !!----   integer,                        intent( in) :: i_ini,i_end  !Lines to explore
47715    !!----   type(job_info_type),            intent(out) :: Job_info     !Object to be constructed here
47716    !!----
47717    !!----
47718    !!----    Constructor of the object Job_info. The arrary of strings file_dat
47719    !!----    have to be provided as input. It contains lines corresponding to the
47720    !!----    input control file. The analysis of the command lines is not given here.
47721    !!----
47722    !!---- Update: February - 2005
47723    !!
47724    Subroutine Get_Job_Info(file_dat,i_ini,i_end,Job_info)
47725       !---- Arguments ----!
47726       character(len=*), dimension(:), intent( in) :: file_dat
47727       integer,                        intent( in) :: i_ini,i_end
47728       type(job_info_type),            intent(out) :: Job_info
47729
47730       !---- Local Variables ----!
47731       integer                           :: i,nphas, ncmd,n_pat,ier, j
47732       integer, dimension(i_end-i_ini+1) :: ip,ic,ipt
47733       real(kind=sp)                     :: a1,a2,a3,a4,a5
47734       character(len=120)                :: line, fmtfields, fmtformat
47735
47736       !--- Initialize FindFMT
47737       call Init_FindFMT(i_ini)
47738       nphas=0
47739       ncmd=0
47740       n_pat=0
47741       ip=i_end
47742       ic=0
47743       ipt=0
47744       Job_info%title=" General Job: CrysFML"
47745       Job_info%Num_Patterns=1
47746
47747       do i=i_ini,i_end
47748          line=u_case(adjustl(file_dat(i)))
47749          if (line(1:5) == "TITLE") Job_info%title=line(7:)
47750          if (line(1:5) == "NPATT") then
47751             read(unit=line(7:), fmt=*,iostat=ier) Job_info%Num_Patterns
47752             if (ier /= 0) Job_info%Num_Patterns=1
47753          end if
47754          if (line(1:6) == "PHASE_") then
47755             nphas=nphas+1
47756             ip(nphas)=i
47757          end if
47758          if (line(1:4) == "CMDL") then
47759             ncmd=ncmd+1
47760             ic(ncmd)=i
47761          end if
47762          if (line(1:5) == "PATT_") then
47763             n_pat=n_pat+1
47764             ipt(n_pat)=i
47765          end if
47766       end do
47767
47768       if (nphas == 0) then
47769          nphas=1
47770          ip(nphas)=0
47771       end if
47772       if (n_pat == 0) then
47773          n_pat=1
47774          ipt(n_pat) = 0
47775       end if
47776
47777       if (Job_info%Num_Patterns /= n_pat) Job_info%Num_Patterns = n_pat
47778       Job_info%Num_Phases=nphas
47779       Job_info%Num_Cmd=ncmd
47780
47781       if (allocated(Job_Info%Patt_typ)) deallocate(Job_Info%Patt_typ)
47782       allocate(Job_Info%Patt_typ(n_pat))
47783
47784       if (allocated(Job_Info%Phas_nam)) deallocate(Job_Info%Phas_nam)
47785       allocate(Job_Info%Phas_nam(nphas))
47786
47787       if (allocated(Job_Info%range_stl)) deallocate(Job_Info%range_stl)
47788       allocate(Job_Info%range_stl(n_pat))
47789
47790       if (allocated(Job_Info%range_q)) deallocate(Job_Info%range_q)
47791       allocate(Job_Info%range_q(n_pat))
47792
47793       if (allocated(Job_Info%range_d)) deallocate(Job_Info%range_d)
47794       allocate(Job_Info%range_d(n_pat))
47795
47796       if (allocated(Job_Info%range_2theta)) deallocate(Job_Info%range_2theta)
47797       allocate(Job_Info%range_2theta(n_pat))
47798
47799       if (allocated(Job_Info%range_energy)) deallocate(Job_Info%range_energy)
47800       allocate(Job_Info%range_energy(n_pat))
47801
47802       if (allocated(Job_Info%range_tof)) deallocate(Job_Info%range_tof)
47803       allocate(Job_Info%range_tof(n_pat))
47804
47805       if (allocated(Job_Info%lambda)) deallocate(Job_Info%lambda)
47806       allocate(Job_Info%lambda(n_pat))
47807
47808       if (allocated(Job_Info%ratio)) deallocate(Job_Info%ratio)
47809       allocate(Job_Info%ratio(n_pat))
47810
47811       if (allocated(Job_Info%dtt1)) deallocate(Job_Info%dtt1)
47812       allocate(Job_Info%dtt1(n_pat))
47813
47814       if (allocated(Job_Info%dtt2)) deallocate(Job_Info%dtt2)
47815       allocate(Job_Info%dtt2(n_pat))
47816
47817       !---- Initialize all variables
47818       Job_Info%Patt_typ    =" "
47819       Job_Info%Phas_nam    =" "
47820       Job_Info%range_stl%mina=0.0
47821       Job_Info%range_stl%maxb=0.0
47822       Job_Info%range_q%mina=0.0
47823       Job_Info%range_q%maxb=0.0
47824       Job_Info%range_d%mina=0.0
47825       Job_Info%range_d%maxb=0.0
47826       Job_Info%range_2theta%mina=0.0
47827       Job_Info%range_2theta%maxb=0.0
47828       Job_Info%range_Energy%mina=0.0
47829       Job_Info%range_Energy%maxb=0.0
47830       Job_Info%range_tof%mina=0.0
47831       Job_Info%range_tof%maxb=0.0
47832       Job_Info%Lambda%mina=0.0
47833       Job_Info%Lambda%maxb=0.0
47834       Job_Info%ratio = 0.0
47835       Job_Info%dtt1 = 0.0
47836       Job_Info%dtt2 = 0.0
47837       if (ncmd > 0) then
47838          if (allocated(Job_Info%cmd)) deallocate(Job_Info%cmd)
47839          allocate(Job_Info%cmd(ncmd))
47840          Job_Info%cmd=" "
47841       end if
47842
47843       !---- Fill the different fields of Job_Info
47844       !---- Start with patterns
47845       fmtfields = "9fffff"
47846
47847       !---- First asks if there is a PATT_ card, if not a standard is taken
47848       if (ipt(1) /= 0) then
47849          do n_pat=1, Job_info%Num_Patterns
47850             i=ipt(n_pat)
47851             line=u_case(adjustl(file_dat(i)))
47852             line=line(8:)
47853             call findfmt(0,line,fmtfields,fmtformat)
47854             read(unit=line,fmt=fmtformat) Job_Info%Patt_typ(n_pat), a1,a2,a3,a4,a5
47855             if (ierr_fmt /= 0) return
47856             line=u_case(Job_Info%Patt_typ(n_pat))
47857
47858             select case(line(1:9))
47859                case("XRAY_2THE","NEUT_2THE","XRAY_SXTA","NEUT_SXTA")
47860                   if ( a1 <= 0.000001) a1=1.5405
47861                   if ( a2 <= 0.000001) then
47862                      a2=a1
47863                      a3=0.0
47864                   end if
47865                   if (a5 <= a4) a5=120.0
47866                   Job_Info%Lambda(n_pat)%mina=a1
47867                   Job_Info%Lambda(n_pat)%maxb=a2
47868                   Job_Info%ratio(n_pat)=a3
47869                   Job_Info%range_2theta(n_pat)%mina=a4
47870                   Job_Info%range_2theta(n_pat)%maxb=a5
47871                   a4=sind(0.5*a4)/a1
47872                   a5=sind(0.5*a5)/a2
47873                   Job_Info%range_stl(n_pat)%mina=a4
47874                   Job_Info%range_stl(n_pat)%maxb=a5
47875                   Job_Info%range_q(n_pat)%mina=a4*4.0*pi
47876                   Job_Info%range_q(n_pat)%maxb=a5*4.0*pi
47877                   Job_Info%range_d(n_pat)%mina=0.5/a5
47878                   Job_Info%range_d(n_pat)%maxb=0.5/a4
47879
47880                case("NEUT_TOF ")
47881                   if (a1 <= 0.000001) a1=1000.0
47882                   if (a4 <= a3) a4=2.0*abs(a3)
47883                   Job_Info%dtt1(n_pat)=a1
47884                   Job_Info%dtt2(n_pat)=a2
47885                   Job_Info%range_tof(n_pat)%mina=a3
47886                   Job_Info%range_tof(n_pat)%maxb=a4
47887                   Job_Info%range_d(n_pat)%mina=0.5*(-1.0+sqrt(1.0+4.0*a2*a3/a1/a1))
47888                   Job_Info%range_d(n_pat)%maxb=0.5*(-1.0+sqrt(1.0+4.0*a2*a4/a1/a1))
47889                   Job_Info%range_stl(n_pat)%mina=0.5/Job_Info%range_d(n_pat)%maxb
47890                   Job_Info%range_stl(n_pat)%maxb=0.5/Job_Info%range_d(n_pat)%mina
47891                   Job_Info%range_q(n_pat)%mina=Job_Info%range_stl(n_pat)%mina*4.0*pi
47892                   Job_Info%range_q(n_pat)%maxb=Job_Info%range_stl(n_pat)%maxb*4.0*pi
47893
47894                case("XRAY_ENER")
47895                   if (a1 <= 0.000001) a1=12.4 !(=hc(keV.Angstr.)
47896                   Job_Info%dtt1(n_pat)=a1
47897                   Job_Info%dtt2(n_pat)=0.0
47898                   Job_Info%range_energy(n_pat)%mina=a3
47899                   Job_Info%range_energy(n_pat)%maxb=a4
47900                   if (a3 <= 0.00001) a3=0.01
47901                   if (a4 <= 0.00001) a4=2.00
47902                   Job_Info%range_d(n_pat)%mina=a1/a4
47903                   Job_Info%range_d(n_pat)%maxb=a1/a3
47904                   Job_Info%range_stl(n_pat)%mina=0.5/Job_Info%range_d(n_pat)%maxb
47905                   Job_Info%range_stl(n_pat)%maxb=0.5/Job_Info%range_d(n_pat)%mina
47906                   Job_Info%range_q(n_pat)%mina=Job_Info%range_stl(n_pat)%mina*4.0*pi
47907                   Job_Info%range_q(n_pat)%maxb=Job_Info%range_stl(n_pat)%maxb*4.0*pi
47908
47909             end select
47910          end do
47911
47912       else
47913          n_pat=1
47914          a1=1.5405
47915          a2=a1
47916          a3=0.0
47917          a4=0.0
47918          a5=120.0
47919          Job_Info%Patt_typ(n_pat)="XRAY_2THE"
47920          Job_Info%Lambda(n_pat)%mina=a1
47921          Job_Info%Lambda(n_pat)%maxb=a2
47922          Job_Info%ratio(n_pat)=a3
47923          Job_Info%range_2theta(n_pat)%mina=a4
47924          Job_Info%range_2theta(n_pat)%maxb=a5
47925          a4=sind(0.5*a4)/a1
47926          a5=sind(0.5*a5)/a2
47927          Job_Info%range_stl(n_pat)%mina=a4
47928          Job_Info%range_stl(n_pat)%maxb=a5
47929          Job_Info%range_q(n_pat)%mina=a4*4.0*pi
47930          Job_Info%range_q(n_pat)%maxb=a5*4.0*pi
47931          Job_Info%range_d(n_pat)%mina=0.5/a5
47932          Job_Info%range_d(n_pat)%maxb=0.5/a4
47933       end if
47934
47935       !---- Phase names
47936       if (ip(1) /= 0) then
47937          do i=1,nphas
47938             j=ip(i)
47939             line=adjustl(file_dat(j))
47940             Job_Info%Phas_nam(i)=line(8:)
47941          end do
47942       else
47943          Job_Info%Phas_nam(1)= Job_info%title
47944       end if
47945
47946       !---- Command Lines, stored but not analysed here
47947       do i=1,ncmd
47948          j=ic(i)
47949          line=adjustl(file_dat(j))
47950          Job_Info%cmd(i)=line(8:)
47951       end do
47952
47953       return
47954    End Subroutine Get_Job_Info
47955
47956    !!----
47957    !!---- Subroutine Init_Err_Form()
47958    !!----
47959    !!----    Initialize Errors Variable for this module
47960    !!----
47961    !!---- Update: February - 2005
47962    !!
47963    Subroutine Init_Err_Form()
47964
47965       err_form=.false.
47966       ERR_Form_Mess=" "
47967
47968       return
47969    End Subroutine Init_Err_Form
47970
47971    !!----
47972    !!---- Subroutine Read_Atom(Line,Atomo)
47973    !!----    character(len=*), intent(in out ) :: line    !  In -> Input String with ATOM directive
47974    !!----    Type (Atom_Type), intent(out)     :: Atomo   ! Out -> Parameters on variable Atomo
47975    !!----
47976    !!----    Subroutine to read the atom parameters from a given "line"
47977    !!----    it construct the object Atomo of type Atom.
47978    !!----    Control of error is present
47979    !!----
47980    !!---- Update: February - 2005
47981    !!
47982    Subroutine Read_Atom(line,Atomo)
47983       !---- Arguments ----!
47984       character(len=*), intent(in out ) :: line
47985       Type (Atom_Type), intent(out)     :: Atomo
47986
47987       !---- Local variables -----!
47988       integer                           :: iv, nlong1,n,ier,q
47989       real(kind=cp), dimension (10)     :: vet1
47990       real(kind=cp), dimension (10)     :: vet2
47991       character(len=4)                  :: dire
47992       character(len=5)                  :: label
47993       character(len=132), dimension(1)  :: filevar
47994       character(len=*), parameter       :: digpm="0123456789+-"
47995
47996       !---- Init ----!
47997       call init_err_form()
47998       call init_atom_type(Atomo)
47999       q=0
48000       iv=index(line,"#")
48001       if(iv /= 0) atomo%AtmInfo=line(iv+1:)
48002
48003       call cutst(line,nlong1,dire)
48004       if (u_case(dire) /= "ATOM") then
48005          err_form=.true.
48006          ERR_Form_Mess=" Error reading the ATOM keyword"
48007          return
48008       end if
48009
48010       !---- Atom Label ----!
48011       call cutst(line,nlong1,label)
48012       atomo%lab=label(1:5)
48013
48014       !---- Atom Type (Chemical symbol & Scattering Factor) ----!
48015       call cutst(line,nlong1,label)
48016       n=index(digpm,label(2:2))
48017       if (n /=0) then
48018         atomo%chemsymb=U_case(label(1:1))
48019       else
48020         atomo%chemsymb=U_case(label(1:1))//L_case(label(2:2))
48021       end if
48022       atomo%SfacSymb=label(1:4)
48023
48024       !---- Parameters ----!
48025       filevar(1)="atm "//trim(line)
48026
48027       n=1
48028       call Read_Key_ValueSTD(filevar,n,n,"atm",vet1,vet2,iv)
48029      ! call getnum(line,vet,ivet,iv)
48030       if (iv <= 0) then
48031          err_form=.true.
48032          ERR_Form_Mess= "Error reading parameters of atom:"//atomo%lab
48033          return
48034       end if
48035
48036       !---- Coordinates  ----!
48037       if (iv < 3) then
48038          err_form=.true.
48039          ERR_Form_Mess= "Error reading Coordinates of atom:"//atomo%lab
48040          return
48041       end if
48042
48043       atomo%x(:)=vet1(1:3)
48044       atomo%x_std(:)=vet2(1:3)
48045
48046       !---- Biso ----!
48047       if (iv > 3) then
48048         atomo%biso=vet1(4)
48049         atomo%biso_std=vet2(4)
48050       end if
48051
48052       !---- Occ ----!
48053       if (iv > 4) then
48054          atomo%occ=vet1(5)
48055          atomo%occ_std=vet2(5)
48056       end if
48057
48058       !---- Moment ----!
48059       if (iv > 5) atomo%moment=vet1(6)
48060
48061       !---- Charge ----!
48062       if (iv > 6) atomo%charge=vet1(7)
48063
48064       !Attempt to get the oxidation state from "Label"
48065       if(abs(atomo%charge) < eps) then
48066         iv=index(label,"+")
48067         Select Case(iv)
48068           Case(0) !No + sign
48069             n=index(label,"-")
48070             Select Case(n)
48071               Case(2) !Element with a single character symbol F-1
48072                  read(unit=label(3:),fmt="(i1)",iostat=ier)  q
48073                  if (ier /= 0) q=0
48074               Case(3) !Element in the form: F1- or Br-1
48075                  read(unit=label(2:2),fmt="(i1)",iostat=ier)  q
48076                  if (ier /= 0) then
48077                        read(unit=label(4:4),fmt="(i1)",iostat=ier)  q
48078                        if (ier /= 0) q=0
48079                  end if
48080               Case(4) !Element in the form: Br1-
48081                  read(unit=label(3:3),fmt="(i1)",iostat=ier)  q
48082                  if (ier /= 0) q=0
48083             End Select
48084             q=-q   !anions
48085           Case(2) !Element with a single character symbol C+4
48086                  read(unit=label(3:),fmt="(i1)",iostat=ier)  q
48087                  if (ier /= 0) q=0
48088           Case(3) !Element in the form: C4+ or Fe+3
48089                  read(unit=label(2:2),fmt="(i1)",iostat=ier)  q
48090                  if (ier /= 0) then
48091                        read(unit=label(4:4),fmt="(i1)",iostat=ier)  q
48092                        if (ier /= 0) q=0
48093                  end if
48094           Case(4) !Element in the form: Fe3+
48095                  read(unit=label(3:3),fmt="(i1)",iostat=ier)  q
48096                  if (ier /= 0) q=0
48097         End Select
48098         atomo%charge=real(q)
48099       end if
48100       return
48101    End Subroutine Read_Atom
48102
48103    !!----
48104    !!---- Subroutine Read_Cell(Line,Celda)
48105    !!----    character(len=*),          intent(in out ) :: line   !  In -> Input String with CELL Directive
48106    !!----    real(kind=cp),dimension(6),intent(out)     :: Celda  !  In -> Parameters on Celda Variable
48107    !!----
48108    !!----    Subroutine to read the cell parameters from a given "line"
48109    !!----    it construct the object Celda of type Crystal_Cell.
48110    !!----    Assumes the string "line" has been read from a file and
48111    !!----    starts with the word "cell", that is removed before reading
48112    !!----    the values of the parameters.
48113    !!----    Control of error is present
48114    !!----
48115    !!---- Update: February - 2005
48116    !!
48117    Subroutine Read_Cell(line,Celda)
48118       !---- Arguments ----!
48119       character(len=*),          intent(in out ) :: line
48120       real(kind=cp),dimension(6),intent(out)     :: Celda
48121
48122       !---- Local variables -----!
48123       integer, dimension (6)               :: ivet
48124       real(kind=cp), dimension (6)         :: vet
48125       integer                              :: nlong1,iv
48126       character(len=4)                     :: dire
48127
48128       call init_err_form()
48129
48130       call cutst(line,nlong1,dire)
48131       if (u_case(dire) /= "CELL") then
48132          err_form=.true.
48133          ERR_Form_Mess=" Error reading the CELL keyword"
48134          return
48135       end if
48136
48137       call getnum(line,vet,ivet,iv)
48138       if (iv /= 6 ) then
48139          err_form=.true.
48140          ERR_Form_Mess=" Error reading the Cell Parameters"
48141          return
48142       else
48143          celda=vet
48144       end if
48145
48146       return
48147    End Subroutine Read_Cell
48148
48149    !!----
48150    !!---- Subroutine Read_Cif_Atom(Filevar,Nline_Ini,Nline_End,N_Atom,Atm_List)
48151    !!----    character(len=*),dimension(:), intent(in)     :: filevar    !  In -> Input strings information
48152    !!----    integer,                       intent(in out) :: nline_ini  !  In -> Line to beginning search
48153    !!----                                                                   Out -> Current line on Filevar
48154    !!----    integer,                       intent(in)     :: nline_end  !  In -> Line to the End search
48155    !!----    integer,                       intent(out)    :: n_atom     ! Out -> Actual number of atom
48156    !!----    type (atom_list_type),        intent(out)    :: Atm_List   ! Out -> Atom list
48157    !!----
48158    !!----    Obtaining Atoms parameters from Cif file. A control error is present.
48159    !!----
48160    !!---- Update: February - 2005
48161    !!
48162    Subroutine Read_Cif_Atom(filevar,nline_ini,nline_end,n_atom,Atm_List)
48163       !---- Arguments ----!
48164       character(len=*), dimension(:),   intent(in)      :: filevar
48165       integer,                          intent(in out)  :: nline_ini
48166       integer,                          intent(in)      :: nline_end
48167       integer,                          intent(out)     :: n_atom
48168       type (atom_list_type),            intent(out)     :: Atm_List
48169
48170       !---- Local Variables ----!
48171       character(len=len(filevar(1)))               :: string,cp_str
48172       character(len=20),dimension(15)              :: label
48173
48174       integer                         :: i, j, nc, nct, nline, iv
48175       !integer, dimension(1)           :: ivet
48176       integer, dimension( 8)          :: lugar   !   1 -> label
48177                                                  !   2 -> Symbol
48178                                                  ! 3-5 -> coordinates
48179                                                  !   6 -> occupancy
48180                                                  !   7 -> Uequi
48181                                                  !   8 -> Biso
48182       real(kind=cp), dimension(1)     :: vet1,vet2
48183       type(atom_list_type)            :: Atm
48184
48185       !---- Estimacion Inicial ----!
48186       lugar=0
48187       call allocate_atom_list(nline_end-nline_ini+1,Atm)
48188
48189       n_atom=0
48190       call Read_Key_StrVal(filevar,nline_ini,nline_end,"_atom_site_",string)
48191
48192       j=0
48193       do i=nline_ini,nline_end
48194          string=adjustl(filevar(i))
48195          if ("_atom_site_label" == string(1:16)) then
48196             j=j+1
48197             lugar(1)=j
48198             cycle
48199          end if
48200          if ("_atom_site_type_symbol" == string(1:22)) then
48201             j=j+1
48202             lugar(2)=j
48203             cycle
48204          end if
48205          if ("_atom_site_fract_x" == string(1:18)) then
48206             j=j+1
48207             lugar(3)=j
48208             cycle
48209          end if
48210          if ("_atom_site_fract_y" == string(1:18)) then
48211             j=j+1
48212             lugar(4)=j
48213             cycle
48214          end if
48215          if ("_atom_site_fract_z" == string(1:18)) then
48216             j=j+1
48217             lugar(5)=j
48218             cycle
48219          end if
48220          if ("_atom_site_occupancy" == string(1:20)) then
48221             j=j+1
48222             lugar(6)=j
48223             cycle
48224          end if
48225          if ("_atom_site_U_iso_or_equiv" == string(1:25)) then
48226             j=j+1
48227             lugar(7)=j
48228             cycle
48229          end if
48230          if ("_atom_site_B_iso_or_equiv" == string(1:25)) then
48231             j=j+1
48232             lugar(8)=j
48233             cycle
48234          end if
48235          if ("_atom_site_" == string(1:11)) then
48236             j=j+1
48237             cycle
48238          end if
48239
48240          if ("_oxford_atom_site_" == string(1:18)) then
48241             j=j+1
48242             cycle
48243          end if
48244
48245          nline=i
48246          exit
48247       end do
48248
48249       if (any(lugar(3:5) == 0)) then
48250          err_form=.true.
48251          ERR_Form_Mess=" Error reading atoms"
48252          return
48253       end if
48254       nct=count(lugar > 0)
48255
48256       nline_ini=nline
48257       string=" "
48258       do i=nline_ini,nline_end
48259          string=adjustl(trim(string)//" "//filevar(i))
48260          if (string(1:1) == "#" .or. string(1:1) == "?") cycle
48261          if (len_trim(string) == 0) exit
48262          if (string(1:1) == "_" .or. string(1:5) == "loop_") exit
48263          cp_str=string
48264          call getword(cp_str,label,nc)
48265          if (nc < nct) cycle
48266
48267          n_atom=n_atom+1
48268
48269          ! _atom_site_label
48270          atm%atom(n_atom)%lab=label(lugar(1))
48271
48272          ! _atom_site_type_symbol
48273          if (lugar(2) /= 0) then
48274             atm%atom(n_atom)%SfacSymb=label(lugar(2))(1:4)
48275             if(index("1234567890+-",label(lugar(2))(2:2)) /= 0 ) then
48276                atm%atom(n_atom)%chemSymb=U_case(label(lugar(2))(1:1))
48277             else
48278                atm%atom(n_atom)%chemSymb=U_case(label(lugar(2))(1:1))//L_case(label(lugar(2))(2:2))
48279             end if
48280           !  call getnum(label(lugar(2))(2:2),vet1,ivet,iv)
48281           !  if (iv <= 0) then
48282           !     atm%atom(n_atom)%chemSymb=label(lugar(2))(1:2)
48283           !  else
48284           !     atm%atom(n_atom)%chemSymb=label(lugar(2))(1:1)
48285           !  end if
48286          else
48287             if(index("1234567890+-",label(lugar(1))(2:2)) /= 0 ) then
48288                atm%atom(n_atom)%chemSymb=U_case(label(lugar(1))(1:1))
48289             else
48290                atm%atom(n_atom)%chemSymb=U_case(label(lugar(1))(1:1))//L_case(label(lugar(1))(2:2))
48291             end if
48292             atm%atom(n_atom)%SfacSymb=atm%atom(n_atom)%chemSymb
48293
48294           !   call getnum(label(lugar(1))(2:2),vet1,ivet,iv)
48295           !  if (iv <= 0) then
48296           !     atm%atom(n_atom)%chemSymb=label(lugar(1))(1:2)
48297           !  else
48298           !     atm%atom(n_atom)%chemSymb=label(lugar(1))(1:1)
48299           !  end if
48300          end if
48301
48302          call getnum_std(label(lugar(3)),vet1,vet2,iv)    ! _atom_site_fract_x
48303          atm%atom(n_atom)%x(1)=vet1(1)
48304          atm%atom(n_atom)%x_std(1)=vet2(1)
48305          call getnum_std(label(lugar(4)),vet1,vet2,iv)    ! _atom_site_fract_y
48306          atm%atom(n_atom)%x(2)=vet1(1)
48307          atm%atom(n_atom)%x_std(2)=vet2(1)
48308          call getnum_std(label(lugar(5)),vet1,vet2,iv)    ! _atom_site_fract_z
48309          atm%atom(n_atom)%x(3)=vet1(1)
48310          atm%atom(n_atom)%x_std(3)=vet2(1)
48311
48312          ! _atom_site_occupancy
48313          if (lugar(6) /= 0) then
48314             call getnum_std(label(lugar(6)),vet1,vet2,iv)
48315          else
48316             vet1=1.0
48317          end if
48318          atm%atom(n_atom)%occ=vet1(1)
48319          atm%atom(n_atom)%occ_std=vet2(1)
48320
48321          if (lugar(7) /= 0) then
48322             call getnum_std(label(lugar(7)),vet1,vet2,iv)    ! _atom_site_U_iso_or_equiv
48323             atm%atom(n_atom)%ueq=vet1(1)
48324             atm%atom(n_atom)%Biso=vet1(1)*78.95683521     !If anisotropic they
48325             atm%atom(n_atom)%Biso_std=vet2(1)*78.95683521 !will be put to zero
48326          else if (lugar(8) /= 0) then
48327             call getnum_std(label(lugar(8)),vet1,vet2,iv)    ! _atom_site_B_iso_or_equiv
48328             atm%atom(n_atom)%ueq=vet1(1)/78.95683521
48329             atm%atom(n_atom)%Biso=vet1(1)     !If anisotropic they
48330             atm%atom(n_atom)%Biso_std=vet2(1) !will be put to zero
48331          else
48332             atm%atom(n_atom)%ueq=0.0
48333             atm%atom(n_atom)%Biso=0.0     !If anisotropic they
48334             atm%atom(n_atom)%Biso_std=0.0 !will be put to zero
48335          end if
48336
48337          atm%atom(n_atom)%utype="u_ij"
48338          string=" "
48339
48340       end do
48341       nline=i
48342
48343       !---- Anisotropic parameters ----!
48344       nline_ini=nline
48345       lugar=0
48346       call Read_Key_StrVal(filevar,nline_ini,nline_end,"_atom_site_aniso_",string)
48347
48348       j=0
48349       do i=nline_ini,nline_end
48350          string=adjustl(filevar(i))
48351          if ("_atom_site_aniso_label" == string(1:22)) then
48352             j=j+1
48353             lugar(1)=j
48354             cycle
48355          end if
48356          if ("_atom_site_aniso_U_11" == string(1:21)) then
48357             j=j+1
48358             lugar(2)=j
48359             cycle
48360          end if
48361          if ("_atom_site_aniso_U_22" == string(1:21)) then
48362             j=j+1
48363             lugar(3)=j
48364             cycle
48365          end if
48366          if ("_atom_site_aniso_U_33" == string(1:21)) then
48367             j=j+1
48368             lugar(4)=j
48369             cycle
48370          end if
48371          if ("_atom_site_aniso_U_12" == string(1:21)) then
48372             j=j+1
48373             lugar(5)=j
48374             cycle
48375          end if
48376          if ("_atom_site_aniso_U_13" == string(1:21)) then
48377             j=j+1
48378             lugar(6)=j
48379             cycle
48380          end if
48381          if ("_atom_site_aniso_U_23" == string(1:21)) then
48382             j=j+1
48383             lugar(7)=j
48384             cycle
48385          end if
48386
48387          if ("_atom_site_aniso" == string(1:16) ) then
48388             j=j+1
48389             cycle
48390          end if
48391
48392          nline=i
48393          exit
48394       end do
48395
48396       if (all(lugar > 0)) then
48397          nct=count(lugar > 0)
48398          nline_ini=nline
48399          string=" "
48400          do i=nline_ini,nline_end
48401             string=adjustl(trim(string)//" "//filevar(i))
48402             if (string(1:1) == "#" .or. string(1:1) =="?") cycle
48403             if (len_trim(string) == 0) exit
48404
48405             cp_str=string
48406             call getword(cp_str,label,nc)
48407             if (nc < nct) cycle
48408
48409             do j=1,n_atom
48410                if (atm%atom(j)%lab(1:4) /= label(lugar(1))(1:4)) cycle
48411
48412                call getnum_std(label(lugar(2)),vet1,vet2,iv)    ! _atom_site_aniso_U_11
48413                atm%atom(j)%u(1)=vet1(1)
48414                atm%atom(j)%u_std(1)=vet2(1)
48415                call getnum_std(label(lugar(3)),vet1,vet2,iv)    ! _atom_site_aniso_U_22
48416                atm%atom(j)%u(2)=vet1(1)
48417                atm%atom(j)%u_std(2)=vet2(1)
48418                call getnum_std(label(lugar(4)),vet1,vet2,iv)    ! _atom_site_aniso_U_33
48419                atm%atom(j)%u(3)=vet1(1)
48420                atm%atom(j)%u_std(3)=vet2(1)
48421                call getnum_std(label(lugar(5)),vet1,vet2,iv)    ! _atom_site_aniso_U_12
48422                atm%atom(j)%u(4)=vet1(1)
48423                atm%atom(j)%u_std(4)=vet2(1)
48424                call getnum_std(label(lugar(6)),vet1,vet2,iv)    ! _atom_site_aniso_U_13
48425                atm%atom(j)%u(5)=vet1(1)
48426                atm%atom(j)%u_std(5)=vet2(1)
48427                call getnum_std(label(lugar(7)),vet1,vet2,iv)    ! _atom_site_aniso_U_23
48428                atm%atom(j)%u(6)=vet1(1)
48429                atm%atom(j)%u_std(6)=vet2(1)
48430
48431                atm%atom(j)%thtype="aniso"
48432                atm%atom(j)%Biso=0.0
48433                atm%atom(j)%Biso_std=0.0
48434                exit
48435             end do
48436             nline=i
48437             string=" "
48438          end do
48439
48440       end if
48441       nline_ini=nline
48442
48443       !---- Adjusting ... ----!
48444       if (n_atom > 0) then
48445          call allocate_atom_list(n_atom,Atm_list)
48446          atm_list%natoms=n_atom
48447          do i=1,n_atom
48448             atm_list%atom(i)=atm%atom(i)
48449          end do
48450       end if
48451       call Deallocate_atom_list(atm)
48452
48453       return
48454    End Subroutine Read_Cif_Atom
48455
48456    !!----
48457    !!---- Subroutine Read_Cif_Cell(Filevar,Nline_Ini,Nline_End,Celda,Stdcelda)
48458    !!----    character(len=*), dimension(:), intent(in)     :: filevar      !  In -> String vector input
48459    !!----    integer,                        intent(in out) :: nline_ini    !  In -> Line to start the search
48460    !!----                                                                      Out -> Current line on Filevar
48461    !!----    integer,                        intent(in)     :: nline_end    !  In -> Line to finish the search
48462    !!----    real(kind=cp),dimension(6),     intent (out)   :: Celda        ! Out -> Cell variable
48463    !!----    real(kind=cp),dimension(6),     intent (out)   :: StdCelda     ! Out -> Cell variable
48464    !!----
48465    !!----    Read Cell Parameters from Cif file
48466    !!----
48467    !!---- Update: February - 2005
48468    !!
48469    Subroutine Read_Cif_Cell(Filevar,Nline_Ini,Nline_End,Celda,StdCelda)
48470       !---- Arguments ----!
48471       character(len=*),  dimension(:),     intent(in)     :: filevar
48472       integer,                             intent(in out) :: nline_ini
48473       integer,                             intent(in)     :: nline_end
48474       real(kind=cp),dimension(6),          intent(out)    :: Celda
48475       real(kind=cp),dimension(6),optional, intent(out)    :: StdCelda
48476
48477       !---- Local Variables ----!
48478       integer                     :: iv,initl
48479       real(kind=cp), dimension(1) :: vet1,vet2
48480       real(kind=cp), dimension(6) :: a
48481
48482       !---- Valores iniciales ----!
48483       celda=(/1.0,1.0,1.0,90.0,90.0,90.0/)
48484       a=0.0
48485       if (present(stdcelda)) stdcelda=0.0
48486
48487       !---- Celda ----!
48488       initl=nline_ini  !Preserve initial line => some CIF files have random order for cell parameters
48489       call read_key_valueSTD(filevar,nline_ini,nline_end,"_cell_length_a",vet1,vet2,iv)
48490       if (iv == 1) then
48491          Celda(1)   =vet1(1)
48492          a(1)=vet2(1)
48493       end if
48494
48495       nline_ini=initl
48496       call read_key_valueSTD(filevar,nline_ini,nline_end,"_cell_length_b",vet1,vet2,iv)
48497       if (iv == 1) then
48498          Celda(2)   =vet1(1)
48499          a(2)=vet2(1)
48500       end if
48501
48502       nline_ini=initl
48503       call read_key_valueSTD(filevar,nline_ini,nline_end,"_cell_length_c",vet1,vet2,iv)
48504       if (iv == 1) then
48505          Celda(3)   =vet1(1)
48506         a(3)=vet2(1)
48507       end if
48508
48509       nline_ini=initl
48510       call read_key_valueSTD(filevar,nline_ini,nline_end,"_cell_angle_alpha",vet1,vet2,iv)
48511       if (iv == 1) then
48512          Celda(4)   =vet1(1)
48513          a(4)=vet2(1)
48514       end if
48515
48516       nline_ini=initl
48517       call read_key_valueSTD(filevar,nline_ini,nline_end,"_cell_angle_beta",vet1,vet2,iv)
48518       if (iv == 1) then
48519          Celda(5)   =vet1(1)
48520          a(5)=vet2(1)
48521       end if
48522
48523       nline_ini=initl
48524       call read_key_valueSTD(filevar,nline_ini,nline_end,"_cell_angle_gamma",vet1,vet2,iv)
48525       if (iv == 1) then
48526          Celda(6)   =vet1(1)
48527          a(6)=vet2(1)
48528       end if
48529       if (present(stdcelda)) stdcelda=a
48530
48531       return
48532    End Subroutine Read_Cif_Cell
48533
48534    !!----
48535    !!---- Subroutine Read_Cif_ChemicalName(Filevar,Nline_Ini,Nline_End,ChemName)
48536    !!----    character(len=*),  dimension(:), intent(in) :: filevar      !  In -> String vector
48537    !!----    integer,           intent(in out)           :: nline_ini    !  In -> Line to start the search
48538    !!----                                                                  Out -> Actual line on Filevar
48539    !!----    integer,           intent(in)               :: nline_end    !  In -> Line to finish the search
48540    !!----    character(len=*),  intent(out)              :: ChemName     ! Out -> Title string
48541    !!----
48542    !!----    Obtaining Chemical Name from Cif file
48543    !!----
48544    !!---- Update: March - 2009
48545    !!
48546    Subroutine Read_Cif_ChemicalName(Filevar,Nline_Ini,Nline_End,ChemName)
48547       !---- Arguments ----!
48548       character(len=*),  dimension(:), intent(in) :: filevar
48549       integer,           intent(in out)           :: nline_ini
48550       integer,           intent(in)               :: nline_end
48551       character(len=*),  intent(out)              :: ChemName
48552
48553       !---- Local variables ----!
48554       integer :: np1, np2
48555
48556       ChemName=" "
48557       call Read_Key_StrVal(filevar,nline_ini,nline_end, &
48558                            "_chemical_name_common",ChemName)
48559
48560       if (len_trim(chemname) == 0) then
48561          call Read_Key_StrVal(filevar,nline_ini,nline_end, &
48562                            "_chemical_name_systematic",ChemName)
48563       end if
48564
48565       if (len_trim(chemname) > 0) then
48566          if (trim(chemname) =="; ?" .or. trim(chemname)=="#") chemname=" "
48567          np1=index(chemname,"'")
48568          np2=index(chemname,"'",back=.true.)
48569          if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48570             chemname=chemname(np1+1:np2-1)
48571          else
48572             np1=index(chemname,'"')
48573             np2=index(chemname,'"',back=.true.)
48574             if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48575                chemname=chemname(np1+1:np2-1)
48576             end if
48577          end if
48578       end if
48579
48580       return
48581    End Subroutine Read_Cif_ChemicalName
48582
48583    !!----
48584    !!---- Subroutine Read_Cif_Cont(Filevar,Nline_Ini,Nline_End,N_Elem_Type,Elem_Type,N_Elem)
48585    !!----    character(len=*), dimension(:),      intent(in)      :: filevar       !  In -> String vector input
48586    !!----    integer,                             intent(in out)  :: nline_ini     !  In -> Line to start the search
48587    !!----                                                                             Out -> Actual line on Filevar
48588    !!----    integer,                             intent(in)      :: nline_end     !  In -> Line to finish the search
48589    !!----    integer,                             intent(out)     :: n_elem_type   ! Out -> N. of different elements
48590    !!----    character(len=*), dimension(:),      intent(out)     :: elem_type     ! Out -> String for Element type
48591    !!----    real(kind=cp), dimension(:),optional,intent(out)     :: n_elem        ! Out -> Number of elements
48592    !!----
48593    !!----    Obtaining the chemical contents from Cif file
48594    !!----
48595    !!---- Update: February - 2005
48596    !!
48597    Subroutine Read_Cif_Cont(Filevar,Nline_Ini,Nline_End,N_Elem_Type,Elem_Type,N_Elem)
48598       !---- Arguments ----!
48599       character(len=*), dimension(:),      intent(in)      :: filevar
48600       integer,                             intent(in out)  :: nline_ini
48601       integer,                             intent(in)      :: nline_end
48602       integer,                             intent(out)     :: n_elem_type
48603       character(len=*), dimension(:),      intent(out)     :: elem_type
48604       real(kind=cp), dimension(:),optional,intent(out)     :: n_elem
48605
48606       !---- Local  variables ----!
48607       character(len=len(filevar(1)))      :: string
48608       character(len=10),dimension(15)     :: label
48609
48610       integer                    :: iv
48611       integer                    :: i,np1,np2,nlabel,nlong
48612       integer, dimension(1)      :: ivet
48613
48614       real(kind=cp),dimension(1) :: vet
48615
48616       n_elem_type = 0
48617       elem_type   = " "
48618       if (present(n_elem)) n_elem = 0.0
48619
48620       call Read_Key_StrVal(filevar,nline_ini,nline_end, &
48621                            "_chemical_formula_sum",string)
48622       if (len_trim(string) ==0) string=filevar(nline_ini+1)
48623       string=adjustl(string)
48624       if (string(1:1) == "?") return
48625       np1=index(string,"'")
48626       np2=index(string,"'",back=.true.)
48627       nlabel=0
48628       if (np1 /= 0 .and. np2 /= 0 .and. np2 > np1) then
48629          call getword(string(np1+1:np2-1),label,nlabel)
48630       end if
48631       if (nlabel /=0) then
48632          n_elem_type = nlabel
48633          do i=1,nlabel
48634             nlong=len_trim(label(i))
48635             select case (nlong)
48636                 case (1)
48637                    elem_type(i)=label(i)(1:1)
48638                    if (present(n_elem)) n_elem(i)   = 1.0
48639
48640                 case (2)
48641                    call getnum(label(i)(2:),vet,ivet,iv)
48642                    if (iv == 1) then
48643                       elem_type(i)=label(i)(1:1)
48644                       if (present(n_elem)) n_elem(i)   =vet(1)
48645                    else
48646                       elem_type(i)=label(i)(1:2)
48647                       if (present(n_elem)) n_elem(i)   = 1.0
48648                    end if
48649
48650                 case (3:)
48651                    call getnum(label(i)(2:),vet,ivet,iv)
48652                    if (iv == 1) then
48653                       elem_type(i)=label(i)(1:1)
48654                       if (present(n_elem)) n_elem(i)   =vet(1)
48655                    else
48656                       call getnum(label(i)(3:),vet,ivet,iv)
48657                       if (iv == 1) then
48658                          elem_type(i)=label(i)(1:2)
48659                          if (present(n_elem)) n_elem(i)   =vet(1)
48660                       else
48661                          elem_type(i)=label(i)(1:2)
48662                          if (present(n_elem)) n_elem(i)   = 1.0
48663                       end if
48664
48665                    end if
48666
48667             end select
48668          end do
48669       end if
48670
48671       return
48672    End Subroutine Read_Cif_Cont
48673
48674    !!----
48675    !!---- Subroutine Read_Cif_Hall(Filevar,Nline_Ini,Nline_End,Spgr_Ha)
48676    !!----    character(len=*), dimension(:), intent(in) :: filevar      !  In -> String vector input
48677    !!----    integer,          intent(in out)           :: nline_ini    !  In -> Line to start the search
48678    !!----                                                                 Out -> Actual line on Filevar
48679    !!----    integer,          intent(in)               :: nline_end    !  In -> Line to finish the search
48680    !!----    character(len=*), intent(out)              :: spgr_ha      ! Out -> Hall symbol
48681    !!----
48682    !!----    Obtaining the Hall symbol of the Space Group
48683    !!----
48684    !!---- Update: February - 2005
48685    !!
48686    Subroutine Read_Cif_Hall(Filevar,Nline_Ini,Nline_End,Spgr_Ha)
48687       !---- Arguments ----!
48688       character(len=*), dimension(:), intent(in) :: filevar
48689       integer,          intent(in out)           :: nline_ini
48690       integer,          intent(in)               :: nline_end
48691       character(len=*), intent(out)              :: spgr_ha
48692
48693       !---- Local variables ----!
48694       integer :: np1, np2
48695
48696       spgr_ha=" "
48697       call Read_Key_StrVal(filevar,nline_ini,nline_end, &
48698                            "_symmetry_space_group_name_Hall",spgr_ha)
48699       if (len_trim(spgr_ha)==0) spgr_ha=adjustl(filevar(nline_ini+1))
48700       ! TR  feb. 2015 .(re-reading the same item with another name)
48701       if(len_trim(spgr_ha) == 0) then
48702        spgr_ha=" "
48703        call Read_Key_StrVal(filevar,nline_ini,nline_end, "_space_group_name_Hall",spgr_ha)
48704        if (len_trim(spgr_ha)==0) spgr_ha=adjustl(filevar(nline_ini+1))
48705       end if
48706
48707       if (spgr_ha =="?" .or. spgr_ha=="#") then
48708          spgr_ha=" "
48709       else
48710          np1=index(spgr_ha,"'")
48711          np2=index(spgr_ha,"'",back=.true.)
48712          if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48713             spgr_ha=spgr_ha(np1+1:np2-1)
48714          else
48715             np1=index(spgr_ha,'"')
48716             np2=index(spgr_ha,'"',back=.true.)
48717             if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48718                spgr_ha=spgr_ha(np1+1:np2-1)
48719             else
48720                spgr_ha=" "
48721             end if
48722          end if
48723       end if
48724
48725       return
48726    End Subroutine Read_Cif_Hall
48727
48728    !!----
48729    !!---- Subroutine Read_Cif_Hm(Filevar,Nline_Ini,Nline_End,Spgr_Hm)
48730    !!----    character(len=*),  dimension(:), intent(in) :: filevar     !  In -> String vector
48731    !!----    integer,           intent(in out)           :: nline_ini   !  In -> Line to start the search
48732    !!----                                                                 Out -> Actual Line on Filevar
48733    !!----    integer,           intent(in)               :: nline_end   !  In -> Line to finish the search
48734    !!----    character(len=*),  intent(out)              :: spgr_hm     ! Out -> Hermann-Mauguin symbol
48735    !!----
48736    !!----    Obtaining the Herman-Mauguin symbol of Space Group
48737    !!----
48738    !!---- Update: March - 2010
48739    !!
48740    Subroutine Read_Cif_Hm(Filevar,Nline_Ini,Nline_End,Spgr_Hm)
48741       !---- Arguments ----!
48742       character(len=*),  dimension(:), intent(in) :: filevar
48743       integer,           intent(in out)           :: nline_ini
48744       integer,           intent(in)               :: nline_end
48745       character(len=*),  intent(out)              :: spgr_hm
48746
48747       !---- Local variables ----!
48748       character(len=1) :: csym, csym2
48749       integer          :: np1, np2
48750
48751       spgr_hm=" "
48752       np1=nline_ini
48753       call Read_Key_Str(filevar,nline_ini,nline_end, &
48754                            "_symmetry_space_group_name_H-M",spgr_hm)
48755       !if (len_trim(spgr_hm) ==0 ) spgr_hm=adjustl(filevar(nline_ini+1))
48756       nline_ini=np1
48757       ! TR  feb. 2015 .(re-reading the same item with another name)
48758       if(len_trim(spgr_hm) == 0) then
48759        spgr_hm = " "
48760        call Read_Key_Str(filevar,nline_ini,nline_end, "_space_group_name_H-M_alt",spgr_hm)
48761        if (len_trim(spgr_hm) ==0 ) spgr_hm=adjustl(filevar(nline_ini+1))
48762       end if
48763
48764       if (spgr_hm =="?" .or. spgr_hm=="#") then
48765          spgr_hm=" "
48766       else
48767          np1=index(spgr_hm,"'")
48768          np2=index(spgr_hm,"'",back=.true.)
48769          if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48770             spgr_hm=spgr_hm(np1+1:np2-1)
48771          else
48772             np1=index(spgr_hm,'"')
48773             np2=index(spgr_hm,'"',back=.true.)
48774             if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48775                spgr_hm=spgr_hm(np1+1:np2-1)
48776             else
48777                spgr_hm=" "
48778             end if
48779          end if
48780       end if
48781
48782       !---- Adapting Nomenclature from ICSD to our model ----!
48783       np1=len_trim(spgr_hm)
48784       if (np1 > 0) then
48785          csym=u_case(spgr_hm(np1:np1))
48786          select case (csym)
48787             case("1")
48788                csym2=u_case(spgr_hm(np1-1:np1-1))
48789                if (csym2 == "Z" .or. csym2 =="S") then
48790                   spgr_hm=spgr_hm(:np1-2)//":1"
48791                end if
48792
48793             case("S","Z")
48794                csym2=u_case(spgr_hm(np1-1:np1-1))
48795                select case (csym2)
48796                   case ("H")
48797                      spgr_hm=spgr_hm(:np1-2)
48798                   case ("R")
48799                      spgr_hm=spgr_hm(:np1-2)//":R"
48800                   case default
48801                      spgr_hm=spgr_hm(:np1-1)
48802                end select
48803
48804             case("R")
48805                csym2=u_case(spgr_hm(np1-1:np1-1))
48806                if (csym2 == "H" ) then
48807                   spgr_hm=spgr_hm(:np1-2)
48808                else
48809                   spgr_hm=spgr_hm(:np1-1)//":R"
48810                end if
48811          end select
48812       end if
48813
48814       return
48815    End Subroutine Read_Cif_Hm
48816
48817    !!----
48818    !!---- Subroutine Read_Cif_Lambda(Filevar,Nline_Ini,Nline_End,Lambda)
48819    !!----    character(len=*), dimension(:), intent(in) :: filevar      !  In -> String vector
48820    !!----    integer,           intent(in out)          :: nline_ini    !  In -> Line to start of search
48821    !!----                                                                  Out -> Actual line on Filevar
48822    !!----    integer,           intent(in)              :: nline_end    !  In -> Line to finish the search
48823    !!----    real(kind=cp),     intent(out)             :: lambda       !  Out -> lamda value
48824    !!----
48825    !!----    Radiation length
48826    !!----
48827    !!---- Update: February - 2005
48828    !!
48829    Subroutine Read_Cif_Lambda(Filevar,Nline_Ini,Nline_End,Lambda)
48830       !---- Arguments ----!
48831       character(len=*),  dimension(:), intent(in) :: filevar
48832       integer,           intent(in out)           :: nline_ini
48833       integer,           intent(in)               :: nline_end
48834       real(kind=cp),     intent(out)              :: lambda
48835
48836       !---- Local Variables ----!
48837       integer                    :: iv
48838       integer,dimension(1)       :: ivet
48839       real(kind=cp), dimension(1):: vet
48840
48841       lambda=0.71073    ! Mo
48842
48843       call read_key_value(filevar,nline_ini,nline_end, &
48844                           "_diffrn_radiation_wavelength",vet,ivet,iv)
48845       if (iv == 1) then
48846          lambda=vet(1)
48847       end if
48848
48849       return
48850    End Subroutine Read_Cif_Lambda
48851
48852    !!----
48853    !!---- Subroutine Read_Cif_Symm(Filevar,Nline_Ini,Nline_End,N_Oper,Oper_Symm)
48854    !!----    character(len=*), dimension(:), intent(in) :: filevar       !  In -> String vector
48855    !!----    integer,          intent(in out)           :: nline_ini     !  In -> Line to start the search
48856    !!----                                                                  Out -> Actual line on Filevar
48857    !!----    integer,          intent(in)               :: nline_end     !  In -> Line to finish the search
48858    !!----    integer,          intent(out)              :: n_oper        ! Out -> Number of Operators
48859    !!----    character(len=*), dimension(:),intent(out) :: oper_symm     ! Out -> Vector with Symmetry Operators
48860    !!----
48861    !!----    Obtaining Symmetry Operators from Cif file
48862    !!----
48863    !!---- Update: February - 2005
48864    !!
48865    Subroutine Read_Cif_Symm(Filevar,Nline_Ini,Nline_End,N_Oper,Oper_Symm)
48866       !---- Arguments ----!
48867       character(len=*), dimension(:), intent(in) :: filevar
48868       integer,          intent(in out)           :: nline_ini
48869       integer,          intent(in)               :: nline_end
48870       integer,          intent(out)              :: n_oper
48871       character(len=*), dimension(:),intent(out) :: oper_symm
48872
48873       !---- Local variables ----!
48874       character(len=len(filevar(1))) :: string
48875       integer                        :: i,np1,np2
48876
48877       n_oper=0
48878       oper_symm=" "
48879       np1=nline_ini
48880       call Read_Key_StrVal(filevar,nline_ini,nline_end, &
48881                            "_symmetry_equiv_pos_as_xyz",string)
48882       nline_ini=np1
48883       ! TR  feb. 2015 .(re-reading the same item with another name)
48884       if(len_trim(string) == 0) then
48885        call Read_Key_StrVal(filevar,nline_ini,nline_end, "_space_group_symop_operation_xyz",string)
48886       end if
48887
48888       if (len_trim(string) /=0) then
48889          string=adjustl(string)
48890
48891          if (string(1:1) /="#" .and. string(1:1) /= "?") then      ! Comentario
48892             np1=index(string,"'")
48893             np2=index(string,"'",back=.true.)
48894             if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48895                n_oper=n_oper+1
48896                oper_symm(n_oper)=string(np1+1:np2-1)
48897             else
48898                np1=index(string,'"')
48899                np2=index(string,'"',back=.true.)
48900                if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48901                   n_oper=n_oper+1
48902                   oper_symm(n_oper)=string(np1+1:np2-1)
48903                end if
48904             end if
48905          end if
48906       end if
48907
48908       do i=nline_ini+1,nline_end
48909          string=adjustl(filevar(i))
48910          if (len_trim(string) /=0) then
48911             if (string(1:1) /="#" .and. string(1:1) /= "?") then      ! Comentario o Vacio
48912                np1=index(string,"'")
48913                np2=index(string,"'",back=.true.)
48914                if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48915                   n_oper=n_oper+1
48916                   oper_symm(n_oper)=string(np1+1:np2-1)
48917                else
48918                   np1=index(string,'"')
48919                   np2=index(string,'"',back=.true.)
48920                   if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48921                      n_oper=n_oper+1
48922                      oper_symm(n_oper)=string(np1+1:np2-1)
48923                   end if
48924                end if
48925             end if
48926          else
48927             nline_ini=i+1
48928             exit
48929          end if
48930       end do
48931
48932       return
48933    End Subroutine Read_Cif_Symm
48934
48935    !!----
48936    !!---- Subroutine Read_Cif_Title(Filevar,Nline_Ini,Nline_End,Title)
48937    !!----    character(len=*),  dimension(:), intent(in) :: filevar      !  In -> String vector
48938    !!----    integer,           intent(in out)           :: nline_ini    !  In -> Line to start the search
48939    !!----                                                                  Out -> Actual line on Filevar
48940    !!----    integer,           intent(in)               :: nline_end    !  In -> Line to finish the search
48941    !!----    character(len=*),  intent(out)              :: title        ! Out -> Title string
48942    !!----
48943    !!----    Obtaining Title from Cif file
48944    !!----
48945    !!---- Update: February - 2005
48946    !!
48947    Subroutine Read_Cif_Title(Filevar,Nline_Ini,Nline_End,title)
48948       !---- Arguments ----!
48949       character(len=*),  dimension(:), intent(in) :: filevar
48950       integer,           intent(in out)           :: nline_ini
48951       integer,           intent(in)               :: nline_end
48952       character(len=*),  intent(out)              :: title
48953
48954       !---- Local variables ----!
48955       integer :: np, np1, np2
48956
48957       title=" "
48958       call Read_Key_StrVal(filevar,nline_ini,nline_end, &
48959                            "_publ_section_title",title)
48960
48961       if (len_trim(title) ==0 ) title=adjustl(filevar(nline_ini+1))
48962       if (title =="; ?" .or. title=="#") then
48963          title=" "
48964       else
48965          np=len_trim(title)
48966          if (np <= 3) title=adjustl(filevar(nline_ini+2))
48967          np1=index(title,"'")
48968          np2=index(title,"'",back=.true.)
48969          if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48970             title=title(np1+1:np2-1)
48971          else
48972             np1=index(title,'"')
48973             np2=index(title,'"',back=.true.)
48974             if (np1 > 0 .and. np2 > 0 .and. np2 > np1) then
48975                title=title(np1+1:np2-1)
48976             end if
48977          end if
48978       end if
48979
48980       return
48981    End Subroutine Read_Cif_Title
48982
48983    !!----
48984    !!---- Subroutine Read_Cif_Z(Filevar,Nline_Ini,Nline_End,Z)
48985    !!----    character(len=*), dimension(:), intent(in) :: filevar     !  In -> String vector
48986    !!----    integer,           intent(in out)          :: nline_ini   !  In -> Line to start the search
48987    !!----                                                                Out -> Actual line on Filevar
48988    !!----    integer,           intent(in)              :: nline_end   !  In -> Line to finish the search
48989    !!----    integer,           intent(out)             :: Z           ! Out -> Z value
48990    !!----
48991    !!----    Unit formula from Cif file
48992    !!----
48993    !!---- Update: February - 2005
48994    !!
48995    Subroutine Read_Cif_Z(filevar,nline_ini,nline_end,z)
48996       !---- Arguments ----!
48997       character(len=*),  dimension(:), intent(in) :: filevar
48998       integer,           intent(in out)           :: nline_ini
48999       integer,           intent(in)               :: nline_end
49000       integer,           intent(out)              :: z
49001
49002       !---- Local Variables ----!
49003       integer                     :: iv
49004       integer,dimension(1)        :: ivet
49005       real(kind=cp), dimension(1) :: vet
49006
49007       z=0
49008       call read_key_value(filevar,nline_ini,nline_end, &
49009                           "_cell_formula_units_Z",vet,ivet,iv)
49010       if (iv == 1) then
49011          z=ivet(1)
49012       end if
49013
49014       return
49015    End Subroutine Read_Cif_Z
49016
49017    !!----
49018    !!---- Subroutine Read_File_Atom(Filevar,Nline_Ini,Nline_End,Atomos)
49019    !!----    character(len=*),dimension(:), intent(in)       :: filevar     !  In -> String vector
49020    !!----    integer,                       intent(in)       :: nline_ini   !  In -> Line to start the search
49021    !!----                                                                     Out -> Actual line on Filevar
49022    !!----    integer,                       intent(in)       :: nline_end   !  In -> Line to finish the search
49023    !!----    type (atom_list_type),        intent(out)      :: Atomos      ! Out -> Atom list
49024    !!----           or
49025    !!----    type (Point_list_Type),        intent(out)      :: Atomos      ! Out -> point list
49026    !!----
49027    !!----     Subroutine to read an atom (or point) list from a file. Atomos should be previously allocated.
49028    !!----     Control of error is present.
49029    !!----
49030    !!---- Update: June - 2005
49031    !!
49032
49033    !!--++
49034    !!--++ Subroutine Read_File_Atomlist(Filevar,Nline_Ini,Nline_End,Atomos)
49035    !!--++    character(len=*),dimension(:), intent(in)       :: filevar     !  In -> String vector
49036    !!--++    integer,                       intent(in)       :: nline_ini   !  In -> Line to start the search
49037    !!--++                                                                     Out -> Actual line on Filevar
49038    !!--++    integer,                       intent(in)       :: nline_end   !  In -> Line to finish the search
49039    !!--++    type (atom_list_type),        intent(out)       :: Atomos      ! Out -> Atom list
49040    !!--++
49041    !!--++     Subroutine to read an atom list from a file. Atomos should be previously allocated.
49042    !!--++     Control of error is present
49043    !!--++
49044    !!--++ Update: June - 2005
49045    !!
49046    Subroutine Read_File_Atomlist(filevar,nline_ini,nline_end,Atomos)
49047       !---- Arguments ----!
49048       character(len=*), dimension(:),   intent(in)      :: filevar
49049       integer,                          intent(in out)  :: nline_ini
49050       integer,                          intent(in)      :: nline_end
49051       type (atom_list_type),            intent(in out)  :: Atomos
49052
49053       !---- Local variables -----!
49054       character(len=len(filevar(1))) :: line
49055       character(len=4)               :: dire
49056       integer                        :: i,na
49057       type (Atom_Type)               :: Atomo
49058
49059       !---- Initial Values ----!
49060       na=0
49061       do i=nline_ini,nline_end
49062          dire=adjustl(u_case(filevar(i)(1:4)))
49063          if (dire /= "ATOM") cycle
49064          line=adjustl(filevar(i))
49065          call read_atom(line,atomo)
49066          if (err_form) cycle
49067
49068          !---- Trial to read anisotropic thermal parameters ----!
49069          if( i < size(filevar) ) then
49070           line=adjustl(filevar(i+1))
49071           select case (u_case(line(1:4)))
49072             case ("U_IJ")
49073                call read_uvals(line,atomo, "u_ij")
49074             case ("B_IJ")
49075                call read_uvals(line,atomo, "b_ij")
49076             case ("BETA")
49077                call read_uvals(line,atomo, "beta")
49078           end select
49079           if (err_form) cycle
49080          end if
49081          na=na+1
49082          Atomos%atom(na)=atomo
49083       end do
49084
49085       Atomos%natoms=na
49086
49087       return
49088    End Subroutine Read_File_Atomlist
49089
49090    !!----
49091    !!---- Subroutine Read_File_PointList(Filevar,Nline_Ini,Nline_End,Atomos)
49092    !!----    character(len=*),dimension(:), intent(in)       :: filevar     !  In -> String vector
49093    !!----    integer,                       intent(in)       :: nline_ini   !  In -> Line to start the search
49094    !!----                                                                     Out -> Actual line on Filevar
49095    !!----    integer,                       intent(in)       :: nline_end   !  In -> Line to finish the search
49096    !!----    type (Point_List_Type),        intent(out)      :: Atomos      ! Out -> point list
49097    !!----
49098    !!----     Subroutine to read an point list from a file. Atomos should be previously allocated.
49099    !!----     Control of error is present
49100    !!----
49101    !!---- Update: June - 2005
49102    !!
49103    Subroutine Read_File_PointList(filevar,nline_ini,nline_end,Atomos)
49104       !---- Arguments ----!
49105       character(len=*), dimension(:),   intent(in)      :: filevar
49106       integer,                          intent(in out)  :: nline_ini
49107       integer,                          intent(in)      :: nline_end
49108       type (Point_List_Type),           intent(in out)  :: Atomos
49109
49110       !---- Local variables -----!
49111       character(len=len(filevar(1))) :: line
49112       character(len=4)               :: dire
49113       integer                        :: i,na
49114       type (Atom_Type)               :: Atomo
49115
49116       !---- Initial Values ----!
49117       na=0
49118
49119       do i=nline_ini,nline_end
49120          dire=adjustl(u_case(filevar(i)(1:4)))
49121          if (dire /= "ATOM") cycle
49122          line=adjustl(filevar(i))
49123          call read_atom(line,atomo)
49124          if (err_form) cycle
49125          na=na+1
49126          Atomos%x(:,na) =atomo%x(:)
49127          Atomos%p(na)   = 0
49128          Atomos%nam(na) = atomo%lab
49129       end do
49130
49131       Atomos%np=na
49132
49133       return
49134    End Subroutine Read_File_PointList
49135
49136    !!----
49137    !!---- Subroutine Read_File_Cell(Filevar,Nline_Ini,Nline_End,Celda)
49138    !!----    character(len=*), dimension(:), intent(in) :: filevar      !  In -> String Vector
49139    !!----    integer,           intent(in out)          :: nline_ini    !  In -> Line to start the search
49140    !!----                                                                 Out -> Atual line on Filevar
49141    !!----    integer,           intent(in)              :: nline_end    !  In -> line to finish the search
49142    !!----
49143    !!----    real(kind=cp),dimension(6), intent (out)   :: Celda        ! Out -> Cell variable
49144    !!----                            or
49145    !!----    type (Crystal_Cell_Type), intent (out)     :: Celda        ! Out -> Cell variable
49146    !!----
49147    !!----    Read Cell Parameters from file. Control error is present
49148    !!----
49149    !!---- Update: February - 2005
49150    !!
49151
49152    !!--++
49153    !!--++ Subroutine Read_File_Cellc(Filevar,Nline_Ini,Nline_End,Celda)
49154    !!--++    character(len=*), dimension(:), intent(in) :: filevar      !  In -> String Vector
49155    !!--++    integer,           intent(in out)          :: nline_ini    !  In -> Line to start the search
49156    !!--++                                                                 Out -> Atual line on Filevar
49157    !!--++    integer,           intent(in)              :: nline_end    !  In -> line to finish the search
49158    !!--++    real(kind=cp),dimension(6), intent (out)   :: Celda        ! Out -> Cell variable
49159    !!--++
49160    !!--++    (OVERLOADED)
49161    !!--++    Read Cell Parameters from file. Control error is present
49162    !!--++
49163    !!--++ Update: February - 2005
49164    !!
49165    Subroutine Read_File_Cellc(filevar,nline_ini,nline_end,Celda)
49166       !---- Arguments ----!
49167       character(len=*),  dimension(:), intent(in)     :: filevar
49168       integer,                         intent(in)     :: nline_ini
49169       integer,                         intent(in)     :: nline_end
49170       real(kind=cp),dimension(6),      intent(out)    :: Celda
49171
49172       !---- Local Variables ----!
49173       integer                     :: iv, i,j
49174       integer, dimension(6)       :: ivet
49175       real(kind=cp), dimension(6) :: vet
49176
49177       !---- Valores iniciales ----!
49178       call init_err_form()
49179
49180       i=nline_ini
49181       j=nline_end
49182
49183       !---- Celda ----!
49184       call read_key_value(filevar,i,j,"cell",vet,ivet,iv)
49185       if (iv /=6) then
49186          err_form=.true.
49187          ERR_Form_Mess=" Bad Cell Parameters..."
49188          return
49189       else
49190          celda=vet(:)
49191       end if
49192
49193       return
49194    End Subroutine Read_File_Cellc
49195
49196    !!--++
49197    !!--++ Subroutine Read_File_Cellt(Filevar,Nline_Ini,Nline_End,Celda,CFrame)
49198    !!--++    character(len=*),  dimension(:), intent(in)     :: filevar     !  In -> String Vector
49199    !!--++    integer,                         intent(in)     :: nline_ini   !  In -> Line to start the search
49200    !!--++    integer,                         intent(in)     :: nline_end   !  In -> line to finish the search
49201    !!--++    type (Crystal_Cell_Type),        intent(out)    :: Celda       ! Out -> Cell structure
49202    !!--++    character(len=*),  optional,     intent(in)     :: CFrame      !  Cartesian Frame "A" or "C" (if absent -> "A")
49203    !!--++          ! Out -> Cell variable
49204    !!--++
49205    !!--++    (OVERLOADED)
49206    !!--++    Read Cell Parameters from file. Control error is present
49207    !!--++    The object Celda is constructed just after reading the cell parameters.
49208    !!--++
49209    !!--++ Update: February - 2005
49210    !!
49211    Subroutine Read_File_Cellt(filevar,nline_ini,nline_end,Celda,CFrame)
49212       !---- Arguments ----!
49213       character(len=*),  dimension(:), intent(in)     :: filevar
49214       integer,                         intent(in)     :: nline_ini
49215       integer,                         intent(in)     :: nline_end
49216       type (Crystal_Cell_Type),        intent(out)    :: Celda
49217       character(len=*),  optional,     intent(in)     :: CFrame
49218
49219       !---- Local Variables ----!
49220       integer                     :: iv, i,j
49221       real(kind=cp), dimension(6) :: vet1,vet2
49222
49223       !---- Valores iniciales ----!
49224       call init_err_form()
49225
49226       i=nline_ini
49227       j=nline_end
49228
49229       !---- Celda ----!
49230
49231       call read_key_valueSTD(filevar,i,j,"cell",vet1,vet2,iv)
49232       if (iv /=6) then
49233          err_form=.true.
49234          ERR_Form_Mess=" Bad Cell Parameters..."
49235          return
49236       end if
49237       if(present(CFrame)) then
49238         call Set_Crystal_Cell(vet1(1:3),vet1(4:6),Celda,CFrame)
49239       else
49240         call Set_Crystal_Cell(vet1(1:3),vet1(4:6),Celda,"A")
49241       end if
49242       celda%cell_std=vet2(1:3)
49243       celda%ang_std=vet2(4:6)
49244
49245       return
49246    End Subroutine Read_File_Cellt
49247
49248    !!----
49249    !!---- Subroutine Read_File_lambda(Filevar,Nline_Ini,Nline_End,v1,v2,v3)
49250    !!----    character(len=*), dimension(:), intent(in)     :: filevar   !  In -> String Vector
49251    !!----    integer,                        intent(in out) :: nline_ini !  In -> Line to start the search
49252    !!----                                                                  Out -> Atual line on Filevar
49253    !!----    integer,                        intent(in)     :: nline_end !  In -> line to finish the search
49254    !!----    real(kind=cp),                  intent(   out) :: v1,v2,v3  ! Out -> Lambda1,lambda2,ratio
49255    !!----
49256    !!----    Read wavelengths and ratio.
49257    !!----    If no value is read, Lambda1=Lambda2=1.54056 Angstroms, ratio=0.0
49258    !!----    If only one value is read Lambda1=Lambda2=v1, ratio=0
49259    !!----    If only two values iare read Lambda1=v1, Lambda2=v2, ratio=0.5
49260    !!----    In other cases Lambda1=v1, Lambda2=v2, ratio=v3
49261    !!----
49262    !!---- Update: February - 2005
49263    !!
49264    Subroutine Read_File_Lambda(Filevar,Nline_Ini,Nline_End,v1,v2,v3)
49265       !---- Arguments ----!
49266       character(len=*), dimension(:), intent(in)     :: filevar
49267       integer,                        intent(in out) :: nline_ini
49268       integer,                        intent(in)     :: nline_end
49269       real(kind=cp),                  intent(   out) :: v1,v2,v3
49270
49271       !---- Local Variables ----!
49272       integer                    :: iv, i,j
49273       integer, dimension(3)      :: ivet
49274       real(kind=cp), dimension(3):: vet
49275
49276       !---- Valores iniciales ----!
49277       call init_err_form()
49278
49279       i=nline_ini
49280       j=nline_end
49281
49282       v3=0.0
49283       v1=1.54056
49284       !---- Read Lambda ----!
49285       call read_key_value(filevar,i,j,"wave",vet,ivet,iv)
49286       if      (iv == 0) then
49287         v2=1.54056
49288       else if (iv == 1) then
49289         v1=vet(1)
49290         v2=vet(1)
49291       else if (iv == 2) then
49292         v1=vet(1)
49293         v2=vet(2)
49294         v3=0.5
49295       else if (iv == 3) then
49296         v1=vet(1)
49297         v2=vet(2)
49298         v3=vet(3)
49299       end if
49300
49301       return
49302    End Subroutine Read_File_Lambda
49303
49304    !!----
49305    !!---- Subroutine Read_File_RngSintL(Filevar,Nline_Ini,Nline_End,v1,v2)
49306    !!----    character(len=*), dimension(:), intent(in)     :: filevar   !  In -> String Vector
49307    !!----    integer,                        intent(in out) :: nline_ini !  In -> Line to start the search
49308    !!----                                                                  Out -> Atual line on Filevar
49309    !!----    integer,                        intent(in)     :: nline_end !  In -> line to finish the search
49310    !!----    real(kind=cp),                  intent(   out) :: v1,v2     ! Out -> Interval [v1,v2] in sinT/Lambda
49311    !!----
49312    !!----    Read range for sintheta/lambda.
49313    !!----    If only one value is read v1=0 and v2= read value
49314    !!----    If the keyword RNGSL is not given in the file, the default
49315    !!----    values are v1=0.0, v2=1.0
49316    !!----
49317    !!---- Update: February - 2005
49318    !!
49319    Subroutine Read_File_RngSintL(Filevar,Nline_Ini,Nline_End,v1,v2)
49320       !---- Arguments ----!
49321       character(len=*), dimension(:), intent(in)     :: filevar
49322       integer,                        intent(in out) :: nline_ini
49323       integer,                        intent(in)     :: nline_end
49324       real(kind=cp),                  intent(   out) :: v1,v2
49325
49326       !---- Local Variables ----!
49327       integer                     :: iv, i,j
49328       integer,       dimension(2) :: ivet
49329       real(kind=cp), dimension(2) :: vet
49330
49331       !---- Valores iniciales ----!
49332       call init_err_form()
49333
49334       i=nline_ini
49335       j=nline_end
49336
49337       !---- Range in sinTheta/Lambda ----!
49338       call read_key_value(filevar,i,j,"rngsl",vet,ivet,iv)
49339       if      (iv == 0) then
49340         v1=0.0
49341         v2=1.0
49342       else if (iv == 1) then
49343         v1=0.0
49344         v2=vet(1)
49345       else if (iv == 2) then
49346         v1=vet(1)
49347         v2=vet(2)
49348       end if
49349
49350       return
49351    End Subroutine Read_File_RngSintL
49352
49353    !!----
49354    !!---- Subroutine Read_File_Spg (Filevar,Nline_Ini,Nline_End,Spg,Sub)
49355    !!----    character(len=*),  dimension(:), intent(in) :: filevar       !  In -> String vector
49356    !!----    integer,           intent(in)               :: nline_ini     !  In -> Line to start the search
49357    !!----                                                                   Out -> Actual line on Filevar
49358    !!----    integer,           intent(in)               :: nline_end     !  In -> Line to Finish the search
49359    !!----    character(len=*),  intent(out)              :: spg           ! Out -> Space Group symbol
49360    !!----    character(len=*),  intent(in ),optional     :: sub           ! in  -> The space sroup symbol is a subgroup
49361    !!----                                                                 !        of an already given space group
49362    !!----    Reads the cards "SPGR", "SPACEG" or "SUBG" in filvar. Control of error is present
49363    !!----
49364    !!---- Update: February - 2011
49365    !!
49366    Subroutine Read_File_Spg(filevar,nline_ini,nline_end,Spg,sub)
49367       !---- Arguments ----!
49368       character(len=*),  dimension(:), intent(in) :: filevar   ! Variable
49369       integer,           intent(in)               :: nline_ini
49370       integer,           intent(in)               :: nline_end
49371       character(len=*),  intent(out)              :: spg
49372       character(len=*),  intent(in),  optional    :: sub
49373
49374       !--Local variables--!
49375       integer  :: i
49376
49377       call init_err_form()
49378       i=nline_ini
49379       if(present(sub)) then
49380         call Read_Key_StrVal(filevar,i,nline_end, "subg",spg)
49381       else
49382         call Read_Key_StrVal(filevar,i,nline_end, "spgr",spg)
49383       end if
49384       if (len_trim(spg) == 0 ) then
49385         call Read_Key_StrVal(filevar,i,nline_end, "spaceg",spg)
49386         if (len_trim(spg) == 0 ) then
49387           err_form=.true.
49388           ERR_Form_Mess=" Problems reading the Space Group symbol/number"
49389           return
49390         end if
49391       end if
49392
49393       return
49394    End Subroutine Read_File_Spg
49395
49396    !!----
49397    !!---- Read_File_Transf(Filevar,Nline_Ini,Nline_End,Transf,Orig)
49398    !!----    character(len=*), dimension(:), intent(in)     :: filevar      !  In -> String Vector
49399    !!----    integer,                        intent(in out) :: nline_ini    !  In -> Line to start the search
49400    !!----                                                                     Out -> Atual line on Filevar
49401    !!----    integer,                        intent(in)     :: nline_end    !  In -> line to finish the search
49402    !!----    real(kind=cp),dimension(3,3),   intent(out)    :: transf       ! Out -> Cell variable
49403    !!----    real(kind=cp),dimension(3  ),   intent(out)    :: orig
49404    !!----
49405    !!----    Read transformation matrix for changing the space group or cell setting.
49406    !!----    First the matrix M is read row by row and then the origin in the old setting
49407    !!----    is finally read. A single line with 12 real numbers should be given.
49408    !!--<<
49409    !!----    e.g.: TRANS  m11 m12 m13  m21 m22 m33  m31 m32 m33   o1 o2 o3
49410    !!----
49411    !!----    That means       a'=m11 a + m12 b + m13 c
49412    !!----                     b'=m21 a + m22 b + m23 c
49413    !!----                     c'=m31 a + m32 b + m33 c
49414    !!----
49415    !!----                     X' = inv(Mt) (X-O)
49416    !!-->>
49417    !!----
49418    !!---- Update: February - 2005
49419    !!
49420    Subroutine Read_File_transf(filevar,nline_ini,nline_end,trans,orig)
49421       !---- Arguments ----!
49422       character(len=*),  dimension(:), intent(in)     :: filevar
49423       integer,                         intent(in)     :: nline_ini
49424       integer,                         intent(in)     :: nline_end
49425       real(kind=cp),dimension(3,3),    intent(out)    :: trans
49426       real(kind=cp),dimension(3  ),    intent(out)    :: orig
49427
49428       !---- Local Variables ----!
49429       integer                      :: iv, i,j
49430       integer,       dimension(12) :: ivet
49431       real(kind=cp), dimension(12) :: vet
49432       character(len=80)            :: transf_key
49433
49434       !---- Initial values ----!
49435       call init_err_form()
49436
49437       i=nline_ini
49438       j=nline_end
49439
49440       !---- transformation matrix ----!
49441       call read_key_value(filevar,i,j,"trans",vet,ivet,iv,"#",transf_key)
49442       if (iv /= 12 .or. err_string) then
49443          !Try to read the transformation from transf_key
49444          if(len_trim(transf_key) /= 0) then
49445            call Get_Transf(transf_key,trans,orig)
49446            if(err_string) then
49447               err_form=.true.
49448               ERR_Form_Mess=" Bad matrix/origin setting in string: "//trim(transf_key)//" -> "//trim(Err_String_Mess)
49449               return
49450            end if
49451          else
49452               err_form=.true.
49453               ERR_Form_Mess=" Bad matrix/origin setting..."
49454               return
49455          end if
49456
49457       else
49458          trans(1,1:3)=vet(1:3)
49459          trans(2,1:3)=vet(4:6)
49460          trans(3,1:3)=vet(7:9)
49461          orig(1:3) = vet(10:12)
49462       end if
49463
49464       return
49465    End Subroutine Read_File_transf
49466
49467    !!----
49468    !!---- Subroutine Read_Shx_Atom(Filevar,Nline_Ini,Nline_End,N_Fvar,Fvar,Elem_Type,Celda,Atm_List)
49469    !!----    character(len=*), dimension(:), intent(in)      :: filevar        !  In -> String vector
49470    !!----    integer,                        intent(in out)  :: nline_ini      !  In -> Line to start the search
49471    !!----                                                                         Out -> Actual line on Filevar
49472    !!----    integer,                        intent(in)      :: nline_end      !  In -> Line to finish the search
49473    !!----    integer,                        intent(in)      :: n_fvar         !  In -> Number of parameters on FVAR
49474    !!----    real(kind=cp), dimension(:),    intent(in)      :: fvar           !  In -> Values for FVAR
49475    !!----    character(len=*), dimension(:), intent(in)      :: elem_type      !  In -> type of elements
49476    !!----    type (Crystal_Cell_Type),       intent(in)      :: Celda          !  In -> Cell type variable
49477    !!----    type (Atom_list_type),          intent(out)     :: Atm_List       ! Out -> number of atoms
49478    !!----         ! Out -> Atom List
49479    !!----
49480    !!----    Obtaining Atoms parameters from Shelx file (.ins or .res)
49481    !!----
49482    !!---- Update: February - 2005
49483    !!
49484    Subroutine Read_Shx_Atom(filevar,nline_ini,nline_end,n_fvar,fvar,elem_type,celda,Atm_List)
49485       !---- Arguments ----!
49486       character(len=*), dimension(:), intent(in)      :: filevar
49487       integer,                        intent(in out)  :: nline_ini
49488       integer,                        intent(in)      :: nline_end
49489       integer,                        intent(in)      :: n_fvar
49490       real(kind=cp), dimension(:),    intent(in)      :: fvar
49491       character(len=*), dimension(:), intent(in)      :: elem_type
49492       type (Crystal_Cell_Type),       intent(in)      :: Celda
49493       type (Atom_list_type),          intent(out)     :: Atm_List
49494
49495       !---- Local Variables ----!
49496       character(len=80)               :: string
49497       character(len=30),dimension(15) :: label
49498       character(len=2)                :: el
49499       integer                         :: i, nc, iv
49500       integer                         :: j, n_atom
49501       integer, dimension(15)          :: ivet
49502       real(kind=cp)                   :: x, p, u
49503       real(kind=cp), dimension(15)    :: vet
49504       type(atom_list_type)            :: Atm
49505
49506       call allocate_atom_list(nline_end-nline_ini+1,Atm)
49507       n_atom=0
49508
49509       do i=nline_ini,nline_end
49510          string=filevar(i)
49511          if (len_trim(string) == 0) cycle
49512          call getword(string,label,nc)
49513          select case (nc)
49514             case (5) ! Atomname Sfac X Y Z
49515                call getnum(label(2),vet,ivet,iv)   ! Is Sfac integer?
49516                if (iv /= 1) cycle
49517                call getnum(label(3),vet,ivet,iv)   ! Is X real?
49518                if (iv /= 1) cycle
49519                call getnum(label(4),vet,ivet,iv)   ! Is Y real?
49520                if (iv /= 1) cycle
49521                call getnum(label(5),vet,ivet,iv)   ! Is Z real?
49522                if (iv /= 1) cycle
49523
49524                n_atom=n_atom+1
49525                atm%atom(n_atom)%lab=label(1)(1:4)
49526                call getnum(label(2),vet,ivet,iv)
49527                el=elem_type(ivet(1))
49528                atm%atom(n_atom)%chemSymb=U_case(el(1:1))//L_case(el(2:2))
49529                call getnum(label(3),vet,ivet,iv)
49530                atm%atom(n_atom)%x(1)=vet(1)
49531                call getnum(label(4),vet,ivet,iv)
49532                atm%atom(n_atom)%x(2)=vet(1)
49533                call getnum(label(5),vet,ivet,iv)
49534                atm%atom(n_atom)%x(3)=vet(1)
49535                atm%atom(n_atom)%utype="u_ij"
49536
49537             case (6) ! Atomname Sfac X Y Z Occ
49538                call getnum(label(2),vet,ivet,iv)   ! Is Sfac integer?
49539                if (iv /= 1) cycle
49540                call getnum(label(3),vet,ivet,iv)   ! Is X real?
49541                if (iv /= 1) cycle
49542                call getnum(label(4),vet,ivet,iv)   ! Is Y real?
49543                if (iv /= 1) cycle
49544                call getnum(label(5),vet,ivet,iv)   ! Is Z real?
49545                if (iv /= 1) cycle
49546                call getnum(label(6),vet,ivet,iv)   ! Is Occ real?
49547                if (iv /= 1) cycle
49548
49549                n_atom=n_atom+1
49550                atm%atom(n_atom)%lab=label(1)(1:4)
49551                call getnum(label(2),vet,ivet,iv)
49552                el=elem_type(ivet(1))
49553                atm%atom(n_atom)%chemSymb=U_case(el(1:1))//L_case(el(2:2))
49554                call getnum(label(3),vet,ivet,iv)
49555                atm%atom(n_atom)%x(1)=vet(1)
49556                call getnum(label(4),vet,ivet,iv)
49557                atm%atom(n_atom)%x(2)=vet(1)
49558                call getnum(label(5),vet,ivet,iv)
49559                atm%atom(n_atom)%x(3)=vet(1)
49560                call getnum(label(6),vet,ivet,iv)
49561                atm%atom(n_atom)%occ=vet(1)
49562                atm%atom(n_atom)%utype="u_ij"
49563
49564             case (7,8) ! Atomname Sfac X Y Z Occ Uiso   (TR: item 8 can be electronic density created by SHELXS)
49565                call getnum(label(2),vet,ivet,iv)   ! Is Sfac integer?
49566                if (iv /= 1) cycle
49567                call getnum(label(3),vet,ivet,iv)   ! Is X real?
49568                if (iv /= 1) cycle
49569                call getnum(label(4),vet,ivet,iv)   ! Is Y real?
49570                if (iv /= 1) cycle
49571                call getnum(label(5),vet,ivet,iv)   ! Is Z real?
49572                if (iv /= 1) cycle
49573                call getnum(label(6),vet,ivet,iv)   ! Is Occ real?
49574                if (iv /= 1) cycle
49575                call getnum(label(7),vet,ivet,iv)   ! Is Uiso real?
49576                if (iv /= 1) cycle
49577
49578                n_atom=n_atom+1
49579                atm%atom(n_atom)%lab=label(1)(1:4)
49580                call getnum(label(2),vet,ivet,iv)
49581                el=elem_type(ivet(1))
49582                atm%atom(n_atom)%chemSymb=U_case(el(1:1))//L_case(el(2:2))
49583                call getnum(label(3),vet,ivet,iv)
49584                atm%atom(n_atom)%x(1)=vet(1)
49585                call getnum(label(4),vet,ivet,iv)
49586                atm%atom(n_atom)%x(2)=vet(1)
49587                call getnum(label(5),vet,ivet,iv)
49588                atm%atom(n_atom)%x(3)=vet(1)
49589                call getnum(label(6),vet,ivet,iv)
49590                atm%atom(n_atom)%occ=vet(1)
49591                call getnum(label(7),vet,ivet,iv)
49592                atm%atom(n_atom)%ueq=vet(1)
49593                atm%atom(n_atom)%utype="u_ij"
49594                atm%atom(n_atom)%thtype="isotr"
49595
49596          case (9) ! Atomname Sfac X Y Z Occ U11 U22 = U33 U23 U13 U12
49597                call getnum(label(2),vet,ivet,iv)   ! Is Sfac integer?
49598                if (iv /= 1) cycle
49599                call getnum(label(3),vet,ivet,iv)   ! Is X real?
49600                if (iv /= 1) cycle
49601                call getnum(label(4),vet,ivet,iv)   ! Is Y real?
49602                if (iv /= 1) cycle
49603                call getnum(label(5),vet,ivet,iv)   ! Is Z real?
49604                if (iv /= 1) cycle
49605                call getnum(label(6),vet,ivet,iv)   ! Is Occ real?
49606                if (iv /= 1) cycle
49607                call getnum(label(7),vet,ivet,iv)   ! Is U11 real?
49608                if (iv /= 1) cycle
49609                call getnum(label(8),vet,ivet,iv)   ! Is U22 real?
49610                if (iv /= 1) cycle
49611                call getnum(filevar(i+1),vet,ivet,iv) ! Are U33 U23 U13 U12?
49612                if (iv /= 4) cycle
49613
49614                n_atom=n_atom+1
49615                atm%atom(n_atom)%lab=label(1)(1:4)
49616                call getnum(label(2),vet,ivet,iv)
49617                el=elem_type(ivet(1))
49618                atm%atom(n_atom)%chemSymb=U_case(el(1:1))//L_case(el(2:2))
49619                call getnum(label(3),vet,ivet,iv)
49620                atm%atom(n_atom)%x(1)=vet(1)
49621                call getnum(label(4),vet,ivet,iv)
49622                atm%atom(n_atom)%x(2)=vet(1)
49623                call getnum(label(5),vet,ivet,iv)
49624                atm%atom(n_atom)%x(3)=vet(1)
49625                call getnum(label(6),vet,ivet,iv)
49626                atm%atom(n_atom)%occ=vet(1)
49627                !---- U11 U22 U33 U12 U13 U23 Order ----!
49628                call getnum(label(7),vet,ivet,iv)
49629                atm%atom(n_atom)%u(1)=vet(1)
49630                call getnum(label(8),vet,ivet,iv)
49631                atm%atom(n_atom)%u(2)=vet(1)
49632                call getnum(filevar(i+1),vet,ivet,iv)
49633                atm%atom(n_atom)%u(3)=vet(1)
49634                atm%atom(n_atom)%u(4)=vet(4)
49635                atm%atom(n_atom)%u(5)=vet(3)
49636                atm%atom(n_atom)%u(6)=vet(2)
49637                atm%atom(n_atom)%utype="u_ij"
49638                atm%atom(n_atom)%thtype="aniso"
49639             case default
49640                cycle
49641          end select
49642       end do
49643
49644       !---- Adjusting ... ----!
49645       call allocate_atom_list(n_atom,Atm_list)
49646       do i=1,n_atom
49647          atm_list%atom(i)=atm%atom(i)
49648       end do
49649       call Deallocate_atom_list(atm)
49650
49651       !---- Tratamiento de Datos del Shelx ----!
49652       do i=1,n_atom
49653          !---- coordinates ----!
49654          if (atm_list%atom(i)%x(1) >= 10.0) atm_list%atom(i)%x(1)=atm_list%atom(i)%x(1)-10.0
49655          if (atm_list%atom(i)%x(2) >= 10.0) atm_list%atom(i)%x(2)=atm_list%atom(i)%x(2)-10.0
49656          if (atm_list%atom(i)%x(3) >= 10.0) atm_list%atom(i)%x(3)=atm_list%atom(i)%x(3)-10.0
49657
49658          !---- ocupancy ----!
49659          if (abs(atm_list%atom(i)%occ)  > 10.0) then
49660             x=atm_list%atom(i)%occ
49661             if (x > 10.0) then
49662                atm_list%atom(i)%occ=x-10.0
49663             else
49664                x=abs(atm_list%atom(i)%occ)
49665                do j=2,n_fvar
49666                   if (x > 10.0*real(j) .and. x < 10.0*real(j+1)) then
49667                      p=x-10.0*real(j)
49668                      if (atm_list%atom(i)%occ > 0.0) then
49669                         atm_list%atom(i)%occ=p*fvar(j)
49670                      else
49671                         atm_list%atom(i)%occ=p*(fvar(j)-1.0)
49672                      end if
49673                   end if
49674                end do
49675             end if
49676          end if
49677
49678          !---- Thermal factors ----!
49679          if (atm_list%atom(i)%thtype == "aniso") then
49680             atm_list%atom(i)%ueq=U_Equiv(celda,atm_list%atom(i)%u(1:6))  ! Uequi
49681             atm_list%atom(i)%biso= atm_list%atom(i)%ueq*78.95683521
49682          else
49683             if (atm_list%atom(i)%ueq < 0.0) then
49684                u=-atm_list%atom(i)%ueq
49685                if (u <= 5.0 .and. u >= 0.5) then
49686                   do j=i-1,1,-1
49687                      if (atm_list%atom(j)%ChemSymb == "H " .or. atm_list%atom(j)%ChemSymb == "h " ) cycle
49688                      atm_list%atom(i)%ueq=u*U_Equiv(celda,atm_list%atom(j)%u(1:6))  ! Uequi
49689                      atm_list%atom(i)%biso= atm_list%atom(i)%ueq*78.95683521
49690                   end do
49691                end if
49692             end if
49693          end if
49694
49695       end do
49696
49697       return
49698    End Subroutine Read_Shx_Atom
49699
49700    !!----
49701    !!---- Subroutine Read_Shx_Cell(Filevar,Nline_Ini,Nline_End,Celda,Stdcelda,Lambda,Z)
49702    !!----    character(len=*), dimension(:), intent(in)     :: filevar       !  In -> String vector
49703    !!----    integer,                        intent(in out) :: nline_ini     !  In -> Line to start the search
49704    !!----                                                                      Out -> Actual line on Filevar
49705    !!----    integer,                        intent(in)     :: nline_end     !  In -> Line to finish the search
49706    !!----    real(kind=cp),dimension(6),     intent(out)    :: celda         ! Out -> Cell Parameters
49707    !!----    real(kind=cp),dimension(6),     intent(out)    :: Stdcelda      ! Out -> Std Cell Parameters
49708    !!----    real(kind=cp),                  intent(out)    :: lambda        ! Out -> Lambda
49709    !!----    integer,                        intent(out)    :: Z             ! Out -> Z
49710    !!----
49711    !!----    Obtaining Cell Parameter from Shelx file
49712    !!----
49713    !!---- Update: February - 2005
49714    !!
49715    Subroutine Read_Shx_Cell(filevar,nline_ini,nline_end,Celda,StdCelda,lambda,z)
49716       !---- Arguments ----!
49717       character(len=*), dimension(:),     intent(in)     :: filevar
49718       integer,                            intent(in out) :: nline_ini
49719       integer,                            intent(in)     :: nline_end
49720       real(kind=cp),dimension(6),         intent(out)    :: Celda
49721       real(kind=cp),dimension(6),optional,intent(out)    :: StdCelda
49722       real(kind=cp),             optional,intent(out)    :: lambda
49723       integer,          optional,         intent(out)    :: z
49724
49725       !---- Local Variables ----!
49726       integer                      :: iv,z_shx
49727       integer, dimension(10)       :: ivet
49728       real(kind=cp), dimension(10) :: vet
49729       real(kind=cp)                :: lambda_shx
49730       real(kind=cp),dimension(6)   :: std
49731
49732       !---- Valores iniciales ----!
49733       celda=0.0
49734       if (present(stdcelda)) stdcelda=0.0
49735       if (present(Lambda))   lambda=0.0
49736       if (present(z))        z=0
49737
49738       !---- CELL ----!
49739       call read_key_value(filevar,nline_ini,nline_end,"CELL",vet,ivet,iv)
49740       if (iv == 7) then
49741          lambda_shx = vet(1)
49742          celda      = vet(2:7)
49743       end if
49744
49745       !---- Z, STD ----!
49746       call read_key_value(filevar,nline_ini,nline_end,"ZERR",vet,ivet,iv)
49747       if (iv == 7) then
49748          z_shx= ivet(1)
49749          std  = vet(2:7)
49750       end if
49751
49752       if (present(stdcelda)) stdcelda=std
49753       if (present(lambda)) lambda=lambda_shx
49754       if (present(z)) z=z_shx
49755
49756       return
49757    End Subroutine Read_Shx_Cell
49758
49759    !!----
49760    !!---- Subroutine Read_Shx_Cont(Filevar,Nline_Ini,Nline_End,N_Elem_Type,Elem_Type,N_Elem)
49761    !!----    character(len=*),  dimension(:),    intent(in)    :: filevar       !  In -> String Vector
49762    !!----    integer,                            intent(in out):: nline_ini     !  In -> Line to start the search
49763    !!----                                                                         Out -> Actual Line on Filevar
49764    !!----    integer,                            intent(in)    :: nline_end     !  In -> Line to finish the search
49765    !!----    integer,                            intent(out)   :: n_elem_type   ! Out -> N. of different species
49766    !!----    character(len=*), dimension(:),     intent(out)   :: elem_type     ! Out -> Character to identify the specie
49767    !!----    real(kind=cp),dimension(:),optional,intent(out)   :: n_elem        ! Out -> Number of elements into the same species
49768    !!----
49769    !!----    Obtaining Chemical contents from Shelx file (.ins or .res)
49770    !!----
49771    !!---- Update: February - 2005
49772    !!
49773    Subroutine Read_Shx_Cont(filevar,nline_ini,nline_end,n_elem_type,elem_type,n_elem)
49774       !---- Arguments ----!
49775       character(len=*), dimension(:),     intent(in)      :: filevar
49776       integer,                            intent(in out)  :: nline_ini
49777       integer,                            intent(in)      :: nline_end
49778       integer,                            intent(out)     :: n_elem_type
49779       character(len=*), dimension(:),     intent(out)     :: elem_type
49780       real(kind=cp),dimension(:),optional,intent(out)     :: n_elem
49781
49782       !---- Local  variables ----!
49783       character(len=len(filevar(1)))      :: string
49784       integer                     :: iv
49785       integer,      dimension(15) :: ivet
49786       real(kind=cp),dimension(15) :: vet
49787
49788       n_elem_type = 0
49789       elem_type   = " "
49790       if (present(n_elem)) n_elem = 0.0
49791
49792       call Read_Key_StrVal(filevar,nline_ini,nline_end,"SFAC",string)
49793       if (len_trim(string) /=0) then
49794          call getword(string,elem_type,n_elem_type)
49795       end if
49796
49797       if (present(n_elem)) then
49798          call read_key_value(filevar,nline_ini,nline_end,"UNIT",vet,ivet,iv)
49799          if (iv /= 0) n_elem=vet
49800       end if
49801
49802       return
49803    End Subroutine Read_Shx_Cont
49804
49805    !!----
49806    !!---- Subroutine Read_Shx_Fvar(Filevar,Nline_Ini,Nline_End,N_Fvar,Fvar)
49807    !!----    character(len=*), dimension(:), intent(in)    :: filevar       !  In -> String vector
49808    !!----    integer,                        intent(in out):: nline_ini     !  In -> Line to start the search
49809    !!----                                                                   ! Out -> Actual line on Filevar
49810    !!----    integer,                        intent(in)    :: nline_end     !  In -> Line to finish the search
49811    !!----    integer,                        intent(out)   :: n_fvar        ! Out -> N. of parameters on FVAR
49812    !!----    real(kind=cp), dimension(:),    intent(out)   :: fvar          ! Out -> values of FVAR
49813    !!----
49814    !!----    Obtaining Fvar parameters from Shelx file (.ins or .res)
49815    !!----
49816    !!---- Update: February - 2003
49817    !!
49818    Subroutine Read_Shx_Fvar(filevar,nline_ini,nline_end,n_fvar,fvar)
49819       !---- Arguments ----!
49820       character(len=*), dimension(:), intent(in)    :: filevar
49821       integer,                        intent(in out):: nline_ini
49822       integer,                        intent(in)    :: nline_end
49823       integer,                        intent(out)   :: n_fvar
49824       real(kind=cp), dimension(:),    intent(out)   :: fvar
49825
49826       !---- Local  variables ----!
49827       integer                      :: iv
49828       integer,       dimension(15) :: ivet
49829       real(kind=cp), dimension(15) :: vet
49830
49831       n_fvar = 1
49832       fvar   = 1.0
49833
49834       call read_key_value(filevar,nline_ini,nline_end,"FVAR",vet,ivet,iv)
49835       if (iv /= 0) then
49836          n_fvar=iv
49837          fvar=vet
49838       end if
49839
49840       return
49841    End Subroutine Read_Shx_Fvar
49842
49843    !!----
49844    !!---- Subroutine Read_Shx_Latt(Filevar,Nline_Ini,Nline_End,Latt)
49845    !!----    character(len=*), dimension(:), intent(in) :: filevar     !  In -> String Vector
49846    !!----    integer,           intent(in out)          :: nline_ini   !  In -> Line to start the search
49847    !!----                                                                Out -> Actual line on Filevar
49848    !!----    integer,           intent(in)              :: nline_end   !  In -> Line to finish the search
49849    !!----    integer,           intent(out)             :: latt        ! Out -> Lattice number
49850    !!----
49851    !!----    Obtaining lattice from Shelx file (.ins or .res)
49852    !!----
49853    !!---- Update: February - 2005
49854    !!
49855    Subroutine Read_Shx_Latt(filevar,nline_ini,nline_end,latt)
49856       !---- Arguments ----!
49857       character(len=*), dimension(:), intent(in) :: filevar
49858       integer,           intent(in out)          :: nline_ini
49859       integer,           intent(in)              :: nline_end
49860       integer,           intent(out)             :: latt
49861
49862       !---- Local Variables ----!
49863       integer                     :: iv
49864       integer,       dimension(2) :: ivet
49865       real(kind=cp), dimension(2) :: vet
49866
49867       latt=1
49868       call read_key_value(filevar,nline_ini,nline_end,"LATT",vet,ivet,iv)
49869       if (iv == 1) latt = ivet(1)
49870
49871       return
49872    End Subroutine Read_Shx_Latt
49873
49874    !!----
49875    !!---- Subroutine Read_Shx_Symm(Filevar,Nline_Ini,Nline_End,N_Oper,Oper_Symm)
49876    !!----    character(len=*), dimension(:), intent(in) :: filevar       !  In -> String Vector
49877    !!----    integer,           intent(in out)          :: nline_ini     !  In -> Line to start the search
49878    !!----                                                                  Out -> Actual Line on Filevar
49879    !!----    integer,           intent(in)              :: nline_end     !  In -> Line to finish the search
49880    !!----    integer,           intent(out)             :: n_oper        ! Out -> Number of Operators
49881    !!----    character(len=*), dimension(:),intent(out) :: oper_symm     ! Out -> String for Symmetry Operators
49882    !!----
49883    !!----    Obtaining Symmetry Operators from Shelx file (.ins or .res)
49884    !!----
49885    !!---- Update: February - 2005
49886    !!
49887    Subroutine Read_Shx_Symm(filevar,nline_ini,nline_end,n_oper,oper_symm)
49888       !---- Arguments ----!
49889       character(len=*), dimension(:), intent(in) :: filevar
49890       integer,          intent(in out)           :: nline_ini
49891       integer,          intent(in)               :: nline_end
49892       integer,          intent(out)              :: n_oper
49893       character(len=*), dimension(:),intent(out) :: oper_symm
49894
49895       !---- Local variables ----!
49896       character(len=80) :: string
49897       integer           :: nline
49898
49899       n_oper=0
49900       oper_symm=" "
49901
49902       do
49903          call Read_Key_StrVal(filevar,nline_ini,nline_end,"SYMM",string)
49904          if (len_trim(string) /=0) then
49905             n_oper=n_oper+1
49906             oper_symm(n_oper)=string
49907             nline_ini=nline_ini+1
49908             nline=nline_ini
49909          else
49910             exit
49911          end if
49912       end do
49913       nline_ini=nline
49914
49915       return
49916    End Subroutine Read_Shx_Symm
49917
49918    !!----
49919    !!---- Subroutine Read_Shx_Titl(Filevar,Nline_Ini,Nline_End,Title)
49920    !!----    character(len=*),dimension(:), intent(in)     :: filevar      !  In -> String Vector
49921    !!----    integer,                       intent(in out) :: nline_ini    !  In -> Line to start the search
49922    !!----                                                                    Out -> Actual Line on Filevar
49923    !!----    integer,                       intent(in)     :: nline_end    !  In -> Line to finish the search
49924    !!----    character(len=*),              intent(out)    :: title        ! Out -> Title
49925    !!----
49926    !!----    Obtaining Title from Shelx file
49927    !!----
49928    !!---- Update: February - 2005
49929    !!
49930    Subroutine Read_Shx_Titl(filevar,nline_ini,nline_end,Title)
49931       !---- Arguments ----!
49932       character(len=*),dimension(:), intent(in)     :: filevar
49933       integer,                       intent(in out) :: nline_ini
49934       integer,                       intent(in)     :: nline_end
49935       character(len=*),              intent(out)    :: title
49936
49937       call Read_Key_StrVal(filevar,nline_ini,nline_end,"TITL",title)
49938
49939       return
49940    End Subroutine Read_Shx_Titl
49941
49942    !!----
49943    !!---- Subroutine Read_Uvals(Line,Atomo,Ulabel)
49944    !!----    character(len=*),  intent(in out)  :: line      !  In -> String
49945    !!----    Type (Atom_Type),  intent(in out)  :: Atomo     !  In -> Atomo variable
49946    !!----                                                      Out ->
49947    !!----    character(len=4),  intent(in)      :: ulabel    !  In -> u_ij, b_ij, beta
49948    !!----
49949    !!----    Subroutine to read the anisotropic thermal parameters from a given Line
49950    !!----    it complets the object Atomo of type Atom.
49951    !!----    Assumes the string Line has been read from a file and
49952    !!----    starts with one of the words (u_ij, b_ij or beta), that is removed before reading
49953    !!----    the values of the parameters.
49954    !!----
49955    !!---- Update: February - 2005
49956    !!
49957    Subroutine Read_Uvals(Line,Atomo,Ulabel)
49958       !---- Arguments ----!
49959       character(len=*),  intent(in )     :: line
49960       Type (Atom_Type),  intent(in out)  :: Atomo
49961       character(len=4),  intent(in)      :: ulabel
49962
49963       !---- Local variables -----!
49964       character(len=len(line)),dimension(1):: line2
49965       real(kind=cp), dimension (6)         :: vet1,vet2
49966       integer                              :: iv,n
49967
49968       call init_err_form()
49969
49970       atomo%utype    = ulabel
49971       line2(1)=line
49972       n=1
49973       call cutst(line2(1))
49974       line2(1)="Uval "//line2(1)
49975       call Read_Key_ValueSTD(line2,n,n,"Uval",vet1,vet2,iv)
49976
49977        if (iv /= 6) then
49978          err_form=.true.
49979          ERR_Form_Mess="  Error reading the anisotropic thermal parameters of atom:"//atomo%lab
49980          return
49981       end if
49982       atomo%U(1:6)=vet1(1:6)
49983       atomo%U_std(1:6)=vet2(1:6)
49984       atomo%thtype="aniso"
49985
49986       return
49987    End Subroutine Read_Uvals
49988
49989    !!--++
49990    !!--++ Subroutine Readn_Set_XTal_CFL(file_dat,nlines,Cell,SpG,A,CFrame,NPhase,Job_Info)
49991    !!--++    character(len=*),dimension(:),intent(in)   :: file_dat
49992    !!--++    integer,                      intent(in)   :: nlines
49993    !!--++    Type (Crystal_Cell_Type),     intent(out)  :: Cell
49994    !!--++    Type (Space_Group_Type),      intent(out)  :: SpG
49995    !!--++    Type (atom_list_type),        intent(out)  :: A
49996    !!--++    character(len=*),    optional,intent(in)   :: CFrame
49997    !!--++    Integer,             optional,intent( in)  :: Nphase
49998    !!--++    Type(Job_Info_type), optional,intent(out)  :: Job_Info
49999    !!--++
50000    !!--++ (Private)
50001    !!--++ Read and Set Crystal Information in a CFL File
50002    !!--++
50003    !!--++ Update: April - 2005
50004    !!
50005    Subroutine Readn_Set_XTal_CFL(file_dat,nlines,Cell,SpG,A,CFrame,NPhase,Job_Info)
50006       !---- Arguments ----!
50007       character(len=*),dimension(:),intent(in)   :: file_dat
50008       integer,                      intent(in)   :: nlines
50009       Type (Crystal_Cell_Type),     intent(out)  :: Cell
50010       Type (Space_Group_Type),      intent(out)  :: SpG
50011       Type (atom_list_type),        intent(out)  :: A
50012       character(len=*),    optional,intent(in)   :: CFrame
50013       Integer,             optional,intent( in)  :: Nphase
50014       Type(Job_Info_type), optional,intent(out)  :: Job_Info
50015
50016       !---- Local variables ----!
50017       character(len=132)               :: line
50018       character(len= 20)               :: Spp
50019       character(len= 40),dimension(192):: gen
50020       integer                          :: i, nauas, ndata, iph, n_ini,n_end,ngen,k,nsym
50021       integer, parameter               :: maxph=21  !Maximum number of phases "maxph-1"
50022       integer, dimension(maxph)        :: ip
50023
50024       real(kind=cp),dimension(3):: vet
50025
50026       !---- Standard CrysFML file *.CFL ----!
50027       nauas=0
50028       ndata=0
50029       ip=nlines
50030       ip(1)=1
50031
50032       !---- Calculating number of Phases ----!
50033       do i=1,nlines
50034          line=adjustl(file_dat(i))
50035          if (l_case(line(1:6)) == "phase_")  then
50036             ndata=ndata+1
50037             ip(ndata)=i
50038          end if
50039       end do
50040
50041       !---- Reading Phase Information ----!
50042       iph=1
50043       if (present(nphase)) iph=nphase
50044       if (present(Job_Info)) then
50045          n_ini=ip(iph)           !Updated values to handle non-conventional order
50046          n_end=ip(iph+1)
50047          call Get_Job_Info(file_dat,n_ini,n_end,Job_info)
50048       end if
50049
50050       !---- Reading Cell Parameters ----!
50051       n_ini=ip(iph)           !Updated values to handle non-conventional order
50052       n_end=ip(iph+1)
50053       if(present(CFrame)) then
50054         call read_File_Cell(file_dat,n_ini,n_end,Cell,CFrame) !Read and construct Cell
50055       else
50056         call read_File_Cell(file_dat,n_ini,n_end,Cell) !Read and construct Cell
50057       end if
50058       if (err_form) return
50059
50060       !---- Reading Space Group Information ----!
50061       n_ini=ip(iph)           !Updated values to handle non-conventional order
50062       n_end=ip(iph+1)
50063       call read_File_Spg (file_dat,n_ini,n_end,Spp)
50064       if (err_form) then !Try to read symmetry operators or generators
50065         ngen=0
50066         nsym=0
50067         do i=n_ini, n_end
50068           line=l_case(adjustl(file_dat(i)))
50069           if(line(1:4) == "symm") nsym=nsym+1
50070           if(line(1:3) == "gen")  ngen=ngen+1
50071         end do
50072         if(ngen > 0) then
50073           k=0
50074           do i=n_ini, n_end
50075             line=l_case(adjustl(file_dat(i)))
50076             if(line(1:3) == "gen")  then
50077              k=k+1
50078              gen(k)=adjustl(line(5:))
50079             end if
50080           end do
50081           call Set_SpaceGroup(" ",SpG,gen,ngen,"gen")   !Construct the space group from generators
50082         else if (nsym > 0) then
50083           k=0
50084           do i=n_ini, n_end
50085             line=l_case(adjustl(file_dat(i)))
50086             if(line(1:4) == "symm")  then
50087              k=k+1
50088              gen(k)=adjustl(line(6:))
50089             end if
50090           end do
50091           call Set_SpaceGroup(" ",SpG,gen,nsym,"fix")  !Construct the space group from fixed symmetry elements
50092         else
50093           return
50094         end if
50095       else
50096          call Set_SpaceGroup(Spp,SpG) !Construct the space group
50097       end if
50098       !---- Read Atoms Information ----!
50099       n_ini=ip(iph)           !Updated values to handle non-conventional order
50100       n_end=ip(iph+1)
50101
50102       !---- Calculating number of Atoms in the Phase ----!
50103       do i=n_ini,n_end
50104          line=adjustl(file_dat(i))
50105          if (l_case(line(1:4)) == "atom")  nauas=nauas+1
50106       end do
50107
50108       if (nauas > 0) then
50109          call Allocate_atom_list(nauas,A)  !allocation space for Atom list
50110          call read_File_Atom(file_dat,n_ini,n_end,A)
50111          if (err_form) return
50112
50113          do i=1,A%natoms
50114             vet=A%atom(i)%x
50115             A%atom(i)%Mult=Get_Multip_Pos(vet,SpG)
50116             if(A%atom(i)%occ < epss) A%atom(i)%occ=real(A%atom(i)%Mult)/real(SpG%Multip)
50117             if (A%atom(i)%thtype == "aniso") then
50118                select case (A%atom(i)%Utype)
50119                   case ("u_ij")
50120                      A%atom(i)%u(1:6) =  Convert_U_Betas(A%atom(i)%u(1:6),Cell)
50121                   case ("b_ij")
50122                      A%atom(i)%u(1:6) =  Convert_B_Betas(A%atom(i)%u(1:6),Cell)
50123                end select
50124                A%atom(i)%Utype="beta"
50125             end if
50126          end do
50127       end if
50128
50129       return
50130    End Subroutine Readn_Set_XTal_CFL
50131
50132    !!--++
50133    !!--++ Subroutine Readn_Set_XTal_CFL_Molec(file_dat, nlines, Molcrys)
50134    !!--++    character(len=*),dimension(:),  intent(in)     :: file_dat
50135    !!--++    integer,                        intent(in)     :: nlines
50136    !!--++    Type (Molecular_Crystal_Type),  intent(in out) :: Molcrys
50137    !!--++
50138    !!--++ (Private)
50139    !!--++ Read Molecule Information in a CFL
50140    !!--++
50141    !!--++ Update: April - 2005
50142    !!
50143    Subroutine Readn_Set_XTal_CFL_Molec(file_dat, nlines, Molcrys, Nphase)
50144       !---- Arguments ----!
50145       character(len=*),dimension(:),  intent(in)     :: file_dat
50146       integer,                        intent(in)     :: nlines
50147       type (Molecular_Crystal_Type),  intent(in out) :: Molcrys
50148       Integer, optional,              intent(in)     :: Nphase
50149
50150       !---- Local variables ----!
50151       character(len=132)            :: line
50152       integer                       :: i,n,nmol,npos,n_ini,n_end,ierr,nauas, iph, ndata
50153       integer, parameter               :: maxph=21  !Maximum number of phases "maxph-1"
50154       integer, dimension(maxph)        :: ip
50155       real(kind=cp)                 :: theta,phi,chi
50156       real(kind=cp), dimension(3)   :: x1f,x2f,x3f
50157       real(kind=cp), dimension(3,3) :: EuM
50158
50159       !---- Standard CrysFML file *.CFL ----!
50160       nauas=0
50161       ndata=0
50162       ip=nlines
50163       ip(1)=1
50164
50165       !---- Calculating number of Phases ----!
50166       do i=1,nlines
50167          line=adjustl(file_dat(i))
50168          if (l_case(line(1:6)) == "phase_")  then
50169             ndata=ndata+1
50170             ip(ndata)=i
50171          end if
50172       end do
50173
50174       !---- Reading Phase Information ----!
50175
50176       if (present(nphase)) then
50177           iph=nphase
50178       else
50179           iph=1
50180       end if
50181
50182       n_ini=ip(iph)
50183       n_end=ip(iph+1)
50184
50185       !---- Detecting the Molecules defined in the file ----!
50186       nmol=0
50187       do i=n_ini,n_end
50188          line=u_case(adjustl(file_dat(i)))
50189          if (line(1:1) == " ") cycle
50190          if (line(1:1) == "!") cycle
50191          npos=index(line,"MOLE")
50192          if (npos /= 0) nmol=nmol+1
50193       end do
50194       if (nmol==0) return
50195
50196       !---- Allocating Memory for all molecules ----!
50197       if (allocated(molcrys%mol)) deallocate(molcrys%mol)
50198       molcrys%n_mol=nmol
50199       allocate(molcrys%mol(nmol))
50200
50201       !---- Reading Molecules ----!
50202
50203       do n=1,nmol
50204          !---- Read ----!
50205          do i=n_ini,n_end
50206             line=u_case(adjustl(file_dat(i)))
50207             if (line(1:1) == " ") cycle
50208             if (line(1:1) == "!") cycle
50209             npos=index(line,"MOLE")
50210             if (npos == 0) cycle
50211             call read_molecule(file_dat,n_ini,n_end,molcrys%mol(n))
50212             err_form=err_molec
50213             ERR_Form_Mess=err_molec_mess
50214             if (err_form) then
50215                molcrys%n_mol=n-1
50216                return
50217             end if
50218             exit
50219          end do
50220
50221          !---- Search for three points (fractional coordinates) ----!
50222          !---- defining a Cartesian frame                       ----!
50223          do
50224             if (n_ini > n_end) exit
50225             line=adjustl(file_dat(n_ini))
50226             if (u_case(line(1:9)) == "XYZ_FRAME") then
50227                read(unit=line(10:),fmt=*,iostat=ierr) x1f,x2f,x3f
50228                if (ierr == 0) then
50229                   call get_euler_from_fract(x1f,x2f,x3f,molcrys%Cell%Cr_Orth_cel,phi,theta,chi,EuM, Code="D")
50230                   molcrys%mol(n)%orient(1)= phi
50231                   molcrys%mol(n)%orient(2)= theta
50232                   molcrys%mol(n)%orient(3)= chi
50233                   molcrys%mol(n)%xcentre= x3f
50234                   call Set_euler_matrix(molcrys%mol(n)%rot_type, phi,theta,chi,EuM)
50235                   molcrys%mol(n)%Euler=EuM
50236                   molcrys%mol(n)%is_EulerMat=.true.
50237                   molcrys%mol(n)%in_Xtal=.true.
50238                end if
50239                n_ini=n_ini+1
50240                exit
50241             else
50242                if (u_case(line(1:4)) =="MOLE") exit
50243                n_ini=n_ini+1
50244             end if
50245          end do
50246
50247       end do
50248
50249       return
50250    End Subroutine Readn_Set_XTal_CFL_Molec
50251
50252    !!--++
50253    !!--++ Subroutine Readn_Set_XTal_CIF(file_dat, nlines, Cell, Spg, A, CFrame, NPhase)
50254    !!--++    character(len=*),dimension(:),intent(in)   :: file_dat
50255    !!--++    integer,                      intent(in)   :: nlines
50256    !!--++    Type (Crystal_Cell_Type),     intent(out)  :: Cell
50257    !!--++    Type (Space_Group_Type),      intent(out)  :: SpG
50258    !!--++    Type (atom_list_type),        intent(out)  :: A
50259    !!--++    Character(len=*),    optional,intent( in)  :: CFrame
50260    !!--++    Integer,             optional,intent( in)  :: Nphase
50261    !!--++
50262    !!--++ (Private)
50263    !!--++ Read and Set Crystal Information in a CIF File
50264    !!--++
50265    !!--++ Update: April - 2005
50266    !!
50267    Subroutine Readn_Set_XTal_CIF(file_dat, nlines, Cell, Spg, A, CFrame, NPhase)
50268       !---- Arguments ----!
50269       character(len=*),dimension(:),intent(in)   :: file_dat
50270       integer,                      intent(in)   :: nlines
50271       Type (Crystal_Cell_Type),     intent(out)  :: Cell
50272       Type (Space_Group_Type),      intent(out)  :: SpG
50273       Type (atom_list_type),        intent(out)  :: A
50274       Character(len=*),    optional,intent( in)  :: CFrame
50275       Integer,             optional,intent( in)  :: Nphase
50276
50277       !---- Local Variables ----!
50278       character(len=132)                :: line
50279       character(len= 20)                :: Spp
50280       character(len=60), dimension(192) :: symm_car
50281
50282       integer                   :: i, nauas, ndata, iph, n_ini,n_end,noper
50283       integer, parameter        :: maxph=21  !Maximum number of phases "maxph-1"
50284       integer, dimension(maxph) :: ip
50285
50286       real(kind=cp),dimension(6):: vet,vet2
50287
50288       ip=nlines
50289       ip(1)=1
50290
50291       !---- First determine if there is more than one structure ----!
50292       do i=1,nlines
50293          line=adjustl(file_dat(i))
50294          if (l_case(line(1:5)) == "data_" .and. l_case(line(1:11)) /= "data_global" )  then
50295             n_ini=i
50296             ip(1)=i
50297             exit
50298          end if
50299       end do
50300
50301       ndata=0
50302       do i=n_ini,nlines
50303          line=adjustl(file_dat(i))
50304          if (l_case(line(1:5)) == "data_")  then
50305             ndata=ndata+1
50306             if (ndata > maxph-1) then
50307                err_form=.true.
50308                ERR_Form_Mess=" => Too many phases in this file "
50309                return
50310             end if
50311             ip(ndata)=i   !Pointer to the number of the line starting a single phase
50312          end if
50313       end do
50314
50315       iph=1
50316       if (present(nphase)) iph=nphase
50317
50318       !---- Read Cell Parameters ----!
50319       n_ini=ip(iph)           !Updated values to handle non-conventional order
50320       n_end=ip(iph+1)
50321       call Read_Cif_Cell(file_dat,n_ini,n_end,vet,vet2)
50322       if (err_form) return
50323       if(present(CFrame)) then
50324         call Set_Crystal_Cell(vet(1:3),vet(4:6),Cell,CFrame,vet2(1:3),vet2(4:6))
50325       else
50326         call Set_Crystal_Cell(vet(1:3),vet(4:6),Cell,"A",vet2(1:3),vet2(4:6))
50327       end if
50328       !---- Read Atoms Information ----!
50329       n_ini=ip(iph)           !Updated values to handle non-conventional order
50330       n_end=ip(iph+1)
50331       call Read_Cif_Atom(file_dat,n_ini,n_end,nauas,A)
50332       if (err_form) return
50333
50334       !---- SpaceGroup Information ----!
50335       n_ini=ip(iph)           !Updated values to handle non-conventional order
50336       n_end=ip(iph+1)
50337       call Read_Cif_Hm(file_dat,n_ini,n_end,Spp)
50338
50339       n_ini=ip(iph)           !Updated values to handle non-conventional order
50340       n_end=ip(iph+1)
50341       if (len_trim(Spp) == 0) call Read_Cif_Hall(file_dat,n_ini,n_end,Spp)
50342
50343       if (len_trim(Spp) == 0) then
50344          n_ini=ip(iph)           !Updated values to handle non-conventional order
50345          n_end=ip(iph+1)
50346          call Read_Cif_Symm(file_dat,n_ini,n_end,noper,symm_car)
50347
50348          if (noper ==0) then
50349             err_form=.true.
50350             ERR_Form_Mess=" => No Space Group/No Symmetry information in this file "
50351             return
50352          else
50353             call Set_SpaceGroup("  ",SpG,symm_car,noper,"GEN")
50354          end if
50355       else
50356          call Set_SpaceGroup(Spp,SpG) !Construct the space group
50357       end if
50358
50359       !---- Modify occupation factors and set multiplicity of atoms
50360       !---- in order to be in agreement with the definitions of Sfac in CrysFML
50361       !---- Convert Us to Betas and Uiso to Biso
50362       do i=1,A%natoms
50363          vet(1:3)=A%atom(i)%x
50364          A%atom(i)%Mult=Get_Multip_Pos(vet(1:3),SpG)
50365          A%atom(i)%Occ=A%atom(i)%Occ*real(A%atom(i)%Mult)/real(SpG%Multip)
50366          if(A%atom(i)%occ < epss) A%atom(i)%occ=real(A%atom(i)%Mult)/real(SpG%Multip)
50367
50368          select case (A%atom(i)%thtype)
50369             case ("isotr")
50370                A%atom(i)%biso= A%atom(i)%ueq*78.95683521
50371
50372             case ("aniso")
50373                select case (A%atom(i)%Utype)
50374                   case ("u_ij")
50375                      A%atom(i)%u(1:6) =  Convert_U_Betas(A%atom(i)%u(1:6),Cell)
50376                   case ("b_ij")
50377                      A%atom(i)%u(1:6) = Convert_B_Betas(A%atom(i)%u(1:6),Cell)
50378                end select
50379                A%atom(i)%Utype="beta"
50380
50381             case default
50382                A%atom(i)%biso = A%atom(i)%ueq*78.95683521
50383                A%atom(i)%thtype = "isotr"
50384          end select
50385       end do
50386
50387       return
50388    End Subroutine Readn_Set_XTal_CIF
50389
50390    !!--++
50391    !!--++ Subroutine Readn_Set_XTal_PCR(file_dat, nlines, Cell, Spg, A, CFrame, NPhase)
50392    !!--++    character(len=*),dimension(:),intent(in)   :: file_dat
50393    !!--++    integer,                      intent(in)   :: nlines
50394    !!--++    Type (Crystal_Cell_Type),     intent(out)  :: Cell
50395    !!--++    Type (Space_Group_Type),      intent(out)  :: SpG
50396    !!--++    Type (atom_list_type),        intent(out)  :: A
50397    !!--++    character(len=*),    optional,intent(in)   :: CFrame
50398    !!--++    Integer,             optional,intent( in)  :: Nphase
50399    !!--++
50400    !!--++ (Private)
50401    !!--++ Read and Set Crystal Information in a PCR File
50402    !!--++
50403    !!--++ Update: 17/05/2010
50404    !!
50405    Subroutine Readn_Set_XTal_PCR(file_dat, nlines, Cell, Spg, A, CFrame, NPhase)
50406       !---- Arguments ----!
50407       character(len=*),dimension(:),intent(in)   :: file_dat
50408       integer,                      intent(in)   :: nlines
50409       Type (Crystal_Cell_Type),     intent(out)  :: Cell
50410       Type (Space_Group_Type),      intent(out)  :: SpG
50411       Type (atom_list_type),        intent(out)  :: A
50412       character(len=*),    optional,intent(in)   :: CFrame
50413       Integer,             optional,intent(in)   :: Nphase
50414
50415       !---- Local Variables ----!
50416       logical                           :: multi,ask_phase,is_codewords
50417       character(len=132)                :: line
50418       character(len= 20)                :: Spp, label
50419       integer                           :: i,j, k,iv, nauas, ndata, iph, n_ini,n_end, nlong1
50420       integer, parameter                :: maxph=21  !Maximum number of phases "maxph-1"
50421       integer, dimension(maxph)         :: ip
50422       integer, dimension(30)            :: ivet
50423
50424       real(kind=cp),dimension(30)       :: vet
50425
50426       ip=nlines
50427       ip(1)=1
50428
50429       !> Simple / Multi format
50430       multi=.false.
50431       do i=1,nlines
50432          line=adjustl(file_dat(i))
50433          if (line(1:1) =='!' .or. line(1:1)==' ') cycle
50434          if (index(line,'NPATT ') <=0) cycle
50435          multi=.true.
50436       end do
50437
50438       !> Number of Phases
50439       if (.not. multi) then
50440          do i=2,nlines
50441             line=adjustl(file_dat(i))
50442             if (line(1:1) =='!' .or. line(1:1)==' ') cycle
50443             call getnum(line,vet,ivet,iv)
50444             if (iv > 3) then
50445                iph=ivet(3)
50446                exit
50447             end if
50448          end do
50449
50450       else
50451          do i=1,nlines
50452             line=adjustl(file_dat(i))
50453             if (line(1:4) /='!Nph') cycle
50454
50455             line=adjustl(file_dat(i+1))
50456             call getnum(line,vet,ivet,iv)
50457             if (iv > 1) then
50458                iph=ivet(1)
50459                exit
50460             end if
50461          end do
50462       end if
50463       if (iph == 0) then
50464          err_form=.true.
50465          ERR_Form_Mess=" No Phase information was found in this PCR file. Please, check it! "
50466          return
50467       end if
50468
50469       !> Locate where begin each Phase
50470       k=0
50471       ask_phase=.true.
50472
50473       do i=1,nlines
50474          line=adjustl(file_dat(i))
50475          if (ask_phase) then
50476             if (index(line,'Data for PHASE') <= 0) cycle
50477          else
50478             if (line(1:1) /='!') then
50479                k=k+1
50480                ip(k)=i
50481                if (k == iph) exit
50482
50483                ask_phase=.true.
50484             end if
50485             cycle
50486          end if
50487          ask_phase=.false.
50488       end do
50489       if (iph /= k) then
50490          err_form=.true.
50491          ERR_Form_Mess=" Locating Phases failed in this PCR. Please, check it!"
50492          return
50493       end if
50494
50495       !> Select the Phase
50496       iph=1
50497       if (present(nphase)) iph=nphase
50498       n_ini=ip(iph)
50499       n_end=ip(iph+1)
50500
50501       !---- Read Cell Parameters ----!
50502       do i=n_ini,n_end
50503          if (index(file_dat(i),'alpha') /=0 .and. index(file_dat(i),'gamma') /=0) then
50504             do j=i+1,n_end
50505                line=adjustl(file_dat(j))
50506                if (line(1:1) == '!' .or. line(1:1) == ' ') cycle
50507                iv=index(line,'#')
50508                if (iv > 1) line=line(1:iv-1)
50509
50510                call getnum(line, vet, ivet,iv)
50511                if (iv /= 6) then
50512                   err_form=.true.
50513                   ERR_Form_Mess=" => Problems reading Cell Parameters on PCR file "
50514                   return
50515                end if
50516                if(present(CFrame)) then
50517                  call Set_Crystal_Cell(vet(1:3),vet(4:6),Cell,CFrame)
50518                else
50519                  call Set_Crystal_Cell(vet(1:3),vet(4:6),Cell)
50520                end if
50521                exit
50522             end do
50523             exit
50524          end if
50525       end do
50526
50527       !---- SpaceGroup Information ----!
50528       Spp=' '
50529       do i=n_ini,n_end
50530          line=adjustl(file_dat(i))
50531          if (line(1:1) == '!' .or. line(1:1)==' ') cycle
50532          if (index(file_dat(i),'<--Space') /=0) then
50533             j=index(file_dat(i),'<--Space')
50534             Spp=adjustl(file_dat(i)(1:j-1))
50535             if (len_trim(Spp) <= 0) then
50536                err_form=.true.
50537                ERR_Form_Mess=" => Problems reading Space group on PCR file "
50538                return
50539             end if
50540             call Set_SpaceGroup(Spp,SpG) !Construct the space group
50541             exit
50542          end if
50543       end do
50544
50545       !---- Read Atoms Information ----!
50546       do i=n_ini,n_end
50547          line=adjustl(file_dat(i))
50548          if (line(1:4) /= '!Nat') cycle
50549          do j=i+1,n_end
50550             line=adjustl(file_dat(j))
50551             if (line(1:1) == '!' .or. line(1:1)==' ') cycle
50552             call getnum(line(1:5),vet,ivet,iv)
50553             ndata=ivet(1)
50554             exit
50555          end do
50556          exit
50557       end do
50558
50559       if (ndata > 0) then
50560          call allocate_atom_list(ndata,A)
50561
50562          is_codewords=.false.
50563          nauas=0
50564
50565          do i=n_ini,n_end
50566             line=adjustl(file_dat(i))
50567             if (index(line,'!Atom') == 0 .or. index(line,'Typ') == 0) cycle
50568
50569             do j=i+1,n_end
50570                line=adjustl(file_dat(j))
50571                if (line(1:1) == '!' .or. line(1:1)==' ') cycle
50572                if (is_codewords) then
50573                   is_codewords=.false.
50574                   cycle
50575                end if
50576
50577                iv=index(line,'#')
50578                if (iv > 1) line=line(1:iv-1)
50579
50580                nauas=nauas+1
50581                ! Atom Label
50582                call cutst(line,nlong1,label)
50583                A%atom(nauas)%lab=trim(label)
50584
50585                ! Atom Type
50586                call cutst(line,nlong1,label)
50587                A%Atom(nauas)%chemsymb=U_case(label(1:1))//L_case(label(2:2))
50588
50589                ! Atom Coordinates,Biso and Occ
50590                call getnum(line,vet,ivet,iv)
50591                if (iv < 5) then    !Line reading for the second time anisotropic temperature factors
50592                   nauas = nauas -1 !see below
50593                   is_codewords=.true.
50594                   cycle
50595                end if
50596
50597                A%atom(nauas)%x=vet(1:3)
50598                A%atom(nauas)%Mult=Get_Multip_Pos(vet(1:3),SpG)
50599                A%atom(nauas)%biso=vet(4)
50600                A%atom(nauas)%occ=vet(5)
50601                A%atom(nauas)%thtype='isotr'
50602                A%atom(nauas)%Utype="beta"
50603                if (ivet(8) == 2) then    ! Anisotropic reading
50604                   A%atom(nauas)%thtype='aniso'
50605                   call getnum(file_dat(j+2),vet,ivet,iv)
50606                   A%atom(nauas)%u(1:6)=vet(1:6)
50607                end if
50608                is_codewords=.true.
50609                if (nauas == ndata) exit
50610             end do
50611             exit
50612          end do
50613       end if
50614
50615       return
50616    End Subroutine Readn_Set_XTal_PCR
50617
50618    !!--++
50619    !!--++ Subroutine Readn_Set_XTal_SHX(file_dat,nlines,Cell,SpG,A,CFrame)
50620    !!--++    character(len=*),dimension(:),intent(in)   :: file_dat
50621    !!--++    integer,                      intent(in)   :: nlines
50622    !!--++    Type (Crystal_Cell_Type),     intent(out)  :: Cell
50623    !!--++    Type (Space_Group_Type),      intent(out)  :: SpG
50624    !!--++    Type (Atom_list_type),        intent(out)  :: A
50625    !!--++    Character(len=*), optional,   intent(in)   :: CFrame
50626    !!--++
50627    !!--++ (Private)
50628    !!--++ Read and Set Crystal Information in a Shelx File
50629    !!--++
50630    !!--++ Update: April - 2005
50631    !!
50632    Subroutine Readn_Set_XTal_SHX(file_dat,nlines,Cell,SpG,A,CFrame)
50633       !---- Arguments ----!
50634       character(len=*),dimension(:),intent(in)   :: file_dat
50635       integer,                      intent(in)   :: nlines
50636       Type (Crystal_Cell_Type),     intent(out)  :: Cell
50637       Type (Space_Group_Type),      intent(out)  :: SpG
50638       Type (Atom_list_type),        intent(out)  :: A
50639       Character(len=*), optional,   intent(in)   :: CFrame
50640
50641       !---- Local Variables ----!
50642       character(len=60), dimension(192) :: symm_car
50643       character(len=2),  dimension(15)  :: elem_atm
50644       integer                           :: i,n_ini, n_end, nl, noper
50645       integer                           :: n_elem_atm, n_fvar
50646       real(kind=cp), dimension(6)       :: vet,vet2
50647       real(kind=cp), dimension(10)      :: fvar
50648
50649       n_ini=1
50650       n_end=nlines
50651
50652       !---- CELL / ZERR ----!
50653       call Read_Shx_Cell(file_dat,n_ini,n_end,vet,vet2)
50654       if(present(CFrame)) then
50655         call Set_Crystal_Cell(vet(1:3),vet(4:6),Cell,CFrame,vet2(1:3),vet2(4:6))
50656       else
50657         call Set_Crystal_Cell(vet(1:3),vet(4:6),Cell,"A",vet2(1:3),vet2(4:6))
50658       end if
50659
50660       !---- OBTAIN SPACE GROUP (LATT / SYMM) ----!
50661       call Read_Shx_Latt(file_dat,n_ini,n_end,nl)
50662       call Read_Shx_Symm(file_dat,n_ini,n_end,noper,symm_car)
50663       if (nl > 0) then
50664          noper=noper+1
50665          symm_car(noper)="-X,-Y,-Z"
50666       end if
50667       select case (abs(nl))
50668          case (2) ! I
50669             noper=noper+1
50670             symm_car(noper)="X+1/2,Y+1/2,Z+1/2"
50671          case (3) ! Rom, Hex
50672             noper=noper+1
50673             symm_car(noper)="X+2/3,Y+1/3,Z+1/3"
50674             noper=noper+1
50675             symm_car(noper)="X+1/3,Y+2/3,Z+2/3"
50676          case (4) ! F
50677             noper=noper+1
50678             symm_car(noper)="X,Y+1/2,Z+1/2"
50679          case (5) ! A
50680             noper=noper+1
50681             symm_car(noper)="X,Y+1/2,Z+1/2"
50682             noper=noper+1
50683             symm_car(noper)="X+1/2,Y,Z+1/2"
50684             noper=noper+1
50685             symm_car(noper)="X+1/2,Y+1/2,Z"
50686          case (6) ! B
50687             noper=noper+1
50688             symm_car(noper)="X+1/2,Y,Z+1/2"
50689          case (7) ! C
50690             noper=noper+1
50691             symm_car(noper)="X+1/2,Y+1/2,Z"
50692       end select ! nl
50693       call set_spacegroup(" ",SPG,symm_car,noper,"gen")
50694
50695       !---- ATOMS ----!
50696       call Read_Shx_Cont(file_dat,n_ini,n_end,n_elem_atm,elem_atm)
50697       call Read_Shx_Fvar(file_dat,n_ini,n_end,n_fvar,fvar)
50698       call Read_Shx_Atom(file_dat,n_ini,n_end,n_fvar,fvar,elem_atm,cell,A)
50699       if (err_form) return
50700
50701       !---- Convert Us to Betas and Uiso to Biso
50702       do i=1,A%natoms
50703          vet(1:3)=A%atom(i)%x
50704          A%atom(i)%Mult=Get_Multip_Pos(vet(1:3),SpG)
50705
50706          select case (A%atom(i)%thtype)
50707             case ("isotr")
50708                A%atom(i)%biso= A%atom(i)%ueq*78.95683521
50709
50710             case ("aniso")
50711                A%atom(i)%ueq=U_Equiv(cell,a%atom(i)%u(1:6))  ! Uequi
50712                A%atom(i)%biso= A%atom(i)%ueq*78.95683521
50713                select case (A%atom(i)%Utype)
50714                   case ("u_ij")
50715                      A%atom(i)%u(1:6) =  Convert_U_Betas(A%atom(i)%u(1:6),Cell)
50716                   case ("b_ij")
50717                      A%atom(i)%u(1:6) = Convert_B_Betas(A%atom(i)%u(1:6),Cell)
50718                end select
50719                A%atom(i)%Utype="beta"
50720
50721             case default
50722                A%atom(i)%ueq=0.05
50723                A%atom(i)%biso = A%atom(i)%ueq*78.95683521
50724                A%atom(i)%thtype = "isotr"
50725          end select
50726       end do
50727
50728       return
50729    End Subroutine Readn_Set_XTal_SHX
50730
50731    !!--++
50732    !!--++ Subroutine Readn_Set_Xtal_Structure_Molcr(filenam,Molcrys,Mode,Iphase, Job_Info, file_list,CFrame)
50733    !!--++    character(len=*),              intent( in)     :: filenam  ! In -> Name of the file
50734    !!--++    Type (Molecular_Crystal_Type), intent(out)     :: Molcrys  ! Molecular crytal
50735    !!--++    Character(len=*),    optional, intent( in)     :: Mode     ! In -> if Mode="CIF" filenam
50736    !!--++                                                                       is of CIF type format
50737    !!--++    Integer,             optional, intent( in)     :: Iphase   ! Number of the phase.
50738    !!--++    Type(Job_Info_type), optional, intent(out)     :: Job_Info ! Diffaction conditions
50739    !!--++    Type(file_list_type),optional, intent(in out)  :: file_list! Complete file to be used by
50740    !!--++                                                              the calling program or other procedures
50741    !!--++    Character(len=*),    optional, intent(in)      :: CFrame
50742    !!--++    Overloaded
50743    !!--++    Subroutine to read and input file and construct the crystal structure
50744    !!--++    in terms of the ofjects Cell, SpG and A. The optional argument Iphase is an integer
50745    !!--++    telling to the program to read the phase number Iphase in the case of the presence
50746    !!--++    of more than one phase. If absent only the first phase is read.
50747    !!--++
50748    !!--++ Update: April - 2005
50749    !!
50750    Subroutine Readn_Set_Xtal_Structure_Molcr(filenam,Molcrys,Mode,Iphase,Job_Info,file_list,CFrame)
50751       !---- Arguments ----!
50752       character(len=*),              intent( in)     :: filenam
50753       Type (Molecular_Crystal_Type), intent(out)     :: Molcrys
50754       Character(len=*),     optional,intent( in)     :: Mode
50755       Integer,              optional,intent( in)     :: Iphase
50756       Type(Job_Info_type),  optional,intent(out)     :: Job_Info
50757       Type(file_list_type), optional,intent(in out)  :: file_list
50758       Character(len=*),     optional,intent(in)      :: CFrame
50759       !---- Local variables -----!
50760       Type (Atom_list_type)                         :: A
50761       character(len=132), allocatable, dimension(:) :: file_dat
50762       character(len=3)                              :: modec
50763       integer                                       :: i,nlines
50764
50765
50766       call init_err_form()
50767
50768       nlines=0
50769       if (present(file_list)) nlines=file_list%nlines
50770
50771       !---- Number of Lines in the input file ----!
50772       if(nlines == 0) then
50773           call Number_Lines(trim(filenam), nlines)
50774           if (nlines==0) then
50775              err_form=.true.
50776              ERR_Form_Mess="The file "//trim(filenam)//" contains nothing"
50777              return
50778           else
50779              if (allocated(file_dat)) deallocate( file_dat)
50780              allocate( file_dat(nlines))
50781              call reading_Lines(trim(filenam),nlines,file_dat)
50782           end if
50783           if (present(file_list)) then
50784              file_list%nlines=nlines
50785              if (allocated(file_list%line)) deallocate(file_list%line)
50786              allocate(file_list%line(nlines))
50787              file_list%line=file_dat
50788           end if
50789       else
50790           if (allocated(file_dat)) deallocate( file_dat)
50791           allocate( file_dat(nlines))
50792           file_dat=file_list%line
50793       end if
50794
50795
50796       !---- Define the type of file: CIF, CFL, RES,... ----!
50797       modec=" "
50798       if (present(mode)) modec=l_case(mode(1:3))
50799
50800       select case(modec)
50801           case("cif")
50802              if (present(iphase)) then
50803                 if(present(CFrame)) then
50804                   call readn_set_xtal_cif(file_dat,nlines,molcrys%Cell,molcrys%Spg, A,CFrame,NPhase=IPhase)
50805                 else
50806                   call readn_set_xtal_cif(file_dat,nlines,molcrys%Cell,molcrys%Spg, A,NPhase=IPhase)
50807                 end if
50808              else
50809                 if(present(CFrame)) then
50810                   call readn_set_xtal_cif(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame)
50811                 else
50812                   call readn_set_xtal_cif(file_dat,nlines,molcrys%Cell,molcrys%Spg,A)
50813                 end if
50814              end if
50815
50816           case("pcr")
50817              if (present(iphase)) then
50818                 if(present(CFrame)) then
50819                   call readn_set_xtal_pcr(file_dat,nlines,molcrys%Cell,molcrys%Spg, A,CFrame,NPhase=IPhase)
50820                 else
50821                   call readn_set_xtal_pcr(file_dat,nlines,molcrys%Cell,molcrys%Spg, A,NPhase=IPhase)
50822                 end if
50823              else
50824                 if(present(CFrame)) then
50825                   call readn_set_xtal_pcr(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame)
50826                 else
50827                   call readn_set_xtal_pcr(file_dat,nlines,molcrys%Cell,molcrys%Spg,A)
50828                 end if
50829              end if
50830
50831           case("shx")
50832              if(present(CFrame)) then
50833                call readn_set_xtal_shx(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame)
50834              else
50835                call readn_set_xtal_shx(file_dat,nlines,molcrys%Cell,molcrys%Spg,A)
50836              end if
50837           case default
50838              !---- CFL Format ----!
50839              if (present(Job_Info)) then
50840                 if (present(iphase)) then
50841                    if(present(CFrame)) then
50842                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame,NPhase=IPhase,Job_Info=Job_Info)
50843                    else
50844                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,NPhase=IPhase,Job_Info=Job_Info)
50845                    end if
50846                 else
50847                    if(present(CFrame)) then
50848                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame,Job_Info=Job_Info)
50849                    else
50850                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,Job_Info=Job_Info)
50851                    end if
50852                 end if
50853              else
50854                 if (present(iphase)) then
50855                    if(present(CFrame)) then
50856                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame,NPhase=IPhase)
50857                    else
50858                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,NPhase=IPhase)
50859                    end if
50860                 else
50861                    if(present(CFrame)) then
50862                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A,CFrame)
50863                    else
50864                      call readn_set_xtal_cfl(file_dat,nlines,molcrys%Cell,molcrys%Spg,A)
50865                    end if
50866                 end if
50867              end if
50868              !---- Reading molecules ----!
50869              if (present(iphase)) then
50870                call readn_set_xtal_cfl_molec(file_dat,nlines,molcrys,NPhase=IPhase)
50871              else
50872                call readn_set_xtal_cfl_molec(file_dat,nlines,molcrys)
50873              end if
50874
50875       end select
50876       if (err_form) return
50877
50878       !---- Passing from Atom_List_Type -> Molcrys ----!
50879       molcrys%n_free=A%natoms
50880       if (A%natoms > 0) then
50881          if (allocated(molcrys%Atm)) deallocate(molcrys%Atm)
50882          allocate(molcrys%Atm(A%natoms))
50883          molcrys%Atm=A%Atom
50884       end if
50885
50886       call deallocate_atom_list(A)
50887
50888       !---- Testing if Xtal was defined ----!
50889       if (all(molcrys%cell%cell > 0.0)) then
50890          do i=1,molcrys%n_mol
50891             if (.not. molcrys%mol(i)%in_xtal) then
50892                 molcrys%mol(i)%in_xtal=.true.
50893             end if
50894          end do
50895       end if
50896
50897       return
50898    End Subroutine Readn_Set_Xtal_Structure_Molcr
50899
50900    !!--++
50901    !!--++ Subroutine Readn_Set_Xtal_Structure_Split(filenam,Cell,SpG,A,Mode,Iphase,Job_Type,File_List,CFrame)
50902    !!--++    character(len=*),              intent( in)     :: filenam  ! In -> Name of the file
50903    !!--++    Type (Crystal_Cell_Type),      intent(out)     :: Cell     ! Out -> Cell object
50904    !!--++    Type (Space_Group_Type),       intent(out)     :: SpG      ! Out -> Space Group object
50905    !!--++    Type (atom_list_type),         intent(out)     :: A        ! Out -> Atom_List object
50906    !!--++    Character(len=*),    optional, intent( in)     :: Mode     ! In -> if Mode="CIF" filenam
50907    !!--++                                                                       is of CIF type format
50908    !!--++    Integer,             optional, intent( in)     :: Iphase   ! Number of the phase.
50909    !!--++    Type(Job_Info_type), optional, intent(out)     :: Job_Info ! Diffaction conditions
50910    !!--++    Type(file_list_type),optional, intent(in out)  :: file_list! Complete file to be used by
50911    !!--++                                                                 the calling program or other procedures
50912    !!--++    Character(len=*),    optional, intent( in)     :: CFrame   !Cartesian Frame
50913    !!--++
50914    !!--++    Overloaded
50915    !!--++    Subroutine to read and input file and construct the crystal structure
50916    !!--++    in terms of the ofjects Cell, SpG and A. The optional argument Iphase is an integer
50917    !!--++    telling to the program to read the phase number Iphase in the case of the presence
50918    !!--++    of more than one phase. If absent only the first phase is read.
50919    !!--++
50920    !!--++ Update: April - 2005
50921    !!
50922    Subroutine Readn_Set_Xtal_Structure_Split(filenam,Cell,SpG,A,Mode,Iphase,Job_Info,file_list,CFrame)
50923       !---- Arguments ----!
50924       character(len=*),             intent( in)     :: filenam
50925       Type (Crystal_Cell_Type),     intent(out)     :: Cell
50926       Type (Space_Group_Type),      intent(out)     :: SpG
50927       Type (atom_list_type),        intent(out)     :: A
50928       Character(len=*),    optional,intent( in)     :: Mode
50929       Integer,             optional,intent( in)     :: Iphase
50930       Type(Job_Info_type), optional,intent(out)     :: Job_Info
50931       Type(file_list_type),optional,intent(in out)  :: file_list
50932       Character(len=*),    optional,intent( in)     :: CFrame
50933
50934       !---- Local variables -----!
50935       character(len=132), allocatable, dimension(:) :: file_dat
50936       character(len=3)                              :: modec
50937       integer                                       :: nlines
50938
50939       call init_err_form()
50940
50941       nlines=0
50942       if (present(file_list)) nlines=file_list%nlines
50943
50944       !---- Number of Lines in the input file ----!
50945       if(nlines == 0) then
50946           call Number_Lines(trim(filenam), nlines)
50947           if (nlines==0) then
50948              err_form=.true.
50949              ERR_Form_Mess="The file "//trim(filenam)//" contains nothing"
50950              return
50951           else
50952              if (allocated(file_dat)) deallocate( file_dat)
50953              allocate( file_dat(nlines))
50954              call reading_Lines(trim(filenam),nlines,file_dat)
50955           end if
50956           if (present(file_list)) then
50957              file_list%nlines=nlines
50958              if (allocated(file_list%line)) deallocate(file_list%line)
50959              allocate(file_list%line(nlines))
50960              file_list%line=file_dat
50961           end if
50962       else
50963           if (allocated(file_dat)) deallocate( file_dat)
50964           allocate( file_dat(nlines))
50965           file_dat=file_list%line
50966       end if
50967
50968       !---- Define the type of file: CIF, CFL, RES,... ----!
50969       modec=" "
50970       if (present(mode)) modec=l_case(mode(1:3))
50971
50972       select case(modec)
50973           case("cif")
50974              if (present(iphase)) then
50975                 if(present(CFrame)) then
50976                   call readn_set_xtal_cif(file_dat,nlines,Cell,Spg, A,CFrame,NPhase=IPhase)
50977                 else
50978                   call readn_set_xtal_cif(file_dat,nlines,Cell,Spg, A,NPhase=IPhase)
50979                 end if
50980              else
50981                 if(present(CFrame)) then
50982                   call readn_set_xtal_cif(file_dat,nlines,Cell,Spg,A,CFrame)
50983                 else
50984                   call readn_set_xtal_cif(file_dat,nlines,Cell,Spg,A)
50985                 end if
50986              end if
50987
50988           case("pcr")
50989              if (present(iphase)) then
50990                 if(present(CFrame)) then
50991                   call readn_set_xtal_pcr(file_dat,nlines,Cell,Spg, A,CFrame,NPhase=IPhase)
50992                 else
50993                   call readn_set_xtal_pcr(file_dat,nlines,Cell,Spg, A,NPhase=IPhase)
50994                 end if
50995              else
50996                 if(present(CFrame)) then
50997                   call readn_set_xtal_pcr(file_dat,nlines,Cell,Spg,A,CFrame)
50998                 else
50999                   call readn_set_xtal_pcr(file_dat,nlines,Cell,Spg,A)
51000                 end if
51001              end if
51002
51003           case("shx")
51004              if(present(CFrame)) then
51005                call readn_set_xtal_shx(file_dat,nlines,Cell,Spg,A,CFrame)
51006              else
51007                call readn_set_xtal_shx(file_dat,nlines,Cell,Spg,A)
51008              end if
51009           case default
51010              !---- CFL Format ----!
51011              if (present(Job_Info)) then
51012                 if (present(iphase)) then
51013                    if(present(CFrame)) then
51014                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,CFrame,NPhase=IPhase,Job_Info=Job_Info)
51015                    else
51016                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,NPhase=IPhase,Job_Info=Job_Info)
51017                    end if
51018                 else
51019                    if(present(CFrame)) then
51020                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,CFrame,Job_Info=Job_Info)
51021                    else
51022                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,Job_Info=Job_Info)
51023                    end if
51024                 end if
51025              else
51026                 if (present(iphase)) then
51027                    if(present(CFrame)) then
51028                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,CFrame,NPhase=IPhase)
51029                    else
51030                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,NPhase=IPhase)
51031                    end if
51032                 else
51033                    if(present(CFrame)) then
51034                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A,CFrame)
51035                    else
51036                      call readn_set_xtal_cfl(file_dat,nlines,Cell,Spg,A)
51037                    end if
51038                 end if
51039              end if
51040
51041       end select
51042
51043       return
51044    End Subroutine Readn_Set_Xtal_Structure_Split
51045
51046    !!----
51047    !!---- Subroutine Write_Cif_Powder_Profile(Filename,Code)
51048    !!----    character(len=*), intent(in) :: filename     !  In -> Name of File
51049    !!----    integer,     intent(in)      :: code         !  In -> 0 Shelxs-Patterson
51050    !!----                                                          1 Shelxs-Direct Methods
51051    !!----                                                          2 Shelxl-Refinement
51052    !!----
51053    !!----    Write a Cif Powder Profile file
51054    !!----
51055    !!---- Update: February - 2005
51056    !!
51057    Subroutine Write_Cif_Powder_Profile(filename,code)
51058       !---- Arguments ----!
51059       character(len=*), intent(in) :: filename
51060       integer,          intent(in) :: code
51061
51062       !---- Local Variables ----!
51063       logical :: info
51064
51065       integer :: iunit !,nlong
51066
51067       !---- Inicializacion de variables ----!
51068       info=.false.
51069       iunit=0
51070
51071       !---- Esta abierto este Fichero? ----!
51072       inquire(file=filename,opened=info)
51073       if (info) then
51074          inquire(file=filename,number=iunit)
51075          close(unit=iunit)
51076       end if
51077
51078       !---- Escritura ----!
51079       if (iunit==0) iunit=61
51080       open(unit=iunit,file=filename,status="unknown",action="write")
51081       rewind(unit=iunit)
51082
51083       !---- Head ----!
51084       write(unit=iunit,fmt="(a)") "data_profile"
51085
51086       write(unit=iunit,fmt="(a)") " "
51087       if (code == 0) then
51088          write(unit=iunit,fmt="(a)")     "_pd_block_id      ?"
51089       else
51090          write(unit=iunit,fmt="(a,i3)")  "_pd_block_id       ",code
51091       end if
51092
51093       !---- Profile ----!
51094       write(unit=iunit,fmt="(a)") " "
51095
51096       write(unit=iunit,fmt="(a)") "loop_"
51097       write(unit=iunit,fmt="(a)") "_pd_proc_point_id"
51098       write(unit=iunit,fmt="(a)") "_pd_proc_2theta_corrected             # one of "
51099       write(unit=iunit,fmt="(a)") "_pd_proc_energy_incident              # these "
51100       write(unit=iunit,fmt="(a)") "_pd_proc_d_spacing                    # three"
51101       write(unit=iunit,fmt="(a)") "_pd_proc_intensity_net"
51102       write(unit=iunit,fmt="(a)") "_pd_calc_intensity_net "
51103       write(unit=iunit,fmt="(a)") "_pd_proc_ls_weight      "
51104       write(unit=iunit,fmt="(a)") "?     ?     ?     ?     ?     ?     ?"
51105
51106       write(unit=iunit,fmt="(a)") " "
51107       write(unit=iunit,fmt="(a)") "# The following lines are used to test the character set of files sent by     "
51108       write(unit=iunit,fmt="(a)") "# network email or other means. They are not part of the CIF data set.        "
51109       write(unit=iunit,fmt="(a)") "# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789              "
51110       write(unit=iunit,fmt="(a)") "# !@#$%^&*()_+{}:"//""""//"~<>?|\-=[];'`,./ "
51111
51112       close (unit=iunit)
51113
51114       return
51115    End Subroutine Write_Cif_Powder_Profile
51116
51117    !!----
51118    !!---- Subroutine Write_Cif_Template(filename,type_data,code,cell,SpG,A)
51119    !!----    character(len=*),        intent(in) :: filename   !  In -> Filename
51120    !!----    integer,                 intent(in) :: type_data  !  In -> 0: Single Crystal, 1: Powder Data, 2:Only structural data
51121    !!----    character(len=*),        intent(in) :: code       !  In -> Code name for the data set
51122    !!----    Type (Crystal_Cell_Type),intent(in) :: Cell       ! Cell type to be output
51123    !!----    Type (Space_Group_Type), intent(in) :: SpG        ! Space group type to be output
51124    !!----    Type (Atom_List_Type),   intent(in) :: A          ! Atom list type to be output
51125    !!----
51126    !!----    Write a Cif File
51127    !!----
51128    !!---- Updated: February - 2005, January 2015
51129    !!
51130    Subroutine Write_Cif_Template(filename,type_data,code,cell,SpG,A)
51131       !---- Arguments ----!
51132       character(len=*),        intent(in) :: filename
51133       integer,                 intent(in) :: type_data
51134       character(len=*),        intent(in) :: code
51135       Type (Crystal_Cell_Type),intent(in) :: Cell
51136       Type (Space_Group_Type), intent(in) :: SpG
51137       Type (Atom_List_Type),   intent(in) :: A
51138
51139       !---- Local Variables ----!
51140       logical                           :: info,aniso
51141       character(len=132)                :: line
51142       character(len=1), parameter       :: qmark='?'
51143       character(len=30)                 :: comm,adptyp
51144       character(len=30),dimension(6)    :: text
51145       real(kind=cp)                     :: u,su, ocf
51146       real(kind=cp), dimension(6)       :: Ua,sua,aux
51147       real(kind=cp), dimension(A%natoms):: occup,soccup
51148       integer                           :: iunit,i, j
51149
51150       !---- Initialization of variables ----!
51151       info=.false.
51152       iunit=0
51153
51154       !---- Is this file opened? ----!
51155       inquire(file=filename,opened=info)
51156       if (info) then
51157          inquire(file=filename,number=iunit)
51158          close(unit=iunit)
51159       end if
51160
51161       !---- Writing ----!
51162       if (iunit==0) iunit=61
51163       open(unit=iunit,file=filename,status="unknown",action="write")
51164       rewind(unit=iunit)
51165
51166       !---- Head Information ----!
51167       if(type_data == 0) then
51168           write(unit=iunit,fmt="(a)") "##############################################################################"
51169           write(unit=iunit,fmt="(a)") "###    CIF submission form for molecular structure report (Acta Cryst. C)  ###"
51170           write(unit=iunit,fmt="(a)") "##############################################################################"
51171           write(unit=iunit,fmt="(a)") " "
51172           write(unit=iunit,fmt="(a)") "#============================================================================="
51173           write(unit=iunit,fmt="(a)") "data_global"
51174           write(unit=iunit,fmt="(a)") "#============================================================================="
51175           write(unit=iunit,fmt="(a)") " "
51176          else if(type_data > 1) then
51177           write(unit=iunit,fmt="(a)") "##################################################################"
51178           write(unit=iunit,fmt="(a)") "###    CIF file from CrysFML, contains only structural data    ###"
51179           write(unit=iunit,fmt="(a)") "##################################################################"
51180
51181       end if
51182
51183       !---- Processing Summary ----!
51184       if(type_data < 2) then
51185         write(unit=iunit,fmt="(a)") "# PROCESSING SUMMARY (IUCr Office Use Only)"
51186
51187         write(unit=iunit,fmt="(a)") " "
51188         write(unit=iunit,fmt="(a)") "_journal_data_validation_number      ?"
51189
51190         write(unit=iunit,fmt="(a)") " "
51191         write(unit=iunit,fmt="(a)") "_journal_date_recd_electronic        ?"
51192         write(unit=iunit,fmt="(a)") "_journal_date_to_coeditor            ?"
51193         write(unit=iunit,fmt="(a)") "_journal_date_from_coeditor          ?"
51194         write(unit=iunit,fmt="(a)") "_journal_date_accepted               ?"
51195         write(unit=iunit,fmt="(a)") "_journal_date_printers_first         ?"
51196         write(unit=iunit,fmt="(a)") "_journal_date_printers_final         ?"
51197         write(unit=iunit,fmt="(a)") "_journal_date_proofs_out             ?"
51198         write(unit=iunit,fmt="(a)") "_journal_date_proofs_in              ?"
51199         write(unit=iunit,fmt="(a)") "_journal_coeditor_name               ?"
51200         write(unit=iunit,fmt="(a)") "_journal_coeditor_code               ?"
51201         write(unit=iunit,fmt="(a)") "_journal_coeditor_notes"
51202         write(unit=iunit,fmt="(a)") "; ?"
51203         write(unit=iunit,fmt="(a)") ";"
51204         write(unit=iunit,fmt="(a)") "_journal_techeditor_code             ?"
51205         write(unit=iunit,fmt="(a)") "_journal_techeditor_notes"
51206         write(unit=iunit,fmt="(a)") "; ?"
51207         write(unit=iunit,fmt="(a)") ";"
51208         write(unit=iunit,fmt="(a)") "_journal_coden_ASTM                  ?"
51209         write(unit=iunit,fmt="(a)") "_journal_name_full                   ?"
51210         write(unit=iunit,fmt="(a)") "_journal_year                        ?"
51211         write(unit=iunit,fmt="(a)") "_journal_volume                      ?"
51212         write(unit=iunit,fmt="(a)") "_journal_issue                       ?"
51213         write(unit=iunit,fmt="(a)") "_journal_page_first                  ?"
51214         write(unit=iunit,fmt="(a)") "_journal_page_last                   ?"
51215         write(unit=iunit,fmt="(a)") "_journal_paper_category              ?"
51216         write(unit=iunit,fmt="(a)") "_journal_suppl_publ_number           ?"
51217         write(unit=iunit,fmt="(a)") "_journal_suppl_publ_pages            ?"
51218
51219         write(unit=iunit,fmt="(a)") " "
51220         write(unit=iunit,fmt="(a)") "#============================================================================="
51221         write(unit=iunit,fmt="(a)") " "
51222
51223         !---- Submission details ----!
51224         write(unit=iunit,fmt="(a)") "# 1. SUBMISSION DETAILS"
51225         write(unit=iunit,fmt="(a)") " "
51226
51227         write(unit=iunit,fmt="(a)") "_publ_contact_author_name            ?   # Name of author for correspondence"
51228         write(unit=iunit,fmt="(a)") "_publ_contact_author_address             # Address of author for correspondence"
51229         write(unit=iunit,fmt="(a)") "; ?"
51230         write(unit=iunit,fmt="(a)") ";"
51231         write(unit=iunit,fmt="(a)") "_publ_contact_author_email           ?"
51232         write(unit=iunit,fmt="(a)") "_publ_contact_author_fax             ?"
51233         write(unit=iunit,fmt="(a)") "_publ_contact_author_phone           ?"
51234
51235         write(unit=iunit,fmt="(a)") " "
51236         write(unit=iunit,fmt="(a)") "_publ_contact_letter"
51237         write(unit=iunit,fmt="(a)") "; ?"
51238         write(unit=iunit,fmt="(a)") ";"
51239
51240         write(unit=iunit,fmt="(a)") " "
51241         write(unit=iunit,fmt="(a)") "_publ_requested_journal              ?"
51242         write(unit=iunit,fmt="(a)") "_publ_requested_coeditor_name        ?"
51243         write(unit=iunit,fmt="(a)") "_publ_requested_category             ?   # Acta C: one of CI/CM/CO/FI/FM/FO"
51244
51245         write(unit=iunit,fmt="(a)") "#=============================================================================="
51246         write(unit=iunit,fmt="(a)") " "
51247
51248         !---- Title  and Author List ----!
51249         write(unit=iunit,fmt="(a)") "# 3. TITLE AND AUTHOR LIST"
51250
51251         write(unit=iunit,fmt="(a)") " "
51252         write(unit=iunit,fmt="(a)") "_publ_section_title"
51253         write(unit=iunit,fmt="(a)") "; ?"
51254         write(unit=iunit,fmt="(a)") ";"
51255         write(unit=iunit,fmt="(a)") "_publ_section_title_footnote"
51256         write(unit=iunit,fmt="(a)") ";"
51257         write(unit=iunit,fmt="(a)") ";"
51258
51259         write(unit=iunit,fmt="(a)") " "
51260         write(unit=iunit,fmt="(a)") "# The loop structure below should contain the names and addresses of all "
51261         write(unit=iunit,fmt="(a)") "# authors, in the required order of publication. Repeat as necessary."
51262
51263         write(unit=iunit,fmt="(a)") " "
51264         write(unit=iunit,fmt="(a)") "loop_"
51265         write(unit=iunit,fmt="(a)") "    _publ_author_name"
51266         write(unit=iunit,fmt="(a)") "    _publ_author_footnote"
51267         write(unit=iunit,fmt="(a)") "    _publ_author_address"
51268         write(unit=iunit,fmt="(a)") "?                                   #<--'Last name, first name' "
51269         write(unit=iunit,fmt="(a)") "; ?"
51270         write(unit=iunit,fmt="(a)") ";"
51271         write(unit=iunit,fmt="(a)") "; ?"
51272         write(unit=iunit,fmt="(a)") ";"
51273
51274         write(unit=iunit,fmt="(a)") " "
51275         write(unit=iunit,fmt="(a)") "#============================================================================="
51276         write(unit=iunit,fmt="(a)") " "
51277
51278         !---- Text ----!
51279         write(unit=iunit,fmt="(a)") "# 4. TEXT"
51280
51281         write(unit=iunit,fmt="(a)") " "
51282         write(unit=iunit,fmt="(a)") "_publ_section_synopsis"
51283         write(unit=iunit,fmt="(a)") ";  ?"
51284         write(unit=iunit,fmt="(a)") ";"
51285         write(unit=iunit,fmt="(a)") "_publ_section_abstract"
51286         write(unit=iunit,fmt="(a)") "; ?"
51287         write(unit=iunit,fmt="(a)") ";          "
51288         write(unit=iunit,fmt="(a)") "_publ_section_comment"
51289         write(unit=iunit,fmt="(a)") "; ?"
51290         write(unit=iunit,fmt="(a)") ";"
51291         write(unit=iunit,fmt="(a)") "_publ_section_exptl_prep      # Details of the preparation of the sample(s)"
51292         write(unit=iunit,fmt="(a)") "                              # should be given here. "
51293         write(unit=iunit,fmt="(a)") "; ?"
51294         write(unit=iunit,fmt="(a)") ";"
51295         write(unit=iunit,fmt="(a)") "_publ_section_exptl_refinement"
51296         write(unit=iunit,fmt="(a)") "; ?"
51297         write(unit=iunit,fmt="(a)") ";"
51298         write(unit=iunit,fmt="(a)") "_publ_section_references"
51299         write(unit=iunit,fmt="(a)") "; ?"
51300         write(unit=iunit,fmt="(a)") ";"
51301         write(unit=iunit,fmt="(a)") "_publ_section_figure_captions"
51302         write(unit=iunit,fmt="(a)") "; ?"
51303         write(unit=iunit,fmt="(a)") ";"
51304         write(unit=iunit,fmt="(a)") "_publ_section_acknowledgements"
51305         write(unit=iunit,fmt="(a)") "; ?"
51306         write(unit=iunit,fmt="(a)") ";"
51307
51308         write(unit=iunit,fmt="(a)") " "
51309         write(unit=iunit,fmt="(a)") "#============================================================================="
51310         write(unit=iunit,fmt="(a)") " "
51311
51312         !---- Identifier ----!
51313         write(unit=iunit,fmt="(a)") "#============================================================================="
51314         write(unit=iunit,fmt="(a)") "# If more than one structure is reported, the remaining sections should be "
51315         write(unit=iunit,fmt="(a)") "# completed per structure. For each data set, replace the '?' in the"
51316         write(unit=iunit,fmt="(a)") "# data_? line below by a unique identifier."
51317       end if !type_data < 2
51318
51319       write(unit=iunit,fmt="(a)") " "
51320       if (len_trim(code) == 0) then
51321          write(unit=iunit,fmt="(a)") "data_?"
51322       else
51323          write(unit=iunit,fmt="(a)") "data_"//code(1:len_trim(code))
51324       end if
51325       write(unit=iunit,fmt="(a)") " "
51326       if(type_data < 2) then
51327         write(unit=iunit,fmt="(a)") " "
51328         write(unit=iunit,fmt="(a)") "#============================================================================="
51329         write(unit=iunit,fmt="(a)") " "
51330
51331         !---- Chemical Data ----!
51332         write(unit=iunit,fmt="(a)") "# 5. CHEMICAL DATA"
51333
51334         write(unit=iunit,fmt="(a)") " "
51335         write(unit=iunit,fmt="(a)") "_chemical_name_systematic"
51336         write(unit=iunit,fmt="(a)") "; ?"
51337         write(unit=iunit,fmt="(a)") ";"
51338         write(unit=iunit,fmt="(a)") "_chemical_name_common             ?"
51339         write(unit=iunit,fmt="(a)") "_chemical_formula_moiety          ?"
51340         write(unit=iunit,fmt="(a)") "_chemical_formula_structural      ?"
51341         write(unit=iunit,fmt="(a)") "_chemical_formula_analytical      ?"
51342         write(unit=iunit,fmt="(a)") "_chemical_formula_iupac           ?"
51343         write(unit=iunit,fmt="(a)") "_chemical_formula_sum             ?"
51344         write(unit=iunit,fmt="(a)") "_chemical_formula_weight          ?"
51345         write(unit=iunit,fmt="(a)") "_chemical_melting_point           ?"
51346         write(unit=iunit,fmt="(a)") "_chemical_compound_source         ?       # for minerals and "
51347         write(unit=iunit,fmt="(a)") "                                          # natural products"
51348
51349         write(unit=iunit,fmt="(a)") " "
51350         write(unit=iunit,fmt="(a)") "loop_"
51351         write(unit=iunit,fmt="(a)") "    _atom_type_symbol               "
51352         write(unit=iunit,fmt="(a)") "    _atom_type_description          "
51353         write(unit=iunit,fmt="(a)") "    _atom_type_scat_dispersion_real "
51354         write(unit=iunit,fmt="(a)") "    _atom_type_scat_dispersion_imag "
51355         write(unit=iunit,fmt="(a)") "    _atom_type_scat_source          "
51356         write(unit=iunit,fmt="(a)") "    _atom_type_scat_length_neutron       # include if applicable"
51357         write(unit=iunit,fmt="(a)") "    ?    ?    ?    ?    ?      ?    "
51358
51359       end if !type_data < 2
51360       write(unit=iunit,fmt="(a)") " "
51361       write(unit=iunit,fmt="(a)") "#============================================================================="
51362       write(unit=iunit,fmt="(a)") " "
51363       !---- Crystal Data ----!
51364       select case (type_data)
51365          case (0,2) ! Single Crystal or structural data only
51366             write(unit=iunit,fmt="(a)") "# 6. CRYSTAL DATA"
51367          case (1) ! Powder Data + Crystal Data
51368             write(unit=iunit,fmt="(a)") "# 6. POWDER SPECIMEN AND CRYSTAL DATA"
51369       end select
51370
51371       write(unit=iunit,fmt="(a)") " "
51372       write(unit=iunit,fmt="(a)") "_symmetry_cell_setting               ?"
51373       line=SpG%SPG_Symb
51374       write(unit=iunit,fmt="(a)") "_symmetry_space_group_name_H-M       '"//trim(line)//"'"
51375       line=SpG%Hall
51376       write(unit=iunit,fmt="(a)") "_symmetry_space_group_name_Hall      '"//trim(line)//"'"
51377
51378       write(unit=iunit,fmt="(a)") " "
51379       write(unit=iunit,fmt="(a)") "loop_"
51380       write(unit=iunit,fmt="(a)") "    _symmetry_equiv_pos_as_xyz   #<--must include 'x,y,z'"
51381       do i=1,SpG%multip
51382          line="'"//trim(SpG%SymopSymb(i))//"'"
51383          write(iunit,'(a)') trim(line)
51384       end do
51385
51386       write(unit=iunit,fmt="(a)") " "
51387       do i=1,3
51388          call setnum_std(Cell%cell(i),Cell%cell_std(i),text(i))
51389       end do
51390       do i=1,3
51391          call setnum_std(Cell%ang(i),Cell%ang_std(i),text(i+3))
51392       end do
51393       write(iunit,'(a)') "_cell_length_a                       "//trim(adjustl(text(1)))
51394       write(iunit,'(a)') "_cell_length_b                       "//trim(adjustl(text(2)))
51395       write(iunit,'(a)') "_cell_length_c                       "//trim(adjustl(text(3)))
51396       write(iunit,'(a)') "_cell_angle_alpha                    "//trim(adjustl(text(4)))
51397       write(iunit,'(a)') "_cell_angle_beta                     "//trim(adjustl(text(5)))
51398       write(iunit,'(a)') "_cell_angle_gamma                    "//trim(adjustl(text(6)))
51399
51400       write(unit=iunit,fmt="(a,f14.4)") "_cell_volume                   ",Cell%CellVol
51401       if(type_data < 2) then
51402         write(unit=iunit,fmt="(a)") "_cell_formula_units_Z                ?"
51403         write(unit=iunit,fmt="(a)") "_cell_measurement_temperature        ?"
51404         write(unit=iunit,fmt="(a)") "_cell_special_details"
51405         write(unit=iunit,fmt="(a)") "; ?"
51406         write(unit=iunit,fmt="(a)") ";"
51407       end if
51408
51409       select case (type_data)
51410          case (0) ! Single Crystal
51411             write(unit=iunit,fmt="(a)") "_cell_measurement_reflns_used        ?"
51412             write(unit=iunit,fmt="(a)") "_cell_measurement_theta_min          ?"
51413             write(unit=iunit,fmt="(a)") "_cell_measurement_theta_max          ?"
51414
51415             write(unit=iunit,fmt="(a)") " "
51416             write(unit=iunit,fmt="(a)") "_exptl_crystal_description           ?"
51417             write(unit=iunit,fmt="(a)") "_exptl_crystal_colour                ?"
51418             write(unit=iunit,fmt="(a)") "_exptl_crystal_size_max              ?"
51419             write(unit=iunit,fmt="(a)") "_exptl_crystal_size_mid              ?"
51420             write(unit=iunit,fmt="(a)") "_exptl_crystal_size_min              ?"
51421             write(unit=iunit,fmt="(a)") "_exptl_crystal_size_rad              ?"
51422             write(unit=iunit,fmt="(a)") "_exptl_crystal_density_diffrn        ?"
51423             write(unit=iunit,fmt="(a)") "_exptl_crystal_density_meas          ?"
51424             write(unit=iunit,fmt="(a)") "_exptl_crystal_density_method        ?"
51425             write(unit=iunit,fmt="(a)") "_exptl_crystal_F_000                 ?"
51426
51427          case (1) ! Powder Data
51428             write(unit=iunit,fmt="(a)") "# The next three fields give the specimen dimensions in mm.  The equatorial"
51429             write(unit=iunit,fmt="(a)") "# plane contains the incident and diffracted beam."
51430
51431             write(unit=iunit,fmt="(a)") " "
51432             write(unit=iunit,fmt="(a)") "_pd_spec_size_axial               ?       # perpendicular to "
51433             write(unit=iunit,fmt="(a)") "                                          # equatorial plane"
51434
51435             write(unit=iunit,fmt="(a)") "_pd_spec_size_equat               ?       # parallel to "
51436             write(unit=iunit,fmt="(a)") "                                          # scattering vector"
51437             write(unit=iunit,fmt="(a)") "                                          # in transmission"
51438             write(unit=iunit,fmt="(a)") "_pd_spec_size_thick               ?       # parallel to "
51439             write(unit=iunit,fmt="(a)") "                                          # scattering vector"
51440             write(unit=iunit,fmt="(a)") "                                          # in reflection"
51441
51442             write(unit=iunit,fmt="(a)") " "
51443             write(unit=iunit,fmt="(a)") "# The next five fields are character fields that describe the specimen."
51444
51445             write(unit=iunit,fmt="(a)") " "
51446             write(unit=iunit,fmt="(a)") "_pd_spec_mounting                         # This field should be"
51447             write(unit=iunit,fmt="(a)") "                                          # used to give details of the "
51448             write(unit=iunit,fmt="(a)") "                                          # container."
51449             write(unit=iunit,fmt="(a)") "; ?"
51450             write(unit=iunit,fmt="(a)") ";"
51451             write(unit=iunit,fmt="(a)") "_pd_spec_mount_mode               ?       # options are 'reflection'"
51452             write(unit=iunit,fmt="(a)") "                                          # or 'transmission'"
51453             write(unit=iunit,fmt="(a)") "_pd_spec_shape                    ?       # options are 'cylinder' "
51454             write(unit=iunit,fmt="(a)") "                                          # 'flat_sheet' or 'irregular'"
51455             write(unit=iunit,fmt="(a)") "_pd_char_particle_morphology      ?"
51456             write(unit=iunit,fmt="(a)") "_pd_char_colour                   ?       # use ICDD colour descriptions"
51457
51458             write(unit=iunit,fmt="(a)") " "
51459             write(unit=iunit,fmt="(a)") "# The following three fields describe the preparation of the specimen."
51460             write(unit=iunit,fmt="(a)") "# The cooling rate is in K/min.  The pressure at which the sample was "
51461             write(unit=iunit,fmt="(a)") "# prepared is in kPa.  The temperature of preparation is in K.        "
51462
51463             write(unit=iunit,fmt="(a)") " "
51464             write(unit=iunit,fmt="(a)") "_pd_prep_cool_rate                ?"
51465             write(unit=iunit,fmt="(a)") "_pd_prep_pressure                 ?"
51466             write(unit=iunit,fmt="(a)") "_pd_prep_temperature              ?"
51467       end select
51468       if(type_data < 2) then
51469         write(unit=iunit,fmt="(a)") " "
51470         write(unit=iunit,fmt="(a)") "# The next four fields are normally only needed for transmission experiments."
51471         write(unit=iunit,fmt="(a)") " "
51472         write(unit=iunit,fmt="(a)") "_exptl_absorpt_coefficient_mu        ?"
51473         write(unit=iunit,fmt="(a)") "_exptl_absorpt_correction_type       ?"
51474         write(unit=iunit,fmt="(a)") "_exptl_absorpt_process_details       ?"
51475         write(unit=iunit,fmt="(a)") "_exptl_absorpt_correction_T_min      ?"
51476         write(unit=iunit,fmt="(a)") "_exptl_absorpt_correction_T_max      ?"
51477
51478         write(unit=iunit,fmt="(a)") " "
51479         write(unit=iunit,fmt="(a)") "#============================================================================="
51480         write(unit=iunit,fmt="(a)") " "
51481
51482         !---- Experimental Data ----!
51483         write(unit=iunit,fmt="(a)") "# 7. EXPERIMENTAL DATA"
51484
51485         write(unit=iunit,fmt="(a)") " "
51486         write(unit=iunit,fmt="(a)") "_exptl_special_details"
51487         write(unit=iunit,fmt="(a)") "; ?"
51488         write(unit=iunit,fmt="(a)") ";"
51489
51490         if (type_data == 1) then
51491            write(unit=iunit,fmt="(a)") " "
51492            write(unit=iunit,fmt="(a)") "# The following item is used to identify the equipment used to record "
51493            write(unit=iunit,fmt="(a)") "# the powder pattern when the diffractogram was measured at a laboratory "
51494            write(unit=iunit,fmt="(a)") "# other than the authors' home institution, e.g. when neutron or synchrotron"
51495            write(unit=iunit,fmt="(a)") "# radiation is used."
51496
51497            write(unit=iunit,fmt="(a)") " "
51498            write(unit=iunit,fmt="(a)") "_pd_instr_location"
51499            write(unit=iunit,fmt="(a)") "; ?"
51500            write(unit=iunit,fmt="(a)") ";"
51501            write(unit=iunit,fmt="(a)") "_pd_calibration_special_details           # description of the method used"
51502            write(unit=iunit,fmt="(a)") "                                          # to calibrate the instrument"
51503            write(unit=iunit,fmt="(a)") "; ?"
51504            write(unit=iunit,fmt="(a)") ";"
51505         end if
51506
51507         write(unit=iunit,fmt="(a)") " "
51508         write(unit=iunit,fmt="(a)") "_diffrn_ambient_temperature          ?"
51509         write(unit=iunit,fmt="(a)") "_diffrn_radiation_type               ?"
51510         write(unit=iunit,fmt="(a)") "_diffrn_radiation_wavelength         ?"
51511         write(unit=iunit,fmt="(a)") "_diffrn_radiation_source             ?"
51512         write(unit=iunit,fmt="(a)") "_diffrn_source                       ?"
51513         write(unit=iunit,fmt="(a)") "_diffrn_source_target                ?"
51514         write(unit=iunit,fmt="(a)") "_diffrn_source_type                  ?"
51515
51516         write(unit=iunit,fmt="(a)") " "
51517         write(unit=iunit,fmt="(a)") "_diffrn_radiation_monochromator      ?"
51518         write(unit=iunit,fmt="(a)") "_diffrn_measurement_device_type      ?"
51519         write(unit=iunit,fmt="(a)") "_diffrn_measurement_method           ?"
51520         write(unit=iunit,fmt="(a)") "_diffrn_detector_area_resol_mean     ?   # Not in version 2.0.1"
51521         write(unit=iunit,fmt="(a)") "_diffrn_detector                     ?"
51522         write(unit=iunit,fmt="(a)") "_diffrn_detector_type                ?   # make or model of detector"
51523         if (type_data == 1) then
51524            write(unit=iunit,fmt="(a)") "_pd_meas_scan_method                 ?   # options are 'step', 'cont',"
51525            write(unit=iunit,fmt="(a)") "                                         # 'tof', 'fixed' or"
51526            write(unit=iunit,fmt="(a)") "                                         # 'disp' (= dispersive)"
51527            write(unit=iunit,fmt="(a)") "_pd_meas_special_details"
51528            write(unit=iunit,fmt="(a)") ";  ?"
51529            write(unit=iunit,fmt="(a)") ";"
51530         end if
51531
51532         select case (type_data)
51533            case (0)
51534               write(unit=iunit,fmt="(a)") " "
51535               write(unit=iunit,fmt="(a)") "_diffrn_reflns_number                ?"
51536               write(unit=iunit,fmt="(a)") "_diffrn_reflns_av_R_equivalents      ?"
51537               write(unit=iunit,fmt="(a)") "_diffrn_reflns_av_sigmaI/netI        ?"
51538               write(unit=iunit,fmt="(a)") "_diffrn_reflns_theta_min             ?"
51539               write(unit=iunit,fmt="(a)") "_diffrn_reflns_theta_max             ?"
51540               write(unit=iunit,fmt="(a)") "_diffrn_reflns_theta_full            ?   # Not in version 2.0.1"
51541               write(unit=iunit,fmt="(a)") "_diffrn_measured_fraction_theta_max  ?   # Not in version 2.0.1"
51542               write(unit=iunit,fmt="(a)") "_diffrn_measured_fraction_theta_full ?   # Not in version 2.0.1"
51543               write(unit=iunit,fmt="(a)") "_diffrn_reflns_limit_h_min           ?"
51544               write(unit=iunit,fmt="(a)") "_diffrn_reflns_limit_h_max           ?"
51545               write(unit=iunit,fmt="(a)") "_diffrn_reflns_limit_k_min           ?"
51546               write(unit=iunit,fmt="(a)") "_diffrn_reflns_limit_k_max           ?"
51547               write(unit=iunit,fmt="(a)") "_diffrn_reflns_limit_l_min           ?"
51548               write(unit=iunit,fmt="(a)") "_diffrn_reflns_limit_l_max           ?"
51549               write(unit=iunit,fmt="(a)") "_diffrn_reflns_reduction_process     ?"
51550
51551               write(unit=iunit,fmt="(a)") " "
51552               write(unit=iunit,fmt="(a)") "_diffrn_standards_number             ?"
51553               write(unit=iunit,fmt="(a)") "_diffrn_standards_interval_count     ?"
51554               write(unit=iunit,fmt="(a)") "_diffrn_standards_interval_time      ?"
51555               write(unit=iunit,fmt="(a)") "_diffrn_standards_decay_%            ?"
51556               write(unit=iunit,fmt="(a)") "loop_"
51557               write(unit=iunit,fmt="(a)") "    _diffrn_standard_refln_index_h"
51558               write(unit=iunit,fmt="(a)") "    _diffrn_standard_refln_index_k"
51559               write(unit=iunit,fmt="(a)") "    _diffrn_standard_refln_index_l"
51560               write(unit=iunit,fmt="(a)") "?   ?   ?"
51561
51562            case (1)
51563               write(unit=iunit,fmt="(a)") " "
51564               write(unit=iunit,fmt="(a)") "#  The following four items give details of the measured (not processed)"
51565               write(unit=iunit,fmt="(a)") "#  powder pattern.  Angles are in degrees."
51566
51567               write(unit=iunit,fmt="(a)") " "
51568               write(unit=iunit,fmt="(a)") "_pd_meas_number_of_points         ?"
51569               write(unit=iunit,fmt="(a)") "_pd_meas_2theta_range_min         ?"
51570               write(unit=iunit,fmt="(a)") "_pd_meas_2theta_range_max         ?"
51571               write(unit=iunit,fmt="(a)") "_pd_meas_2theta_range_inc         ?"
51572
51573               write(unit=iunit,fmt="(a)") " "
51574               write(unit=iunit,fmt="(a)") "# The following three items are used for time-of-flight measurements only."
51575
51576               write(unit=iunit,fmt="(a)") " "
51577               write(unit=iunit,fmt="(a)") "_pd_instr_dist_src/spec           ?"
51578               write(unit=iunit,fmt="(a)") "_pd_instr_dist_spec/detc          ?"
51579               write(unit=iunit,fmt="(a)") "_pd_meas_2theta_fixed             ?"
51580
51581         end select
51582
51583         write(unit=iunit,fmt="(a)") " "
51584         write(unit=iunit,fmt="(a)") "#============================================================================="
51585         write(unit=iunit,fmt="(a)") " "
51586
51587         !---- Refinement Data ----!
51588         write(unit=iunit,fmt="(a)") "# 8. REFINEMENT DATA"
51589
51590         write(unit=iunit,fmt="(a)") " "
51591
51592         write(unit=iunit,fmt="(a)") "_refine_special_details"
51593         write(unit=iunit,fmt="(a)") "; ?"
51594         write(unit=iunit,fmt="(a)") ";"
51595
51596         if (type_data == 1) then
51597            write(unit=iunit,fmt="(a)") " "
51598            write(unit=iunit,fmt="(a)") "# Use the next field to give any special details about the fitting of the"
51599            write(unit=iunit,fmt="(a)") "# powder pattern."
51600
51601            write(unit=iunit,fmt="(a)") " "
51602            write(unit=iunit,fmt="(a)") "_pd_proc_ls_special_details"
51603            write(unit=iunit,fmt="(a)") "; ?"
51604            write(unit=iunit,fmt="(a)") ";"
51605
51606            write(unit=iunit,fmt="(a)") " "
51607            write(unit=iunit,fmt="(a)") "# The next three items are given as text."
51608            write(unit=iunit,fmt="(a)") " "
51609
51610            write(unit=iunit,fmt="(a)") "_pd_proc_ls_profile_function      ?"
51611            write(unit=iunit,fmt="(a)") "_pd_proc_ls_background_function   ?"
51612            write(unit=iunit,fmt="(a)") "_pd_proc_ls_pref_orient_corr"
51613            write(unit=iunit,fmt="(a)") "; ?"
51614            write(unit=iunit,fmt="(a)") ";"
51615         end if
51616
51617         select case (type_data)
51618            case (0)
51619               write(unit=iunit,fmt="(a)") " "
51620               write(unit=iunit,fmt="(a)") "_reflns_number_total                 ?"
51621               write(unit=iunit,fmt="(a)") "_reflns_number_gt                    ?  # Not in version 2.0.1"
51622               write(unit=iunit,fmt="(a)") "_reflns_threshold_expression         ?  # Not in version 2.0.1"
51623
51624            case (1)
51625               write(unit=iunit,fmt="(a)") " "
51626               write(unit=iunit,fmt="(a)") "_pd_proc_ls_prof_R_factor         ?"
51627               write(unit=iunit,fmt="(a)") "_pd_proc_ls_prof_wR_factor        ?"
51628               write(unit=iunit,fmt="(a)") "_pd_proc_ls_prof_wR_expected      ?"
51629
51630              write(unit=iunit,fmt="(a)") " "
51631              write(unit=iunit,fmt="(a)") "# The following four items apply to angular dispersive measurements."
51632              write(unit=iunit,fmt="(a)") "# 2theta minimum, maximum and increment (in degrees) are for the "
51633              write(unit=iunit,fmt="(a)") "# intensities used in the refinement."
51634
51635              write(unit=iunit,fmt="(a)") " "
51636              write(unit=iunit,fmt="(a)") "_pd_proc_2theta_range_min         ?"
51637              write(unit=iunit,fmt="(a)") "_pd_proc_2theta_range_max         ?"
51638              write(unit=iunit,fmt="(a)") "_pd_proc_2theta_range_inc         ?"
51639              write(unit=iunit,fmt="(a)") "_pd_proc_wavelength               ?"
51640
51641              write(unit=iunit,fmt="(a)") " "
51642              write(unit=iunit,fmt="(a)") "_pd_block_diffractogram_id        ?  # The id used for the block containing"
51643              write(unit=iunit,fmt="(a)") "                                     # the powder pattern profile (section 11)."
51644
51645              write(unit=iunit,fmt="(a)") " "
51646              write(unit=iunit,fmt="(a)") "# Give appropriate details in the next two text fields."
51647              write(unit=iunit,fmt="(a)") " "
51648              write(unit=iunit,fmt="(a)") "_pd_proc_info_excluded_regions    ?"
51649              write(unit=iunit,fmt="(a)") "_pd_proc_info_data_reduction      ?"
51650
51651         end select
51652
51653         write(unit=iunit,fmt="(a)") " "
51654         write(unit=iunit,fmt="(a)") "_refine_ls_structure_factor_coef     ?"
51655         write(unit=iunit,fmt="(a)") "_refine_ls_matrix_type               ?"
51656         write(unit=iunit,fmt="(a)") "_refine_ls_R_I_factor                ?"
51657         write(unit=iunit,fmt="(a)") "_refine_ls_R_Fsqd_factor             ?"
51658         write(unit=iunit,fmt="(a)") "_refine_ls_R_factor_all              ?"
51659         write(unit=iunit,fmt="(a)") "_refine_ls_R_factor_gt               ?   # Not in version 2.0.1"
51660         write(unit=iunit,fmt="(a)") "_refine_ls_wR_factor_all             ?"
51661         write(unit=iunit,fmt="(a)") "_refine_ls_wR_factor_ref             ?   # Not in version 2.0.1"
51662         write(unit=iunit,fmt="(a)") "_refine_ls_goodness_of_fit_all       ?"
51663         write(unit=iunit,fmt="(a)") "_refine_ls_goodness_of_fit_ref       ?   # Not in version 2.0.1"
51664         write(unit=iunit,fmt="(a)") "_refine_ls_restrained_S_all          ?"
51665         write(unit=iunit,fmt="(a)") "_refine_ls_restrained_S_obs          ?"
51666         write(unit=iunit,fmt="(a)") "_refine_ls_number_reflns             ?"
51667         write(unit=iunit,fmt="(a)") "_refine_ls_number_parameters         ?"
51668         write(unit=iunit,fmt="(a)") "_refine_ls_number_restraints         ?"
51669         write(unit=iunit,fmt="(a)") "_refine_ls_number_constraints        ?"
51670         write(unit=iunit,fmt="(a)") "_refine_ls_hydrogen_treatment        ?"
51671         write(unit=iunit,fmt="(a)") "_refine_ls_weighting_scheme          ?"
51672         write(unit=iunit,fmt="(a)") "_refine_ls_weighting_details         ?"
51673         write(unit=iunit,fmt="(a)") "_refine_ls_shift/su_max              ?   # Not in version 2.0.1"
51674         write(unit=iunit,fmt="(a)") "_refine_ls_shift/su_mean             ?   # Not in version 2.0.1"
51675         write(unit=iunit,fmt="(a)") "_refine_diff_density_max             ?"
51676         write(unit=iunit,fmt="(a)") "_refine_diff_density_min             ?"
51677         write(unit=iunit,fmt="(a)") "_refine_ls_extinction_method         ?"
51678         write(unit=iunit,fmt="(a)") "_refine_ls_extinction_coef           ?"
51679         write(unit=iunit,fmt="(a)") "_refine_ls_abs_structure_details     ?"
51680         write(unit=iunit,fmt="(a)") "_refine_ls_abs_structure_Flack       ?"
51681         write(unit=iunit,fmt="(a)") "_refine_ls_abs_structure_Rogers      ?"
51682
51683         write(unit=iunit,fmt="(a)") " "
51684         write(unit=iunit,fmt="(a)") "# The following items are used to identify the programs used."
51685         write(unit=iunit,fmt="(a)") " "
51686
51687         write(unit=iunit,fmt="(a)") "_computing_data_collection           ?"
51688         write(unit=iunit,fmt="(a)") "_computing_cell_refinement           ?"
51689         write(unit=iunit,fmt="(a)") "_computing_data_reduction            ?"
51690         write(unit=iunit,fmt="(a)") "_computing_structure_solution        ?"
51691         write(unit=iunit,fmt="(a)") "_computing_structure_refinement      ?"
51692         write(unit=iunit,fmt="(a)") "_computing_molecular_graphics        ?"
51693         write(unit=iunit,fmt="(a)") "_computing_publication_material      ?"
51694
51695       End if  !(type_data < 2) then
51696       write(unit=iunit,fmt="(a)") " "
51697       write(unit=iunit,fmt="(a)") "#============================================================================="
51698       write(unit=iunit,fmt="(a)") " "
51699       !---- Atomic Coordinates and Displacement Parameters ----!
51700       write(unit=iunit,fmt="(a)") "# 9. ATOMIC COORDINATES AND DISPLACEMENT PARAMETERS"
51701
51702       write(unit=iunit,fmt="(a)") " "
51703
51704       write(unit=iunit,fmt="(a)") "loop_"
51705       write(unit=iunit,fmt='(a)') "    _atom_site_label"
51706       write(unit=iunit,fmt='(a)') "    _atom_site_fract_x"
51707       write(unit=iunit,fmt='(a)') "    _atom_site_fract_y"
51708       write(unit=iunit,fmt='(a)') "    _atom_site_fract_z"
51709       write(unit=iunit,fmt='(a)') "    _atom_site_U_iso_or_equiv"
51710       write(unit=iunit,fmt='(a)') "    _atom_site_occupancy"
51711       write(unit=iunit,fmt='(a)') "    _atom_site_adp_type              # Not in version 2.0.1"
51712       write(unit=iunit,fmt='(a)') "    _atom_site_type_symbol"
51713
51714       !Calculation of the factor corresponding to the occupation factor provided in A
51715       do i=1,A%natoms
51716         occup(i)=A%Atom(i)%occ/(real(A%Atom(i)%mult)/real(SpG%multip))
51717         soccup(i)=A%Atom(i)%occ_std/(real(A%Atom(i)%mult)/real(SpG%multip))
51718       end do
51719       ocf=sum(abs(A%atom(1)%x-A%atom(2)%x))
51720       if( ocf < 0.001) then
51721         ocf=occup(1)+occup(2)
51722       else
51723         ocf=occup(1)
51724       end if
51725       occup=occup/ocf; soccup=soccup/ocf
51726       aniso=.false.
51727       do i=1,A%natoms
51728          line(1:132)=" "
51729          line(2:)= A%Atom(i)%Lab
51730           ! _atom_site_fract_x, _atom_site_fract_y, _atom_site_fract_z
51731          do j=1,3
51732            comm=" "
51733            call setnum_std(A%Atom(i)%x(j),A%Atom(i)%x_std(j),comm)
51734            line=trim(line)//" "//trim(comm)
51735          end do
51736          ! _atom_site_U_iso_or_equiv
51737            comm=" "
51738          if(A%Atom(i)%thtype == "isotr") then
51739            adptyp='Uiso'
51740            u=A%Atom(i)%Biso/(8.0*pi*pi)
51741            su=A%Atom(i)%Biso_std/(8.0*pi*pi)
51742            call setnum_std(u,su,comm)
51743
51744          else if(A%Atom(i)%thtype == "aniso") then
51745            aniso=.true.
51746            adptyp='Uani'
51747            if(A%atom(i)%Utype == "beta") then
51748               aux=A%atom(i)%u
51749               ua=convert_betas_u(aux,cell)
51750               aux=A%atom(i)%u_std
51751               sua=convert_betas_u(aux,cell)
51752            else if(A%atom(i)%Utype == "u_ij") then
51753               ua=A%atom(i)%u
51754               sua=A%atom(i)%u_std
51755            end if
51756            u=(ua(1)+ua(2)+ua(3))/3.0
51757            su=(ua(1)+ua(2)+ua(3))/3.0
51758            call setnum_std(u,su,comm)
51759          else
51760            adptyp='.'
51761          end if
51762            line=trim(line)//" "//trim(comm)
51763
51764           !_atom_site_occupancy
51765            comm=" "
51766            call setnum_std(occup(i),soccup(i),comm)
51767            line=trim(line)//" "//trim(comm)
51768
51769          WRITE(iunit,"(a)") trim(line)//" "//trim(adptyp)//" "//A%atom(i)%SfacSymb
51770       end do
51771       if(aniso) then
51772          write(unit=iunit,fmt="(a)") " "
51773          write(unit=iunit,fmt="(a)") "loop_"
51774          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_label "
51775          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_U_11  "
51776          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_U_22  "
51777          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_U_33  "
51778          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_U_12  "
51779          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_U_13  "
51780          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_U_23  "
51781          write(unit=iunit,fmt="(a)") "    _atom_site_aniso_type_symbol"
51782          do i=1,A%natoms
51783             if(A%Atom(i)%thtype /= "aniso") cycle
51784             line(1:132)=" "
51785             line(2:)= A%Atom(i)%Lab
51786             if(A%atom(i)%Utype == "beta") then
51787                aux=A%atom(i)%u
51788                ua=convert_betas_u(aux,cell)
51789                aux=A%atom(i)%u_std
51790                sua=convert_betas_u(aux,cell)
51791             else if(A%atom(i)%Utype == "u_ij") then
51792                ua=A%atom(i)%u
51793                sua=A%atom(i)%u_std
51794             end if
51795             do j=1,6
51796               comm=" "
51797               call setnum_std(ua(j),sua(j),comm)
51798               line=trim(line)//" "//trim(comm)
51799             end do
51800              WRITE(iunit,"(a)") trim(line)//"  "//A%atom(i)%SfacSymb
51801          end do
51802       end if
51803
51804       if(type_data < 2) then
51805          write(unit=iunit,fmt="(a)") " "
51806          write(unit=iunit,fmt="(a)") "# Note: if the displacement parameters were refined anisotropically"
51807          write(unit=iunit,fmt="(a)") "# the U matrices should be given as for single-crystal studies."
51808
51809          write(unit=iunit,fmt="(a)") " "
51810          write(unit=iunit,fmt="(a)") "#============================================================================="
51811          write(unit=iunit,fmt="(a)") " "
51812
51813          !---- Molecular Geometry ----!
51814          write(unit=iunit,fmt="(a)") "# 10. MOLECULAR GEOMETRY"
51815
51816          write(unit=iunit,fmt="(a)") " "
51817
51818
51819          write(unit=iunit,fmt="(a)") "_geom_special_details                ?"
51820
51821          write(unit=iunit,fmt="(a)") " "
51822          write(unit=iunit,fmt="(a)") "loop_"
51823          write(unit=iunit,fmt="(a)") "    _geom_bond_atom_site_label_1  "
51824          write(unit=iunit,fmt="(a)") "    _geom_bond_atom_site_label_2  "
51825          write(unit=iunit,fmt="(a)") "    _geom_bond_site_symmetry_1    "
51826          write(unit=iunit,fmt="(a)") "    _geom_bond_site_symmetry_2    "
51827          write(unit=iunit,fmt="(a)") "    _geom_bond_distance           "
51828          write(unit=iunit,fmt="(a)") "    _geom_bond_publ_flag          "
51829          write(unit=iunit,fmt="(a)") "    ?   ?   ?   ?   ?   ?"
51830
51831          write(unit=iunit,fmt="(a)") " "
51832          write(unit=iunit,fmt="(a)") "loop_"
51833          write(unit=iunit,fmt="(a)") "    _geom_contact_atom_site_label_1 "
51834          write(unit=iunit,fmt="(a)") "    _geom_contact_atom_site_label_2 "
51835          write(unit=iunit,fmt="(a)") "    _geom_contact_distance          "
51836          write(unit=iunit,fmt="(a)") "    _geom_contact_site_symmetry_1   "
51837          write(unit=iunit,fmt="(a)") "    _geom_contact_site_symmetry_2   "
51838          write(unit=iunit,fmt="(a)") "    _geom_contact_publ_flag         "
51839          write(unit=iunit,fmt="(a)") "    ?   ?   ?   ?   ?   ?"
51840
51841          write(unit=iunit,fmt="(a)") " "
51842          write(unit=iunit,fmt="(a)") "loop_"
51843          write(unit=iunit,fmt="(a)") "_geom_angle_atom_site_label_1 "
51844          write(unit=iunit,fmt="(a)") "_geom_angle_atom_site_label_2 "
51845          write(unit=iunit,fmt="(a)") "_geom_angle_atom_site_label_3 "
51846          write(unit=iunit,fmt="(a)") "_geom_angle_site_symmetry_1   "
51847          write(unit=iunit,fmt="(a)") "_geom_angle_site_symmetry_2   "
51848          write(unit=iunit,fmt="(a)") "_geom_angle_site_symmetry_3   "
51849          write(unit=iunit,fmt="(a)") "_geom_angle                   "
51850          write(unit=iunit,fmt="(a)") "_geom_angle_publ_flag         "
51851          write(unit=iunit,fmt="(a)") "?   ?   ?   ?   ?   ?   ?   ?"
51852
51853          write(unit=iunit,fmt="(a)") " "
51854          write(unit=iunit,fmt="(a)") "loop_"
51855          write(unit=iunit,fmt="(a)") "_geom_torsion_atom_site_label_1 "
51856          write(unit=iunit,fmt="(a)") "_geom_torsion_atom_site_label_2 "
51857          write(unit=iunit,fmt="(a)") "_geom_torsion_atom_site_label_3 "
51858          write(unit=iunit,fmt="(a)") "_geom_torsion_atom_site_label_4 "
51859          write(unit=iunit,fmt="(a)") "_geom_torsion_site_symmetry_1   "
51860          write(unit=iunit,fmt="(a)") "_geom_torsion_site_symmetry_2   "
51861          write(unit=iunit,fmt="(a)") "_geom_torsion_site_symmetry_3   "
51862          write(unit=iunit,fmt="(a)") "_geom_torsion_site_symmetry_4   "
51863          write(unit=iunit,fmt="(a)") "_geom_torsion                   "
51864          write(unit=iunit,fmt="(a)") "_geom_torsion_publ_flag         "
51865          write(unit=iunit,fmt="(a)") "?   ?   ?   ?   ?   ?   ?   ?   ?   ?"
51866
51867          write(unit=iunit,fmt="(a)") " "
51868          write(unit=iunit,fmt="(a)") "loop_"
51869          write(unit=iunit,fmt="(a)") "_geom_hbond_atom_site_label_D "
51870          write(unit=iunit,fmt="(a)") "_geom_hbond_atom_site_label_H "
51871          write(unit=iunit,fmt="(a)") "_geom_hbond_atom_site_label_A "
51872          write(unit=iunit,fmt="(a)") "_geom_hbond_site_symmetry_D   "
51873          write(unit=iunit,fmt="(a)") "_geom_hbond_site_symmetry_H   "
51874          write(unit=iunit,fmt="(a)") "_geom_hbond_site_symmetry_A   "
51875          write(unit=iunit,fmt="(a)") "_geom_hbond_distance_DH       "
51876          write(unit=iunit,fmt="(a)") "_geom_hbond_distance_HA       "
51877          write(unit=iunit,fmt="(a)") "_geom_hbond_distance_DA       "
51878          write(unit=iunit,fmt="(a)") "_geom_hbond_angle_DHA         "
51879          write(unit=iunit,fmt="(a)") "_geom_hbond_publ_flag         "
51880          write(unit=iunit,fmt="(a)") "?   ?   ?   ?   ?   ?   ?   ?   ?   ?   ?"
51881
51882          write(unit=iunit,fmt="(a)") " "
51883          write(unit=iunit,fmt="(a)") "#============================================================================="
51884          write(unit=iunit,fmt="(a)") " "
51885
51886
51887          !---- Final Informations ----!
51888          write(unit=iunit,fmt="(a)") "#============================================================================="
51889          write(unit=iunit,fmt="(a)") "# Additional structures (last six sections and associated data_? identifiers) "
51890          write(unit=iunit,fmt="(a)") "# may be added at this point.                                                 "
51891          write(unit=iunit,fmt="(a)") "#============================================================================="
51892
51893          write(unit=iunit,fmt="(a)") " "
51894          write(unit=iunit,fmt="(a)") "# The following lines are used to test the character set of files sent by     "
51895          write(unit=iunit,fmt="(a)") "# network email or other means. They are not part of the CIF data set.        "
51896          write(unit=iunit,fmt="(a)") "# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789              "
51897          write(unit=iunit,fmt="(a)") "# !@#$%^&*()_+{}:"//""""//"~<>?|\-=[];'`,./ "
51898       end if
51899
51900       close(unit=iunit)
51901
51902       return
51903    End Subroutine Write_Cif_Template
51904
51905    !!----
51906    !!---- Subroutine Write_Shx_Template(Filename,Code,Title,Lambda,Z,Celda,Space,Atomos)
51907    !!----    character(len=*),        intent(in) :: filename  !  In -> Filename
51908    !!----    integer,                 intent(in) :: code      !  In -> 0 Shelxs-Patterson
51909    !!----                                                              1 Shelxs-Direct Methods
51910    !!----                                                              2 Shelxl-Refinement
51911    !!----    character(len=*),        intent(in) :: title     !  In -> Title
51912    !!----    real(kind=cp),           intent(in) :: lambda    !  In -> Lambda
51913    !!----    integer,                 intent(in) :: z         !  In -> Z
51914    !!----    type(Crystal_cell_Type), intent(in) :: celda     !  In -> Cell variable
51915    !!----    type(Space_Group_Type),  intent(in) :: Space     !  In -> SpaceGroup variable
51916    !!----    type(atom_list_type),    intent(in) :: atomos    !  In -> Atom List
51917    !!----
51918    !!----    Write a Shelx File
51919    !!----
51920    !!---- Update: February - 2005
51921    !!
51922    Subroutine Write_Shx_Template(filename,code,title,lambda,z,celda,space,atomos)
51923       !---- Arguments ----!
51924       character(len=*),        intent(in) :: filename
51925       integer,                 intent(in) :: code
51926       character(len=*),        intent(in) :: title
51927       real(kind=cp),           intent(in) :: lambda
51928       integer,                 intent(in) :: z
51929       type(Crystal_cell_Type), intent(in) :: celda
51930       type(Space_Group_Type),  intent(in) :: Space
51931       type(atom_list_type),    intent(in) :: atomos
51932
51933       !---- Local Variables ----!
51934       logical                :: info
51935
51936       integer                :: i,j,k,nc,iunit !,nlong
51937       integer                :: nlat
51938       integer, dimension(15) :: z_cont
51939
51940       !---- Inicializacion de variables ----!
51941       info=.false.
51942       iunit=0
51943       z_cont=0
51944       nc=0  !this depends on scattering factor?
51945
51946       !---- Esta abierto este Fichero? ----!
51947       inquire(file=filename,opened=info)
51948       if (info) then
51949          inquire(file=filename,number=iunit)
51950          close(unit=iunit)
51951       end if
51952
51953       !---- Escritura ----!
51954       if (iunit == 0) iunit=61
51955       open(unit=iunit,file=filename,status="unknown",action="write")
51956       rewind(unit=iunit)
51957
51958       !---- Title ----!
51959       write(unit=iunit,fmt="(a)") "TITL "//title(1:len_trim(title))
51960
51961       !---- Lambda, Cell ----!
51962       write(unit=iunit,fmt="(a,f8.5,3f9.4,3f7.3)") "CELL ",lambda,celda%cell,celda%ang
51963
51964       !---- Z, Std ----!
51965       write(unit=iunit,fmt="(a,i3,a,3f8.4,3f7.3)") "ZERR ",z,"     ",celda%cell_std,celda%ang_std
51966
51967       !---- Latt ----!
51968       nlat=1
51969       select case (space%centred)
51970          case (0) ! Centric
51971
51972          case (1) ! Acentric
51973             nlat=-1
51974
51975          case (2) ! Not used in Shelx
51976             write(unit=iunit,fmt="(a)") " ERROR: Origin not at -1 "
51977             close(unit=iunit)
51978             return
51979
51980       end select
51981       select case (space%spg_lat)
51982          case ("P")
51983
51984          case ("I")
51985             nlat=2*nlat
51986
51987          case ("R")
51988             nlat=3*nlat
51989
51990          case ("F")
51991             nlat=4*nlat
51992
51993          case ("A")
51994             nlat=5*nlat
51995
51996          case ("B")
51997             nlat=6*nlat
51998
51999          case ("C")
52000             nlat=7*nlat
52001
52002       end select
52003       write(unit=iunit,fmt="(a,i2)") "LATT ",nlat
52004
52005       !---- Symm ----!
52006       do i=2,space%numops
52007          write(unit=iunit,fmt="(a)") "SYMM "//u_case(space%symopsymb(i))
52008       end do
52009
52010       !---- Sfac ----!
52011       j=0
52012       do i=1,atomos%natoms
52013          if (j == 0) then
52014             j=1
52015             z_cont(j)=atomos%atom(i)%z
52016          else
52017             do k=1,j
52018                if (z_cont(k) == atomos%atom(i)%z) exit
52019             end do
52020             if (z_cont(k) /= atomos%atom(i)%z) then
52021                j=j+1
52022                z_cont(j)=atomos%atom(i)%z
52023             end if
52024          end if
52025       end do
52026
52027
52028       write(unit=iunit,fmt="(a)") "SFAC "
52029
52030       !---- Unit ----!
52031       write(unit=iunit,fmt="(a)") "UNIT "
52032
52033       select case (code)
52034          case (0) ! Shelxs - Patterson
52035             write(unit=iunit,fmt="(a)") "PATT "
52036
52037          case (1) ! Shelxs - Direct Methods
52038             write(unit=iunit,fmt="(a)") "TREF "
52039
52040          case (2) ! Shelxl - Refinement
52041             !---- L.S. ----!
52042             write(unit=iunit,fmt="(a)") "L.S. 10"
52043
52044             !---- Fvar ----!
52045             write(unit=iunit,fmt="(a)") "FVAR 1.0"
52046
52047             !---- Weight ----!
52048             write(unit=iunit,fmt="(a)") "WGHT 0.2"
52049
52050             !---- Fmap ----!
52051             write(unit=iunit,fmt="(a)") "FMAP 2"
52052
52053             !---- Atoms ----!
52054             do i=1,atomos%natoms
52055                write(unit=iunit,fmt="(a4,i3,4f11.5)") &
52056                     atomos%atom(i)%lab, nc, atomos%atom(i)%x, atomos%atom(i)%occ+10.0
52057             end do
52058       end select
52059
52060       !---- Format ----!
52061       write(unit=iunit,fmt="(a)") "HKLF 4"
52062
52063       !---- End ----!
52064       write(unit=iunit,fmt="(a)") "END "
52065
52066       return
52067    End Subroutine Write_Shx_Template
52068
52069    !!----
52070    !!---- Subroutine Get_Phases_File(filecode, Nphas, PhasesName,ILines)
52071    !!----    character(len=*),                intent(in)   :: filecode
52072    !!----    Integer,                         intent(out)  :: Nphas
52073    !!----    Character(len=80), dimension(:), intent(out)  :: PhasesName
52074    !!----    Integer,dimension(2,:),          intent(out)  :: ILines
52075    !!----
52076    !!---- Determine how many phases there are in a CIF or PCR file and
52077    !!---- give the lines to locate
52078    !!----
52079    !!---- Update: 01/05/2013
52080    !!
52081    Subroutine Get_Phases_File(filecode, NPhas, PhasesName,ILines)
52082       !---- Arguments ----!
52083       character(len=*),             intent(in)   :: filecode
52084       integer,                      intent(out)  :: Nphas
52085       character(len=*),dimension(:),intent(out)  :: PhasesName
52086       integer,dimension(:,:),       intent(out)  :: ILines
52087
52088       !---- Local Variables ----!
52089       character(len=3) :: ext
52090       integer          :: npos
52091
52092       !> Error
52093       call init_err_form()
52094
52095       !> Init
52096       Nphas=0
52097       PhasesName=' '
52098       Ilines=0
52099
52100       !> PCR or CIF file
52101       npos=index(filecode,'.',back=.true.)
52102       if (npos <=0) then
52103          err_form=.true.
52104          err_form_mess='No extension was found in the name of the file!'
52105          return
52106       end if
52107
52108       ext=filecode(npos+1:)
52109       ext=u_case(ext)
52110       select case (ext)
52111          case ('CIF')
52112             call get_nphases_ciffile(filecode, NPhas, PhasesName,ILines)
52113          case ('PCR')
52114             call get_nphases_pcrfile(filecode, NPhas, PhasesName,ILines)
52115          case default
52116             err_form=.true.
52117             err_form_mess='Extension for this file not valid!'
52118       end select
52119
52120       return
52121    End Subroutine Get_Phases_File
52122
52123    !!--++
52124    !!--++ Subroutine Get_NPhases_CIFFile(Filecode,NPhas,PhasesName,ILines)
52125    !!--++    character(len=*),                 intent(in)  :: Filecode    ! Filename
52126    !!--++    integer,                          intent(out) :: NPhas       ! Number of Phases in the file
52127    !!--++    character(len=*), dimension(:),   intent(out) :: PhasesName     ! Name of Phases in the file
52128    !!--++    integer,          dimension(:,:), intent(out) :: ILines        ! Index for lines for each Phase
52129    !!--++
52130    !!--++ Determine the number of phases are included into the file
52131    !!--++
52132    !!--++ Date: 01/05/2013
52133    !!
52134    Subroutine Get_NPhases_CIFFile(Filecode,NPhas,PhasesName,ILines)
52135       !---- Arguments ----!
52136       character(len=*),                 intent(in)  :: Filecode    ! Filename
52137       integer,                          intent(out) :: NPhas       ! Number of Phases in the file
52138       character(len=*), dimension(:),   intent(out) :: PhasesName     ! Name of Phases in the file
52139       integer,          dimension(:,:), intent(out) :: ILines        ! Index for lines for each Phase
52140
52141       !---- Local Variables ----!
52142       character(len=150), dimension(:), allocatable :: filen
52143       character(len=150)                            :: line
52144       integer                                       :: i,j,nl
52145
52146       !> Error
52147       call init_err_form()
52148
52149       !> Initialize
52150       NPhas=0
52151       PhasesName=' '
52152       ILines=0
52153
52154       !> Reading file
52155       nl=0
52156       call number_lines(trim(filecode),nl)
52157       if (nl <=0) then
52158          err_form=.true.
52159          err_form_mess='No lines were readen for '//trim(filecode)//' !!'
52160          return
52161       end if
52162       allocate(filen(nl))
52163       call reading_lines(trim(filecode),nl,filen)
52164
52165       !> Number of Phases
52166       do i=1,nl
52167          line=adjustl(filen(i))
52168
52169          !> empty line
52170          if (len_trim(line) <= 0) cycle
52171
52172          !> comment line
52173          if (line(1:1) =='#') cycle
52174
52175          !> No data_global
52176          j=index(line,'data_global')
52177          if (j > 0) cycle
52178
52179          !> Just only lines beginning with data...
52180          j=index(line,'data_')
52181          if (j /= 1) cycle
52182
52183          nphas=nphas+1
52184          ILines(1,Nphas)=i
52185          PhasesName(nphas)=trim(line(j+5:))
52186          if (nphas > 1) ILines(2,nphas-1)=i-1
52187       end do
52188       if (nphas > 0 .and. ILines(2,nphas)==0) ILines(2,nphas)=nl
52189
52190       if (allocated(filen)) deallocate(filen)
52191
52192       return
52193    End Subroutine  Get_NPhases_CIFFile
52194
52195    !!--++
52196    !!--++ Subroutine Get_NPhases_PCRFile(filecode, Nphas,PhasesName,ILines)
52197    !!--++    character(len=*),                intent(in)   :: filecode
52198    !!--++    Integer,                         intent(out)  :: Nphas
52199    !!--++    Character(len=80), dimension(:), intent(out)  :: PhasesName
52200    !!--++    Integer,dimension(2,:),          intent(out)  :: ILines
52201    !!--++
52202    !!--++ Determine how many phases and where there in a PCR file
52203    !!--++
52204    !!--++ Update: 01/05/2013
52205    !!
52206    Subroutine Get_NPhases_PCRFile(filecode, NPhas, PhasesName,ILines)
52207       !---- Arguments ----!
52208       character(len=*),             intent(in)   :: filecode
52209       integer,                      intent(out)  :: Nphas
52210       character(len=*),dimension(:),intent(out)  :: PhasesName
52211       integer,dimension(:,:),       intent(out)  :: ILines
52212
52213       !---- Local Variables ----!
52214       logical                                      :: multi, ask_phase
52215       character(len=80), dimension(:), allocatable :: file_dat
52216       character(len=80)                            :: line
52217       integer                                      :: i,k,iv,nlines
52218       integer, dimension(30)                       :: ivet
52219       real(kind=cp), dimension(30)                 :: vet
52220
52221       !> Err
52222       call init_err_form()
52223
52224       !> Init
52225       NPhas=0
52226       PhasesName=' '
52227       ILines=0
52228
52229       !> Reading file
52230       nlines=0
52231       call number_lines(trim(filecode),nlines)
52232       if (nlines <=0) then
52233          err_form=.true.
52234          err_form_mess='No lines were readen for '//trim(filecode)//' !!'
52235          return
52236       end if
52237       allocate(file_dat(nlines))
52238       call reading_lines(trim(filecode),nlines,file_dat)
52239
52240       ILines(1,:)=1
52241       ILines(2,:)=nlines
52242
52243       !> Simple / Multi format
52244       multi=.false.
52245       do i=1,nlines
52246          line=adjustl(file_dat(i))
52247          if (line(1:1) =='!' .or. line(1:1)==' ') cycle
52248          if (index(line,'NPATT ') <=0) cycle
52249          multi=.true.
52250       end do
52251
52252       !> Number of Phases
52253       if (.not. multi) then
52254          do i=2,nlines
52255             line=adjustl(file_dat(i))
52256             if (line(1:1) =='!' .or. line(1:1)==' ') cycle
52257             call getnum(line,vet,ivet,iv)
52258             if (iv > 3) then
52259                NPhas=ivet(3)
52260                exit
52261             end if
52262          end do
52263
52264       else
52265          do i=1,nlines
52266             line=adjustl(file_dat(i))
52267             if (line(1:4) /='!Nph') cycle
52268
52269             line=adjustl(file_dat(i+1))
52270             call getnum(line,vet,ivet,iv)
52271             if (iv > 1) then
52272                NPhas=ivet(1)
52273                exit
52274             end if
52275          end do
52276       end if
52277
52278       if (NPhas == 0) then
52279          err_form=.true.
52280          err_form_mess=" No Phase information was found in this PCR file. Please, check it! "
52281          return
52282       end if
52283
52284       !> Locate where begin each Phase
52285       k=0
52286       ask_phase=.true.
52287
52288       do i=1,nlines
52289          line=adjustl(file_dat(i))
52290          if (ask_phase) then
52291             if (index(line,'Data for PHASE') <= 0) cycle
52292          else
52293             if (line(1:1) /='!') then
52294                k=k+1
52295                ILines(1,k)=i
52296                PhasesName(k)=trim(adjustl(line))
52297                if (k == NPhas) exit
52298
52299                ask_phase=.true.
52300             end if
52301             cycle
52302          end if
52303          ask_phase=.false.
52304       end do
52305
52306       if (NPhas /= k) then
52307          err_form=.true.
52308          err_form_mess=" Locating Phases failed in this PCR. Please, check it!"
52309          return
52310       end if
52311
52312       do i=1,Nphas
52313          if (nphas > 1) then
52314             ilines(2,i)=ilines(1,i+1)-1
52315          end if
52316       end do
52317
52318       return
52319    End Subroutine Get_NPhases_PCRFile
52320    !!----
52321    !!---- Subroutine Write_CFL(lun,Cel,SpG,Atm,comment)
52322    !!----    integer,                  intent(in)    :: lun
52323    !!----    type (Space_Group_Type),  intent(in)    :: SpG
52324    !!----    type (Crystal_Cell_Type), intent(in)    :: Cel
52325    !!----    type (atom_list_type),    intent(in)    :: Atm
52326    !!----    character(len=*),optional,intent(in)    :: comment
52327    !!----
52328    !!----    (OVERLOADED)
52329    !!----
52330    !!----    Write a CFL-file with atom_list_type
52331    !!----
52332    !!---- Update: July - 2014
52333    !!
52334    Subroutine Write_CFL_Atom_List_Type(lun,Cel,SpG,Atm,comment)
52335       !---- Arguments ----!
52336       integer,                  intent(in)    :: lun
52337       type (Space_Group_Type),  intent(in)    :: SpG
52338       type (Crystal_Cell_Type), intent(in)    :: Cel
52339       type (atom_list_type),    intent(in)    :: Atm
52340       character(len=*),optional,intent(in)    :: comment
52341
52342       !----- Local variables -----!
52343       integer                         :: j !,loc
52344       real(kind=cp), dimension(6)     :: a,sa
52345       character(len=30), dimension(6) :: text
52346
52347       if(present(comment)) write(unit=lun,fmt="(a)") "TITLE "//trim(comment)
52348       write(unit=lun,fmt="(a)") "!  Automatically generated CFL file (Write_CFL)"
52349
52350       a(1:3)=Cel%Cell
52351       a(4:6)=Cel%ang
52352       sa(1:3)=Cel%Cell_std
52353       sa(4:6)=Cel%ang_std
52354       do j=1,6
52355          call SetNum_Std(a(j), sa(j), text(j))
52356       end do
52357       write(unit=lun,fmt="(a)") "!         a               b               c            alpha           beta            gamma"
52358       write(unit=lun,fmt="(a,6a16)") "Cell ",text
52359       write(unit=lun,fmt="(a,i3)")"!     Space Group # ",SpG%NumSpg
52360       write(unit=lun,fmt="(a,a)") "Spgr  ",SpG%SPG_Symb
52361       call Write_Atoms_CFL(Atm,Lun,cel)
52362
52363       return
52364    End Subroutine Write_CFL_Atom_List_Type
52365    !!----
52366    !!---- Subroutine Write_CFL(lun,Molx,comment)
52367    !!----    integer,                       intent(in) :: lun
52368    !!----    type (Molecular_Crystal_Type), intent(in) :: Molx
52369    !!----    character(len=*),optional,     intent(in) :: comment
52370    !!----
52371    !!----    (OVERLOADED)
52372    !!----
52373    !!----    Write a CFL-file with molecular_crystal_type
52374    !!----
52375    !!---- Update: July - 2014
52376    !!
52377    Subroutine Write_CFL_Molcrys(lun,Molx,comment)
52378       !---- Arguments ----!
52379       integer,                       intent(in) :: lun
52380       type (Molecular_Crystal_Type), intent(in) :: Molx
52381       character(len=*),optional,     intent(in) :: comment
52382
52383       !----- Local variables -----!
52384       integer                         :: j !,loc
52385       real(kind=cp), dimension(6)     :: a,sa
52386       character(len=30), dimension(6) :: text
52387
52388       if(present(comment)) write(unit=lun,fmt="(a)") "TITLE "//trim(comment)
52389       write(unit=lun,fmt="(a)") "!  Automatically generated CFL file (Write_CFL)"
52390
52391       a(1:3)=molx%cell%Cell
52392       a(4:6)=molx%cell%ang
52393       sa(1:3)=molx%cell%Cell_std
52394       sa(4:6)=molx%cell%ang_std
52395       do j=1,6
52396          call SetNum_Std(a(j), sa(j), text(j))
52397       end do
52398       write(unit=lun,fmt="(a)") "!         a               b               c            alpha           beta            gamma"
52399       write(unit=lun,fmt="(a,6a16)") "Cell ",text
52400       write(unit=lun,fmt="(a,i3)")"!     Space Group # ",molx%spg%NumSpg
52401       write(unit=lun,fmt="(a,a)") "Spgr  ",molx%spg%SPG_Symb
52402       call Write_Atoms_CFL(Molx,Lun)
52403
52404       return
52405    End Subroutine Write_CFL_Molcrys
52406    !!----
52407    !!---- Subroutine Write_Atoms_CFL(Ats,Lun,Cell)
52408    !!----    Type (atom_list_type),dimension(:),  intent(in) :: Ats     !  In -> Atom List
52409    !!----    integer, optional,                   intent(in) :: lun     !  In -> Unit to write
52410    !!----    Type(Crystal_Cell_Type), optional,   intent(in) :: Cell    !  In -> Transform to thermal parameters
52411    !!----
52412    !!----    Write the atoms in the asymmetric unit for a CFL file
52413    !!----
52414    !!---- Update: February - 2003
52415    !!
52416    Subroutine Write_Atoms_CFL_ATM(Ats,Lun,cell)
52417       !---- Arguments ----!
52418       type (atom_list_type),            intent(in) :: Ats
52419       integer, optional,                intent(in) :: Lun
52420       Type(Crystal_Cell_Type), optional,intent(in) :: Cell
52421
52422       !---- Local Variables ----!
52423       character(len=30),dimension(6) :: text
52424       character(len=36)              :: forma,fom
52425       integer                        :: i, j, iunit, leng, maxl,ish
52426       real(kind=cp), dimension(6)    :: u,bet,sb
52427
52428       iunit=6
52429       if (present(lun)) iunit=lun
52430
52431       if(ats%natoms == 0) then
52432         write (unit=iunit,fmt="(a)") "!  No atoms ..."
52433         return
52434       end if
52435       !Determine the maximum length of the atom labels
52436       maxl=0
52437       do i=1,ats%natoms
52438         leng=len_trim(ats%atom(i)%lab)
52439         if(leng > maxl) maxl=leng
52440       end do
52441       maxl=max(maxl,4)+1
52442       ish=maxl-4
52443       fom   ="(a,tr  ,a)"
52444       Select Case(ish)
52445          Case(:9)
52446            write(unit=fom(6:6),fmt="(i1)") ish
52447          Case(10:)
52448            write(unit=fom(6:7),fmt="(i2)") ish
52449       End Select
52450       forma="(a,a  ,tr2,a,tr3,5a14,2f8.2,tr3,a)"
52451       Select Case(maxl)
52452         Case(:9)
52453             write(unit=forma(5:5),fmt="(i1)") maxl
52454         Case(10:)
52455             write(unit=forma(5:6),fmt="(i2)") maxl
52456       End Select
52457       write (unit=iunit,fmt=fom) "!     ", &
52458             "Atom  Type     x/a           y/b           z/c           Biso          Occ           Spin    Charge    Info"
52459       do i=1,ats%natoms
52460
52461          do j=1,3
52462             call SetNum_Std(ats%atom(i)%x(j), ats%atom(i)%x_std(j), text(j))
52463          end do
52464          call SetNum_Std(ats%atom(i)%Biso, ats%atom(i)%Biso_std, text(4))
52465          call SetNum_Std(ats%atom(i)%Occ, ats%atom(i)%Occ_std, text(5))
52466
52467          write (unit=iunit,fmt=forma) &
52468                "Atom   ",trim(ats%atom(i)%lab),ats%atom(i)%chemsymb, (text(j),j=1,5), &
52469                 ats%atom(i)%moment,ats%atom(i)%charge,"# "//ats%atom(i)%AtmInfo
52470
52471          if (ats%atom(i)%thtype == "aniso") then
52472
52473             if (ats%atom(i)%utype == "beta") then
52474                bet=ats%atom(i)%u(1:6)
52475                sb=ats%atom(i)%u_std(1:6)
52476                do j=1,6
52477                   call SetNum_Std(bet(j), sb(j), text(j))
52478                end do
52479                write (unit=iunit,fmt="(a,tr1,6a14)") "Beta  ", text
52480                if (present(Cell)) then
52481                   u=convert_betas_u(bet,cell)
52482                   sb=convert_betas_u(ats%atom(i)%u_std,cell)
52483                   do j=1,6
52484                      call SetNum_Std(u(j), sb(j), text(j))
52485                   end do
52486                   write(unit=iunit,fmt="(a,6a14)") "!U_ij  ", text
52487                end if
52488
52489             else if(ats%atom(i)%thtype == "u_ij") then
52490                u=ats%atom(i)%u(1:6)
52491                sb=ats%atom(i)%u_std(1:6)
52492                do j=1,6
52493                   call SetNum_Std(u(j), sb(j), text(j))
52494                end do
52495                write(unit=iunit,fmt="(a,6a14)") "U_ij  ", text
52496                if (present(Cell)) then
52497                   bet=convert_u_betas(u,cell)
52498                   sb=convert_u_betas(ats%atom(i)%u_std,cell)
52499                   do j=1,6
52500                      call SetNum_Std(bet(j), sb(j), text(j))
52501                   end do
52502                   write(unit=iunit,fmt="(a,6a14)") "!Beta  ", text
52503                end if
52504             end if
52505
52506          end if
52507       end do
52508
52509       return
52510    End Subroutine Write_Atoms_CFL_ATM
52511
52512    !!----
52513    !!---- Subroutine Write_Atoms_CFL(Ats,Lun,Cell)
52514    !!----    Type (atom_list_type),dimension(:),  intent(in) :: Ats     !  In -> Atom List
52515    !!----    integer, optional,                   intent(in) :: lun     !  In -> Unit to write
52516    !!----    Type(Crystal_Cell_Type), optional,   intent(in) :: Cell    !  In -> Transform to thermal parameters
52517    !!----
52518    !!----    Write the atoms in the asymmetric unit for a CFL file
52519    !!----
52520    !!---- Update: February - 2003
52521    !!
52522    Subroutine Write_Atoms_CFL_MOLX(Molx,Lun)
52523        !---- Arguments ----!
52524        type (Molecular_Crystal_Type), intent(in) :: Molx
52525        integer, optional,             intent(in) :: Lun
52526
52527        !---- Local Variables ----!
52528        character(len=30),dimension(6) :: text
52529        character(len=36)              :: forma,fom
52530        integer                        :: i, j, iunit, leng, maxl,ish
52531        real(kind=cp), dimension(6)    :: u,bet,sb
52532
52533        iunit=6
52534        if (present(lun)) iunit=lun
52535
52536        if(molx%n_free > 0) then
52537            !Determine the maximum length of the atom labels
52538            maxl=0
52539            do i=1,molx%n_free
52540                leng=len_trim(molx%atm(i)%lab)
52541                if(leng > maxl) maxl=leng
52542            end do
52543            maxl=max(maxl,4)+1
52544            ish=maxl-4
52545            fom   ="(a,tr  ,a)"
52546            Select Case(ish)
52547                Case(:9)
52548                    write(unit=fom(6:6),fmt="(i1)") ish
52549                Case(10:)
52550                    write(unit=fom(6:7),fmt="(i2)") ish
52551            End Select
52552            forma="(a,a  ,tr2,a,tr3,5a14,2f8.2,tr3,a)"
52553            Select Case(maxl)
52554                Case(:9)
52555                    write(unit=forma(5:5),fmt="(i1)") maxl
52556                Case(10:)
52557                    write(unit=forma(5:6),fmt="(i2)") maxl
52558            End Select
52559            write (unit=iunit,fmt=fom) "!     ", &
52560                  "Atom  Type     x/a           y/b           z/c           Biso          Occ           Spin    Charge    Info"
52561            do i=1,molx%n_free
52562
52563                do j=1,3
52564                   call SetNum_Std(molx%atm(i)%x(j), molx%atm(i)%x_std(j), text(j))
52565                end do
52566                call SetNum_Std(molx%atm(i)%Biso, molx%atm(i)%Biso_std, text(4))
52567                call SetNum_Std(molx%atm(i)%Occ, molx%atm(i)%Occ_std, text(5))
52568
52569                write (unit=iunit,fmt=forma) &
52570                      "Atom   ",trim(molx%atm(i)%lab),molx%atm(i)%chemsymb, (text(j),j=1,5), &
52571                       molx%atm(i)%moment,molx%atm(i)%charge,"# "//molx%atm(i)%AtmInfo
52572
52573                if (molx%atm(i)%thtype == "aniso") then
52574
52575                    if (molx%atm(i)%utype == "beta") then
52576                        bet=molx%atm(i)%u(1:6)
52577                        sb=molx%atm(i)%u_std(1:6)
52578                        do j=1,6
52579                            call SetNum_Std(bet(j), sb(j), text(j))
52580                        end do
52581                        write (unit=iunit,fmt="(a,tr1,6a14)") "Beta  ", text
52582                        u=convert_betas_u(bet,molx%cell)
52583                        sb=convert_betas_u(molx%atm(i)%u_std,molx%cell)
52584                        do j=1,6
52585                            call SetNum_Std(u(j), sb(j), text(j))
52586                        end do
52587                        write(unit=iunit,fmt="(a,6a14)") "!U_ij  ", text
52588                    else if(molx%atm(i)%thtype == "u_ij") then
52589                        u=molx%atm(i)%u(1:6)
52590                        sb=molx%atm(i)%u_std(1:6)
52591                        do j=1,6
52592                            call SetNum_Std(u(j), sb(j), text(j))
52593                        end do
52594                        write(unit=iunit,fmt="(a,6a14)") "U_ij  ", text
52595                        bet=convert_u_betas(u,molx%cell)
52596                        sb=convert_u_betas(molx%atm(i)%u_std,molx%cell)
52597                        do j=1,6
52598                            call SetNum_Std(bet(j), sb(j), text(j))
52599                        end do
52600                        write(unit=iunit,fmt="(a,6a14)") "!Beta  ", text
52601                    end if
52602                end if
52603            end do ! i=1,molx%n_free
52604        end if ! molx%n_free > 0
52605
52606        if (molx%n_mol > 0) then
52607            do i=1,molx%n_mol
52608                write(unit=iunit,fmt="(/,a,tr2,i3,tr2,a,tr2,a)") &
52609                     "MOLEX",molx%mol(i)%natoms,trim(molx%mol(i)%Name_mol),molx%mol(i)%coor_type
52610                write(unit=iunit,fmt="(a)") &
52611                     "!    Xc         Yc          Zc        Phi        Theta      Chi     TypeAngles TypeThermal"
52612                write(unit=iunit,fmt="(6f11.5,tr6,a,tr10,a)") &
52613                     molx%mol(i)%xcentre,molx%mol(i)%orient,molx%mol(i)%rot_type,molx%mol(i)%therm_type
52614                write(unit=iunit,fmt="(t1,6i10,tr2,a)") &
52615                     molx%mol(i)%lxcentre,molx%mol(i)%lorient," ! Refinemencodes"
52616
52617                select case (molx%mol(i)%coor_type)
52618                    case ("C","c")
52619                        write(unit=iunit,fmt="(a)") &
52620                        "!Atom   Type        XC          YC          ZC    N1  N2  N3      Biso        Occ "
52621                    case ("F","f")
52622                        write(unit=iunit,fmt="(a)") &
52623                        "!Atom   Type        X           Y           Z     N1  N2  N3      Biso        Occ "
52624                    case ("S","s")
52625                        write(unit=iunit,fmt="(a)") &
52626                        "!Atom   Type    distance      Theta       Phi     N1  N2  N3      Biso        Occ "
52627                    case ("Z","z")
52628                        write(unit=iunit,fmt="(a)") &
52629                        "!Atom   Type    distance  Bond-Angle Torsion-Ang  N1  N2  N3      Biso        Occ "
52630                    case default
52631                        write(unit=iunit,fmt="(a)") &
52632                        "!Atom   Type      Coor1       Coor2       Coor3   N1  N2  N3      Biso        Occ "
52633                end select ! molx%mol(i)%coor_type
52634
52635                do j=1,molx%mol(i)%natoms
52636                    write(unit=iunit,fmt="(a,tr2,a,3f12.5,3i4,2f12.5)")  &
52637                          molx%mol(i)%AtName(j), molx%mol(i)%AtSymb(j),molx%mol(i)%I_Coor(:,j),  &
52638                          molx%mol(i)%Conn(:,j), molx%mol(i)%Biso(j),  molx%mol(i)%Occ(j)
52639                end do ! j = molx%mol(i)%natoms
52640            end do ! i = 1,molx%n_mol
52641        end if ! molx%n_mol > 0
52642        return
52643    End Subroutine Write_Atoms_CFL_MOLX
52644    !!----
52645    !!---- Subroutine Write_Atoms_CFL(Ats,Lun,Cell)
52646    !!----    Type (atom_list_type),dimension(:),  intent(in) :: Ats     !  In -> Atom List
52647    !!----    integer, optional,                   intent(in) :: lun     !  In -> Unit to write
52648    !!----    Type(Crystal_Cell_Type), optional,   intent(in) :: Cell    !  In -> Transform to thermal parameters
52649    !!----
52650    !!----    Write the atoms in the asymmetric unit for a CFL file
52651    !!----
52652    !!---- Update: February - 2003
52653    !!
52654    Subroutine Write_Atoms_CFL_MOLX_orig(Molx,Lun)
52655       !---- Arguments ----!
52656       type (Molecular_Crystal_Type), intent(in) :: Molx
52657       integer, optional,             intent(in) :: Lun
52658
52659       !---- Local Variables ----!
52660       character(len=30),dimension(6) :: text
52661       character(len=36)              :: forma,fom
52662       integer                        :: i, j, iunit, leng, maxl,ish
52663       real(kind=cp), dimension(6)    :: u,bet,sb
52664
52665       iunit=6
52666       if (present(lun)) iunit=lun
52667
52668       if(molx%n_free == 0) then
52669         write (unit=iunit,fmt="(a)") "!  No atoms ..."
52670         return
52671       end if
52672       !Determine the maximum length of the atom labels
52673       maxl=0
52674       do i=1,molx%n_free
52675         leng=len_trim(molx%atm(i)%lab)
52676         if(leng > maxl) maxl=leng
52677       end do
52678       maxl=max(maxl,4)+1
52679       ish=maxl-4
52680       fom   ="(a,tr  ,a)"
52681       Select Case(ish)
52682          Case(:9)
52683            write(unit=fom(6:6),fmt="(i1)") ish
52684          Case(10:)
52685            write(unit=fom(6:7),fmt="(i2)") ish
52686       End Select
52687       forma="(a,a  ,tr2,a,tr3,5a14,2f8.2,tr3,a)"
52688       Select Case(maxl)
52689         Case(:9)
52690             write(unit=forma(5:5),fmt="(i1)") maxl
52691         Case(10:)
52692             write(unit=forma(5:6),fmt="(i2)") maxl
52693       End Select
52694       write (unit=iunit,fmt=fom) "!     ", &
52695             "Atom  Type     x/a           y/b           z/c           Biso          Occ           Spin    Charge    Info"
52696       do i=1,molx%n_free
52697
52698          do j=1,3
52699             call SetNum_Std(molx%atm(i)%x(j), molx%atm(i)%x_std(j), text(j))
52700          end do
52701          call SetNum_Std(molx%atm(i)%Biso, molx%atm(i)%Biso_std, text(4))
52702          call SetNum_Std(molx%atm(i)%Occ, molx%atm(i)%Occ_std, text(5))
52703
52704          write (unit=iunit,fmt=forma) &
52705                "Atom   ",trim(molx%atm(i)%lab),molx%atm(i)%chemsymb, (text(j),j=1,5), &
52706                 molx%atm(i)%moment,molx%atm(i)%charge,"# "//molx%atm(i)%AtmInfo
52707
52708          if (molx%atm(i)%thtype == "aniso") then
52709
52710             if (molx%atm(i)%utype == "beta") then
52711                bet=molx%atm(i)%u(1:6)
52712                sb=molx%atm(i)%u_std(1:6)
52713                do j=1,6
52714                   call SetNum_Std(bet(j), sb(j), text(j))
52715                end do
52716                write (unit=iunit,fmt="(a,tr1,6a14)") "Beta  ", text
52717                u=convert_betas_u(bet,molx%cell)
52718                sb=convert_betas_u(molx%atm(i)%u_std,molx%cell)
52719                do j=1,6
52720                    call SetNum_Std(u(j), sb(j), text(j))
52721                end do
52722                write(unit=iunit,fmt="(a,6a14)") "!U_ij  ", text
52723             else if(molx%atm(i)%thtype == "u_ij") then
52724                u=molx%atm(i)%u(1:6)
52725                sb=molx%atm(i)%u_std(1:6)
52726                do j=1,6
52727                   call SetNum_Std(u(j), sb(j), text(j))
52728                end do
52729                write(unit=iunit,fmt="(a,6a14)") "U_ij  ", text
52730                bet=convert_u_betas(u,molx%cell)
52731                sb=convert_u_betas(molx%atm(i)%u_std,molx%cell)
52732                do j=1,6
52733                    call SetNum_Std(bet(j), sb(j), text(j))
52734                end do
52735                write(unit=iunit,fmt="(a,6a14)") "!Beta  ", text
52736             end if
52737          end if
52738       end do
52739
52740       return
52741    End Subroutine Write_Atoms_CFL_MOLX_orig
52742
52743 End Module CFML_IO_Formats
52744
52745!!-------------------------------------------------------
52746!!---- Crystallographic Fortran Modules Library (CrysFML)
52747!!-------------------------------------------------------
52748!!---- The CrysFML project is distributed under LGPL. In agreement with the
52749!!---- Intergovernmental Convention of the ILL, this software cannot be used
52750!!---- in military applications.
52751!!----
52752!!---- Copyright (C) 1999-2012  Institut Laue-Langevin (ILL), Grenoble, FRANCE
52753!!----                          Universidad de La Laguna (ULL), Tenerife, SPAIN
52754!!----                          Laboratoire Leon Brillouin(LLB), Saclay, FRANCE
52755!!----
52756!!---- Authors: Juan Rodriguez-Carvajal (ILL)
52757!!----          Javier Gonzalez-Platas  (ULL)
52758!!----
52759!!---- Contributors: Laurent Chapon     (ILL)
52760!!----               Marc Janoschek     (Los Alamos National Laboratory, USA)
52761!!----               Oksana Zaharko     (Paul Scherrer Institute, Switzerland)
52762!!----               Tierry Roisnel     (CDIFX,Rennes France)
52763!!----               Eric Pellegrini    (ILL)
52764!!----
52765!!---- This library is free software; you can redistribute it and/or
52766!!---- modify it under the terms of the GNU Lesser General Public
52767!!---- License as published by the Free Software Foundation; either
52768!!---- version 3.0 of the License, or (at your option) any later version.
52769!!----
52770!!---- This library is distributed in the hope that it will be useful,
52771!!---- but WITHOUT ANY WARRANTY; without even the implied warranty of
52772!!---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
52773!!---- Lesser General Public License for more details.
52774!!----
52775!!---- You should have received a copy of the GNU Lesser General Public
52776!!---- License along with this library; if not, see <http://www.gnu.org/licenses/>.
52777!!----
52778!!----
52779!!---- MODULE: CFML_Structure_Factors
52780!!----   INFO: Main module for Structure Factors Calculations
52781!!----
52782!!---- HISTORY
52783!!----    Update: 06/03/2011
52784!!----
52785!!----
52786!!---- DEPENDENCIES
52787!!----
52788!!--++     Use CFML_Scattering_Chemical_Tables
52789!!--++     Use CFML_Crystallographic_Symmetry,   only: Space_Group_Type
52790!!--++     Use CFML_Reflections_Utilities,       only: Reflection_List_Type, HKL_R
52791!!--++     Use CFML_Atom_TypeDef,                only: atom_list_type
52792!!--++     Use CFML_GlobalDeps,                  only: sp, tpi
52793!!--++     Use CFML_Math_General,                only: atan2d
52794!!--++     Use CFML_String_Utilities,            only: L_Case,U_Case
52795!!----
52796!!---- VARIABLES
52797!!--++    AF0                             [Private]
52798!!--++    AFP                             [Private]
52799!!--++    AFPP                            [Private]
52800!!--++    AJH                             [Private]
52801!!--++    BJH                             [Private]
52802!!----    ERR_SFAC
52803!!----    ERR_SFAC_MESS
52804!!--++    HR_TYPE                         [Private]
52805!!--++    HR                              [Private]
52806!!--++    HT                              [Private]
52807!!--++    SF_INITIALIZED                  [Private]
52808!!--++    TH                              [Private]
52809!!----
52810!!---- PUBLIC PROCEDURES
52811!!----    Functions:
52812!!--++       FJ                           [Private]
52813!!----
52814!!----    Subroutines:
52815!!--++       CALC_TABLE_AB                [Private]
52816!!--++       CALC_TABLE_TH                [Private]
52817!!----       CALC_HKL_STRFACTOR
52818!!----       CALC_STRFACTOR
52819!!--++       CREATE_TABLE_AF0_ELECTRONS   [Private]
52820!!--++       CREATE_TABLE_AF0_XRAY        [Private]
52821!!--++       CREATE_TABLE_AFP_NEUTNUC     [Private]
52822!!--++       CREATE_TABLE_FABC_XRAY       [Private]
52823!!--++       CREATE_TABLE_HR_HT           [Private]
52824!!----       INIT_HKL_STRUCTURE_FACTORS
52825!!----       INIT_STRUCTURE_FACTORS
52826!!----       MODIFY_SF
52827!!--++       SET_FIXED_TABLES             [Private]
52828!!----       STRUCTURE_FACTORS
52829!!--++       SUM_AB                       [Private]
52830!!--++       SUM_AB_NEUTNUC               [Private]
52831!!----       WRITE_STRUCTURE_FACTORS
52832!!----
52833!!
52834 Module CFML_Structure_Factors
52835
52836    !---- Use Modules ----!
52837    Use CFML_GlobalDeps,                  only: cp, tpi
52838    Use CFML_Math_General,                only: atan2d
52839    Use CFML_String_Utilities,            only: L_Case,U_Case
52840    Use CFML_Scattering_Chemical_Tables
52841    Use CFML_Crystallographic_Symmetry,   only: Space_Group_Type
52842    Use CFML_Reflections_Utilities,       only: Reflection_List_Type, HKL_R
52843    Use CFML_Atom_TypeDef,                only: atom_list_type
52844
52845    !---- Variables ----!
52846    implicit none
52847
52848    private
52849
52850    !---- List of public functions ----!
52851
52852    !---- List of public subroutines ----!
52853    public :: Init_Structure_Factors,Init_Calc_hkl_StrFactors, Structure_Factors,  &
52854              Modify_SF, Write_Structure_Factors,Calc_StrFactor, Calc_hkl_StrFactor, &
52855              Init_Calc_StrFactors
52856
52857    !---- List of private functions ----!
52858    private :: Fj
52859
52860    !---- List of private subroutines ----!
52861    private :: Calc_Table_AB, Create_Table_AF0_Xray, Create_Table_AFP_NeutNuc, &
52862               Create_Table_HR_HT, Set_Fixed_Tables, Calc_Table_TH, Sum_AB,    &
52863               Sum_AB_NeutNuc, Create_Table_Fabc_Xray, Create_Table_AF0_Electrons
52864
52865    !---- Definitions ----!
52866
52867    !!--++
52868    !!--++ AF0
52869    !!--++     real(kind=cp), dimension(:,:), allocatable, private :: AF0
52870    !!--++
52871    !!--++     Array for Atomic Factor. The dimensions are
52872    !!--++           AF0(Natoms,NRef)
52873    !!--++
52874    !!--++ Update: December - 2003
52875    !!
52876    real(kind=cp), dimension(:,:), allocatable, private :: AF0
52877
52878    !!--++
52879    !!--++ AFP
52880    !!--++     real(kind=cp), dimension(:), allocatable, private :: AFP
52881    !!--++
52882    !!--++     Array for real part of anomalous scattering form factor.
52883    !!--++     The dimension is: AFP(Natoms)
52884    !!--++
52885    !!--++ Update: December - 2003
52886    !!
52887    real(kind=cp), dimension(:), allocatable, private :: AFP
52888
52889    !!--++
52890    !!--++ AFPP
52891    !!--++     real(kind=cp), dimension(:), allocatable, private :: AFPP
52892    !!--++
52893    !!--++     Array for imaginary part of anomalous scattering form factor.
52894    !!--++     The dimension is: AFPP(Natoms)
52895    !!--++
52896    !!--++ Update: December - 2003
52897    !!
52898    real(kind=cp), dimension(:), allocatable, private :: AFPP
52899
52900    !!--++
52901    !!--++ AJH
52902    !!--++     real(kind=cp), dimension(:,:), allocatable, private :: Ajh
52903    !!--++
52904    !!--++     Array for Aj(h). The dimensions are
52905    !!--++           Ajh(Natoms,Nref)
52906    !!--++     where
52907    !!--++           F(h)=Sum_j[Fj(h){Aj(h)+i Bj(h)}]
52908    !!--++
52909    !!--++ Update: December - 2003
52910    !!
52911    real(kind=cp), dimension(:,:), allocatable, private :: AJH
52912
52913    !!--++
52914    !!--++ BJH
52915    !!--++     real(kind=cp), dimension(:,:), allocatable, private :: Bjh
52916    !!--++
52917    !!--++     Array for Bj(h). The dimensions are
52918    !!--++           Bjh(Natoms,Nref)
52919    !!--++     where
52920    !!--++           F(h)=Sum_j[Fj(h){Aj(h)+i Bj(h)}]
52921    !!--++
52922    !!--++ Update: December - 2003
52923    !!
52924    real(kind=cp), dimension(:,:), allocatable, private :: BJH
52925
52926    !!----
52927    !!---- ERR_SFAC
52928    !!----    logical, public ::
52929    !!----
52930    !!----    Logical Variable in
52931    !!----
52932    !!---- Update: February - 200
52933    !!
52934    logical, public :: ERR_SFac
52935
52936    !!----
52937    !!---- ERR_SFac_Mess
52938    !!----    character(len=150), public :: ERR_SFac_Mess
52939    !!----
52940    !!----    String containing information about the last error
52941    !!----
52942    !!---- Update: February - 2005
52943    !!
52944    character(len=150), public :: ERR_SFac_Mess
52945
52946
52947    !!--++
52948    !!--++ FF_A, FF_B, FF_C, FF_Z
52949    !!--++     real(kind=cp), dimension(:,:), allocatable, private :: FF_a,FF_b
52950    !!--++     real(kind=cp), dimension(  :), allocatable, private :: FF_c
52951    !!--++
52952    !!--++     Arrays for coefficients of X-rays scattering form factors.
52953    !!--++     The dimensions are: AFP(Nspecies)
52954    !!--++      FF_A(4,Nspecies), FF_B(4,Nspecies), FF_C(Nspecies), FF_Z(Nspecies)
52955    !!--++     Constructed in Create_Table_fabc_Xray(Atm,lambda,lun)
52956    !!--++     FF_Z contains atomic number Z (useful for electron diffraction)
52957    !!--++
52958    !!--++ Update: April - 2009
52959    !!
52960    real(kind=cp), dimension(:,:), allocatable, private :: FF_a, FF_b
52961    real(kind=cp), dimension(  :), allocatable, private :: FF_c
52962    real(kind=cp), dimension(  :), allocatable, private :: FF_Z
52963
52964    !!--++
52965    !!--++    Type :: HR_Type
52966    !!--++       integer,dimension(3) :: H
52967    !!--++    End Type HR_Type
52968    !!--++
52969    !!--++    (Private)
52970    !!--++    Define a H vector
52971    !!--++
52972    !!--++ Update: February - 2005
52973    !!
52974    Type, Private :: HR_Type
52975       integer, dimension(3) :: H
52976    End Type HR_Type
52977
52978    !!--++
52979    !!--++ HR
52980    !!--++     type(HR_Type), dimension(:,:), allocatable, private :: Hr
52981    !!--++
52982    !!--++     Array for HR Calculations. The dimension are
52983    !!--++           HR(Natoms,NRef)
52984    !!--++
52985    !!--++ Update: February - 2005
52986    !!
52987    type(HR_Type), dimension(:,:), allocatable, private :: HR
52988
52989    !!--++
52990    !!--++ HT
52991    !!--++    real(kind=cp), dimension(:,:), allocatable, private :: Ht
52992    !!--++
52993    !!--++    Array for HT Calculations. The dimension are
52994    !!--++          HT(Natoms,Nref)
52995    !!--++
52996    !!--++ Update: February - 2005
52997    !!
52998    real(kind=cp), dimension(:,:), allocatable, private :: HT
52999
53000    !!--++
53001    !!--++ Nspecies
53002    !!--++     integer, private :: Nspecies
53003    !!--++
53004    !!--++     Number of chemical species for X-rays scattering form factors.
53005    !!--++  Constructed in Create_Table_fabc_Xray(Atm,lambda,lun)
53006    !!--++
53007    !!--++ Update: April - 2009
53008    !!
53009    integer, private :: Nspecies
53010
53011    !!--++
53012    !!--++ P_A
53013    !!--++     integer, dimension(:), allocatable, private :: P_A
53014    !!--++
53015    !!--++     Integer pointer from atoms to species: P_A(Natoms), contains the species
53016    !!--++     of atom Natoms. Constructed in Create_Table_fabc_Xray(Atm,lambda,lun)
53017    !!--++
53018    !!--++ Update: April - 2009
53019    !!
53020    integer, dimension(:), allocatable, private :: P_A
53021
53022    !!----
53023    !!---- SF_Initialized
53024    !!----    logical, private :: SF_Initialized
53025    !!----
53026    !!----  Logical Variable indicating if the module has been initialized.
53027    !!----
53028    !!---- Update: February - 2005
53029    !!
53030    logical, private :: SF_Initialized=.false.
53031
53032    !!--++
53033    !!--++ TH
53034    !!--++    real(kind=cp), dimension(:,:), allocatable, private :: Th
53035    !!--++
53036    !!--++    Array for TH Calculations. The dimension are
53037    !!--++          TH(Natoms,Nref)
53038    !!--++
53039    !!--++ Update: February - 2005
53040    !!
53041    real(kind=cp), dimension(:,:), allocatable, private :: TH
53042
53043 Contains
53044
53045    !---- Functions ----!
53046
53047    !!--++
53048    !!--++ Pure Function Fj(s,a,b,c)
53049    !!--++    real(kind=cp),             intent(in) :: s
53050    !!--++    real(kind=cp),dimension(4),intent(in) :: a
53051    !!--++    real(kind=cp),dimension(4),intent(in) :: b
53052    !!--++    real(kind=cp),             intent(in) :: c
53053    !!--++
53054    !!--++    (Private)
53055    !!--++    Atomic scattering factor calculation according to:
53056    !!--++       Fj(s)=Sum_i[Ai*exp(-Bi*s*s)] + C (i=1..4)
53057    !!--++
53058    !!--++ Update: February - 2005
53059    !!
53060    Pure Function Fj(s,a,b,c) Result(res)
53061       !---- Arguments ----!
53062       real(kind=cp),             intent(in) :: s
53063       real(kind=cp),dimension(4),intent(in) :: a
53064       real(kind=cp),dimension(4),intent(in) :: b
53065       real(kind=cp),             intent(in) :: c
53066       real(kind=cp)                         :: res
53067
53068       !---- Local variables ----!
53069       integer :: i
53070
53071       res=0.0
53072       do i=1,4
53073          res=res + a(i)*exp(-b(i)*s*s)
53074       end do
53075       res=res+c
53076
53077       return
53078    End Function Fj
53079
53080    !---- Subroutines ----!
53081
53082    !!--++
53083    !!--++ Subroutine Calc_Table_AB(Nref,Atm,Grp)
53084    !!--++    integer,                            intent(in) :: Nref
53085    !!--++    type(atom_list_type),              intent(in) :: Atm
53086    !!--++    type(space_group_type),             intent(in) :: Grp
53087    !!--++
53088    !!--++    (Private)
53089    !!--++    Calculate Table with Aj(h) and Bj(h) values
53090    !!--++
53091    !!--++ Update: February - 2005
53092    !!
53093    Subroutine Calc_Table_AB(Nref,Atm,Grp)
53094       !---- Arguments ----!
53095       integer,                            intent(in) :: Nref
53096       type(atom_list_type),               intent(in) :: Atm
53097       type(space_group_type),             intent(in) :: Grp
53098
53099       !---- Local Variables ----!
53100       integer                       :: i,j,k
53101       real(kind=cp)                 :: arg,anis
53102       real(kind=cp),dimension(3)    :: h
53103       real(kind=cp),dimension(6)    :: beta
53104
53105       Ajh=0.0
53106       Bjh=0.0
53107       if(Grp%Centred == 2) then
53108         do j=1,Nref
53109            do i=1,Atm%natoms
53110               arg=0.0
53111               do k=1,grp%NumOps
53112                  h=hr(k,j)%h
53113                  arg=tpi*(dot_product(h,Atm%atom(i)%x)+ht(k,j))
53114                  anis=1.0
53115                  if(Atm%atom(i)%thtype == "aniso") then
53116                    beta=Atm%atom(i)%u(1:6)
53117                    anis=     h(1)*h(1)*beta(1)+     h(2)*h(2)*beta(2)+    h(3)*h(3)*beta(3) &
53118                         +2.0*h(1)*h(2)*beta(4)+ 2.0*h(1)*h(3)*beta(5)+2.0*h(2)*h(3)*beta(6)
53119                    anis=exp(-anis)
53120                  end if
53121                  Ajh(i,j)=Ajh(i,j)+cos(arg)*anis
53122               end do ! symmetry
53123            end do ! Atoms
53124         end do ! Reflections
53125       else
53126         do j=1,Nref
53127            do i=1,Atm%natoms
53128               arg=0.0
53129               do k=1,grp%NumOps
53130                  h=hr(k,j)%h
53131                  arg=tpi*(dot_product(h,Atm%atom(i)%x)+ht(k,j))
53132                  anis=1.0
53133                  if(Atm%atom(i)%thtype == "aniso") then
53134                    beta=Atm%atom(i)%u(1:6)
53135                    anis=     h(1)*h(1)*beta(1)+     h(2)*h(2)*beta(2)+    h(3)*h(3)*beta(3) &
53136                         +2.0*h(1)*h(2)*beta(4)+ 2.0*h(1)*h(3)*beta(5)+2.0*h(2)*h(3)*beta(6)
53137                    anis=exp(-anis)
53138                  end if
53139                  Ajh(i,j)=Ajh(i,j)+cos(arg)*anis
53140                  Bjh(i,j)=Bjh(i,j)+sin(arg)*anis
53141               end do ! symmetry
53142            end do ! Atoms
53143         end do ! Reflections
53144       end if
53145
53146       return
53147    End Subroutine Calc_Table_AB
53148
53149    !!----
53150    !!---- Subroutine Calc_StrFactor(mode,rad,nn,sn,Atm,Grp,sf2,deriv,fc)
53151    !!----    character(len=*),                   intent(in) :: mode !S-XTAL (S) or Powder (P)
53152    !!----    character(len=*),                   intent(in) :: rad  !Radiation: X-rays, Neutrons
53153    !!----    integer,                            intent(in) :: nn
53154    !!----    real(kind=cp)                       intent(in) :: sn !(sinTheta/Lambda)**2
53155    !!----    type(atom_list_type),               intent(in) :: Atm
53156    !!----    type(space_group_type),             intent(in) :: Grp
53157    !!----    real(kind=cp)                       intent(out):: sf2
53158    !!----    real(kind=cp),dimension(:),optional,intent(out):: deriv
53159    !!----    complex, optional,                  intent(out):: fc
53160    !!----
53161    !!----    Calculate Structure Factor for reflection "nn" in the list
53162    !!----    and derivatives with respect to refined parameters
53163    !!----
53164    !!---- Update: February - 2005
53165    !!
53166    Subroutine Calc_StrFactor(mode,rad,nn,sn,Atm,Grp,sf2,deriv,fc)
53167       !---- Arguments ----!
53168       character(len=*),                   intent(in) :: mode
53169       character(len=*),                   intent(in) :: rad
53170       integer,                            intent(in) :: nn
53171       real(kind=cp),                      intent(in) :: sn !(sinTheta/Lambda)**2
53172       type(atom_list_type),               intent(in) :: Atm
53173       type(space_group_type),             intent(in) :: Grp
53174       real(kind=cp),                      intent(out):: sf2
53175       real(kind=cp),dimension(:),optional,intent(out):: deriv
53176       complex, optional,                  intent(out):: fc
53177
53178       !---- Local Variables ----!
53179       character(len=1)                      :: modi
53180       integer                               :: i,j,k,m
53181       real(kind=cp)                         :: arg,anis,cosr,sinr,scosr,ssinr,fr,der !,fi
53182       real(kind=cp)                         :: a1,a2,a3,a4,b1,b2,b3,b4,av,bv,f
53183       real(kind=cp),dimension(3)            :: h
53184       real(kind=cp),dimension(6)            :: beta
53185       real(kind=cp),dimension(Atm%natoms)   :: frc,frs,otr,oti,afpxn
53186       real(kind=cp),dimension(9,Atm%natoms) :: drs,drc
53187
53188       !--- Initialising local variables
53189       a1=0.0
53190       a2=0.0
53191       a3=0.0
53192       a4=0.0
53193       b1=0.0
53194       b2=0.0
53195       b3=0.0
53196       b4=0.0
53197       av=0.0
53198       bv=0.0
53199       fr=1.0
53200       !fi=0.0
53201       frc=0.0
53202       frs=0.0
53203       otr=0.0
53204       oti=0.0
53205       modi=u_case(mode(1:1))
53206       if(rad(1:1) == "N") then
53207         afpxn(:)=afp(:)
53208       else
53209         afpxn(:)=af0(:,nn)
53210       end if
53211
53212       if(Grp%Centred == 2) then
53213            do i=1,Atm%natoms
53214               arg=0.0
53215               scosr=0.0
53216               ssinr=0.0
53217               drs(:,i)=0.0
53218               drc(:,i)=0.0
53219               do k=1,grp%NumOps
53220                  h=hr(k,nn)%h
53221                  arg=tpi*(dot_product(h,Atm%atom(i)%x)+ht(k,nn))
53222                  anis=1.0
53223                  if(Atm%atom(i)%thtype == "aniso") then
53224                    beta=Atm%atom(i)%u(1:6)
53225                    anis=     h(1)*h(1)*beta(1)+     h(2)*h(2)*beta(2)+    h(3)*h(3)*beta(3) &
53226                         +2.0*h(1)*h(2)*beta(4)+ 2.0*h(1)*h(3)*beta(5)+2.0*h(2)*h(3)*beta(6)
53227                    anis=exp(-anis)
53228                  end if
53229                  cosr=COS(arg)*anis*fr     !fr*cos{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53230                  scosr=scosr+cosr          !FRC= SIG fr(j,s)cos{2pi(hT Rs rj+ts)}*Ta(s)
53231
53232                  if(present(deriv)) then
53233                     sinr=SIN(arg)*anis*fr   !fr*sin{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53234                     drc(1:3,i)=drc(1:3,i)+h(1:3)*sinr      ! -
53235                     drc(4,i)=drc(4,i)+h(1)*h(1)*cosr
53236                     drc(5,i)=drc(5,i)+h(2)*h(2)*cosr
53237                     drc(6,i)=drc(6,i)+h(3)*h(3)*cosr
53238                     drc(7,i)=drc(7,i)+h(1)*h(2)*cosr
53239                     drc(8,i)=drc(8,i)+h(1)*h(3)*cosr
53240                     drc(9,i)=drc(9,i)+h(2)*h(3)*cosr
53241                  end if
53242
53243               end do ! symmetry
53244
53245               frc(i) = scosr
53246               otr(i) = afpxn(i)*th(i,nn)
53247               oti(i) =  afpp(i)*th(i,nn)
53248               a1= a1 + otr(i)*frc(i)
53249               b1= b1 + oti(i)*frc(i)
53250
53251            end do ! Atoms
53252
53253            av = a1-a2-a3-a4    !real part of the structure factor
53254            bv = b1-b2+b3+b4    !imaginary part of the structure factor
53255
53256       else
53257
53258            do i=1,Atm%natoms
53259               arg=0.0
53260               scosr=0.0
53261               ssinr=0.0
53262               drs(:,i)=0.0
53263               drc(:,i)=0.0
53264               do k=1,grp%NumOps
53265                  h=hr(k,nn)%h
53266                  arg=tpi*(dot_product(h,Atm%atom(i)%x)+ht(k,nn))
53267                  anis=1.0
53268                  if(Atm%atom(i)%thtype == "aniso") then
53269                    beta=Atm%atom(i)%u(1:6)
53270                    anis=     h(1)*h(1)*beta(1)+     h(2)*h(2)*beta(2)+    h(3)*h(3)*beta(3) &
53271                         +2.0*h(1)*h(2)*beta(4)+ 2.0*h(1)*h(3)*beta(5)+2.0*h(2)*h(3)*beta(6)
53272                    anis=exp(-anis)
53273                  end if
53274                  cosr=COS(arg)*anis*fr     !fr*cos{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53275                  sinr=SIN(arg)*anis*fr     !fr*sin{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53276                  scosr=scosr+cosr          !FRC= SIG fr(j,s)cos{2pi(hT Rs rj+ts)}*Ta(s)
53277                  ssinr=ssinr+sinr          !FRS= SIG fr(j,s)sin{2pi(hT Rs rj+ts)}*Ta(s)
53278
53279                  if(present(deriv)) then
53280                     drc(1:3,i)=drc(1:3,i)+h(1:3)*sinr      ! -
53281                     drs(1:3,i)=drs(1:3,i)+h(1:3)*cosr      ! +
53282
53283                     drc(4,i)=drc(4,i)+h(1)*h(1)*cosr
53284                     drc(5,i)=drc(5,i)+h(2)*h(2)*cosr
53285                     drc(6,i)=drc(6,i)+h(3)*h(3)*cosr
53286                     drc(7,i)=drc(7,i)+h(1)*h(2)*cosr
53287                     drc(8,i)=drc(8,i)+h(1)*h(3)*cosr
53288                     drc(9,i)=drc(9,i)+h(2)*h(3)*cosr
53289
53290                     drs(4,i)=drs(4,i)+h(1)*h(1)*sinr
53291                     drs(5,i)=drs(5,i)+h(2)*h(2)*sinr
53292                     drs(6,i)=drs(6,i)+h(3)*h(3)*sinr
53293                     drs(7,i)=drs(7,i)+h(1)*h(2)*sinr
53294                     drs(8,i)=drs(8,i)+h(1)*h(3)*sinr
53295                     drs(9,i)=drs(9,i)+h(2)*h(3)*sinr
53296                  end if
53297
53298               end do ! symmetry
53299
53300               frc(i) = scosr
53301               frs(i) = ssinr
53302               otr(i) = afpxn(i)*th(i,nn)
53303               oti(i) =  afpp(i)*th(i,nn)
53304               a1= a1 + otr(i)*frc(i)
53305               b1= b1 + oti(i)*frc(i)
53306               a3 = a3 + oti(i)*frs(i)
53307               b3 = b3 + otr(i)*frs(i)
53308
53309            end do ! Atoms
53310
53311            av = a1-a2-a3-a4    !real part of the structure factor
53312            bv = b1-b2+b3+b4    !imaginary part of the structure factor
53313
53314       end if
53315
53316       If(modi == "P") then
53317          sf2 = a1*a1 + a2*a2 + a3*a3 + a4*a4 + b1*b1 + b2*b2 + b3*b3 + b4*b4
53318          sf2 = sf2 + 2.0*(b1*b4 -  a1*a4 + a2*a3 - b2*b3)
53319       else
53320          sf2= av*av+bv*bv
53321       End if
53322
53323       if(present(fc)) then
53324         fc=cmplx(av,bv)
53325       end if
53326
53327       if(present(deriv)) then
53328
53329         if(modi == "P") then
53330
53331             do i=1,Atm%natoms
53332                !derivatives with respect to coordinates  POWDER
53333                do m=1,3
53334                   k= Atm%atom(i)%lx(m)
53335                   if(k /= 0) then
53336                     f=atm%atom(i)%mx(m)
53337                     der= otr(i)*(-a1*drc(m,i)+b3*drs(m,i))+oti(i)*(-b1*drc(m,i)+a3*drs(m,i))
53338                     der=2.0*der*tpi
53339                     deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53340                   end if
53341                 end do
53342
53343                 k=Atm%atom(i)%lbiso  !Derivatives w.r.t. Biso  POWDER
53344                 if(k /= 0) then
53345                   f=Atm%atom(i)%mbiso
53346                   der= otr(i)*(a1*frc(i) +b3*frs(i))+oti(i)*(b1*frc(i) +a3*frs(i))
53347                   der=-2.0*der*sn
53348                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53349                 end if
53350
53351                 k=Atm%atom(i)%locc    !Derivatives w.r.t. occupation factor   POWDER
53352                 if(k /= 0) then
53353                   f=Atm%atom(i)%mocc
53354                   der= otr(i)*(a1*frc(i)+b3*frs(i))+oti(i)*(b1*frc(i)+a3*frs(i))
53355                   der=2.0*der/atm%atom(i)%occ
53356                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53357                 end if
53358
53359                 do m=4,9      !Derivatives w.r.t. anisotropic temperature factors   POWDER
53360                    j=m-3
53361                    k=Atm%atom(i)%lu(j)
53362                    if(k /= 0) then
53363                      f=Atm%atom(i)%mu(j)
53364                      der=  otr(i)*(a1*drc(i,j)+b3*drs(m,i))+oti(i)*(b1*drc(m,i)+a3*drs(m,i))
53365                      der=-2.0*der
53366                      if(j > 3) der=2.0*der
53367                      deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53368                    end if
53369                 end do
53370
53371             end do
53372
53373         else
53374
53375             do i=1,Atm%natoms
53376                !derivatives with respect to coordinates  S-XTAL
53377                do m=1,3
53378                   k= Atm%atom(i)%lx(m)
53379                   if(k /= 0) then
53380                     f=atm%atom(i)%mx(m)
53381                     der=   -av*(otr(i)*drc(m,i) + oti(i)*drs(m,i))
53382                     der=der-bv*(oti(i)*drc(m,i) - otr(i)*drs(m,i))
53383                     der=2.0*der*tpi
53384                     deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53385                   end if
53386                 end do
53387
53388                 k=Atm%atom(i)%lbiso  !Derivatives w.r.t. Biso  S-XTAL
53389                 if(k /= 0) then
53390                   f=Atm%atom(i)%mbiso
53391                   der=   -av*( otr(i)*frc(i) - oti(i)*frs(i) )
53392                   der=der-bv*( oti(i)*frc(i) + otr(i)*frs(i) )
53393                   der=2.0*der*sn
53394                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53395                 end if
53396
53397                 k=Atm%atom(i)%locc    !Derivatives w.r.t. occupation factor  S-XTAL
53398                 if(k /= 0) then
53399                   f=Atm%atom(i)%mocc
53400                   der=    av*( otr(i)*frc(i) - oti(i)*frs(i) )
53401                   der=der+bv*( oti(i)*frc(i) + otr(i)*frs(i) )
53402                   der=2.0*der/atm%atom(i)%occ
53403                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53404                 end if
53405
53406                 do m=4,9        !Derivatives w.r.t. anisotropic temperature factors S-XTAL
53407                    j=m-3
53408                    k=Atm%atom(i)%lu(j)
53409                    if(k /= 0) then
53410                      f=Atm%atom(i)%mu(j)
53411                      der=   -av*(otr(i)*drc(m,i) - oti(i)*drs(m,i))
53412                      der=der-bv*(oti(i)*drc(m,i) + otr(i)*drs(m,i))
53413                      der=2.0*der
53414                      if(j > 3) der=2.0*der
53415                      deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53416                    end if
53417                 end do
53418
53419             end do
53420         end if !modi
53421       end if  !derivatives
53422
53423       return
53424    End Subroutine Calc_StrFactor
53425
53426    !!--++
53427    !!----
53428    !!---- Subroutine Calc_hkl_StrFactor(mode,rad,hn,sn,Atm,Grp,sf2,deriv,fc)
53429    !!----    character(len=*),                   intent(in) :: mode !S-XTAL (S) or Powder (P)
53430    !!----    character(len=*),                   intent(in) :: rad  !Radiation: X-rays, Neutrons
53431    !!----    integer, dimension(3)               intent(in) :: hn
53432    !!----    real(kind=cp)                       intent(in) :: sn !(sinTheta/Lambda)**2
53433    !!----    type(atom_list_type),               intent(in) :: Atm
53434    !!----    type(space_group_type),             intent(in) :: Grp
53435    !!----    real(kind=cp)                       intent(out):: sf2
53436    !!----    real(kind=cp),dimension(:),optional,intent(out):: deriv
53437    !!----    complex, optional,                  intent(out):: fc
53438    !!----
53439    !!----    Calculate Structure Factor for reflection "h=(hkl)" not related with
53440    !!----    previous lists and derivatives with respect to refined parameters.
53441    !!----    This subroutine calculates the form-factors internally without using
53442    !!----    global tables. The purpose of this procedure is to avoid the use of
53443    !!----    too much memory in tables.
53444    !!----
53445    !!---- Update: April - 2009
53446    !!
53447    Subroutine Calc_hkl_StrFactor(mode,rad,hn,sn,Atm,Grp,sf2,deriv,fc)
53448       !---- Arguments ----!
53449       character(len=*),                   intent(in) :: mode
53450       character(len=*),                   intent(in) :: rad
53451       integer,dimension(3),               intent(in) :: hn
53452       real(kind=cp),                      intent(in) :: sn !(sinTheta/Lambda)**2
53453       type(atom_list_type),               intent(in) :: Atm
53454       type(space_group_type),             intent(in) :: Grp
53455       real(kind=cp),                      intent(out):: sf2
53456       real(kind=cp),dimension(:),optional,intent(out):: deriv
53457       complex, optional,                  intent(out):: fc
53458
53459       !---- Local Variables ----!
53460       character(len=1)                      :: modi
53461       integer                               :: i,j,k,m
53462       real(kind=cp)                         :: arg,anis,cosr,sinr,scosr,ssinr,fr,fi,der, hnt
53463       real(kind=cp)                         :: a1,a2,a3,a4,b1,b2,b3,b4,av,bv,f,occ,b, Tob
53464       real(kind=cp),dimension(3)            :: h
53465       real(kind=cp),dimension(6)            :: beta
53466       real(kind=cp),dimension(Atm%natoms)   :: frc,frs,otr,oti,afpxn,ff
53467       real(kind=cp),dimension(9,Atm%natoms) :: drs,drc
53468
53469
53470       !--- Initialising local variables
53471       a1=0.0
53472       a2=0.0
53473       a3=0.0
53474       a4=0.0
53475       b1=0.0
53476       b2=0.0
53477       b3=0.0
53478       b4=0.0
53479       av=0.0
53480       bv=0.0
53481       frc=0.0
53482       frs=0.0
53483       otr=0.0
53484       oti=0.0
53485       modi=u_case(mode(1:1))
53486       !Setting up the scattering form factors and multiply by group specific
53487       !coefficients for calculating structure factors per conventional cell
53488       !---- Modify the scattering factors to include the
53489       !---- multipliers factors concerning centre of symmetry and
53490       !---- centred translations
53491       fr=1.0; fi=1.0
53492       if (Grp%Centred == 2) fr=2.0
53493       if (Grp%NumLat  > 1)  fi=Grp%NumLat
53494       Select Case (rad(1:1))
53495          Case("N")
53496              afpxn(:)=fr*fi*afp(:)
53497          Case("X","E")
53498              do i=1,Nspecies
53499                ff(i)=FF_c(i)
53500                do j=1,4
53501                 ff(i)=ff(i)+FF_a(j,i)*exp(-sn*FF_b(j,i))
53502                end do
53503                 if (rad(1:1) == "E") ff(i)=0.023934*(FF_Z(i)-ff(i))/sn !Mott-Bethe formula fe=me^2/(8pi Eps0 h^2) (Z-fx(s))/s^2
53504              end do
53505              do i=1,Atm%natoms
53506                j=P_a(i)   !pointer has been set up in Initialization subroutine
53507                afpxn(i)= fr*fi*ff(j)
53508              end do
53509       End Select
53510
53511       fr=1.0
53512       fi=0.0
53513       if(Grp%Centred == 2) then
53514            do i=1,Atm%natoms
53515               arg=0.0
53516               scosr=0.0
53517               ssinr=0.0
53518               drs(:,i)=0.0
53519               drc(:,i)=0.0
53520               do k=1,grp%NumOps
53521                  h=Hkl_R(hn,grp%symop(k))                   !Calculations in-lining
53522                  hnt=dot_product(real(hn),Grp%SymOp(k)%Tr)  !Calculations in-lining
53523                  arg=tpi*(dot_product(h,Atm%atom(i)%x)+hnt)
53524                  anis=1.0
53525                  if(Atm%atom(i)%thtype == "aniso") then
53526                    beta=Atm%atom(i)%u(1:6)
53527                    anis=     h(1)*h(1)*beta(1)+     h(2)*h(2)*beta(2)+    h(3)*h(3)*beta(3) &
53528                         +2.0*h(1)*h(2)*beta(4)+ 2.0*h(1)*h(3)*beta(5)+2.0*h(2)*h(3)*beta(6)
53529                    anis=exp(-anis)
53530                  end if
53531                  cosr=COS(arg)*anis*fr     !fr*cos{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53532                  scosr=scosr+cosr          !FRC= SIG fr(j,s)cos{2pi(hT Rs rj+ts)}*Ta(s)
53533
53534                  if(present(deriv)) then
53535                     sinr=SIN(arg)*anis*fr   !fr*sin{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53536                     drc(1:3,i)=drc(1:3,i)+h(1:3)*sinr      ! -
53537                     drc(4,i)=drc(4,i)+h(1)*h(1)*cosr
53538                     drc(5,i)=drc(5,i)+h(2)*h(2)*cosr
53539                     drc(6,i)=drc(6,i)+h(3)*h(3)*cosr
53540                     drc(7,i)=drc(7,i)+h(1)*h(2)*cosr
53541                     drc(8,i)=drc(8,i)+h(1)*h(3)*cosr
53542                     drc(9,i)=drc(9,i)+h(2)*h(3)*cosr
53543                  end if
53544
53545               end do ! symmetry
53546               occ= atm%atom(i)%occ
53547               b=atm%atom(i)%biso
53548               Tob= occ * exp(-b*sn)
53549               frc(i) = scosr
53550               otr(i) = afpxn(i)* Tob
53551               oti(i) =  afpp(i)* Tob
53552               a1= a1 + otr(i)*frc(i)
53553               b1= b1 + oti(i)*frc(i)
53554
53555            end do ! Atoms
53556
53557            av = a1-a2-a3-a4    !real part of the structure factor
53558            bv = b1-b2+b3+b4    !imaginary part of the structure factor
53559
53560       else
53561
53562            do i=1,Atm%natoms
53563               arg=0.0
53564               scosr=0.0
53565               ssinr=0.0
53566               drs(:,i)=0.0
53567               drc(:,i)=0.0
53568               do k=1,grp%NumOps
53569                  h=Hkl_R(hn,grp%symop(k))
53570                  hnt=dot_product(real(hn),Grp%SymOp(k)%Tr)
53571                  arg=tpi*(dot_product(h,Atm%atom(i)%x)+hnt)
53572                  anis=1.0
53573                  if(Atm%atom(i)%thtype == "aniso") then
53574                    beta=Atm%atom(i)%u(1:6)
53575                    anis=     h(1)*h(1)*beta(1)+     h(2)*h(2)*beta(2)+    h(3)*h(3)*beta(3) &
53576                         +2.0*h(1)*h(2)*beta(4)+ 2.0*h(1)*h(3)*beta(5)+2.0*h(2)*h(3)*beta(6)
53577                    anis=exp(-anis)
53578                  end if
53579                  cosr=COS(arg)*anis*fr     !fr*cos{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53580                  sinr=SIN(arg)*anis*fr     !fr*sin{2pi(hT Rs rj+ts)}*exp(-{hTRsBetaj RsTh})
53581                  scosr=scosr+cosr          !FRC= SIG fr(j,s)cos{2pi(hT Rs rj+ts)}*Ta(s)
53582                  ssinr=ssinr+sinr          !FRS= SIG fr(j,s)sin{2pi(hT Rs rj+ts)}*Ta(s)
53583
53584                  if(present(deriv)) then
53585                     drc(1:3,i)=drc(1:3,i)+h(1:3)*sinr      ! -
53586                     drs(1:3,i)=drs(1:3,i)+h(1:3)*cosr      ! +
53587
53588                     drc(4,i)=drc(4,i)+h(1)*h(1)*cosr
53589                     drc(5,i)=drc(5,i)+h(2)*h(2)*cosr
53590                     drc(6,i)=drc(6,i)+h(3)*h(3)*cosr
53591                     drc(7,i)=drc(7,i)+h(1)*h(2)*cosr
53592                     drc(8,i)=drc(8,i)+h(1)*h(3)*cosr
53593                     drc(9,i)=drc(9,i)+h(2)*h(3)*cosr
53594
53595                     drs(4,i)=drs(4,i)+h(1)*h(1)*sinr
53596                     drs(5,i)=drs(5,i)+h(2)*h(2)*sinr
53597                     drs(6,i)=drs(6,i)+h(3)*h(3)*sinr
53598                     drs(7,i)=drs(7,i)+h(1)*h(2)*sinr
53599                     drs(8,i)=drs(8,i)+h(1)*h(3)*sinr
53600                     drs(9,i)=drs(9,i)+h(2)*h(3)*sinr
53601                  end if
53602
53603               end do ! symmetry
53604               occ= atm%atom(i)%occ
53605               b=atm%atom(i)%biso
53606               Tob= occ * exp(-b*sn)
53607               frc(i) = scosr
53608               frs(i) = ssinr
53609               otr(i) = afpxn(i)* Tob
53610               oti(i) =  afpp(i)* Tob
53611               a1= a1 + otr(i)*frc(i)
53612               b1= b1 + oti(i)*frc(i)
53613               a3 = a3 + oti(i)*frs(i)
53614               b3 = b3 + otr(i)*frs(i)
53615
53616            end do ! Atoms
53617
53618            av = a1-a2-a3-a4    !real part of the structure factor
53619            bv = b1-b2+b3+b4    !imaginary part of the structure factor
53620
53621       end if
53622
53623       If(modi == "P") then
53624          sf2 = a1*a1 + a2*a2 + a3*a3 + a4*a4 + b1*b1 + b2*b2 + b3*b3 + b4*b4
53625          sf2 = sf2 + 2.0*(b1*b4 -  a1*a4 + a2*a3 - b2*b3)
53626       else
53627          sf2= av*av+bv*bv
53628       End if
53629
53630       if(present(fc)) then
53631         fc=cmplx(av,bv)
53632       end if
53633
53634       if(present(deriv)) then
53635
53636         if(modi == "P") then
53637
53638             do i=1,Atm%natoms
53639                !derivatives with respect to coordinates  POWDER
53640                do m=1,3
53641                   k= Atm%atom(i)%lx(m)
53642                   if(k /= 0) then
53643                     f=atm%atom(i)%mx(m)
53644                     der= otr(i)*(-a1*drc(m,i)+b3*drs(m,i))+oti(i)*(-b1*drc(m,i)+a3*drs(m,i))
53645                     der=2.0*der*tpi
53646                     deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53647                   end if
53648                 end do
53649
53650                 k=Atm%atom(i)%lbiso  !Derivatives w.r.t. Biso  POWDER
53651                 if(k /= 0) then
53652                   f=Atm%atom(i)%mbiso
53653                   der= otr(i)*(a1*frc(i) +b3*frs(i))+oti(i)*(b1*frc(i) +a3*frs(i))
53654                   der=-2.0*der*sn
53655                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53656                 end if
53657
53658                 k=Atm%atom(i)%locc    !Derivatives w.r.t. occupation factor   POWDER
53659                 if(k /= 0) then
53660                   f=Atm%atom(i)%mocc
53661                   der= otr(i)*(a1*frc(i)+b3*frs(i))+oti(i)*(b1*frc(i)+a3*frs(i))
53662                   der=2.0*der/atm%atom(i)%occ
53663                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53664                 end if
53665
53666                 do m=4,9      !Derivatives w.r.t. anisotropic temperature factors   POWDER
53667                    j=m-3
53668                    k=Atm%atom(i)%lu(j)
53669                    if(k /= 0) then
53670                      f=Atm%atom(i)%mu(j)
53671                      der=  otr(i)*(a1*drc(i,j)+b3*drs(m,i))+oti(i)*(b1*drc(m,i)+a3*drs(m,i))
53672                      der=-2.0*der
53673                      if(j > 3) der=2.0*der
53674                      deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53675                    end if
53676                 end do
53677
53678             end do
53679
53680         else
53681
53682             do i=1,Atm%natoms
53683                !derivatives with respect to coordinates  S-XTAL
53684                do m=1,3
53685                   k= Atm%atom(i)%lx(m)
53686                   if(k /= 0) then
53687                     f=atm%atom(i)%mx(m)
53688                     der=   -av*(otr(i)*drc(m,i) + oti(i)*drs(m,i))
53689                     der=der-bv*(oti(i)*drc(m,i) - otr(i)*drs(m,i))
53690                     der=2.0*der*tpi
53691                     deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53692                   end if
53693                 end do
53694
53695                 k=Atm%atom(i)%lbiso  !Derivatives w.r.t. Biso  S-XTAL
53696                 if(k /= 0) then
53697                   f=Atm%atom(i)%mbiso
53698                   der=   -av*( otr(i)*frc(i) - oti(i)*frs(i) )
53699                   der=der-bv*( oti(i)*frc(i) + otr(i)*frs(i) )
53700                   der=2.0*der*sn
53701                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53702                 end if
53703
53704                 k=Atm%atom(i)%locc    !Derivatives w.r.t. occupation factor  S-XTAL
53705                 if(k /= 0) then
53706                   f=Atm%atom(i)%mocc
53707                   der=    av*( otr(i)*frc(i) - oti(i)*frs(i) )
53708                   der=der+bv*( oti(i)*frc(i) + otr(i)*frs(i) )
53709                   der=2.0*der/atm%atom(i)%occ
53710                   deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53711                 end if
53712
53713                 do m=4,9        !Derivatives w.r.t. anisotropic temperature factors S-XTAL
53714                    j=m-3
53715                    k=Atm%atom(i)%lu(j)
53716                    if(k /= 0) then
53717                      f=Atm%atom(i)%mu(j)
53718                      der=   -av*(otr(i)*drc(m,i) - oti(i)*drs(m,i))
53719                      der=der-bv*(oti(i)*drc(m,i) + otr(i)*drs(m,i))
53720                      der=2.0*der
53721                      if(j > 3) der=2.0*der
53722                      deriv(k) = sign(1.0_cp,f)*der+deriv(k)
53723                    end if
53724                 end do
53725
53726             end do
53727         end if !modi
53728       end if  !derivatives
53729
53730       return
53731    End Subroutine Calc_hkl_StrFactor
53732
53733    !!--++ Subroutine Calc_Table_TH(Reflex,Atm)
53734    !!--++    type(reflection_List_type),   intent(in) :: Reflex
53735    !!--++    type(atom_list_type),        intent(in) :: Atm
53736    !!--++
53737    !!--++    (Private)
53738    !!--++    Calculate a Table of Isotropinc Thermal contribution and occupation
53739    !!--..         TH(Natoms,Nref)
53740    !!--++
53741    !!--++ Update: February - 2005
53742    !!
53743    Subroutine Calc_Table_TH(Reflex,Atm)
53744       !---- Argument ----!
53745       type(reflection_list_type), intent(in) :: Reflex
53746       type(atom_list_type),      intent(in) :: Atm
53747
53748       !---- Local variables ----!
53749       integer          :: i,j
53750       real(kind=cp)    :: b,s
53751
53752       !---- Isotropic model ----!
53753       do j=1,reflex%nref
53754          s=reflex%ref(j)%s
53755          do i=1,atm%natoms
53756             b=atm%atom(i)%biso
53757             th(i,j)= atm%atom(i)%occ * exp(-b*s*s)
53758          end do
53759       end do
53760
53761       return
53762    End Subroutine Calc_Table_TH
53763
53764    !!--++
53765    !!--++ Subroutine Create_Table_fabc_Xray(Atm,lambda,lun)
53766    !!--++    type(atom_list_type),      intent(in) :: Atm
53767    !!--++    real(kind=cp), optiona      intent(in) :: lambda
53768    !!--++    integer, optional,          intent(in) :: lun
53769    !!--++
53770    !!--++    (Private)
53771    !!--++    Calculate a Table of Coefficients for Atomic Form Factors for X-Ray
53772    !!--++    ff_A(4,species),ff_B(4,Nspecies),ff_C(Nspecies), AFP(Nspecies), AFPP(Nspecies)
53773    !!--++    ff_z(Nspecies) contains the atomic number of the chemical species (useful for Electron diffraction)
53774    !!--++    p_a(Natoms) => pointer to the species of each atom
53775    !!--++
53776    !!--++ Update: April - 2009
53777    !!
53778    Subroutine Create_Table_fabc_Xray(Atm,lambda,elect,lun)
53779       !---- Arguments ----!
53780       type(atom_list_type),       intent(in) :: Atm
53781       real(kind=cp), optional,    intent(in) :: lambda
53782       integer, optional,          intent(in) :: elect
53783       integer, optional,          intent(in) :: lun
53784
53785       !---- Local Variables ----!
53786       character(len=4)               :: symbcar
53787       integer                        :: i,j, k,n,L
53788       integer, dimension(atm%natoms) :: ix,jx,ia
53789       real(kind=cp)                  :: dmin,d
53790
53791       !---- Init ----!
53792       err_sfac=.false.
53793
53794       !---- Load form factor values for XRay ----!
53795       call Set_Xray_Form()
53796
53797       !---- Found Species on Xray_Form ----!
53798       ix=0
53799       jx=0
53800       n=0
53801       if(allocated(P_a)) deallocate(P_a)
53802       allocate(P_a(atm%natoms))
53803
53804       do i=1,atm%natoms
53805          symbcar=l_case(atm%atom(i)%SfacSymb)
53806          do j=1,Num_Xray_Form
53807             if (symbcar /= Xray_form(j)%Symb) cycle
53808             ix(i)=j
53809             if(any(jx == j) ) exit
53810             n=n+1
53811             jx(n)=j
53812             ia(n)=i
53813             exit
53814          end do
53815       end do
53816
53817       if (any(ix==0)) then
53818          err_sfac=.true.
53819          ERR_SFac_Mess="The Species "//symbcar//" was not found"
53820          return
53821       end if
53822
53823       do i=1,atm%natoms
53824         j=ix(i)
53825         do k=1,n
53826           if(jx(k) == j) then
53827             P_a(i)=k              !The atom i is of species k
53828             exit
53829           end if
53830         end do
53831       end do
53832       Nspecies=n !Global private variable (Total number of chemical species)
53833       if(allocated(FF_a)) deallocate (FF_a)
53834       if(allocated(FF_b)) deallocate (FF_b)
53835       if(allocated(FF_c)) deallocate (FF_c)
53836       if(allocated(FF_z)) deallocate (FF_z)
53837       allocate(FF_a(4,n),FF_b(4,n),FF_c(n),FF_z(n))
53838       do k=1,n
53839          j = jx(k)
53840          i = ia(k)
53841          FF_a(:,k)= xray_form(j)%a(:)
53842          FF_b(:,k)= xray_form(j)%b(:)
53843          FF_c(  k)= xray_form(j)%c
53844          FF_z(  k)= xray_form(j)%Z
53845       end do
53846
53847       if (present(lun)) then
53848          if(present(elect)) then
53849            write(unit=lun,fmt="(/,a)") "  INFORMATION FROM TABULATED X-RAY SCATTERING FACTORS (For Electron Diffraction)"
53850            write(unit=lun,fmt="(a,/)") "  =============================================================================="
53851          else
53852            write(unit=lun,fmt="(/,a)") "  INFORMATION FROM TABULATED X-RAY SCATTERING FACTORS"
53853            write(unit=lun,fmt="(a,/)") "  ==================================================="
53854          end if
53855       End if
53856       if(.not. present(elect)) then
53857        if (present(lambda)) then
53858          !---- Load anomalous scattering form factor values for XRays ----!
53859          call Set_Delta_Fp_Fpp()
53860
53861          !---- Select wavelength (by default is CuKalpha1: k=5 in the list) ----!
53862          dmin=1000.0
53863          do i=1,5
53864             d=abs(lambda-Xray_Wavelengths(i)%Kalfa(1))
53865             if (d < dmin) then
53866                dmin=d
53867                k=i        !Selection of the index for fp and fpp lists
53868             end if
53869          end do
53870
53871          !---- Found Species on Anomalous_ScFac ----!
53872          do i=1,atm%natoms
53873             symbcar=l_case(atm%atom(i)%chemsymb)
53874             do j=1,Num_Delta_Fp
53875                if (symbcar /= Anomalous_ScFac(j)%Symb) cycle
53876                afp(i)=Anomalous_ScFac(j)%fp(k)
53877                afpp(i)=Anomalous_ScFac(j)%fpp(k)
53878                exit
53879             end do
53880          end do
53881          call Remove_Delta_Fp_Fpp()
53882        else
53883           if (present(lun)) then
53884             write(unit=lun,fmt="(a)")    "  Missed lambda, anomalous dipersion corrections not applied   "
53885             write(unit=lun,fmt="(a)")    "  The default wavelength is that of Cu-Kalpha1 spectral line  "
53886           end if
53887        end if
53888       end if !present(elect)
53889
53890
53891       !---- Printing Information ----!
53892       if (present(lun)) then
53893         if(present(elect)) then
53894          write(unit=lun,fmt="(/,a,/)")    "   ATOMIC SCATTERING FACTOR COEFFICIENTS: {A(i),B(i),I=1,4},C  and Atomic Number "
53895          write(unit=lun,fmt="(a,i3)")     "   Number of chemically different species: ",n
53896         write(unit=lun,fmt="(/,a)") &
53897               "   Atom     a1       b1       a2       b2       a3       b3       a4       b4        c       Z"
53898          do k=1,n
53899             j = jx(k)
53900             i = ia(k)
53901             write(unit=lun,fmt="(a,9F9.5,i7)")    &
53902                           "     "//atm%atom(i)%chemsymb, &
53903                           (xray_form(j)%a(L),xray_form(j)%b(L), L=1,4), xray_form(j)%c, &
53904                           xray_form(j)%z
53905          end do
53906        else
53907          write(unit=lun,fmt="(/,a,/)")    "   ATOMIC SCATTERING FACTOR COEFFICIENTS: {A(i),B(i),I=1,4},C  Dfp  Dfpp "
53908          write(unit=lun,fmt="(a,i3)")     "   Number of chemically different species: ",n
53909          write(unit=lun,fmt="(/,a)") &
53910               "   Atom     a1       b1       a2       b2       a3       b3       a4       b4        c      Dfp     Dfpp"
53911          do k=1,n
53912             j = jx(k)
53913             i = ia(k)
53914             write(unit=lun,fmt="(a,11F9.5)")    &
53915                           "     "//atm%atom(i)%chemsymb, &
53916                           (xray_form(j)%a(L),xray_form(j)%b(L), L=1,4), xray_form(j)%c, &
53917                           afp(i), afpp(i)
53918          end do
53919         end if
53920          write(unit=lun,fmt="(/,/)")
53921       end if
53922
53923       call Remove_Xray_Form()
53924
53925       return
53926    End Subroutine Create_Table_fabc_Xray
53927
53928    !!--++
53929    !!--++ Subroutine Create_Table_AF0_Electrons(Reflex,Atm,lun)
53930    !!--++    type(reflection_List_type), intent(in) :: Reflex
53931    !!--++    type(atom_list_type),       intent(in) :: Atm
53932    !!--++    integer, optional,          intent(in) :: lun
53933    !!--++
53934    !!--++    (Private)
53935    !!--++    Calculate a Table of Atomic Factors for Electrons
53936    !!--++    applying the Mott-Bethe formula:
53937    !!--++    fe=me^2/(8pi Eps0 h^2) (Z-fx(s))/s^2
53938    !!--++
53939    !!--++ Update: April - 2009
53940    !!
53941    Subroutine Create_Table_AF0_Electrons(Reflex,Atm,lun)
53942       !---- Arguments ----!
53943       type(reflection_list_type), intent(in) :: Reflex
53944       type(atom_list_type),       intent(in) :: Atm
53945       integer, optional,          intent(in) :: lun
53946
53947       !---- Local Variables ----!
53948       character(len=4)               :: symbcar
53949       integer                        :: i,j, k,n,L
53950       integer, dimension(atm%natoms) :: ix,jx,ia
53951       real(kind=cp)                  :: fx
53952
53953       !---- Init ----!
53954       err_sfac=.false.
53955
53956       !---- Load form factor values for XRay ----!
53957       call Set_Xray_Form()
53958
53959       !---- Found Species on Xray_Form ----!
53960       ix=0
53961       jx=0
53962       n=0
53963       do i=1,atm%natoms
53964          symbcar=l_case(atm%atom(i)%SfacSymb)
53965          do j=1,Num_Xray_Form
53966             if (symbcar /= Xray_form(j)%Symb) cycle
53967             ix(i)=j
53968             if(any(jx == j) ) exit
53969             n=n+1
53970             jx(n)=j
53971             ia(n)=i
53972             exit
53973          end do
53974       end do
53975
53976       if (present(lun)) then
53977         write(unit=lun,fmt="(/,a)") "  INFORMATION FROM TABULATED X-RAY SCATTERING FACTORS (For Electron Diffraction)"
53978          write(unit=lun,fmt="(a,/)") "  =============================================================================="
53979       End if
53980
53981       if (any(ix==0)) then
53982          err_sfac=.true.
53983          ERR_SFac_Mess="The Species "//symbcar//" was not found"
53984       else
53985          !---- Fill AF Table ----!
53986          do j=1,reflex%nref
53987             do i=1,atm%natoms
53988                fx=fj(reflex%ref(j)%s,xray_form(ix(i))%a,xray_form(ix(i))%b,xray_form(ix(i))%c)+afp(i)
53989                !Mott-Bethe formula fe=me^2/(8pi Eps0 h^2) (Z-fx(s))/s^2
53990                af0(i,j)=0.023934*(xray_form(ix(i))%Z-fx)/(reflex%ref(j)%s*reflex%ref(j)%s)
53991             end do
53992          end do
53993       end if
53994
53995       !---- Printing Information ----!
53996       if (present(lun)) then
53997          write(unit=lun,fmt="(/,a,/)")    "   ATOMIC SCATTERING FACTOR COEFFICIENTS: {A(i),B(i),I=1,4},C  and Atomic Number "
53998          write(unit=lun,fmt="(a,i3)")     "   Number of chemically different species: ",n
53999          write(unit=lun,fmt="(/,a)") &
54000               "   Atom     a1       b1       a2       b2       a3       b3       a4       b4        c       Z"
54001          do k=1,n
54002             j = jx(k)
54003             i = ia(k)
54004             write(unit=lun,fmt="(a,9F9.5,i7)")    &
54005                           "     "//atm%atom(i)%chemsymb, &
54006                           (xray_form(j)%a(L),xray_form(j)%b(L), L=1,4), xray_form(j)%c, &
54007                            xray_form(j)%Z
54008          end do
54009          write(unit=lun,fmt="(/,/)")
54010       end if
54011
54012       call Remove_Xray_Form()
54013
54014       return
54015    End Subroutine Create_Table_AF0_Electrons
54016
54017    !!--++
54018    !!--++ Subroutine Create_Table_AF0_Xray(Reflex,Atm,lambda,lun)
54019    !!--++    type(reflection_List_type), intent(in) :: Reflex
54020    !!--++    type(atom_list_type),      intent(in) :: Atm
54021    !!--++    real(kind=cp), optiona      intent(in) :: lambda
54022    !!--++    integer, optional,          intent(in) :: lun
54023    !!--++
54024    !!--++    (Private)
54025    !!--++    Calculate a Table of Atomic Factors for X-Ray
54026    !!--..      AF0(Natoms,Nref), AFP(Natoms), AFPP(Natoms)
54027    !!--++
54028    !!--++ Update: February - 2005
54029    !!
54030    Subroutine Create_Table_AF0_Xray(Reflex,Atm,lambda,lun)
54031       !---- Arguments ----!
54032       type(reflection_list_type), intent(in) :: Reflex
54033       type(atom_list_type),      intent(in) :: Atm
54034       real(kind=cp), optional,    intent(in) :: lambda
54035       integer, optional,          intent(in) :: lun
54036
54037       !---- Local Variables ----!
54038       character(len=4)               :: symbcar
54039       integer                        :: i,j, k,n,L
54040       integer, dimension(atm%natoms) :: ix,jx,ia
54041       real(kind=cp)                  :: dmin,d
54042
54043       !---- Init ----!
54044       err_sfac=.false.
54045
54046       !---- Load form factor values for XRay ----!
54047       call Set_Xray_Form()
54048
54049       !---- Found Species on Xray_Form ----!
54050       ix=0
54051       jx=0
54052       n=0
54053       do i=1,atm%natoms
54054          symbcar=l_case(atm%atom(i)%SfacSymb)
54055          do j=1,Num_Xray_Form
54056             if (symbcar /= Xray_form(j)%Symb) cycle
54057             ix(i)=j
54058             if(any(jx == j) ) exit
54059             n=n+1
54060             jx(n)=j
54061             ia(n)=i
54062             exit
54063          end do
54064       end do
54065
54066       if (present(lun)) then
54067          write(unit=lun,fmt="(/,a)") "  INFORMATION FROM TABULATED X-RAY SCATTERING FACTORS"
54068          write(unit=lun,fmt="(a,/)") "  ==================================================="
54069       End if
54070       if (present(lambda)) then
54071          !---- Load anomalous scattering form factor values for XRays ----!
54072          call Set_Delta_Fp_Fpp()
54073
54074          !---- Select wavelength (by default is CuKalpha1: k=5 in the list) ----!
54075          dmin=1000.0
54076          do i=1,5
54077             d=abs(lambda-Xray_Wavelengths(i)%Kalfa(1))
54078             if (d < dmin) then
54079                dmin=d
54080                k=i        !Selection of the index for fp and fpp lists
54081             end if
54082          end do
54083
54084          !---- Found Species on Anomalous_ScFac ----!
54085          do i=1,atm%natoms
54086             symbcar=l_case(atm%atom(i)%chemsymb)
54087             do j=1,Num_Delta_Fp
54088                if (symbcar /= Anomalous_ScFac(j)%Symb) cycle
54089                afp(i)=Anomalous_ScFac(j)%fp(k)
54090                afpp(i)=Anomalous_ScFac(j)%fpp(k)
54091                exit
54092             end do
54093          end do
54094          call Remove_Delta_Fp_Fpp()
54095       else
54096           if (present(lun)) then
54097             write(unit=lun,fmt="(a)")    "  Missed lambda, anomalous dipersion corrections not applied   "
54098             write(unit=lun,fmt="(a)")    "  The default wavelength is that of Cu-Kalpha1 spectral line  "
54099           end if
54100       end if
54101
54102       if (any(ix==0)) then
54103          err_sfac=.true.
54104          ERR_SFac_Mess="The Species "//symbcar//" was not found"
54105       else
54106          !---- Fill AF Table ----!
54107          do j=1,reflex%nref
54108             do i=1,atm%natoms
54109                af0(i,j)=fj(reflex%ref(j)%s,xray_form(ix(i))%a,xray_form(ix(i))%b,xray_form(ix(i))%c)+afp(i)
54110             end do
54111          end do
54112       end if
54113
54114       !---- Printing Information ----!
54115       if (present(lun)) then
54116          write(unit=lun,fmt="(/,a,/)")    "   ATOMIC SCATTERING FACTOR COEFFICIENTS: {A(i),B(i),I=1,4},C  Dfp  Dfpp "
54117          write(unit=lun,fmt="(a,i3)")     "   Number of chemically different species: ",n
54118          write(unit=lun,fmt="(/,a)") &
54119               "   Atom     a1       b1       a2       b2       a3       b3       a4       b4        c      Dfp     Dfpp"
54120          do k=1,n
54121             j = jx(k)
54122             i = ia(k)
54123             write(unit=lun,fmt="(a,11F9.5)")    &
54124                           "     "//atm%atom(i)%chemsymb, &
54125                           (xray_form(j)%a(L),xray_form(j)%b(L), L=1,4), xray_form(j)%c, &
54126                           afp(i), afpp(i)
54127          end do
54128          write(unit=lun,fmt="(/,/)")
54129       end if
54130
54131       call Remove_Xray_Form()
54132
54133       return
54134    End Subroutine Create_Table_AF0_Xray
54135
54136    !!--++
54137    !!--++ Subroutine Create_Table_AFP_NeutNuc(Atm,lun)
54138    !!--++    type(atom_list_type),              intent(in) :: Atm
54139    !!--++    integer, optional,                  intent(in) :: lun
54140    !!--++
54141    !!--++    (Private)
54142    !!--++    Setting a Table of Fermi Lengths for Neutron Nuclear Scattering
54143    !!--..      AFP(Natoms)
54144    !!--++
54145    !!--++ Update: February - 2005
54146    !!
54147    Subroutine Create_Table_AFP_NeutNuc(Atm,lun)
54148       !---- Arguments ----!
54149       type(atom_list_type),    intent(in) :: Atm
54150       integer, optional,       intent(in) :: lun
54151
54152       !---- Local Variables ----!
54153       character(len=4)                        :: symbcar
54154       integer                                 :: i,k,n
54155       character(len=4), dimension(atm%natoms) :: symb
54156       real(kind=cp),    dimension(atm%natoms) :: bs
54157       real(kind=cp)                           :: b
54158
54159       !---- Init ----!
54160       err_sfac=.false.
54161
54162       !---- Load chemical information ----!
54163       call set_chem_info()
54164
54165       !---- Getting Fermi Lengths of atoms ----!
54166       symb="    "
54167       bs=0.0
54168       n=0
54169       do i=1,atm%natoms
54170          symbcar=u_case(atm%atom(i)%chemsymb)
54171          call Get_Fermi_Length(symbcar,b)
54172          if (abs(b) < 0.0001) then
54173             err_sfac=.true.
54174             ERR_SFac_Mess="The Fermi Length of Species "//symbcar//" was not found"
54175             return
54176          else
54177             afp(i) = b
54178             if(any(symb == symbcar)) cycle
54179             n=n+1
54180             symb(n)=symbcar
54181             bs(n) = b
54182          end if
54183       end do
54184
54185       !---- Printing Information ----!
54186       if (present(lun)) then
54187          write(unit=lun,fmt="(/,a)")  "  INFORMATION FROM TABULATED NEUTRON SCATTERING FACTORS"
54188          write(unit=lun,fmt="(a,/)")  "  ==================================================="
54189          write(unit=lun,fmt="(a)")    "  FERMI LENGTHS "
54190          write(unit=lun,fmt="(a,i3)") "   Number of chemically different species: ",n
54191          write(unit=lun,fmt="(/,a)")  "   Atom     Fermi Length [10^(-12) cm]"
54192          do k=1,n
54193             write(unit=lun,fmt="(a,F15.6)")  "     "//symb(k), bs(k)
54194          end do
54195          write(unit=lun,fmt="(/,/)")
54196       end if
54197
54198       call Remove_chem_info()
54199
54200       return
54201    End Subroutine Create_Table_AFP_NeutNuc
54202
54203    !!--++
54204    !!--++ Subroutine Create_Table_HR_HT(Reflex,Grp)
54205    !!--++    type(reflection_list_type), intent(in) :: Hkl
54206    !!--++    type(space_group_type),     intent(in) :: Grp
54207    !!--++
54208    !!--++    (Private)
54209    !!--++    Calculate a Table with HR and HT values
54210    !!--..       Hr(Grp%Numops,Reflex%Nref)
54211    !!--..       HT(Grp%Numops,Reflex%Nref)
54212    !!--++
54213    !!--++ Update: February - 2005
54214    !!
54215    Subroutine Create_Table_HR_HT(Reflex,Grp)
54216       !---- Arguments ----!
54217       type(reflection_list_type), intent(in) :: Reflex
54218       type(space_group_type),     intent(in) :: Grp
54219
54220       !---- Local Variables ----!
54221       integer :: i,j
54222
54223       do j=1,reflex%nref
54224          do i=1,grp%NumOps
54225             hr(i,j)%h=Hkl_R(reflex%ref(j)%h,grp%symop(i))
54226             ht(i,j)=dot_product(real(reflex%ref(j)%h),Grp%SymOp(i)%Tr)
54227          end do
54228       end do
54229
54230       return
54231    End Subroutine Create_Table_HR_HT
54232
54233    !!----
54234    !!---- Subroutine Init_Calc_hkl_StrFactors(Atm,Mode,lambda,lun)
54235    !!----    type(atom_list_type),                intent(in) :: Atm
54236    !!----    character(len=*),          optional, intent(in) :: Mode
54237    !!----    real(kind=cp),             optional, intent(in) :: lambda
54238    !!----    integer,                   optional, intent(in) :: lun  !Logical unit for writing scatt-factors
54239    !!----
54240    !!----    Allocates and initializes arrays for hkl - Structure Factors calculations.
54241    !!----    No calculation of fixed tables is performed. Should be called before using
54242    !!----    the subroutine Calc_hkl_StrFactor
54243    !!----
54244    !!---- Update: April - 2009
54245    !!
54246    Subroutine Init_Calc_hkl_StrFactors(Atm,Mode,lambda,lun)
54247       !---Arguments ---!
54248       type(atom_list_type),                intent(in) :: Atm
54249       character(len=*),          optional, intent(in) :: Mode
54250       real(kind=cp),             optional, intent(in) :: lambda
54251       integer,                   optional, intent(in) :: lun
54252
54253       !--- Local variables ---!
54254
54255       integer :: Natm
54256       integer :: ierr
54257       character(len=3) :: tipo
54258
54259       tipo="XRA"
54260       if (present(mode)) tipo=adjustl(mode)
54261       tipo=U_Case(tipo)
54262       err_sfac=.false.
54263       Natm = Atm%natoms
54264
54265
54266       !---- Anomalous Scattering factor tables ----!
54267       if (allocated(AFP)) deallocate(AFP)
54268       allocate(AFP(Natm),stat=ierr)
54269       if (ierr /=0) then
54270          err_sfac=.true.
54271          ERR_SFac_Mess="Error on memory for AFP"
54272          return
54273       end if
54274       AFP=0.0
54275
54276       if (allocated(AFPP)) deallocate(AFPP)
54277       allocate(AFPP(Natm),stat=ierr)
54278       if (ierr /=0) then
54279          err_sfac=.true.
54280          ERR_SFac_Mess="Error on memory for AFPP"
54281          return
54282       end if
54283       AFPP=0.0
54284
54285
54286       !---- Table Fabc ----!
54287       select case (tipo)
54288
54289          case ("XRA")
54290             if (present(lambda)) then
54291                if (present(lun)) then
54292                   call Create_Table_Fabc_Xray(Atm,lambda,lun)
54293                else
54294                   call Create_Table_Fabc_Xray(Atm,lambda)
54295                end if
54296             else
54297                if (present(lun)) then
54298                   call Create_Table_Fabc_Xray(Atm,lun=lun)
54299                else
54300                   call Create_Table_Fabc_Xray(Atm)
54301                end if
54302             end if
54303
54304          case ("ELE")
54305
54306             if (present(lun)) then
54307                call Create_Table_Fabc_Xray(Atm,lun=lun)
54308             else
54309                call Create_Table_Fabc_Xray(Atm)
54310             end if
54311
54312
54313          case ("NUC")
54314             if (present(lun)) then
54315                call Create_Table_AFP_NeutNuc(Atm,lun=lun)
54316             else
54317                call Create_Table_AFP_NeutNuc(Atm)
54318             end if
54319
54320       end select
54321
54322       if (.not. err_sfac) SF_Initialized=.true.
54323
54324       return
54325    End Subroutine Init_Calc_hkl_StrFactors
54326
54327    !!----
54328    !!---- Subroutine Init_Calc_StrFactors(Reflex,Atm,Grp,Mode,lambda,lun)
54329    !!----    type(reflection_list_type),          intent(in) :: Reflex
54330    !!----    type(atom_list_type),                intent(in) :: Atm
54331    !!----    type(space_group_type),              intent(in) :: Grp
54332    !!----    character(len=*),          optional, intent(in) :: Mode
54333    !!----    real(kind=cp),             optional, intent(in) :: lambda
54334    !!----    integer,                   optional, intent(in) :: lun  !Logical unit for writing scatt-factors
54335    !!----
54336    !!----    Allocates and initializes arrays for Calc_StrFactors calculations.
54337    !!----    Calculations of fixed tables are performed. Should be called before using
54338    !!----    the subroutine Calc_StrFactor
54339    !!----
54340    !!---- Update: April - 2009
54341    !!
54342    Subroutine Init_Calc_StrFactors(Reflex,Atm,Grp,Mode,lambda,lun)
54343       !---Arguments ---!
54344       type(reflection_list_type),          intent(in) :: Reflex
54345       type(atom_list_type),                intent(in) :: Atm
54346       type(space_group_type),              intent(in) :: Grp
54347       character(len=*),          optional, intent(in) :: Mode
54348       real(kind=cp),             optional, intent(in) :: lambda
54349       integer,                   optional, intent(in) :: lun
54350
54351       !--- Local variables ---!
54352
54353       Call Init_Structure_Factors(Reflex,Atm,Grp,Mode,lambda,lun)
54354       !---- Table TH ----!
54355       Call Calc_Table_TH(Reflex,Atm)
54356
54357       return
54358    End Subroutine Init_Calc_StrFactors
54359
54360    !!----
54361    !!---- Subroutine Init_Structure_Factors(Reflex,Atm,Grp,Mode,lambda,lun)
54362    !!----    type(reflection_list_type),          intent(in) :: Reflex
54363    !!----    type(atom_list_type),                intent(in) :: Atm
54364    !!----    type(space_group_type),              intent(in) :: Grp
54365    !!----    character(len=*),          optional, intent(in) :: Mode
54366    !!----    real(kind=cp),             optional, intent(in) :: lambda
54367    !!----    integer,                   optional, intent(in) :: lun  !Logical unit for writing scatt-factors
54368    !!----
54369    !!----    Allocates and initializes arrays for Structure Factors calculations.
54370    !!----    A calculation of fixed tables is also performed.
54371    !!----
54372    !!---- Update: February - 2005
54373    !!
54374    Subroutine Init_Structure_Factors(Reflex,Atm,Grp,Mode,lambda,lun)
54375       !---Arguments ---!
54376       type(reflection_list_type),          intent(in) :: Reflex
54377       type(atom_list_type),                intent(in) :: Atm
54378       type(space_group_type),              intent(in) :: Grp
54379       character(len=*),          optional, intent(in) :: Mode
54380       real(kind=cp),             optional, intent(in) :: lambda
54381       integer,                   optional, intent(in) :: lun
54382
54383       !--- Local variables ---!
54384
54385       integer :: Natm, Multr
54386       integer :: ierr
54387
54388       err_sfac=.false.
54389       Natm = Atm%natoms
54390       Multr= Grp%Numops
54391
54392       !---- Scattering factor tables ----!
54393       if (allocated(AF0)) deallocate(AF0)
54394       allocate(AF0(Natm,Reflex%Nref),stat=ierr)
54395       if (ierr /=0) then
54396          err_sfac=.true.
54397          ERR_SFac_Mess="Error on memory for AF0"
54398          return
54399       end if
54400       AF0=0.0
54401
54402       !---- Anomalous Scattering factor tables ----!
54403       if (allocated(AFP)) deallocate(AFP)
54404       allocate(AFP(Natm),stat=ierr)
54405       if (ierr /=0) then
54406          err_sfac=.true.
54407          ERR_SFac_Mess="Error on memory for AFP"
54408          return
54409       end if
54410       AFP=0.0
54411
54412       if (allocated(AFPP)) deallocate(AFPP)
54413       allocate(AFPP(Natm),stat=ierr)
54414       if (ierr /=0) then
54415          err_sfac=.true.
54416          ERR_SFac_Mess="Error on memory for AFPP"
54417          return
54418       end if
54419       AFPP=0.0
54420
54421       !---- HR Table ----!
54422       if (allocated(HR)) deallocate(HR)
54423       allocate(HR(Multr,Reflex%Nref),stat=ierr)
54424       if (ierr /=0) then
54425          err_sfac=.true.
54426          ERR_SFac_Mess="Error on memory for HR"
54427          return
54428       end if
54429       HR=HR_Type(0)
54430
54431       !---- HT Table ----!
54432       if (allocated(HT)) deallocate(HT)
54433       allocate(HT(Multr,Reflex%Nref),stat=ierr)
54434       if (ierr /=0) then
54435          err_sfac=.true.
54436          ERR_SFac_Mess="Error on memory for HTR"
54437          return
54438       end if
54439       HT=0.0
54440
54441       if (allocated(TH)) deallocate(TH)
54442       allocate(TH(Natm,Reflex%Nref),stat=ierr)
54443       if (ierr /=0) then
54444          err_sfac=.true.
54445          ERR_SFac_Mess="Error on memory for HTR"
54446          return
54447       end if
54448       TH=0.0
54449
54450       if (allocated(Ajh)) deallocate(Ajh)
54451       allocate(Ajh(Natm,Reflex%Nref), stat=ierr)
54452       if (ierr /=0) then
54453          err_sfac=.true.
54454          ERR_SFac_Mess="Error in Memory for Aj(h)"
54455          return
54456       end if
54457       Ajh=0.0
54458
54459       if (allocated(Bjh)) deallocate(Bjh)
54460       allocate(Bjh(Natm,Reflex%Nref), stat=ierr)
54461       if (ierr /=0) then
54462          err_sfac=.true.
54463          ERR_SFac_Mess="Error in Memory for Bj(h)"
54464          return
54465       end if
54466       Bjh=0.0
54467
54468       if (present(mode)) then
54469          if (present(lambda)) then
54470             if (present(lun)) then
54471                call Set_Fixed_Tables(Reflex,Atm,Grp,Mode,lambda,lun)
54472             else
54473                call Set_Fixed_Tables(Reflex,Atm,Grp,Mode,lambda)
54474             end if
54475          else
54476             if (present(lun)) then
54477                call Set_Fixed_Tables(Reflex,Atm,Grp,Mode,lun=lun)
54478             else
54479                call Set_Fixed_Tables(Reflex,Atm,Grp,Mode)
54480             end if
54481          end if
54482       else
54483          if (present(lambda)) then
54484             if (present(lun)) then
54485                call Set_Fixed_Tables(Reflex,Atm,Grp,lambda=lambda,lun=lun)
54486             else
54487                call Set_Fixed_Tables(Reflex,Atm,Grp,lambda=lambda)
54488             end if
54489          else
54490             if (present(lun)) then
54491                call Set_Fixed_Tables(Reflex,Atm,Grp,lun=lun)
54492             else
54493                call Set_Fixed_Tables(Reflex,Atm,Grp)
54494             end if
54495          end if
54496       end if
54497
54498       if (.not. err_sfac) SF_Initialized=.true.
54499
54500       return
54501    End Subroutine Init_Structure_Factors
54502
54503    !!----
54504    !!---- Subroutine Modify_SF(Reflex,Atm,Grp,List,Nlist,Mode)
54505    !!----    type(reflection_list_type),         intent(in out) :: Reflex
54506    !!----    type(atom_list_type),              intent(in)     :: Atm
54507    !!----    type(space_group_type),             intent(in)     :: Grp
54508    !!----    integer,dimension(:),               intent(in)     :: List
54509    !!----    integer,                            intent(in)     :: Nlist
54510    !!----    character(len=*),optional,          intent(in)     :: Mode
54511    !!----
54512    !!----    Recalculation of Structure Factors because a list of Atoms
54513    !!----    parameters were modified. List variable
54514    !!----    contains the number of atoms to be changed.
54515    !!----
54516    !!---- Update: February - 2005
54517    !!
54518    Subroutine Modify_SF(Reflex,Atm,Grp,List,Nlist,partyp,Mode)
54519       !---- Arguments ----!
54520       type(reflection_list_type),   intent(in out) :: Reflex
54521       type(atom_list_type),         intent(in)     :: Atm
54522       type(space_group_type),       intent(in)     :: Grp
54523       integer,dimension(:),         intent(in)     :: List
54524       integer,                      intent(in)     :: NList
54525       character(len=*),optional,    intent(in)     :: partyp
54526       character(len=*),optional,    intent(in)     :: Mode
54527
54528       !---- Local variables ----!
54529       character(len=2) :: typ
54530       integer          :: i,j,k,ii
54531       real(kind=cp)    :: arg,b,s
54532
54533       typ="CO"
54534       if (present(partyp)) typ=adjustl(partyp)
54535       typ=U_Case(typ)
54536
54537       select case (typ)
54538
54539          case ("CO") ! by coordinates
54540
54541            if(Grp%Centred == 2) then
54542
54543               do j=1,Reflex%Nref
54544                  do ii=1,Nlist
54545                     i=list(ii)
54546                     Ajh(i,j)=0.0
54547                     arg=0.0
54548                     do k=1,grp%NumOps
54549                        arg=tpi*(dot_product(hr(k,j)%h,Atm%atom(i)%x)+ht(k,j))
54550                        Ajh(i,j)=Ajh(i,j)+cos(arg)
54551                     end do ! symmetry
54552                  end do ! NList
54553               end do ! Reflections
54554
54555            else
54556
54557               do j=1,Reflex%Nref
54558                  do ii=1,Nlist
54559                     i=list(ii)
54560                     arg=0.0
54561                     Ajh(i,j)=0.0
54562                     Bjh(i,j)=0.0
54563                     do k=1,grp%NumOps
54564                        arg=tpi*(dot_product(hr(k,j)%h,Atm%atom(i)%x)+ht(k,j))
54565                        Ajh(i,j)=Ajh(i,j)+cos(arg)
54566                        Bjh(i,j)=Bjh(i,j)+sin(arg)
54567                     end do ! symmetry
54568                  end do ! NList
54569               end do ! Reflections
54570
54571            end if
54572
54573          case ("TH") ! by thermal parameter or occupation number
54574
54575             do j=1,Reflex%Nref
54576                s=reflex%ref(j)%s
54577                do ii=1,Nlist
54578                   i=list(ii)
54579                   b=atm%atom(i)%biso
54580                   th(i,j)=atm%atom(i)%occ*exp(-b*s*s)
54581                end do ! NList
54582             end do ! Reflections
54583
54584       end select
54585
54586       !---- Recalculation of SF ----!
54587       if(present(mode)) then
54588         if(mode == "XRA" .or. mode == "ELE") then
54589            call Sum_AB(Reflex,Atm%Natoms,Grp%Centred)
54590         else if(mode == "NUC") then
54591            call Sum_AB_NeutNuc(Reflex,Atm%Natoms,Grp%Centred)
54592         end if
54593       else
54594         call Sum_AB(Reflex,Atm%Natoms,Grp%Centred)
54595       end if
54596
54597
54598       return
54599    End Subroutine Modify_SF
54600
54601    !!--++
54602    !!--++ Subroutine Set_Fixed_Tables(Reflex,Atm,Grp,mode,lambda,lun)
54603    !!--++    type(reflection_list_type),         intent(in) :: Reflex
54604    !!--++    type(atom_list_type),              intent(in) :: Atm
54605    !!--++    type(space_group_type),             intent(in) :: Grp
54606    !!--++    character(len=*), optional,         intent(in) :: Mode
54607    !!--++    real(kind=cp), optional,            intent(in) :: lambda
54608    !!--++    integer, optional,                  intent(in) :: lun
54609    !!--++
54610    !!--++    (Private)
54611    !!--++    Calculates arrays that are fixed during all further
54612    !!--++    calculations
54613    !!--++
54614    !!--++ Update: February - 2005
54615    !!
54616    Subroutine Set_Fixed_Tables(Reflex,Atm,Grp,Mode,lambda,lun)
54617       !---- Arguments ----!
54618       type(reflection_list_type),         intent(in) :: Reflex
54619       type(atom_list_type),               intent(in) :: Atm
54620       type(space_group_type),             intent(in) :: Grp
54621       character(len=*), optional,         intent(in) :: Mode
54622       real(kind=cp), optional,            intent(in) :: lambda
54623       integer, optional,                  intent(in) :: lun
54624
54625       !---- Local variables ----!
54626       character(len=3) :: tipo
54627
54628       tipo="XRA"
54629       if (present(mode)) tipo=adjustl(mode)
54630       tipo=U_Case(tipo)
54631
54632       !---- Table HR - HT ----!
54633       call Create_Table_HR_HT(Reflex,Grp)
54634
54635       !---- Table AF0 ----!
54636       select case (tipo)
54637
54638          case ("XRA")
54639             if (present(lambda)) then
54640                if (present(lun)) then
54641                   call Create_Table_AF0_Xray(Reflex,Atm,lambda,lun)
54642                else
54643                   call Create_Table_AF0_Xray(Reflex,Atm,lambda)
54644                end if
54645             else
54646                if (present(lun)) then
54647                   call Create_Table_AF0_Xray(Reflex,Atm,lun=lun)
54648                else
54649                   call Create_Table_AF0_Xray(Reflex,Atm)
54650                end if
54651             end if
54652
54653             !---- Modify the scattering factor tables to include the
54654             !---- multipliers factors concerning centre of symmetry and
54655             !---- centred translations
54656             if (Grp%Centred == 2) then
54657                af0=2.0*af0
54658                afpp=2.0*afpp
54659             end if
54660
54661             if (Grp%NumLat  > 1) then
54662                af0=Grp%NumLat*af0
54663                afpp=Grp%NumLat*afpp
54664             end if
54665
54666          case ("ELE")
54667
54668             if (present(lun)) then
54669                call Create_Table_AF0_Electrons(Reflex,Atm,lun=lun)
54670             else
54671                call Create_Table_AF0_Electrons(Reflex,Atm)
54672             end if
54673
54674             !---- Modify the scattering factor tables to include the
54675             !---- multipliers factors concerning centre of symmetry and
54676             !---- centred translations
54677             if (Grp%Centred == 2) then
54678                af0=2.0*af0
54679                afpp=0.0
54680             end if
54681
54682             if (Grp%NumLat  > 1) then
54683                af0=Grp%NumLat*af0
54684                afpp=0.0
54685             end if
54686
54687          case ("NUC","NEU")
54688             if (present(lun)) then
54689                call Create_Table_AFP_NeutNuc(Atm,lun=lun)
54690             else
54691                call Create_Table_AFP_NeutNuc(Atm)
54692             end if
54693             if (Grp%Centred == 2) afp=2.0*afp
54694             if (Grp%NumLat  > 1) afp=Grp%NumLat*afp
54695
54696       end select
54697
54698       return
54699    End Subroutine Set_Fixed_Tables
54700
54701    !!----
54702    !!---- Subroutine Structure_Factors(Atm,Grp,Reflex,Mode,lambda)
54703    !!----    type(atom_list_type),               intent(in)     :: Atm
54704    !!----    type(space_group_type),             intent(in)     :: Grp
54705    !!----    type(reflection_list_type),         intent(in out) :: Reflex
54706    !!----    character(len=*), optional,         intent(in)     :: Mode
54707    !!----    real(kind=cp), optional,            intent(in)     :: lambda
54708    !!----
54709    !!----    Calculate the Structure Factors from a list of Atoms
54710    !!----    and a set of reflections. A call to Init_Structure_Factors
54711    !!----    is a pre-requisite for using this subroutine. In any case
54712    !!----    the subroutine calls Init_Structure_Factors if SF_initialized=.false.
54713    !!----
54714    !!---- Update: February - 2005
54715    !!
54716    Subroutine Structure_Factors(Atm,Grp,Reflex,Mode,lambda)
54717       !---- Arguments ----!
54718       type(atom_list_type),               intent(in)     :: Atm
54719       type(space_group_type),             intent(in)     :: Grp
54720       type(reflection_list_type),         intent(in out) :: Reflex
54721       character(len=*), optional,         intent(in)     :: Mode
54722       real(kind=cp), optional,            intent(in)     :: lambda
54723
54724       !Provisional items
54725       ! integer::i,j
54726       !---------------
54727       if(present(Mode)) then
54728          if(present(lambda)) then
54729            if(.not. SF_Initialized) call Init_Structure_Factors(Reflex,Atm,Grp,Mode,lambda)
54730          else
54731            if(.not. SF_Initialized) call Init_Structure_Factors(Reflex,Atm,Grp,Mode)
54732          end if
54733       else
54734          if(present(lambda)) then
54735            if(.not. SF_Initialized) call Init_Structure_Factors(Reflex,Atm,Grp,Lambda=lambda)
54736          else
54737            if(.not. SF_Initialized) call Init_Structure_Factors(Reflex,Atm,Grp)
54738          end if
54739       end if
54740
54741       !---- Table TH ----!
54742       Call Calc_Table_TH(Reflex,Atm)
54743
54744       !---- Table AB ----!
54745       call Calc_Table_AB(Reflex%Nref,Atm,Grp)
54746
54747       !Provisional items
54748       !open(unit=111,file="stfac.inf",status="replace",action="write")
54749       !do j=1,Nref
54750       !  write(111,"(a,3i4)") " Reflection:  ",hkl(j)%h
54751       !
54752       !  write(111,"(a)") " Atom              F0         occ*W         Ajh         Bjh"
54753       !  do i=1,Atm%natoms
54754       !       write(111,"(a,4f12.4)") "  "//atm%atom(i)%lab, af0(i,j),th(i,j),Ajh(i,j),Bjh(i,j)
54755       !  end do ! Atoms
54756       !end do ! Reflections
54757       !close(unit=111)
54758       !End Provisional items
54759
54760       !---- Final Calculation ----!
54761       if(present(mode)) then
54762         if(mode == "XRA" .or. mode == "ELE" ) then
54763            call Sum_AB(Reflex,Atm%Natoms,Grp%Centred)
54764         else if(mode == "NUC") then
54765            call Sum_AB_NeutNuc(Reflex,Atm%Natoms,Grp%Centred)
54766         else if(mode == "MAG") then
54767         end if
54768       else
54769         call Sum_AB(Reflex,Atm%Natoms,Grp%Centred)
54770       end if
54771       return
54772    End Subroutine Structure_Factors
54773
54774    !!--++
54775    !!--++ Subroutine Sum_AB(Reflex,Natm,icent)
54776    !!--++    type(reflection_list_type), intent(in out) :: Reflex
54777    !!--++    integer,                    intent(in)     :: Natm
54778    !!--++    integer,                    intent(in)     :: icent
54779    !!--++
54780    !!--++    (Private)
54781    !!--++    Calculate the Final Sum for Structure Factors calculations
54782    !!--++
54783    !!--++ Update: February - 2005
54784    !!
54785    Subroutine Sum_AB(Reflex,Natm,icent)
54786       !---- Arguments ----!
54787       type(reflection_list_type), intent(in out)  :: Reflex
54788       integer,                    intent(in)      :: Natm
54789       integer,                    intent(in)      :: icent
54790
54791       !---- Local Variables ----!
54792       integer                                     :: i,j
54793       real(kind=cp)                               :: a,b, ph
54794       real(kind=cp), dimension(natm,reflex%nref)  :: aa,bb,cc,dd
54795
54796
54797       ! A(h)=SIG(i){(f0+Deltaf')*OCC*Tiso*Ag}    asfa=a-d
54798       ! C(h)=SIG(i){    Deltaf" *OCC*Tiso*Ag}    bsfa=b+c
54799
54800       ! B(h)=SIG(i){(f0+Deltaf')*OCC*Tiso*Bg}
54801       ! D(h)=SIG(i){    Deltaf" *OCC*Tiso*Bg}
54802
54803       !---- Fj(h)*Aj(h) ----!
54804
54805       aa=af0*th*ajh
54806
54807       if (icent == 2) then    !Calculation for centrosymmetric structures
54808          do j=1,reflex%nref
54809             cc(:,j)= afpp(:)*th(:,j)*ajh(:,j)
54810          end do
54811
54812          !---- Final Sum ----!
54813          do i=1,reflex%Nref
54814             a=sum(aa(:,i))
54815             b=sum(cc(:,i))
54816             reflex%ref(i)%Fc=sqrt(a*a+b*b)
54817             ph = atan2d(b,a)
54818             if (ph < 0.0) ph=ph+360.0
54819             reflex%ref(i)%Phase = ph
54820             reflex%ref(i)%A=a
54821             reflex%ref(i)%B=b
54822          end do
54823
54824       else       !Calculation for non-centrosymmetric structures
54825          !---- Fj(h)*Bj(h) ----!
54826          bb=af0*th*bjh
54827
54828          do j=1,reflex%nref
54829             cc(:,j)= afpp(:)*th(:,j)*ajh(:,j)
54830             dd(:,j)= afpp(:)*th(:,j)*bjh(:,j)
54831          end do
54832
54833          !---- Final Sum ----!
54834          do i=1,reflex%Nref
54835             a=sum(aa(:,i)-dd(:,i))
54836             b=sum(bb(:,i)+cc(:,i))
54837             reflex%ref(i)%Fc=sqrt(a*a+b*b)
54838             ph = atan2d(b,a)
54839             if (ph < 0.0) ph=ph+360.0
54840             reflex%ref(i)%Phase = ph
54841             reflex%ref(i)%A=a
54842             reflex%ref(i)%B=b
54843          end do
54844       end if
54845
54846       return
54847    End Subroutine Sum_AB
54848
54849    !!--++
54850    !!--++ Subroutine Sum_AB_NeutNuc(Reflex,Natm,icent)
54851    !!--++    type(reflection_list_type),         intent(in out) :: Reflex
54852    !!--++    integer,                            intent(in)     :: Natm
54853    !!--++    integer,                            intent(in)     :: icent
54854    !!--++
54855    !!--++    (Private)
54856    !!--++    Calculate the Final Sum for Structure Factors calculations
54857    !!--++    Adapted for Neutron Nuclear Scattering (real scattering lengths)
54858    !!--++
54859    !!--++ Update: February - 2005
54860    !!
54861    Subroutine Sum_AB_NeutNuc(Reflex,Natm,icent)
54862       !---- Arguments ----!
54863       type(reflection_list_type),   intent(in out) :: Reflex
54864       integer,                      intent(in)     :: Natm
54865       integer,                      intent(in)     :: icent
54866
54867       !---- Local Variables ----!
54868       integer                                     :: i,j
54869       real(kind=cp)                               :: a,b, ph
54870       real(kind=cp), dimension(natm,reflex%nref)  :: aa,bb
54871
54872       if (icent == 2) then    !Calculation for centrosymmetric structures
54873
54874          !---- Fj(h)*Aj(h) ----!
54875          do j=1,reflex%nref
54876             aa(:,j)= afp(:)*th(:,j)*ajh(:,j)
54877          end do
54878
54879          !---- Final Sum ----!
54880          do i=1,reflex%Nref
54881             a=sum(aa(:,i))
54882             reflex%ref(i)%Fc=abs(a)
54883             reflex%ref(i)%Phase = 90.0_cp - 90.0_cp * sign(1.0_cp,a)
54884             reflex%ref(i)%A=a
54885             reflex%ref(i)%B=0.0
54886          end do
54887
54888       else       !Calculation for non-centrosymmetric structures
54889          !---- Fj(h)*Bj(h) ----!
54890          !---- Fj(h)*Aj(h) ----!
54891          do j=1,reflex%nref
54892             aa(:,j)= afp(:)*th(:,j)*ajh(:,j)
54893             bb(:,j)= afp(:)*th(:,j)*bjh(:,j)
54894          end do
54895
54896          !---- Final Sum ----!
54897          do i=1,reflex%Nref
54898             a=sum(aa(:,i))
54899             b=sum(bb(:,i))
54900             reflex%ref(i)%Fc=sqrt(a*a+b*b)
54901             ph = atan2d(b,a)
54902             if (ph < 0.0) ph=ph+360.0
54903             reflex%ref(i)%Phase = ph
54904             reflex%ref(i)%A=a
54905             reflex%ref(i)%B=b
54906          end do
54907       end if
54908
54909       return
54910    End Subroutine Sum_AB_NeutNuc
54911
54912    !!----
54913    !!---- Subroutine Write_Structure_Factors(lun,Reflex,Mode)
54914    !!----    integer,                            intent(in) :: lun
54915    !!----    type(reflection_list_type),         intent(in) :: Reflex
54916    !!----    Character(len=*), optional,         intent(in) :: Mode
54917    !!----
54918    !!----    Writes in logical unit=lun the list of structure factors
54919    !!----    contained in the array hkl
54920    !!----
54921    !!---- Update: February - 2005
54922    !!
54923    Subroutine Write_Structure_Factors(lun,Reflex,Mode)
54924       !---- Argument ----!
54925       integer,                            intent(in) :: lun
54926       type(reflection_list_type),         intent(in) :: Reflex
54927       Character(len=*), optional,         intent(in) :: Mode
54928       !---- Local Variables ----!
54929       integer :: i
54930
54931       If(present(mode)) then
54932         Select Case (mode(1:3))
54933           Case("NUC","nuc")
54934             write(unit=lun,fmt="(/,/,a)") "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(NEUTRONS)"
54935             write(unit=lun,fmt="(a)")     "    ==================================================="
54936           Case("ELE","ele")
54937             write(unit=lun,fmt="(/,/,a)") "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(ELECTRONS)"
54938             write(unit=lun,fmt="(a)")     "    ===================================================="
54939           Case default
54940             write(unit=lun,fmt="(/,/,a)") "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(X-RAYS)"
54941             write(unit=lun,fmt="(a)")     "    ================================================="
54942         End Select
54943       else
54944         write(unit=lun,fmt="(a)")   "    LIST OF REFLECTIONS AND STRUCTURE FACTORS(X-RAYS)"
54945         write(unit=lun,fmt="(a)")   "    ================================================="
54946       end if
54947
54948       write(unit=lun,fmt="(/,a,/)") &
54949 "   H   K   L   Mult    SinTh/Lda       dspc          |Fc|         Phase          F-Real        F-Imag       |Fc|^2      Num"
54950       do i=1,reflex%Nref
54951             write(unit=lun,fmt="(3i4,i5,6f14.5,f14.3,i8)") reflex%ref(i)%h, reflex%ref(i)%mult, &
54952                                 reflex%ref(i)%S,0.5/reflex%ref(i)%S, reflex%ref(i)%Fc, reflex%ref(i)%Phase,   &
54953                                 reflex%ref(i)%a, reflex%ref(i)%b, reflex%ref(i)%Fc*reflex%ref(i)%Fc,i
54954       end do
54955       return
54956    End Subroutine Write_Structure_Factors
54957
54958 End Module CFML_Structure_Factors
54959!
54960!   cif2hkl: convert a CIF or CFL crystal structure file into a PowderN reflection list.
54961!
54962!   cif2hkl 1.1 (18 Dec 2012) by Farhi E. [farhi@ill.fr] using crysFML <http://forge.ill.fr/projects/crysfml>
54963!   Copyright (C) 2009 Institut Laue Langevin, EUPL license.
54964!   This is free software; see the source for copying conditions.
54965!   There is NO warranty; not even for MERCHANTABILITY or FITNESS
54966!   FOR A PARTICULAR PURPOSE.
54967!
54968! Usage: ./cif2hkl [options][-o outfile] file1 file2 ...
54969! Action: Read a CIF/CFL/SHX/PCR crystallographic description
54970!         and generates a HKL F^2 reflection list.
54971! Input:
54972!   file1...          Input file in CIF, PCR, CFL, SHX, INS, RES format.
54973!                       The file format is determined from its extension
54974!                         .CIF           Crystallographic Information File
54975!                         .PCR/.CFL      FullProf file
54976!                         .SHX/.INS/.RES ShelX file
54977! Output:
54978!   a file with readable header, and reflection list with columns
54979!     [ H K L Multiplicity Sin(Theta/Lambda) d_spacing |F|^2 ]
54980! Options:
54981! --help     or -h    Show this help
54982! --version  or -v    Display program version
54983! --out FILE          Specify the name of the next output file.
54984!    -o FILE            Default is to add .hkl to the initial file name.
54985! --lambda LAMBDA     Set the incoming probe wavelength [Angs].
54986!    -l    LAMBDA       Default is 0.5
54987! --powder   or -p    Generate a list of unique HKL reflections (for powders). Default.
54988! --xtal     or -x    Generate a list of all HKL reflections (for single crystals).
54989! --verbose           Display processing details.
54990! --no-outout-files   Just read the CIF/CFL/ShelX file (for checking).
54991! Example: ./cif2hkl -o CaF2.laz CaF2.cfl
54992
54993! Compile with:
54994!   gfortran -O2 CFML_GlobalDeps_Linux.f90 CFML_Math_Gen.f90 CFML_String_Util_gf.f90 CFML_Math_3D.f90 CFML_Sym_Table.f90 CFML_Chem_Scatt.f90 CFML_Symmetry.f90 CFML_Cryst_Types.f90 CFML_Reflct_Util.f90 CFML_Atom_Mod.f90 CFML_Geom_Calc.f90 CFML_Molecules.f90 CFML_Form_CIF.f90 CFML_Sfac.f90 -o cif2hkl cif2hkl.F90 -lm
54995!   rm *.mod
54996!   ./cif2hkl ../CIF/CaF2.cfl
54997!
54998! Create Matlab Mex with:
54999!     mex -c -O cif2hkl.F90
55000!     mex -O cif2hkl_mex.c cif2hkl.o -o cif2hkl -lgfortran
55001
55002! ==============================================================================
55003
55004! cif2hkl is available under the EUPL license (see below). It uses CrysFML which
55005! is a LGPL library. In agreement with the Intergovernmental Convention of the
55006! ILL, this software cannot be used in military applications.
55007
55008! ==============================================================================
55009
55010!		   European Union Public Licence
55011!		            V. 1.1
55012!		EUPL (c) the European Community 2007
55013
55014!This European Union Public Licence (the “EUPL”) applies to the Work or Software
55015!(as defined below) which is provided under the terms of this Licence. Any use of the
55016!Work, other than as authorised under this Licence is prohibited (to the extent such use
55017!is covered by a right of the copyright holder of the Work).
55018
55019!The Original Work is provided under the terms of this Licence when the Licensor (as
55020!defined below) has placed the following notice immediately following the copyright
55021!notice for the Original Work:
55022
55023!                          Licensed under the EUPL V.1.1
55024
55025!or has expressed by any other mean his willingness to license under the EUPL.
55026
55027!1. Definitions
55028
55029!In this Licence, the following terms have the following meaning:
55030
55031!- The Licence: this Licence.
55032
55033!- The Original Work or the Software: the software distributed and/or communicated
55034!by the Licensor under this Licence, available as Source Code and also as Executable
55035!Code as the case may be.
55036
55037!- Derivative Works: the works or software that could be created by the Licensee,
55038!based upon the Original Work or modifications thereof. This Licence does not define
55039!the extent of modification or dependence on the Original Work required in order to
55040!classify a work as a Derivative Work; this extent is determined by copyright law
55041!applicable in the country mentioned in Article 15.
55042
55043!- The Work: the Original Work and/or its Derivative Works.
55044
55045!- The Source Code: the human-readable form of the Work which is the most
55046!convenient for people to study and modify.
55047
55048!- The Executable Code: any code which has generally been compiled and which is
55049!meant to be interpreted by a computer as a program.
55050
55051!- The Licensor: the natural or legal person that distributes and/or communicates the
55052!Work under the Licence.
55053
55054!- Contributor(s): any natural or legal person who modifies the Work under the
55055!Licence, or otherwise contributes to the creation of a Derivative Work.
55056
55057!- The Licensee or “You”: any natural or legal person who makes any usage of the
55058!Software under the terms of the Licence.
55059
55060!- Distribution and/or Communication: any act of selling, giving, lending, renting,
55061!distributing, communicating, transmitting, or otherwise making available, on-line or
55062!off-line, copies of the Work or providing access to its essential functionalities at the
55063!disposal of any other natural or legal person.
55064
55065!2. Scope of the rights granted by the Licence
55066
55067!The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, sublicensable
55068!licence to do the following, for the duration of copyright vested in the
55069!Original Work:
55070
55071!- use the Work in any circumstance and for all usage,
55072!- reproduce the Work,
55073!- modify the Original Work, and make Derivative Works based upon the Work,
55074!- communicate to the public, including the right to make available or display the
55075!Work or copies thereof to the public and perform publicly, as the case may be,
55076!the Work,
55077!- distribute the Work or copies thereof,
55078!- lend and rent the Work or copies thereof,
55079!- sub-license rights in the Work or copies thereof.
55080
55081!Those rights can be exercised on any media, supports and formats, whether now
55082!known or later invented, as far as the applicable law permits so.
55083
55084!In the countries where moral rights apply, the Licensor waives his right to exercise his
55085!moral right to the extent allowed by law in order to make effective the licence of the
55086!economic rights here above listed.
55087
55088!The Licensor grants to the Licensee royalty-free, non exclusive usage rights to any
55089!patents held by the Licensor, to the extent necessary to make use of the rights granted
55090!on the Work under this Licence.
55091
55092!3. Communication of the Source Code
55093
55094!The Licensor may provide the Work either in its Source Code form, or as Executable
55095!Code. If the Work is provided as Executable Code, the Licensor provides in addition a
55096!machine-readable copy of the Source Code of the Work along with each copy of the
55097!Work that the Licensor distributes or indicates, in a notice following the copyright
55098!notice attached to the Work, a repository where the Source Code is easily and freely
55099!accessible for as long as the Licensor continues to distribute and/or communicate the
55100!Work.
55101
55102!4. Limitations on copyright
55103
55104!Nothing in this Licence is intended to deprive the Licensee of the benefits from any
55105!exception or limitation to the exclusive rights of the rights owners in the Original
55106!Work or Software, of the exhaustion of those rights or of other applicable limitations
55107!thereto.
55108
55109!5. Obligations of the Licensee
55110
55111!The grant of the rights mentioned above is subject to some restrictions and obligations
55112!imposed on the Licensee. Those obligations are the following:
55113!Attribution right: the Licensee shall keep intact all copyright, patent or trademarks
55114!notices and all notices that refer to the Licence and to the disclaimer of warranties.
55115
55116!The Licensee must include a copy of such notices and a copy of the Licence with
55117!every copy of the Work he/she distributes and/or communicates. The Licensee must
55118!cause any Derivative Work to carry prominent notices stating that the Work has been
55119!modified and the date of modification.
55120
55121!Copyleft clause: If the Licensee distributes and/or communicates copies of the
55122!Original Works or Derivative Works based upon the Original Work, this Distribution
55123!and/or Communication will be done under the terms of this Licence or of a later
55124!version of this Licence unless the Original Work is expressly distributed only under
55125!this version of the Licence. The Licensee (becoming Licensor) cannot offer or impose
55126!any additional terms or conditions on the Work or Derivative Work that alter or
55127!restrict the terms of the Licence.
55128
55129!Compatibility clause: If the Licensee Distributes and/or Communicates Derivative
55130!Works or copies thereof based upon both the Original Work and another work
55131!licensed under a Compatible Licence, this Distribution and/or Communication can be
55132!done under the terms of this Compatible Licence. For the sake of this clause,
55133!“Compatible Licence” refers to the licences listed in the appendix attached to this
55134!Licence. Should the Licensee’s obligations under the Compatible Licence conflict
55135!with his/her obligations under this Licence, the obligations of the Compatible Licence
55136!shall prevail.
55137
55138!Provision of Source Code: When distributing and/or communicating copies of the
55139!Work, the Licensee will provide a machine-readable copy of the Source Code or
55140!indicate a repository where this Source will be easily and freely available for as long
55141!as the Licensee continues to distribute and/or communicate the Work.
55142
55143!Legal Protection: This Licence does not grant permission to use the trade names,
55144!trademarks, service marks, or names of the Licensor, except as required for
55145!reasonable and customary use in describing the origin of the Work and reproducing
55146!the content of the copyright notice.
55147
55148!6. Chain of Authorship
55149
55150!The original Licensor warrants that the copyright in the Original Work granted
55151!hereunder is owned by him/her or licensed to him/her and that he/she has the power
55152!and authority to grant the Licence.
55153
55154!Each Contributor warrants that the copyright in the modifications he/she brings to the
55155!Work are owned by him/her or licensed to him/her and that he/she has the power and
55156!authority to grant the Licence.
55157
55158!Each time You accept the Licence, the original Licensor and subsequent Contributors
55159!grant You a licence to their contributions to the Work, under the terms of this
55160!Licence.
55161
55162!7. Disclaimer of Warranty
55163
55164!The Work is a work in progress, which is continuously improved by numerous
55165!contributors. It is not a finished work and may therefore contain defects or “bugs”
55166!inherent to this type of software development.
55167
55168!For the above reason, the Work is provided under the Licence on an “as is” basis and
55169!without warranties of any kind concerning the Work, including without limitation
55170!merchantability, fitness for a particular purpose, absence of defects or errors,
55171!accuracy, non-infringement of intellectual property rights other than copyright as
55172!stated in Article 6 of this Licence.
55173
55174!This disclaimer of warranty is an essential part of the Licence and a condition for the
55175!grant of any rights to the Work.
55176
55177!8. Disclaimer of Liability
55178
55179!Except in the cases of wilful misconduct or damages directly caused to natural
55180!persons, the Licensor will in no event be liable for any direct or indirect, material or
55181!moral, damages of any kind, arising out of the Licence or of the use of the Work,
55182!including without limitation, damages for loss of goodwill, work stoppage, computer
55183!failure or malfunction, loss of data or any commercial damage, even if the Licensor
55184!has been advised of the possibility of such damage. However, the Licensor will be
55185!liable under statutory product liability laws as far such laws apply to the Work.
55186
55187!9. Additional agreements
55188
55189!While distributing the Original Work or Derivative Works, You may choose to
55190!conclude an additional agreement to offer, and charge a fee for, acceptance of support,
55191!warranty, indemnity, or other liability obligations and/or services consistent with this
55192!Licence. However, in accepting such obligations, You may act only on your own
55193!behalf and on your sole responsibility, not on behalf of the original Licensor or any
55194!other Contributor, and only if You agree to indemnify, defend, and hold each
55195!Contributor harmless for any liability incurred by, or claims asserted against such
55196!Contributor by the fact You have accepted any such warranty or additional liability.
55197
55198!10. Acceptance of the Licence
55199
55200!The provisions of this Licence can be accepted by clicking on an icon “I agree”
55201!placed under the bottom of a window displaying the text of this Licence or by
55202!affirming consent in any other similar way, in accordance with the rules of applicable
55203!law. Clicking on that icon indicates your clear and irrevocable acceptance of this
55204!Licence and all of its terms and conditions.
55205
55206!Similarly, you irrevocably accept this Licence and all of its terms and conditions by
55207!exercising any rights granted to You by Article 2 of this Licence, such as the use of
55208!the Work, the creation by You of a Derivative Work or the Distribution and/or
55209!Communication by You of the Work or copies thereof.
55210
55211!11. Information to the public
55212
55213!In case of any Distribution and/or Communication of the Work by means of electronic
55214!communication by You (for example, by offering to download the Work from a
55215!remote location) the distribution channel or media (for example, a website) must at
55216!least provide to the public the information requested by the applicable law regarding
55217!the Licensor, the Licence and the way it may be accessible, concluded, stored and
55218!reproduced by the Licensee.
55219
55220!12. Termination of the Licence
55221
55222!The Licence and the rights granted hereunder will terminate automatically upon any
55223!breach by the Licensee of the terms of the Licence.
55224!Such a termination will not terminate the licences of any person who has received the
55225!Work from the Licensee under the Licence, provided such persons remain in full
55226!compliance with the Licence.
55227
55228!13. Miscellaneous
55229
55230!Without prejudice of Article 9 above, the Licence represents the complete agreement
55231!between the Parties as to the Work licensed hereunder.
55232
55233!If any provision of the Licence is invalid or unenforceable under applicable law, this
55234!will not affect the validity or enforceability of the Licence as a whole. Such provision
55235!will be construed and/or reformed so as necessary to make it valid and enforceable.
55236!The European Commission may publish other linguistic versions and/or new versions
55237!of this Licence, so far this is required and reasonable, without reducing the scope of
55238!the rights granted by the Licence. New versions of the Licence will be published with
55239!a unique version number.
55240
55241!All linguistic versions of this Licence, approved by the European Commission, have
55242!identical value. Parties can take advantage of the linguistic version of their choice.
55243
55244!14. Jurisdiction
55245
55246!Any litigation resulting from the interpretation of this License, arising between the
55247!European Commission, as a Licensor, and any Licensee, will be subject to the
55248!jurisdiction of the Court of Justice of the European Communities, as laid down in
55249!article 238 of the Treaty establishing the European Community.
55250!Any litigation arising between Parties, other than the European Commission, and
55251!resulting from the interpretation of this License, will be subject to the exclusive
55252!jurisdiction of the competent court where the Licensor resides or conducts its primary
55253!business.
55254
55255!15. Applicable Law
55256
55257!This Licence shall be governed by the law of the European Union country where the
55258!Licensor resides or has his registered office.
55259
55260!This licence shall be governed by the Belgian law if:
55261
55262!- a litigation arises between the European Commission, as a Licensor, and any
55263!Licensee;
55264!- the Licensor, other than the European Commission, has no residence or
55265!registered office inside a European Union country.
55266
55267!===
55268
55269!Appendix
55270
55271!“Compatible Licences” according to article 5 EUPL are:
55272
55273!- GNU General Public License (GNU GPL) v. 2
55274!- Open Software License (OSL) v. 2.1, v. 3.0
55275!- Common Public License v. 1.0
55276!- Eclipse Public License v. 1.0
55277!- Cecill v. 2.0
55278
55279! ==============================================================================
55280
55281
55282
55283! ==============================================================================
55284! Modules needed to compile this program:
55285! Module CFML_GlobalDeps                     CFML_GlobalDeps_Linux.f90
55286! Module CFML_Math_General                   CFML_Math_Gen.f90
55287! Module CFML_String_Utilities               CFML_String_Util_gf.f90
55288! Module CFML_Math_3D                        CFML_Math_3D.f90
55289! Module CFML_Symmetry_Tables                CFML_Sym_Table.f90
55290! Module CFML_Scattering_Chemical_Tables     CFML_Chem_Scatt.f90
55291! Module CFML_Crystallographic_Symmetry      CFML_Symmetry.f90
55292! Module CFML_Crystal_Metrics                CFML_Cryst_Types.f90
55293! Module CFML_Reflections_Utilities          CFML_Reflct_Util.f90
55294! Module CFML_Atom_TypeDef                   CFML_Atom_Mod.f90
55295! Module CFML_Structure_Factors              CFML_Sfac.f90
55296! Module CFML_Geometry_Calc                  CFML_Geom_Calc.f90
55297! Module CFML_Molecular_Crystals             CFML_Molecules.f90
55298! Module CFML_IO_Formats                     CFML_Form_CIF.f90
55299!
55300! CFML_GlobalDeps_Linux.f90 CFML_Math_Gen.f90 CFML_String_Util_gf.f90 CFML_Math_3D.f90 CFML_Sym_Table.f90 CFML_Chem_Scatt.f90 CFML_Symmetry.f90 CFML_Cryst_Types.f90 CFML_Reflct_Util.f90 CFML_Atom_Mod.f90 CFML_Geom_Calc.f90 CFML_Molecules.f90 CFML_Form_CIF.f90 CFML_Sfac.f90
55301
55302
55303! ==============================================================================
55304! routine to sort HKL reflections with decreasing d-spacing
55305subroutine sort_d(hkl)
55306  use CFML_Reflections_Utilities,      only: Reflection_List_Type, Reflection_Type
55307  use CFML_Math_General,               only: sort
55308  use CFML_GlobalDeps,                 only: cp
55309
55310  type (Reflection_List_Type), INTENT(in out) :: hkl
55311
55312  real(kind=cp),  dimension(hkl%Nref) :: S
55313  integer,        dimension(hkl%Nref) :: ind
55314  type (Reflection_Type),  dimension(hkl%Nref) :: ref
55315
55316  integer :: i
55317  type (Reflection_Type) :: temp
55318
55319  do i=1,hkl%Nref
55320    S(i)   = hkl%ref(i)%S
55321    ref(i) = hkl%ref(i)
55322  end do
55323  call sort(S, hkl%Nref, ind)
55324  ! now swap reflections: hkl%ref(ind(i))%S is in ascending order
55325  do i=1,hkl%Nref
55326    hkl%ref(i) = ref(ind(i))
55327  end do
55328
55329end subroutine sort_d
55330
55331
55332! ==============================================================================
55333! CFML_cif2hkl: convert 'file_in' (CIF/CFL) into a reflection list 'file_out' for PowderN
55334! INPUT:
55335!   file_in:   the CIF/CFL file name (string)
55336!   lambda:    neutron wavelength, which limits the number of reflections ;
55337!              use e.g. 1.0 (float*8)
55338!   mode:      "p" or "x" for powder and Xtal handling resp.
55339!   verbose:   0 or 1 for silent and verbose display resp.
55340! OUPUT:
55341!   file_out: the reflection list file name (string)
55342!   message:  a message to display (string)
55343subroutine CFML_cif2hkl(file_in, file_out, lambda, powxtal, verbose, message, mode)
55344
55345  use CFML_Crystallographic_Symmetry,  only: Space_Group_Type
55346  use CFML_Crystal_Metrics,            only: Crystal_Cell_Type
55347  use CFML_Atom_TypeDef,               only: Atom_List_Type
55348  use CFML_IO_Formats,                 only: Readn_Set_Xtal_Structure, File_List_Type
55349  use CFML_Reflections_Utilities,      only: Reflection_List_Type, Hkl_Uni, Hkl_Gen_SXtal,Get_MaxNumRef,WRITE_REFLIST_INFO
55350  use CFML_Structure_Factors,          only: Structure_Factors,Init_Structure_Factors,Calc_StrFactor
55351  use CFML_String_Utilities,           only: L_case
55352  use CFML_GlobalDeps,                 only: pi, dp
55353
55354  implicit none
55355
55356  ! subroutine I/O
55357  character(len=1024)         :: file_in, file_out     ! Name of the input/output file
55358  real*8                      :: lambda                ! probe wavelength
55359  character(len=1024)         :: powxtal               ! 'p' or 'x' or '-'
55360  integer                     :: verbose               ! 0 or 1 for verbose mode
55361  character*4096              :: message
55362  character(len=1024)         :: mode                  ! NUC,XRA,MAG,ELE
55363
55364  ! local variables
55365  type (File_List_Type)       :: fich_cfl
55366  type (Space_Group_Type)     :: SpG
55367  type (Crystal_Cell_Type)    :: Cell
55368  type (Atom_List_Type)       :: A
55369  type (Reflection_List_Type) :: hkl
55370  real                        :: stlmax
55371  integer                     :: lun=1, MaxNumRef, I, Y
55372  character(len=1024)         :: ext                   ! file name extension
55373
55374  integer, parameter                             :: n_elements=423
55375  character (Len = 8), dimension(n_elements)     :: element
55376  real ( KIND = dp ), dimension(n_elements)      :: Bcoh, Binc, weight, Sabs
55377  real                                           :: sigma_coh, sigma_inc, sigma_abs, mass, F
55378
55379  character(len=1024)                            :: formula
55380  character(len=4096)                            :: s1,s2,s3  ! temporary string for concatenation
55381  integer*4, dimension(3)                        :: today, now
55382  character*2   eol
55383
55384  integer dot_pos
55385  integer sep_pos
55386  integer end_pos
55387
55388  !values to test CFML_cif2hkl(program)
55389  !file_in  = 'Na2Ca3Al2F14.cfl'
55390  !file_out = 'Na2Ca3Al2F14_out'
55391  !lambda   = 2.4105
55392  if (lambda > 0) then
55393    stlmax = 1/lambda
55394  else
55395    stlmax= 1.0
55396  end if
55397
55398  eol=char(13)//char(10)
55399  message = ''
55400
55401  ! set the element name, cross sections and weight
55402  ! list of isotopes
55403  element   = (/'H    ','D    ','2H   ','3H   ','He   ','3He  ','4He  ','Li   ','6Li  ','7Li  ','Be   ',&
55404  '9Be  ','B    ','10B  ','11B  ','C    ','12C  ','13C  ','14C  ','N    ','14N  ','15N  ','O    ','16O  ',&
55405  '17O  ','18O  ','F    ','19F  ','Ne   ','20Ne ','21Ne ','22Ne ','Na   ','23Na ','Mg   ','24Mg ','25Mg ',&
55406  '26Mg ','Al   ','27Al ','Si   ','28Si ','29Si ','30Si ','P    ','31P  ','S    ','32S  ','33S  ','34S  ',&
55407  '36S  ','Cl   ','35Cl ','37Cl ','Ar   ','36Ar ','38Ar ','40Ar ','K    ','39K  ','40K  ','41K  ','Ca   ',&
55408  '40Ca ','42Ca ','43Ca ','44Ca ','46Ca ','48Ca ','Sc   ','45Sc ','Ti   ','46Ti ','47Ti ','48Ti ','49Ti ',&
55409  '50Ti ','V    ','50V  ','51V  ','Cr   ','50Cr ','52Cr ','53Cr ','54Cr ','Mn   ','55Mn ','Fe   ','54Fe ',&
55410  '56Fe ','57Fe ','58Fe ','Co   ','59Co ','Ni   ','58Ni ','60Ni ','61Ni ','62Ni ','64Ni ','Cu   ','63Cu ',&
55411  '65Cu ','Zn   ','64Zn ','66Zn ','67Zn ','68Zn ','70Zn ','Ga   ','69Ga ','71Ga ','Ge   ','70Ge ','72Ge ',&
55412  '73Ge ','74Ge ','76Ge ','As   ','75As ','Se   ','74Se ','76Se ','77Se ','78Se ','80Se ','82Se ','Br   ',&
55413  '79Br ','81Br ','Kr   ','78Kr ','80Kr ','82Kr ','83Kr ','84Kr ','86Kr ','Rb   ','85Rb ','87Rb ','Sr   ',&
55414  '84Sr ','86Sr ','87Sr ','88Sr ','Y    ','89Y  ','Zr   ','90Zr ','91Zr ','92Zr ','94Zr ','96Zr ','Nb   ',&
55415  '93Nb ','Mo   ','92Mo ','94Mo ','95Mo ','96Mo ','97Mo ','98Mo ','100Mo','Tc   ','99Tc ','Ru   ','96Ru ',&
55416  '98Ru ','99Ru ','100Ru','101Ru','102Ru','104Ru','Rh   ','103Rh','Pd   ','102Pd','104Pd','105Pd','106Pd',&
55417  '108Pd','110Pd','Ag   ','107Ag','109Ag','Cd   ','106Cd','108Cd','110Cd','111Cd','112Cd','113Cd','114Cd',&
55418  '116Cd','In   ','113In','115In','Sn   ','112Sn','114Sn','115Sn','116Sn','117Sn','118Sn','119Sn','120Sn',&
55419  '122Sn','124Sn','Sb   ','121Sb','123Sb','Te   ','120Te','122Te','123Te','124Te','125Te','126Te','128Te',&
55420  '130Te','I    ','127I ','Xe   ','124Xe','126Xe','128Xe','129Xe','130Xe','131Xe','132Xe','134Xe','136Xe',&
55421  'Cs   ','133Cs','Ba   ','130Ba','132Ba','134Ba','135Ba','136Ba','137Ba','138Ba','La   ','138La','139La',&
55422  'Ce   ','136Ce','138Ce','140Ce','142Ce','Pr   ','141Pr','Nd   ','142Nd','143Nd','144Nd','145Nd','146Nd',&
55423  '148Nd','150Nd','Pm   ','147Pm','Sm   ','144Sm','147Sm','148Sm','149Sm','150Sm','152Sm','154Sm','Eu   ',&
55424  '151Eu','153Eu','Gd   ','152Gd','154Gd','155Gd','156Gd','157Gd','158Gd','160Gd','Tb   ','159Tb','Dy   ',&
55425  '156Dy','158Dy','160Dy','161Dy','162Dy','163Dy','164Dy','Ho   ','165Ho','Er   ','162Er','164Er','166Er',&
55426  '167Er','168Er','170Er','Tm   ','169Tm','Yb   ','168Yb','170Yb','171Yb','172Yb','173Yb','174Yb','176Yb',&
55427  'Lu   ','175Lu','176Lu','Hf   ','174Hf','176Hf','177Hf','178Hf','179Hf','180Hf','Ta   ','180Ta','181Ta',&
55428  'W    ','180W ','182W ','183W ','184W ','186W ','Re   ','185Re','187Re','Os   ','184Os','186Os','187Os',&
55429  '188Os','189Os','190Os','192Os','Ir   ','191Ir','193Ir','Pt   ','190Pt','192Pt','194Pt','195Pt','196Pt',&
55430  '198Pt','Au   ','196Au','Hg   ','196Hg','198Hg','199Hg','200Hg','201Hg','202Hg','204Hg','Tl   ','203Tl',&
55431  '205Tl','Pb   ','204Pb','206Pb','207Pb','208Pb','Bi   ','209Bi','Po   ','210Po','At   ','Rn   ','222Rn',&
55432  'Fr   ','Ra   ','226Ra','Ac   ','Th   ','232Th','Pa   ','231Pa','U    ','233U ','234U ','235U ','238U ',&
55433  'Np   ','237Np','Pu   ','238Pu','239Pu','240Pu','242Pu','Am   ','243Am','Cm   ','244Cm','246Cm','248Cm',&
55434  'Bk   ','Cf   ','Es   ','Fm   ','Md   ','No   ','Lr   ','Rf   ','Db   ','Sg   ','Bh   ','Hs   ','Mt   ',&
55435  'Ds   ','Rg   ','Cn   ','Uut  ','Uuq  ','Uup  ','Uuh  ','Uus  ','Uuo  '/)
55436  ! list of coherent lengths
55437  Bcoh      = (/-0.00003739, -0.00003741, 0.00006671, 0.00004792, &
55438   0.00003260, 0.00000000, 0.00003260, -0.00001900, 0.00000000, -0.00002220,&
55439    0.00007790, 0.00007790, 0.00000000	, 0.00000000, 0.00006650,&
55440    0.00006646	, 0.00006651, 0.00006190, 0.00000000, 0.00009360	,&
55441    0.00009370, 0.00006440, 0.00005803	, 0.00005803, 0.00005780,&
55442    0.00005840, 0.00005654	, 0.00005654, 0.00004566, 0.00004631,&
55443    0.00006660, 0.00003870, 0.00003630, 0.00003630, 0.00005375, 0.00005660,&
55444    0.00003620, 0.00004890, 0.00003449, 0.00003449, 0.00004149, 0.00004107,&
55445    0.00004700, 0.00004580, 0.00005130	, 0.00005130, 0.00002847	,&
55446    0.00002804, 0.00004740, 0.00003480, 0.00003000, 0.00009577, 0.00011650,&
55447    0.00003080, 0.00001909, 0.00024900, 0.00003500, 0.00001830, 0.00003670	, 0.00003740, 0.00003000,&
55448    0.00002690, 0.00004700, 0.00004800, 0.00003360, -0.00001560, 0.00001420, 0.00003600, 0.00000390,&
55449    0.00012290, 0.00012290, -0.00003438, 0.00004930, 0.00003630, -0.00006080, 0.00001040, 0.00006180,&
55450    -0.00000382, 0.00007600, -0.00000402, 0.00003635, -0.00004500, 0.00004920, -0.00004200, 0.00004550,&
55451    -0.00003730, -0.00003730, 0.00009450, 0.00004200, 0.00009940, 0.00002300, 0.00015000, 0.00002490,&
55452    0.00002490, 0.00010300, 0.00014400, 0.00002800, 0.00007600, -0.00008700, -0.00000370, 0.00007718,&
55453    0.00006430, 0.00010610, 0.00005680, 0.00005220, 0.00005970, 0.00007560, 0.00006030, 0.00006000, 0.00007288,&
55454    0.00007880, 0.00006400, 0.00008185, 0.00010000, 0.00008510, 0.00005020, 0.00007580, 0.00008200, 0.00006580,&
55455    0.00006580, 0.00007970, 0.00000800, 0.00012200, 0.00008250, 0.00008240, 0.00007480, 0.00006340, 0.00006795,&
55456    0.00006800, 0.00006790, 0.00007810, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00008100,&
55457    0.00007090, 0.00007030, 0.00007230, 0.00007020, 0.00007000, 0.00005670, 0.00007400, 0.00007150,&
55458    0.00007750	, 0.00007750, 0.00007160, 0.00006400, 0.00008700, 0.00007400, 0.00008200, 0.00005500,&
55459    0.00007054, 0.00007054, 0.00006715, 0.00006910, 0.00006800, 0.00006910, 0.00006200, 0.00007240, 0.00006580,&
55460    0.00006730, 0.00006800, 0.00006800, 0.00007030, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55461    0.00000000, 0.00000000, 0.00005880, 0.00005880, 0.00005910, 0.00007700, 0.00007700, 0.00005500, 0.00006400,&
55462    0.00004100, 0.00007700, 0.00005922, 0.00007555, 0.00004165, 0.00000000, 0.00005000, 0.00005400, 0.00005900,&
55463    0.00006500, 0.00006400, 0.00000000, 0.00007500, 0.00006300, 0.00000000, 0.00005390, 0.00000000, 0.00006225,&
55464    0.00006000, 0.00006200, 0.00006000, 0.00005930, 0.00006480, 0.00006070, 0.00006120, 0.00006490, 0.00005740,&
55465    0.00005970, 0.00005570, 0.00005710, 0.00005380, 0.00005800, 0.00005300, 0.00003800, 0.00000000, 0.00007960,&
55466    0.00005020, 0.00005560, 0.00005890, 0.00006020, 0.00005280	, 0.00005280, 0.00004920, 0.00000000,&
55467    0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00005420,&
55468    0.00005420, 0.00005070, -0.00003600, 0.00007800, 0.00005700, 0.00004670, 0.00004910, 0.00006830,&
55469    0.00004840, 0.00008240, 0.00008000, 0.00008240, 0.00004840, 0.00005800, 0.00006700, 0.00004840, 0.00004750,&
55470    0.00004580, 0.00004580, 0.00007690, 0.00007700, 0.00014000, 0.00002800, 0.00014000, 0.00008700, 0.00005700,&
55471    0.00005300, 0.00012600, 0.00012600, 0.00000000, -0.00003000, 0.00014000, -0.00003000, 0.00000000,&
55472    0.00014000, -0.00005000, 0.00009300, 0.00000000, 0.00000000, 0.00008220, 0.00000000, 0.00010000,&
55473    0.00010000, 0.00000000, 0.00006300, 0.00000000, 0.00009000, 0.00009150, 0.00007380, 0.00007380, 0.00000000,&
55474    0.00006100, 0.00006000, 0.00006700, 0.00010300, -0.00001400, 0.00005000, 0.00000000, 0.00008010,&
55475    0.00008010, 0.00007790, 0.00008800, 0.00008200, 0.00010600, 0.00003000, 0.00007400, 0.00009600, 0.00007070,&
55476    0.00007070, 0.00012430, 0.00000000, 0.00006770, 0.00009660, 0.00009430, 0.00009560, 0.00019300, 0.00008720,&
55477    0.00007210, 0.00007240, 0.00000000, 0.00007700, 0.00010900, 0.00006610, 0.00000800, 0.00005900, 0.00007460,&
55478    0.00013200, 0.00006910, 0.00007000, 0.00006910, 0.00004860	, 0.00005000, 0.00006970, 0.00006530,&
55479    0.00007480, -0.00000720, 0.00009200, 0.00009000, 0.00009300, 0.00010700, 0.00010000, 0.00011600,&
55480    0.00010000, 0.00007600, 0.00010700, 0.00011000, 0.00011500, 0.00010600, 0.00000000, 0.00000000, 0.00009600,&
55481    0.00009000, 0.00009900, 0.00010550, 0.00008830, 0.00009890, 0.00007800, 0.00007630, 0.00007630, 0.00012692,&
55482    0.00030300, 0.00000000, 0.00016900, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00008776, 0.00006990,&
55483    0.00009520, 0.00009405, 0.00009900, 0.00009220, 0.00009280, 0.00009500, 0.00008532, 0.00008532, 0.00000000,&
55484    0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00010000, 0.00010000, 0.00000000, 0.00010310,&
55485    0.00010310, 0.00009100, 0.00009100, 0.00008417	, 0.00010100, 0.00012400, 0.00010470, 0.00008402,&
55486    0.00010550, 0.00010550, 0.00000000, 0.00014100, 0.00007700, 0.00003500, 0.00008100, 0.00008300, 0.00008300,&
55487    0.00000000, 0.00009500, 0.00009300, 0.00007700, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55488    0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55489    0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000 /)
55490  ! list of incoherent lengths
55491  Binc      = (/0.00025272	, 0.00025274, 0.00004040	, -0.00001040, 0.00000000	, 0.00000000, 0.00000000,&
55492    2.70576E-05, 0.00000000, -0.00002490, 0.00000120	, 0.00000120, 3.67807E-05, 0.00000000, -0.00001300,&
55493    8.92062E-07, 0.00000000, -0.00000520, 0.00000000, 1.99471E-05, 0.00002000, -0.00000020, 7.97885E-07,&
55494    0.00000000, 0.00000180, 0.00000000, -0.00000082	, -0.00000082, 2.52313E-06, 0.00000000, 0.00000600,&
55495    0.00000000, 0.00003590	, 0.00003590, 7.97885E-06, 0.00000000, 0.00001480, 0.00000000, 0.00000256	,&
55496    0.00000256, 1.78412E-06, 0.00000000, 0.00000090, 0.00000000, 0.00000200	, 0.00000200, 2.36017E-06,&
55497    0.00000000, 0.00001500, 0.00000000, 0.00000000, 6.49431E-05, 0.00006100, 0.00000100, 1.33809E-05,&
55498    0.00000000, 0.00000000, 0.00000000, 1.46581E-05, 0.00001400, 1.99471E-05, 0.00001500, 6.30783E-06,&
55499    0.00000000, 0.00000000, 1.99471E-05, 0.00000000, 0.00000000, 0.00000000, -0.00006000, -0.00006000,&
55500    4.77899E-05, 0.00000000, -0.00003500, 0.00000000, 0.00005100, 0.00000000, 6.35809E-05, 1.99471E-05,&
55501    0.00006350, 3.81611E-05, 0.00000000, 0.00000000, 0.00006870, 0.00000000, 0.00001790, 0.00001790,&
55502    1.78412E-05, 0.00000000, 0.00000000, 1.5451E-05, 0.00000000, -0.00006200, -0.00006200, 6.43275E-05,&
55503    0.00000000, 0.00000000, 0.00003900, 0.00000000, 0.00000000, 2.09207E-05, 0.00000220, 0.00001790,&
55504    7.82781E-06, 0.00000000, 0.00000000, -0.00001500, 0.00000000, 0.00000000, 1.12838E-05, -0.00000850,&
55505    -0.00000820, 1.19683E-05, 0.00000000, 0.00000000, 0.00003400, 0.00000000, 0.00000000, -0.00000690,&
55506    -0.00000690, 1.59577E-05, 0.00000000, 0.00000000, 0.00000600, 0.00000000, 0.00000000, 0.00000000,&
55507    8.92062E-06, -0.00001100, 0.00000600, 2.82095E-06, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55508    0.00000000, 0.00000000, 1.99471E-05, 1.99471E-05, 1.99471E-05, 6.90988E-06, 0.00000000, 0.00000000,&
55509    1.99471E-05, 0.00000000, 0.00001100	, 0.00001100, 3.98942E-06, 0.00000000, -0.00001080, 0.00000000,&
55510    0.00000000, 0.00000000, -0.00000139, -0.00000139, 5.6419E-06, 0.00000000, 0.00000000, 1.99471E-05,&
55511    0.00000000, 1.99471E-05, 0.00000000, 0.00000000, 1.99471E-05, 1.99471E-05, 1.78412E-05, 0.00000000,&
55512    0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 1.5451E-05, 1.5451E-05,&
55513    8.60273E-06, 0.00000000, 0.00000000, -0.00002600, 0.00000000, 0.00000000, 0.00000000, 2.14837E-05,&
55514    0.00001000, -0.00001600, 5.24727E-05, 0.00000000, 0.00000000, 0.00000000, 1.5451E-05, 0.00000000,&
55515    1.5451E-05, 0.00000000, 0.00000000, 2.07296E-05, 0.00000017, -0.00002100, 4.18414E-06, 0.00000000,&
55516    0.00000000, 1.5451E-05, 0.00000000, 1.5451E-05, 0.00000000, 1.5451E-05, 0.00000000, 0.00000000, 0.00000000,&
55517    2.36017E-06, -0.00000050, -0.00000100, 8.46284E-06, 0.00000000, 0.00000000, -0.00002040, 0.00000000,&
55518    -0.00000260, 0.00000000, 0.00000000, 0.00000000, 0.00001580	, 0.00001580, 0.00003040	, 0.00000000,&
55519    0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55520    0.00001290	, 0.00001290, 1.09255E-05, 0.00000000, 0.00000000, 0.00000000, 1.99471E-05, 0.00000000,&
55521    1.99471E-05, 0.00000000, 2.99871E-05, 1.99471E-05, 0.00003000, 8.92062E-07, 0.00000000, 0.00000000,&
55522    0.00000000, 0.00000000, -0.00000350, -0.00000350, 8.55636E-05, 0.00000000, 0.00021000, 0.00000000,&
55523    6.30783E-05, 0.00000000, 0.00000000, 0.00000000, 0.00003200	, 0.00003200, 0.00017617	, 0.00000000,&
55524    0.00011000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 4.46031E-05, 0.00000000,&
55525    0.00003200, 0.00034664	, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55526    0.00000000, -0.00000170, -0.00000170, 0.00020806	, 0.00000000, 0.00000000, 0.00000000, 0.00004900,&
55527    0.00000000, 0.00001300, 0.00000000, -0.00001700, -0.00001700, 2.95864E-05, 0.00000000, 0.00000000,&
55528    0.00000000, 0.00001000, 0.00000000, 0.00000000, 0.00000900	, 0.00000900, 5.6419E-05, 0.00000000,&
55529    0.00000000, -0.00005590, 0.00000000, -0.00005300, 0.00000000, 0.00000000, 2.36017E-05, 0.00002200,&
55530    0.00000000, 4.54864E-05, 0.00000000, 0.00000000, 0.00000900, 0.00000000, 0.00001060, 0.00000000,&
55531    2.82095E-06, 1.99471E-05, -0.00000290, 3.60155E-05, 0.00000000, 0.00000000, 1.5451E-05, 0.00000000,&
55532    0.00000000, 2.67619E-05, 0.00002000, 0.00002800, 1.5451E-05, 0.00000000, 0.00000000, 1.5451E-05,&
55533    0.00000000, 1.99471E-05, 0.00000000, 0.00000000, 0.00000000	, 0.00000000, 0.00000000, 1.01711E-05,&
55534    0.00000000, 0.00000000, 0.00000000, -0.00001000, 0.00000000, 0.00000000, -0.00001840, -0.00001840,&
55535    7.24715E-05, 0.00000000, 0.00000000, 0.00015500, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55536    1.29272E-05, 0.00001060, -0.00000242, 1.5451E-06, 0.00000000, 0.00000000, 0.00000140, 0.00000000,&
55537    2.58544E-06, 2.58544E-06, 0.00000259	, 0.00000259, 0.00000000	, 0.00000000	, 0.00000000, 0.00000000	,&
55538    0.00000000	, 0.00000000, 0.00000000	, 0.00000000	, 0.00000000, 8.92062E-06, 8.92062E-06, 1.99471E-06,&
55539    0.00001000, 0.00000000, 0.00001300, 0.00000000, 1.99471E-05, 1.99471E-05, 0.00000000	, 0.00000000,&
55540    0.00001300, 0.00000000, 0.00000000, 0.00002000	, 0.00002000, 0.00000000	, 0.00000000, 0.00000000,&
55541    0.00000000, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	,&
55542    0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	,&
55543    0.00000000	, 0.00000000	, 0.00000000	, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000,&
55544    0.00000000/)
55545  ! list of absorption cross sections
55546  Sabs = (/0.33260000	, 0.33260000	, 0.00051900	, 0.00000000	, 0.00747000	, 5333.00000000,&
55547    0.00000000	, 70.50000000, 940.00000000, 0.04540000, 0.00760000	, 0.00760000	, 767.00000000,&
55548    3835.00000000, 0.00550000, 0.00350000	, 0.00353000	, 0.00137000, 0.00000000	, 1.90000000	, 1.91000000	,&
55549    0.00002400, 0.00019000	, 0.00010000	, 0.23600000	, 0.00016000	, 0.00960000	, 0.00960000, 0.03900000,&
55550    0.03600000, 0.67000000, 0.04600000, 0.53000000	, 0.53000000, 0.06300000, 0.05000000, 0.19000000,&
55551    0.03820000, 0.23100000	, 0.23100000, 0.17100000, 0.17700000, 0.10100000, 0.10700000, 0.17200000	,&
55552    0.17200000	, 0.53000000	, 0.54000000	, 0.54000000	, 0.22700000	, 0.15000000	, 33.50000000,&
55553    44.10000000, 0.43300000, 0.67500000, 5.20000000, 0.80000000, 0.66000000, 2.10000000	, 2.10000000	,&
55554    35.00000000, 1.46000000	, 0.43000000, 0.41000000, 0.68000000, 6.20000000, 0.88000000, 0.74000000,&
55555    1.09000000, 27.50000000, 27.50000000, 6.09000000, 0.59000000, 1.70000000, 7.84000000, 2.20000000,&
55556    0.17900000, 5.08000000, 60.00000000, 4.90000000, 3.05000000, 15.80000000, 0.76000000, 18.10000000,&
55557    0.36000000, 13.30000000, 13.30000000, 2.56000000, 2.25000000, 2.59000000, 2.48000000, 1.28000000,&
55558    37.18000000, 37.18000000, 4.49000000, 4.60000000, 2.90000000, 2.50000000, 14.50000000, 1.52000000,&
55559    3.78000000, 4.50000000, 2.17000000, 1.11000000, 0.93000000, 0.62000000, 6.80000000, 1.10000000, 0.09200000,&
55560    2.75000000, 2.18000000, 3.61000000, 2.20000000, 3.00000000, 0.80000000, 15.10000000, 0.40000000,&
55561    0.16000000, 4.50000000	, 4.50000000, 11.70000000, 51.80000000, 85.00000000, 42.00000000, 0.43000000,&
55562    0.61000000, 0.04400000, 6.90000000, 11.00000000, 2.70000000, 25.00000000, 6.40000000, 11.80000000,&
55563    29.00000000, 185.00000000, 0.11300000, 0.00300000, 0.38000000, 0.48000000, 0.12000000, 1.28000000,&
55564    0.87000000, 1.04000000, 16.00000000, 0.05800000, 1.28000000	, 1.28000000	, 0.18500000, 0.01100000,&
55565    1.17000000, 0.22000000, 0.04990000, 0.02290000, 1.15000000	, 1.15000000, 2.48000000	, 0.01900000,&
55566    0.01500000, 13.10000000, 0.50000000, 2.50000000, 0.12700000, 0.40000000, 20.00000000, 20.00000000,&
55567    2.56000000, 0.28000000, 8.00000000, 6.90000000, 4.80000000, 3.30000000, 1.17000000, 0.31000000,&
55568    144.80000000, 144.80000000, 6.90000000, 3.40000000, 0.60000000, 20.00000000, 0.30400000, 8.55000000,&
55569    0.22600000, 63.30000000, 37.60000000, 91.00000000, 2520.00000000, 1.00000000, 1.10000000, 11.00000000,&
55570    24.00000000, 2.20000000, 20600.00000000, 0.34000000, 0.07500000, 193.80000000, 12.00000000, 202.00000000,&
55571    0.62600000, 1.00000000, 0.11400000, 30.00000000, 0.14000000, 2.30000000, 0.22000000, 2.20000000,&
55572    0.14000000, 0.18000000, 0.13300000, 4.91000000, 5.75000000, 3.80000000, 4.70000000, 2.30000000, 3.40000000,&
55573    418.00000000, 6.80000000, 1.55000000, 1.04000000, 0.21500000, 0.29000000, 6.15000000	, 6.15000000,&
55574    23.90000000	, 165.00000000, 3.50000000, 8.00000000, 21.00000000, 26.00000000, 85.00000000, 0.45000000,&
55575    0.26500000, 0.26000000, 29.00000000	, 29.00000000, 1.10000000, 30.00000000, 7.00000000, 2.00000000,&
55576    5.80000000, 0.68000000, 3.60000000, 0.27000000, 8.97000000, 57.00000000, 8.93000000, 0.63000000,&
55577    7.30000000, 1.10000000, 0.57000000, 0.95000000, 11.50000000, 11.50000000, 50.50000000, 18.70000000,&
55578    337.00000000, 3.60000000, 42.00000000, 1.40000000, 2.50000000, 1.20000000, 168.40000000, 168.40000000,&
55579    5922.00000000, 0.70000000, 57.00000000, 2.40000000, 42080.00000000, 104.00000000, 206.00000000, 8.40000000,&
55580    4530.00000000, 9100.00000000, 312.00000000, 49700.00000000, 735.00000000, 85.00000000, 61100.00000000,&
55581    1.50000000, 259000.00000000, 2.20000000, 0.77000000, 23.40000000, 23.40000000, 994.00000000, 33.00000000,&
55582    43.00000000, 56.00000000, 600.00000000, 194.00000000, 124.00000000, 2840.00000000, 64.70000000,&
55583    64.70000000, 159.00000000, 19.00000000, 13.00000000, 19.60000000, 659.00000000, 2.74000000, 5.80000000,&
55584    100.00000000, 100.00000000, 34.80000000, 2230.00000000, 11.40000000, 48.60000000, 0.80000000, 17.10000000,&
55585    69.40000000, 2.85000000, 74.00000000, 21.00000000, 2065.00000000, 104.10000000, 561.00000000, 23.50000000,&
55586    373.00000000, 84.00000000, 41.00000000, 13.04000000, 20.60000000, 563.00000000, 20.50000000, 18.30000000,&
55587    30.00000000, 20.70000000, 10.10000000, 1.70000000, 37.90000000, 89.70000000, 112.00000000, 76.40000000,&
55588    16.00000000, 3000.00000000, 80.00000000, 320.00000000, 4.70000000, 25.00000000, 13.10000000, 2.00000000,&
55589    425.00000000, 954.00000000, 111.00000000, 10.30000000, 152.00000000, 10.00000000, 1.44000000, 27.50000000,&
55590    0.72000000, 3.66000000, 98.65000000, 98.65000000, 372.30000000, 3080.00000000, 2.00000000, 2150.00000000,&
55591    60.00000000, 7.80000000, 4.89000000, 0.43000000, 3.43000000, 11.40000000, 0.10400000, 0.17100000	,&
55592    0.65000000, 0.03000000, 0.69900000, 0.00048000, 0.03380000, 0.03380000, 0.00000000	, 0.00000000,&
55593    0.00000000	, 0.00000000	, 0.00000000, 0.00000000	, 12.80000000	, 12.80000000, 0.00000000	, 7.37000000	,&
55594    7.37000000, 200.60000000, 200.60000000, 7.57000000	, 574.70000000, 100.10000000, 680.90000000, 2.68000000,&
55595    175.90000000, 175.90000000, 0.00000000	, 558.00000000, 1017.30000000, 289.60000000, 18.50000000,&
55596    75.30000000	, 75.30000000, 0.00000000	, 16.20000000, 1.36000000, 3.00000000, 0.00000000	, 0.00000000	,&
55597    0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	,&
55598    0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	,&
55599    0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	, 0.00000000	/)
55600  ! list of isotopes weights
55601  weight = (/1.0079000, 1.0078250, 2.0141018, 3.0160493, 4.0026000, 3.0160293, 4.0026033, 6.9410000, 6.0151223,&
55602    7.0160040, 9.0121821, 9.0121821, 10.8110000, 10.0129370, 11.0093055, 12.0107000, 12.0000000, 13.0033548,&
55603    14.0032420, 14.0067000, 14.0030740, 15.0001089, 15.9994000, 15.9949146, 16.9991315, 17.9991604, 18.9984032,&
55604    18.9984032, 20.1797000, 19.9924402, 20.9938467, 21.9913855, 22.9897697, 22.9897697, 24.3050000, 23.9850419,&
55605    24.9858370, 25.9825930, 26.9815384, 26.9815384, 28.0855000, 27.9769265, 28.9764947, 29.9737702, 30.9737615,&
55606    30.9737615, 32.0650000, 31.9720707, 32.9714585, 33.9678668, 35.9670809, 35.4530000, 34.9688527, 36.9659026,&
55607    39.9480000, 35.9675463, 37.9627322, 39.9623831, 39.0983000, 38.9637069, 39.9639987, 40.96182597,&
55608    40.0780000, 39.9625912, 41.9586183, 42.9587668, 43.9554811, 45.9536928, 47.9525340, 44.9559102, 44.9559102,&
55609    47.8670000, 45.9526295, 46.9517638, 47.9479471, 48.9478708, 49.9447921, 50.9415000, 49.9471628, 50.9439637,&
55610    51.9961000, 49.9460496, 51.9405119, 52.9406538, 53.9388849, 54.9380496, 54.9380496, 55.8450000, 53.9396148,&
55611    55.9349421, 56.9353987, 57.9332805, 58.9332002, 58.9332002, 58.6934000, 57.9353479, 59.9307906, 60.9310604,&
55612    61.9283488, 63.9279696, 63.5460000, 62.9296011, 64.9277937, 65.3900000, 63.9291466, 65.9260368, 66.9271309,&
55613    67.9248476, 69.9253250, 69.7230000, 68.9255810, 70.9247050, 72.6400000, 69.9242504, 71.9220762, 72.9234594,&
55614    73.9211782, 75.9214027, 74.9215964, 74.9215964, 78.9600000, 73.9224766, 75.9192141, 76.9199146, 77.9173095,&
55615    79.9165218, 81.9167000, 79.9040000, 78.9183376, 80.9162910, 83.8000000, 77.9203860, 79.9163780, 81.9134846,&
55616    82.9141360, 83.9115070, 85.9106103, 85.4678000, 84.9117893, 86.9091835, 87.6200000, 83.9134250, 85.9092624,&
55617    86.9088793, 87.9056143, 88.9058479, 88.9058479, 91.2240000, 89.9047037, 90.9056450, 91.9050401, 93.9063158,&
55618    95.9082760, 92.9063775, 92.9063775, 95.9400000, 91.9068100, 93.9050876, 94.9058415, 95.9046789, 96.9060210,&
55619    97.9054078, 99.9074770, 98.0000000, 98.0000000, 101.0700000, 95.9075980, 97.9052870, 98.9059393, 99.9042197,&
55620    100.9055822, 101.9043495, 103.9054300, 102.9055040, 102.9055040, 106.4200000, 101.9056080, 103.9040350,&
55621    104.9050840, 105.9034830, 107.9038940, 109.9051520, 107.8682000, 106.9050930, 108.9047560, 112.4110000,&
55622    105.9064580, 107.9041830, 109.9030060, 110.9041820, 111.9027572, 112.9044009, 113.9033581, 115.9047550,&
55623    114.8180000, 112.9040610, 114.9038780, 118.7100000, 111.9048210, 113.9027820, 114.9033460, 115.9017440,&
55624    116.9029540, 117.9016060, 118.9033090, 119.9021966, 121.9034401, 123.9052746, 121.7600000, 120.9038180,&
55625    122.9042157, 127.6000000, 119.9040200, 121.9030471, 122.9042730, 123.9028195, 124.9044247, 125.9033055,&
55626    127.9044614, 129.9062228, 126.9044680, 126.9044680, 131.2930000, 123.9058958, 125.9042690, 127.9035304,&
55627    128.9047795, 129.9035079, 130.9050819, 131.9041545, 133.9053945, 135.9072200, 132.9054470, 132.9054470,&
55628    137.3270000, 129.9063100, 131.9050560, 133.9045030, 134.9056830, 135.9045700, 136.9058210, 137.9052410,&
55629    138.9055000, 137.9071070, 138.9063480, 140.1160000, 135.9071400, 137.9059860, 139.9054340, 141.9092400,&
55630    140.9076480, 140.9076480, 144.2400000, 141.9077190, 142.9098100, 143.9100830, 144.9125690, 145.9131120,&
55631    147.9168890, 149.9208870, 145.0000000, 145.0000000, 150.3600000, 143.9119950, 146.9148930, 147.9148180,&
55632    148.9171800, 149.9172710, 151.9197280, 153.9222050, 151.9640000, 150.9198460, 152.9212260, 157.2500000,&
55633    151.9197880, 153.9208620, 154.9226190, 155.9221200, 156.9239570, 157.9241010, 159.9270510, 158.9253430,&
55634    158.9253430, 162.5000000, 155.9242780, 157.9244050, 159.9251940, 160.9269300, 161.9267950, 162.9287280,&
55635    163.9291710, 164.9303190, 164.9303190, 167.2590000, 161.9287750, 163.9291970, 165.9302900, 166.9320450,&
55636    167.9323680, 169.9354600, 168.9342110, 168.9342110, 173.0400000, 167.9338940, 169.9347590, 170.9363220,&
55637    171.9363777, 172.9382068, 173.9388581, 175.9425680, 174.9670000, 174.9407679, 175.9426824, 178.4900000,&
55638    173.9400400, 175.9414018, 176.9432200, 177.9436977, 178.9458151, 179.9465488, 180.9479000, 179.9474660,&
55639    180.9479960, 183.8400000, 179.9467060, 181.9482060, 182.9502245, 183.9509326, 185.9543620, 186.2070000,&
55640    184.9529557, 186.9557508, 190.2300000, 183.9524910, 185.9538380, 186.9557479, 187.9558360, 188.9581449,&
55641    189.9584450, 191.9614790, 192.2170000, 190.9605910, 192.9629240, 195.0780000, 189.9599300, 191.9610350,&
55642    193.9626640, 194.9647740, 195.9649350, 197.9678760, 196.9665520, 196.9665520, 200.5900000, 195.9658150,&
55643    197.9667520, 198.9682620, 199.9683090, 200.9702850, 201.9706260, 203.9734760, 204.3833000, 202.9723290,&
55644    204.9744120, 207.2000000, 203.9730290, 205.9744490, 206.9758810, 207.9766360, 208.9803830, 208.9803830,&
55645    209.0000000, 209.0000000, 210.0000000, 222.0000000, 222.0000000, 223.0000000, 226.0000000, 226.0000000,&
55646    227.0000000, 232.0381000, 232.0381000, 231.0359000, 231.0359000, 238.0289000, 233.0396280, 234.0409456,&
55647    235.0439231, 238.0507826, 237.0000000, 237.0000000, 244.0000000, 238.0495534, 239.0521565, 240.0538075,&
55648    242.0587368, 243.0000000, 243.0000000, 247.0000000, 244.0627463, 246.0672176, 248.0723420, 247.0000000,&
55649    251.0000000, 252.0829700, 257.0950990, 258.0000000, 259.1010200, 262.1096900, 261.1087500, 262.1141500,&
55650    266.1219300, 264.1247300, 277.0000000, 268.1388200, 281.0000000, 272.1534800, 285.0000000, 284.0000000,&
55651    289.0000000, 288.0000000, 293.0000000, 291.0000000, 294.0000000/)
55652
55653  ! get_filename_ext: get file name extension ================================
55654  dot_pos = index(file_in, '.', back=.true.)  ! position of last dot
55655  sep_pos = scan(file_in, '/\\', back=.true.) ! position of last separator
55656  end_pos = len(file_in)
55657  if (sep_pos > dot_pos) then
55658    dot_pos = 0
55659  end if
55660  if (dot_pos == 0 .or. dot_pos == end_pos) then
55661    ext = ""
55662  else
55663    dot_pos = dot_pos+1 ! skip '.' char
55664    ext = l_case(file_in(dot_pos:end_pos))
55665  end if
55666  if (ext == "ins" .or. ext == "res") then
55667    ext = "shx"
55668  end if
55669
55670  ! Compute reflections: mode could be an option (CFL, CIF, SHX, PCR)
55671  call ReadN_set_Xtal_Structure(file_in, Cell, SpG, A , Mode=ext, file_list=fich_cfl)
55672  if (A%Natoms .eq. 0) then
55673    message = "ERROR: cif2hkl: Could not extract a crystallographic structure from file "//&
55674      trim(file_in)//eol//&
55675      "       Check file existence/permissions and type (should be a CFL,CIF,ShelX)."//eol
55676    return
55677  end if
55678  if (verbose .ne. 0) then
55679    message = "file='"//trim(file_in)//"';"//eol
55680    s1 = trim(ADJUSTL(message))//eol//&
55681      "% cell         [    a         b         c        alpha     beta      gamma ]"//eol
55682    write(s2,fmt="(a,6f10.5,a)") "cell=[ ", &
55683         Cell%cell(1), Cell%cell(2), Cell%cell(3), &
55684         Cell%ang(1), Cell%ang(2), Cell%ang(3), "];"//eol
55685    write(s3,fmt="(a,i4,a)") "Spgr='"//trim(SpG%SPG_Symb)//"'; % space group [Number ",&
55686         SpG%NumSpg, "]"//eol
55687    message = trim(s1)//trim(s2)//trim(s3)//&
55688      "%             [    x/a       y/b       z/c      Biso      Occ       Spin      Charge ]"//eol
55689  end if
55690
55691  !Compute cross section
55692  sigma_coh=0
55693  sigma_inc=0
55694  sigma_abs=0
55695  mass     =0
55696  formula  =""
55697
55698  do I=1, A%Natoms
55699    do Y = 1,n_elements
55700      if (trim(L_case(A%atom(i)%ChemSymb)) == trim(L_case(element(Y)))) THEN
55701        ! an atom from the fomula (i) matches one in the isotopes list (y)
55702        ! compute total cross sections and weight
55703        sigma_coh = sigma_coh + 4*pi*bcoh(Y)*bcoh(Y)*A%atom(i)%Mult*1E8
55704        sigma_inc = sigma_inc + 4*pi*binc(Y)*binc(Y)*A%atom(i)%Mult*1E8
55705        sigma_abs = sigma_abs + Sabs(Y)*A%atom(i)%Mult
55706        mass      = mass+weight(Y)*A%atom(i)%Mult
55707        s1 = adjustl(formula)
55708        write(unit=s2, fmt='(I3)') A%atom(i)%Mult
55709        formula   = trim(s1)//" "//trim(element(Y))//trim(adjustl(s2))
55710        ! display verbose information
55711        ! Label,x/a, y/b, z/c, B, occ, Spin, Charge
55712        if (verbose .ne. 0) then
55713          write(s2,fmt="(a,a,a,7f10.5,a)") trim(message),trim(A%atom(i)%lab),"=[",A%atom(i)%X, &
55714            A%atom(i)%Biso,A%atom(i)%Occ,A%atom(i)%moment,A%atom(i)%Charge,"];"//eol
55715          message = s2
55716        end if
55717        exit
55718      end if
55719    end do
55720  end do
55721  if (verbose .ne. 0) then
55722    s1 = trim(message)//"title='"//trim(formula)//" ["//trim(SpG%SPG_Symb)//&
55723      ", "//trim(SpG%CrystalSys)//", "//trim(SpG%Centre)//"]';"//eol
55724!    write(*,*) "% sigma_coh  ",  sigma_coh, " coherent   scattering cross section in [barn]"
55725!    write(*,*) "% sigma_inc  " , sigma_inc, " incoherent scattering cross section in [barn]"
55726!    write(*,*) "% sigma_abs  " , sigma_abs, " absorption scattering cross section in [barn]"
55727!    write(*,*) "% density    ",  mass/cell%cellVol, " in [g/cm^3]"
55728!    write(*,*) "% weight     ",  mass,         " in [g/mol]"
55729!    write(*,*) "% Vc         ",  cell%cellVol, " volume of unit cell in [A^3]"
55730    message = s1
55731  end if
55732
55733  ! suppress Sfac computation and output when has --no-output-files option
55734  if (powxtal(1:1) .ne. '-') then
55735    MaxNumRef = Get_MaxNumRef(stlmax,Cell%CellVol,mult=SpG%NumOps)
55736    if (powxtal(1:1) == "p") then
55737      ! powder mode:
55738      !    Hkl_Uni(Crystalcell, Spacegroup,Friedel,Value1,Value2,Code,Num_Ref,Reflex, no_order)
55739      call Hkl_Uni(Cell,Spg,.true.,0.0,stlmax,"s",MaxNumRef,hkl)
55740    else
55741      ! SX mode:
55742      call Hkl_Gen_SXtal(Cell,Spg,0.0,stlmax,MaxNumRef,hkl)
55743      ! sort SX Bragg peaks
55744      call sort_d(hkl)
55745    end if
55746    ! exit when no reflection can be computed
55747    if (hkl%Nref == 0) then
55748      message = "ERROR: cif2hkl: No reflection list can be set from file "//&
55749        trim(file_in)//eol//&
55750        "       Check file existence/permissions and type (should be a CFL,CIF,ShelX)."//eol
55751      return
55752    end if
55753    ! mode="nuc" (neutron), "ele" (electrons), "xra" x-rays
55754    call Structure_Factors(A,SpG,hkl,mode=mode)
55755
55756    ! get current date/time
55757    call idate(today)   ! today(1)=day, (2)=month, (3)=year
55758    call itime(now)     ! now(1)=hour, (2)=minute, (3)=second
55759
55760    !Write reflection file
55761    open( unit=lun,file=file_out,status="replace",action="write")
55762    write(unit=lun,fmt="(a,a,a)")    "# TITLE  ",     trim(formula), " ["//trim(SpG%CrystalSys)//", "//trim(SpG%Centre)//"]"
55763    write(unit=lun,fmt="(a)") "#        a         b         c       alpha     beta      gamma"
55764    write(unit=lun,fmt="(a,6f10.5)") "# CELL ", Cell%cell(1), Cell%cell(2), Cell%cell(3), Cell%ang(1), Cell%ang(2), Cell%ang(3)
55765    write(unit=lun,fmt="(a,a,a,i4,a)") "# SPCGRP  ",    trim(SpG%SPG_Symb)," [Number ",SpG%NumSpg, "]"
55766    write(unit=lun,fmt="(a)") "#                    X         Y         Z         B         Occ       Spin      Charge"
55767    do I=1, A%Natoms
55768      write(unit=lun,fmt="(a,a,7f10.5)") "# Atom  ",A%atom(i)%lab,&
55769            A%atom(i)%X, &
55770            A%atom(i)%Biso,A%atom(i)%Occ,A%atom(i)%moment,A%atom(i)%Charge
55771    end do
55772    write(unit=lun,fmt="(a)")        "# COMMAND cif2hkl "//trim(file_in)//" --output "//trim(file_out)
55773    write(unit=lun,fmt="(a)")        "# CIF2HKL (c) ILL 2012 E. Farhi <farhi@ill.eu> based on CrysFML"
55774    write(unit=lun,fmt=1000) today, now
55775  1000 format ( '# DATE    ', i2.2, '/', i2.2, '/', i4.4, ' at ', i2.2, ':', i2.2, ':', i2.2)
55776    write(unit=lun,fmt="(a)") "#"
55777    write(unit=lun,fmt="(a,f14.5,a)") "# Physical parameters:"
55778    write(unit=lun,fmt="(a,f14.5,a)") "# sigma_coh  ",  sigma_coh, " coherent   scattering cross section in [barn]"
55779    write(unit=lun,fmt="(a,f14.5,a)") "# sigma_inc  " , sigma_inc, " incoherent scattering cross section in [barn]"
55780    write(unit=lun,fmt="(a,f14.5,a)") "# sigma_abs  " , sigma_abs, " absorption scattering cross section in [barn]"
55781    write(unit=lun,fmt="(a,f14.5,a)") "# density    ",  mass/cell%cellVol, " in [g/cm^3]"
55782    write(unit=lun,fmt="(a,f14.5,a)") "# weight     ",  mass,         " in [g/mol]"
55783    write(unit=lun,fmt="(a,f14.5,a)") "# Vc         ",  cell%cellVol, " volume of unit cell in [A^3]"
55784    write(unit=lun,fmt="(a,f14.5,a)") "# lattice_a  ", Cell%cell(1),  " lattice parameter a in [Angs]"
55785    write(unit=lun,fmt="(a,f14.5,a)") "# lattice_b  ", Cell%cell(2),  " lattice parameter b in [Angs]"
55786    write(unit=lun,fmt="(a,f14.5,a)") "# lattice_c  ", Cell%cell(3),  " lattice parameter c in [Angs]"
55787    write(unit=lun,fmt="(a,f14.5,a)") "# lattice_aa ", Cell%ang(1),   " lattice angle alpha in [deg]"
55788    write(unit=lun,fmt="(a,f14.5,a)") "# lattice_bb ", Cell%ang(2),   " lattice angle beta in [deg]"
55789    write(unit=lun,fmt="(a,f14.5,a)") "# lattice_cc ", Cell%ang(3),   " lattice angle gamma in [deg]"
55790    Select Case (l_case(mode(1:3)))
55791      Case("nuc")
55792        write(unit=lun,fmt="(a)") "# STRUCTURE FACTORS(NEUTRONS)"
55793      Case("xra")
55794        write(unit=lun,fmt="(a)") "# STRUCTURE FACTORS(X-RAYS)"
55795      Case("ele")
55796        write(unit=lun,fmt="(a)") "# STRUCTURE FACTORS(ELECTRONS)"
55797      Case default
55798        message = "ERROR: cif2hkl: unknown option: --mode "//trim(mode)//eol
55799        return
55800    End Select
55801    write(unit=lun,fmt="(a)") "#"
55802    write(unit=lun,fmt="(a)") "# Format parameters: Crystallographica format"
55803    write(unit=lun,fmt="(a)") "# column_h  1"
55804    write(unit=lun,fmt="(a)") "# column_k  2"
55805    write(unit=lun,fmt="(a)") "# column_l  3"
55806    write(unit=lun,fmt="(a)") "# column_j  4   multiplicity 'j'"
55807    write(unit=lun,fmt="(a)") "# column_d  5   d-spacing 'd' in [Angs]"
55808    write(unit=lun,fmt="(a)") "# column_F2 6   norm of scattering factor |F|^2 in [barn]"
55809    write(unit=lun,fmt="(a)") "#"
55810    write(unit=lun,fmt="(a,i5,a,f10.4,a)") "# List ",hkl%Nref, " reflections for lambda > ", &
55811            lambda, " [Angs], decreasing d-spacing."
55812    write(unit=lun,fmt="(a)") &
55813            "# H   K   L     Mult    dspc                   |Fc|^2"
55814    do i=1,hkl%Nref
55815      F    = hkl%ref(i)%Fc
55816      if ((F+1.0) .ne. F) then ! except for NaN's
55817        write(unit=lun,fmt="(3(i4,1x),i5,1x,2(f13.5,1x),f25.5)") &
55818        hkl%ref(i)%h, hkl%ref(i)%mult, &
55819        0.5/hkl%ref(i)%S, hkl%ref(i)%Fc*hkl%ref(i)%Fc
55820      end if
55821    end do
55822
55823    ! write with Write_RefList_Info(Rfl, Iunit, Mode)
55824    ! call Write_RefList_Info(hkl, lun, mode)
55825
55826    close (unit=lun)
55827  end if
55828
55829End subroutine CFML_cif2hkl
55830
55831
55832subroutine print_version(pgmname,message)
55833  ! Show program version. pgmname = argv[0] ================================
55834  character*1024 pgmname
55835  character*1024, intent(out) :: message
55836
55837  character*80 AUTHOR, DATE, VERSION
55838  character*2   eol
55839
55840  eol=char(13)//char(10)
55841
55842  AUTHOR ="Farhi E. [farhi@ill.fr] using crysFML <http://forge.ill.fr/projects/crysfml>"
55843  DATE   ="11 Mar 2016"
55844  VERSION="1.2"
55845
55846
55847  message = trim(pgmname)//" "//trim(VERSION)//" ("//trim(DATE)//") by "//trim(AUTHOR)//eol//&
55848   "  Copyright (C) 2009 Institut Laue Langevin, EUPL license."//eol//&
55849   "  This is free software; see the source for copying conditions."//eol//&
55850   "  There is NO warranty; not even for MERCHANTABILITY or FITNESS"//eol//&
55851   "  FOR A PARTICULAR PURPOSE."//eol
55852end subroutine print_version
55853
55854subroutine print_usage(pgmname,message)
55855  ! Show program help. pgmname = argv[0] ===================================
55856  character*1024 pgmname
55857  character*4096,intent(out) :: message
55858
55859  character*2   eol
55860
55861  eol=char(13)//char(10)
55862
55863  message = "Usage: "//trim(pgmname)//" [options][-o outfile] file1 file2 ..."//eol//&
55864    "Action: Read a CIF/CFL/SHX/PCR crystallographic description"//eol//&
55865    "        and generates a HKL F^2 reflection list."//eol//&
55866    "Input:"//eol//&
55867    "  file1...          Input file in CIF, PCR, CFL, SHX, INS, RES format."//eol//&
55868    "                      The file format is determined from its extension"//eol//&
55869    "                        .CIF           Crystallographic Information File"//eol//&
55870    "                        .PCR/.CFL      FullProf file"//eol//&
55871    "                        .SHX/.INS/.RES ShelX file"//eol//&
55872    "Output:"//eol//&
55873    "  a file with readable header, and reflection list with columns"//eol//&
55874    "    [ H K L Multiplicity Sin(Theta/Lambda) d_spacing |F|^2 ]"//eol//&
55875    "Options:"//eol//&
55876    "--help     or -h    Show this help"//eol//&
55877    "--version  or -v    Display program version"//eol//&
55878    "--out FILE          Specify the name of the next output file."//eol//&
55879    "   -o FILE            Default is to add .hkl to the initial file name."//eol//&
55880    "--lambda LAMBDA     Set the incoming probe wavelength [Angs]."//eol//&
55881    "   -l    LAMBDA       Default is 0.5"//eol//&
55882    "--powder   or -p    Generate a list of unique HKL reflections (for powders). Default."//eol//&
55883    "--xtal     or -x    Generate a list of all HKL reflections (for single crystals)."//eol//&
55884    "--mode MODE         Generate structure factors for given probe, where MODE is"//eol//&
55885    "   -m  MODE           NUC=neutron(default) XRA=xrays ELE=electrons"//eol//&
55886    "--verbose           Display processing details."//eol//&
55887    "--no-outout-files   Just read the CIF/CFL/ShelX file (for checking)."//eol//&
55888    "Example: "//trim(pgmname)//" --powder --mode NUC -o CaF2.laz CaF2.cfl"//eol
55889
55890end subroutine print_usage
55891
55892!*****************************************************************************
55893! main: Entry point
55894!****************************************************************************/
55895program cif2hkl
55896
55897  character(len=1024) :: pgmname
55898  integer             :: i=0
55899  integer             :: argc=0
55900  character(len=1024) :: argv
55901  character(len=1024) :: outfile
55902  character(len=1024) :: ext            ! input file name extension
55903  real*8              :: lambda= 0.5    ! wavelength (determines minimum d)
55904  character(len=1024) :: powxtal="p"    ! 'p'=powder, 's'=SX output file, '-'=no output
55905  integer             :: verbose=0      ! verbose mode to display additional information
55906  character(len=1024) :: mode="NUC"     ! 'NUC','XRA','ELE'
55907
55908  character*4096      :: message
55909
55910  argc    = iargc()       ! number of arguments
55911  call getarg(0, pgmname) ! program name
55912  outfile = ""
55913  message = ""
55914
55915  if (argc == 0) then
55916    call print_usage(pgmname, message)
55917    write(*,*) trim(message)
55918  else
55919    do while (i < argc)
55920      i = i + 1
55921      call getarg(i, argv)
55922      if (argv(1:2) == "-h" .or. argv(1:6) == "--help") then
55923        call print_usage(pgmname, message)
55924        write(*,*) trim(message)
55925        stop
55926      end if
55927      if (argv(1:2) == "-v" .or. argv(1:9) == "--version") then
55928        call print_version(pgmname, message)
55929        write(*,*) trim(message)
55930        stop
55931      end if
55932      if ( (argv(1:8) == "--lambda" .or. argv(1:2) == "-l") .and. i<argc) then
55933        i=i+1
55934        call getarg(i, argv)
55935        read(argv, *) lambda
55936        cycle
55937      end if
55938      if ( (argv(1:5) == "--out".or. argv(1:2) == "-o") .and. i < argc) then
55939        i=i+1
55940        call getarg(i, outfile)
55941        cycle
55942      end if
55943      if ( (argv(1:6) == "--mode".or. argv(1:2) == "-m") .and. i < argc) then
55944        i=i+1
55945        call getarg(i, mode)
55946        cycle
55947      end if
55948      if (argv(1:2) == "-p" .or. argv(1:3) == "--p") then
55949        powxtal = "p"
55950        cycle
55951      end if
55952      if (argv(1:2) == "-x" .or. argv(1:3) == "--x") then
55953        powxtal = "x"
55954        cycle
55955      end if
55956      if (argv(1:8) == "-verbose" .or. argv(1:9) == "--verbose") then
55957        verbose = 1
55958        cycle
55959      end if
55960      if (argv(1:4) == "--no") then
55961        powxtal = "-"
55962        cycle
55963      end if
55964      if (argv(1:1) .ne. '-') then
55965        ! convert argv[i]: process conversion
55966
55967        ! check outfile
55968        if (len_trim(outfile) == 0) then
55969          outfile = trim(argv)//".hkl"  ! append .hkl extension
55970        end if
55971        call cfml_cif2hkl(argv, outfile, lambda, powxtal, verbose, message, mode)
55972        write(*,*) trim(message)
55973
55974        ! revert outfile to default
55975        outfile = ""
55976        cycle
55977      end if
55978    end do
55979  end if
55980
55981end program cif2hkl
55982
55983