include 'Parameters.f90'
include 'Allocation.f90'
include 'AdditonTh.f90'
include 'BesLeg.f90'
include 'Check.f90'
include 'EFMED.f90'
include 'GeomLib.f90'
include 'GeomTrans.f90'
include 'IncCoeff.f90'
include 'InputOutput.f90'
include 'Integr.f90'
include 'Interp.f90'
include 'MachParam.f90'
include 'MatrixOp.f90'
include 'MatrixQ.f90'
include 'MatrixSolv.f90'
include 'MatrixTrans.f90'
include 'PostProces1.f90'
include 'PostProces2.f90'
include 'PostProces3.f90'
include 'Proces1.f90'
include 'Proces2.f90'
include 'Proces3.f90'
include 'Random.f90'
include 'SCT.f90'
include 'SCTAVRGSPH.f90'
include 'SVWF.f90'
include 'TCOMP.f90'
include 'TINHOM.f90'
include 'TINHOM2SPH.f90'
include 'TINHOMSPH.f90'
include 'TINHOMSPHREC.f90'
include 'TLAY.f90'
include 'TMULT.f90'
include 'TMULT2SPH.f90'	
include 'TMULTSPH.f90'
include 'TMULTSPHREC.f90'
include 'TNONAXSYM.f90'
include 'TPARTSUB.f90'
include 'TSPHERE.f90'
program TAXSYM
!------------------------------------------------------------------------------------
! 1. General Considerations                                                         !
! --------------------------                                                        !
! TAXSYM is a routine for computing the T matrix and the scattering characteristics !
! of homogeneous, dielectric (isotropic, chiral) and perfectly conducting,          !
! axisymmetric particles.                                                           !
!                                                                                   !
! The transition matrix of a homogeneous particle can be written as:                !
!                                                                                   !
!                        T = - Q11 * Q31^(-1),                                      !
!                                                                                   ! 
! where the expressions of the matrices Q31 and Q11 follow from the extinction      !
! theorem and Huygens principle, respectively. The elements of the matrices Q31     !
! and Q11 are expressed as integrals over the particle surface. For axisymmetric    !
! particles, the T-matrix computation decouples over the azimuthal modes and the    !
! surface integrals reduce to line integrals over the generatrix. The integrals     !
! are evaluated by means of the Gauss-Legendre quadrature method, and note that for !
! particles with a plane of symmetry perpendicular to the axis of rotation (mirror  !
! symmetric particles), the integration can be performed along the half-generatrix  !
! curve. The numerical stability and accuracy of T-matrix computations for an       !
! nonsmooth generatrix can be enhanced by dividing the generatrix into piecewise    !
! smooth curves and applying separate quadrature formulas to each curve.            !
!                                                                                   !
! Localized or distributed sources can be used for T-matrix calculation and note    !
! that distributed sources are preferable for highly aspherical particles. For      !
! highly elongated particles, the sources are distributed along the axis of         !
! symmetry of the particle, while for highly flattened particles, the sources       !
! are distributed in the complex plane. 			                    !
!                                                                                   !
! Particle geometries currently supported include: spheroids, cylinders and         !
! rounded oblate cylinders. The following routines (from the file "GeomLib.f90")    !
! provide the required geometry parameters:                                         !
! - the routine "interpolation_listAXSYM" computes the integration nodes and        !
!   weights for an axisymmmetric surface,                                           !
! - the routine "elem_geomAXSYM" provides the geometry parameters (position vector, !
!   zenith and azimuthal angles, and normal unit vector in spherical coordinates)   !
!   at each integration node, and                                                   !
! - the routine "zDSAXSYM" generates the coordinates of the distributed sources.    !
! The user can easily modify these routines to generate particles with other        !
! geometries. Note that the list of parameters must be maintained and only          !
! geometries with an analytical description of the surface can be implemented.      !
! Alternatively, the option FileGeom  = .true., causes the code to read the         !
! particle geometry information from the file FileFEM. The file FileFEM is read     !
! by the routine "read_FileFEMAxsym" from the file "InputOutput.f90". The user can  !
! customize the routine "read_FileFEMAxsym" as needed to conform to the manner in   !
! which the particle geometry is stored in the file FileFEM. However, as supplied,  !
! the routine "read_FileFEMAxsym" expects the file FileFEM to have the following    !
! structure:                                                                        !
! - one line providing the number of smooth curves Nlines; the format for           !
!   reading Nlines is i7, i.e.,                                                     !
!                   read (iFEM, "(i7)", iostat = ios)  Nlines;                      ! 
! - a set of Nlines-sequences of data specifying the geometry parameters on each     !
!   smooth curve; each sequence includes:                                           !
!   - one line containing the number of curve elements (vertices) NVvr; the         !
!     format for reading NVvr is i7, i.e.,                                          !
!                   read (iFEM, "(i7)", iostat = ios) NVvr;                         !                                         
!   - NVvr lines containing the current index ielem, the Cartesian coordinates      !   
!     of the curve element center: x = r(1) and z = r(2), the Cartesian components  !
!     of the unit normal vector at the curve element center: nx = n(1) and          !
!     nz = n(2), and the area of the surface element; the format for reading the    !
!     data is:                                                                      !
!                   read (iFEM, "(i7,2x,5(e15.7,2x))", iostat = ios)                !
!                         ielem, r(1), r(2), n(1), n(2), area.                      !
! As provided, the file FileFEM is contained in the directory "GEOMFILES".          !
! If the particle geometry is read from file, the coordinates of the distributed    !
! sources (if used) must be supplied by the user.                                   ! 
!                                                                                   !
! 2. Convergence Test                                                               !
! -------------------                                                               !
! Convergence tests precede the scattering characteristics calculation. Three       !
! parameters control the T-matrix computation:                                      !
! - the number of integration points for computing integrals over the generatrix,   !
!   Nint,                                                                           !
! - the maximum expansion order Nrank, and                                          !
! - the maximum azimuthal order Mrank.                                              ! 
! Nint is the global number of integration points on the generatrix curve. As       ! 
! mentioned before, the generatrix of an nonsmooth surface is divided into Nparam   !
! piecewise smooth curves and the number of integration points on the curve j is    !
!                   Nint_curve(j) = int { c(j) * Nint },                            !
! where c(j) is a multiplicative factor and j = 1, 2,.., Nparam. The parameters     !
! c(j), j = 1, 2,..., Nparam, do not appear as explicit parameters; they are hard   !
! coded in the routine "interpolation_listAXSYM" from the file "GeomLib.f90".       !
! For example, the generatrix of a cylinder is divided into three straight lines.   !
! The first and third lines are perpendicular to the axis of symmetry, while the    ! 
! second line is parallel to the axis of symmetry. Denoting by a the                !
! half-length of the cylinder and by b the cylinder radius, we have:                !
!                                                                                   !
!     Nint_curve(first line) = Nint_curve(third line) = int {[b/2/(a+b)] * Nint}    !
!                                                                                   !
! and                                                                               !
!                                                                                   ! 
!     Nint_curve(second line) = Nint - 2 * int {[b/2/(a+b)] * Nint }.               !
!                                                                                   !
! For convergence tests, the incident wave is assumed to be a vector plane wave     !
! traveling along the Z-axis of the global coordinate system and the scattering     !
! characteristics are computed in the azimuthal plane phi = 0°. The convergence     !
! tests over Nint and Nrank are interactive, while the convergence test over Mrank  !
! is automatically performed.                                                       ! 
!                                                                                   !
! The convergence tests discussed in the literature are based on the analysis of    !
! the differential scattering cross section or extinction and scattering cross      !
! sections. The convergence test based on differential scattering cross section     !
! analysis is more conservative and is implemented in our code.                     !
!                                                                                   !
! For the integration and expansion order test an axisymmetric orientation of the   !
! particle is considered, i.e., the incident wave propagates along the axis of      !
! symmetry of the particle. In this case, all azimuthal modes are zero except       !
! for m = - 1 and m = 1. For the convergence test over Nint the scattering problem  !
! is solved for Nint and Nint + dNint, while for the convergence test over Nrank    !
! the scattering problem is solved for Nrank and Nrank - 1. The normalized          !
! differential scattering cross section (DSCS) will be checked at 20° increments    !
! for convergence within epsX (epsNint or epsNrank) tolerance. If the calculated    !
! results converge within this tolerance at 80% of the scattering angles, then      !
! convergence is achieved. At each calculation, the extinction and scattering       !
! cross sections Cext and Cscat are also computed. Although the convergence of Cext !
! and Cscat does not guarantee that the DSCS converges, the divergence of Cext and  !
! Cscat implies the divergence of the DSCS. The results of the convergence          !
! analysis are written to the file "/OUTPUTFILES/Output.dat". The above             !
! convergence tests (based on the analysis of the differential scattering cross     !
! section) have been proposed by Barber and Hill [P. W. Barber and S. C. Hill,      !
! Light scattering by particles: Computational Methods, World Scientific,           !
! Singapore, 1990].                                                                 ! 
!                                                                                   ! 
! After Nrank and Nint have been determined we pass to the azimuthal order test.    !
! The program automatically sets the particle to a more general orientation, i.e.,  !
! alpha = beta = 45°, and solves the scattering problem  for increasing m values    !
! until convergence of the angular scattering is achieved. The T matrix is stored   !
! for later use by other programs, and the values of Nrank and Mrank are printed to !
! the screen and to the T-matrix information file (see "Description.txt"). These    !
! values together with the T matrix serve as INPUT PARAMETERS for other programs.   ! 
!                                                                                   !
! 3. Estimates of Nint and Nrank                                                    !
! -------------------------------                                                   !
! The above convergence tests require estimates of Nint and Nrank. These            !
! estimates must be supplied by the user, and for this purpose, the automatic       !
! convergence procedure proposed by Mishchenko [M. I. Mishchenko, Light scattering  !
! by a size-shape distributions of randomly oriented axially symmetric particles    !
! of a size comparable to the wavelength, Applied Optics, 32, 4652-4666, 1993]      !
! or Wiscombe's truncation limit criterion [W. J. Wiscombe, Improved Mie            !
! scattering algorithms, Applied Optics, 19, 1505-1509, 1980] can be used.          !
!                                                                                   !
! The procedure developed by Mishchenko finds reliable a priori estimates of        !
! both Nint and Nrank by using only the zeroth order block matrices of the T        !
! matrix. The estimates are computed by checking the convergence of the quantities: !
!                                                                                   !
!        Ce = - (2Pi / k**2) Re {SUM (2n + 1) * [T11_0n0n + T22_0n0n] }             !
!                                                                                   !
! and                                                                               !
!                                                                                   !
!        Cs =   (2Pi / k**2) SUM (2n + 1) * [|T11_0n0n|**2 + |T22_0n0n|**2]         !
!                                                                                   ! 
! where T11_0n0n' and T22_0n0n' are the zeroth order block matrices of the T        !
! matrix. Note that for spherical particles, Ce and Cs are the extinction and       !
! scattering cross sections. An important numerical parameter of the convergence    !
! procedure is the multiplicity factor Ndgs,                                        !
!                                                                                   !
!                          Nint = Ndgs * Nrank,                                     !
!                                                                                   !
! which controls the number of integration points and must be optimized for each    !
! particle shape. The main steps of the convergence procedure are                   !
! 1. choose Ndgs;                                                                   !
! 2. compute a starting value of Nrank, as for instance                             !
!                                                                                   !
!                 NrankW = int(x + 4.05 * x**0.33),                                 !
!                                                                                   !
!    where x is the size parameter, x = k * Rcirc, and Rcirc is the radius of the   !
!    smallest circumscribing sphere;                                                !
! 3. solve the scattering problem for increasing Nrank-values (in unit steps) and   !
!    Nint = Ndgs * Nrank until the convergence criterion                            !
!                                                                                   !
!          max { [Cs(Nrank) - Cs(Nrank-1) ] / Cs(Nrank),                            !
!                [Ce(Nrank)  - Ce(Nrank-1)] / Ce(Nrank) } < delta                   !
!                                                                                   !
!    is satisfied, where delta is the desired accuracy;                             !
! 4. after Nrank has been determined, increase Nint in dNint steps until Cs(Nrank)  !
!    and Ce(Nrank) converge within delta.                                           !
!                                                                                   !
! If the convergence procedure is finished WE CAN PASS DIRECTLY TO THE AZIMUTHAL    !
! ORDER TEST. However, it is recommended to check at least the value of Nrank by    !
! using the convergence procedures based on the differential scattering cross       !
! section analysis. The convergence procedure proposed by Mishchenko can not be     !
! used for chiral particles, if the coordinates of the discrete sources are         !
! user-defined and if the particle geometry is read from file.                      !
!                                                                                   !
! A reasonable starting value of Nrank is given by Wiscombe's truncation limit      !
! criterion, i.e.,                                                                  !
!                                                                                   !    
!                NrankW = int(x + 4.05 * x**0.33 + 2),                              !
!                                                                                   !
! and note that the convergence procedure proposed by Mishchenko also uses NrankW   !
! as initial Nrank-value.                                                           !
!                                                                                   !
! The value of Nint depends on the type of discrete sources, the size parameter,    !
! the particle shape and the relative refractive index. For localized sources,      !
! size parameters smaller than 15.0, and particle aspect ratios ranging between     !
! 0.33 and 3.0, the recommended values are:                                         !
!                for spheroids:       Ndgs = (3...5), and                           !
!                for cylinders:       Ndgs = (4...7).                               !
! These values should be substantially increased as the size parameter increases,   !
! the particles become less aspherical or distributed sources are used.             !
! For spheroids with a size parameter smaller than 30.0, the following routine      !
! can be used to compute a conservative estimate of Nint:                           !
!                                                                                   !
! a = surf(1), length of the semi-axis along the axis of symmetry                   !
! b = surf(2), knight of the second semi-axis                                       !
! e = a / b                                                                         !
! xmax  = k * max(a,b)                                                              !
! Nrank = int(xmax + 4.05 * xmax**0.33 + 2.0)                                       !
! if (xmax <= 30.0) then                                                            !
!     if (e == 1.0) then                                                            !
!         Nint = 4 * Nrank                                                          !
!     else if (e < 1.0) then                                                        !
!         kb = k * b                                                                !
!         if (kb < 5.0) then                                                        !
!             Nint = 100                                                            !
!         else                                                                      !
!             Nint = 20 * int(kb)                                                   !
!         end if                                                                    !
!         if (e < 0.5) then                                                         !
!             dNr  = 25.0 + 10.0 * kb                                               !
!             Nint = Nint + int(dNr * (1.0 / e - 2.0))                              !
!         end if                                                                    ! 
!     else                                                                          !
!         ka = k * a                                                                !
!         if (ka < 10.0) then                                                       !
!             Nint = 40                                                             !
!         else                                                                      !
!             Nint = 4 * int(ka)                                                    !
!         end if                                                                    !
!         if (e > 2) then                                                           !
!             if (ka < 10.0) then                                                   !
!                 dNr = 30.0                                                        !
!             else                                                                  !
!                 dNr = 30.0 + 3.5 * (ka - 10.0)                                    !
!             end if                                                                !
!             Nint = Nint + int(dNr * (e - 2.0))                                    !
!         end if                                                                    !
!     end if                                                                        !
! end if                                                                            !
!                                                                                   !
! 4. Strategies for Performing Convergence Tests                                    !
! ----------------------------------------------                                    !
! Two strategies for performing convergence tests over Nint and Nrank are           !
! recommended. The following technique has been proposed by Barber and Hill:        !
! 1. choose a value of Nrank close to the value predicted by Wiscombe's truncation  !
!    limit criterion;                                                               !
! 2. for Nrank, perform the expansion order test with Nint = Ndgs * Nrank (in the   !
!    original code of Barber and Hill, Ndgs = 2);                                   !
! 3. if convergence is not achieved, set Nrank = Nrank + 1, maintain the relation   !
!    Nint = Ndgs * Nrank and go to Step 2;                                          !
! 4. if convergence is achieved, perform several integration tests with the         !
!    initial Nint-value, Nint = Ndgs * Nrank, until the DSCS converges.             !
!                                                                                   !
! For large and/or highly aspherical particles, T-matrix computations become        !
! poorly convergent or even divergent. Frequently, a semi-convergent behaviour is   !
! attended: the errors decrease with increasing the maximum expansion order,        !
! attain a relative constant level and afterwards increase. The region of           !
! stability can be localized by using the following technique:                      !
! 1. choose a value of Nrank smaller (or significantly smaller) than the value      !
!    predicted by Wiscombe's truncation limit criterion;                            !
! 2. for Nrank, perform several integration tests with the initial Nint-value,      !
!    Nint = Ndgs * Nrank, until the DSCS converges;                                 !
! 3. if convergence can not be achieved, set Nrank = Nrank - 1 or increase the      !
!    tolerance epsNint, and go to Step 2;                                           !
! 4. if convergence is achieved (for some Nint), perform several expansion order    !
!    tests for increasing Nrank-values and monitor the errors of the differential   !
!    scattering cross sections.                                                     !
!                                                                                   !
! For particles which are too extreme in size and/or aspect ratio, the errors of    !
! the extinction and scattering cross sections (instead of the differential         !
! scattering cross section) can be analyzed.                                        ! 
!                                                                                   !
! 5. Additional Comments                                                            !
! ----------------------                                                            !
! For the expansion order test and distributed sources, two configurations of       !
! sources (with Nrank and Nrank - 1 discrete sources) are considered. For both      !
! configurations, the coordinates of the distributed sources can be generated       !
! automatically or can be specified in the input file.                              !
!                                                                                   !
! The convergence tests over Nint and Nrank can be switched off by setting the      !
! logical variable DoConvTest to false. In this case, the values of Nint and        !
! Nrank must be specified in the input file.                                        !
!                                                                                   !
! The number of integration points has been determined for the azimuthal orders     !
! m = 1 and m = - 1. For higher azimuthal orders and sources distributed in the     !
! complex plane, the chosen value of Nint may lead to false convergence. Therefore, !
! the number of integration points should be increased at each azimuthal mode       !
! calculation. The integation step is dNintMrank. The parameter dNintMrank should   !
! be found experimentally by repeating the azimuthal order test for different       !
! input values until the differential scattering cross section converges.           !
! A conservative estimate is: dNintMrank = (0.1,...,0.2) * Nint.                    !
!                                                                                   !
! 6. Input Parameters                                                               !
! --------------------                                                              !
! The parameters specified in the input file "/INPUTFILES/InputAXSYM.dat" are       !
! listed below.                                                                     !
!                                                                                   !
! - wavelength (real) - wavelength of the incident light in vacuo.                  !
!                                                                                   !
! - ind_refMed (real) - refractive index of the ambient medium (nonabsorbing        !
!   dielectric medium).                                                             !
!                                                                                   !
! - ind_refRel (complex) - relative refractive index of the particle with respect   !
!   to the ambient medium. The imaginary part of the relative refractive index      !
!   must be zero for nonabsorbing particles and positive for absorbing particles.   !
!                                                                                   !
! - perfectcond (logical) - if perfectcond = t, the particle is perfectly           !
!   conducting.                                                                     !
!                                                                                   !
! - chiral (logical) - if chiral = t, the particle is optical active (chiral).      !
!                                                                                   !
!   The permissive values of the logical variables perfectcond and chiral are       !
!   given below.                                                                    !
!                                                                                   !
!       particle              perfectcond            chiral                         !
!      dielectric                  f                   f                            !
!   perfectly conducting           t                   f                            !
!        chiral                    f                   t                            !
!                                                                                   !
! - kb (real) - parameter of chirality. This parameter is used for chiral           !
!   particles and is ignored for dielectric and perfectly conducting particles.     !
!   The wave numbers for the left- and right-handed circularly polarized waves      !
!   are given by:                                                                   !
!               kil = ki / (1.0 - kb)  and   kir = ki / (1.0 + kb)                  !
!   where ki is the wave number in the chiral medium.                               !
!                                                                                   !
! - FileGeom (logical) - if FileGeom = t, the particle geometry is supplied by the  !
!   input file FileFEM,                                                             ! 
!                                                                                   !
! - FileFEM (character(80)) - name of the file containing the particle geometry.    !
!                                                                                   !
! - TypeGeom (integer) - parameter specifying the type of the particle geometry.    !
!                                                                                   !
! - Nsurf (integer) - number of surface parameters.                                 !
!                                                                                   !
! - surf (real array: surf(1), surf(2),...,surf(Nsurf)) - surface parameters        !
!   specifying the shape of the particle. The dimension of the array surf is        !
!   NsurfPD. The integer parameter NsurfPD is specified in the routine              !
!   "Parameters.f90" and has the value NsurfPD = 10. If Nsurf > NsurfPD, the        !
!   execution is automatically terminated.                                          !
!                                                                                   !
! - Nparam (integer) - number of smooth curves forming the generatrix curve.        !
!                                                                                   !
!   The permissive values of the surface parameters (for the supported geometries)  !
!   are summarized below.                                                           !
!                                                                                   !
!   Particle      TypeGeom   Nsurf   Nparam                surf                     !
!   spheroid         1         2       1         surf(1) - length of the semi-      !
!                                                          axis along the           !
!                                                          axis of symmetry         !
!                                                surf(2) - length of the second     !
!                                                          semi-axis                !
!                                                                                   !
!   cylinder         2         2       3         surf(1) - half-length of           !
!                                                          the cylinder             !
!                                                surf(2) - cylinder radius          !
!                                                                                   !
!   rounded          3         2       3         surf(1) - half-length of           !
!    oblate                                                the cylinder             !
!   cylinder                                     surf(2) - cylinder radius          ! 
!                                                          including the rounded    !
!                                                          part                     !
!                                                                                   !
! - anorm (real) - characteristic length of the particle which is used to           !
!   normalize the differential scattering cross sections.                           !
!                                                                                   !
! - Rcirc (real) - characteristic length of the particle (usually the radius of     !
!   the smallest circumscribing sphere) which is used to compute an estimate of the !
!   maximum expansion order by using Wiscombe's truncation limit criterion (the     !
!   size parameter is x = k * Rcirc, where k is the wave number in the ambient      !
!   medium). Alternatively, Rcirc can be chosen as the equal-volume sphere radius   !
!   or the surface-equivalent-sphere radius. This parameter is used if the          !
!   interactive convergence tests over Nint and Nrank are performed                 !
!  (DoConvTest = t). Otherwise, Rcirc is ignored.                                   !
!                                                                                   !
! - miror (logical) - if miror = t, the particle is mirror symmetric (the plane of  !
!   symmetry or the plane of reflection is perpendicular to the axis of rotation).  !
!                                                                                   ! 
! NOTE: FOR CHIRAL PARTICLES AND DISTRIBUTED SOURCES SET miror = f.                 ! 
!                                                                                   !
! - DoConvTest (logical) - if DoConvTest = t, the interactive convergence tests     !
!   over Nint and Nrank are invoked. Estimates of Nint and Nrank can be obtained    !
!   by using Mishchenko's convergence procedure. Alternatively, an estimate of      !
!   Nrank is given by Wiscombe's truncation limit criterion.                        !
!                                                                                   !
! - MishConvTest (logical) - if MishConvTest = t, estimates of Nint and Nrank are   !
!   computed with the convergence procedure proposed by Mishchenko. The code        !
!   prompts for the integer parameter Ndgs which controls the initial value of the  !
!   number of integration points. Some orientative values of Ndgs are printed and   !
!   the user can enter his option. This convergence test can be performed if:       !
!   - localized sources are used, the interactive convergence tests are performed,  !
!     the particle is not optical active, and the particle geometry is not read from!
!     file (DS = f and DoConvTest = t and chiral = f and FileGeom = f), or          !
!   - distributed sources are used, the coordinates of the distributed sources are  !
!     not user-defined, the interactive convergence tests are performed, the        !
!     particle is not optical active, and the particle geometry is not read from    ! 
!     file (DS = t and autGenDS = t and DoConvTest = t and chiral = f and           !
!     FileGeom = f).                                                                !
!                                                                                   !
! NOTE: IF THE PARTICLE IS OPTICAL ACTIVE (chiral = t) OR THE PARTICLE GEOMETRY IS  !
! SUPPLIED BY THE FILE FileFEM (FileGeom = t), THE CODE SETS MishConvTest = f.      !
!                                                                                   !
! - DS (logical) - if DS = t, distributed sources are used for T-matrix             !
!   calculation, otherwise localized sources are employed.                          !
!                                                                                   !
! - autGenDS (logical) - if autGenDS = t, the routine "zDSAXSYM" generates the      !
!   coordinates of the distributed sources. Otherwise, the coordinates of the       !
!   distributed sources must be provided by the user. If DS = f, the logical        !
!   variable autGenDS is ignored. If the particle geometry is read from file        !  
!   (FileGeom = t), the coordinates of the distributed sources are user-defined,    !
!   and the code sets autgenDS = f.                                                 !
!                                                                                   !
! - ComplexPlane (logical) - if ComplexPlane = t, the distributed sources are       !
!   situated in the complex plane. This parameter is used if distributed sources    !
!   are required and the coordinates of the distributed sources are automatically   !
!   generated (DS = t and autGenDS = t).                                            !
!                                                                                   !
! - epsZReIm (real) - input parameter of the routine "zDSAXSYM" which controls      !
!   the distribution of the discrete sources. This parameter is used if distributed !
!   sources are required and the coordinates of the distributed sources are         !
!   automatically generated (DS = t and autGenDS = t).                              !
!                                                                                   !
! - Nint (integer) - number of integration points in computing integrals over       !
!   the generatrix curve. This parameter is used (for localized and distributed     !
!   sources) if the convergence tests are not performed and the particle geometry   !
!   is not supplied by the file FileFEM. More specifically, Nint is used if         !
!   - (DS = f and DoConvTest = f and FileGeom = f) or,                              !
!   - (DS = t and autGenDS = t and DoConvTest = f) or,                              !
!   - (DS = t and autGenDS = f and DoConvTest = f and FileGeom = f).                !
!                                                                                   !
! - Nrank (integer) - maximum expansion order. This parameter is used (for localized!
!   and distributed sources) if the convergence tests are not performed, or the     !
!   coordinates of the distributed sources are user-defined. More specifically,     !
!   Nrank is used if                                                                !
!   - (DS = f and DoConvTest = f), or                                               !
!   - (DS = t and autGenDS = t and DoConvTest = f), or                              !
!   - (DS = t and autGenDS = f and DoConvTest = t), or                              !
!   - (DS = t and autGenDS = f and DoConvTest = f).                                 !
!                                                                                   !
! NOTE: IN ORDER TO SIMPLIFY THE ROUTINE FOR READING THE DATA, THE VARIABLES Nint   !
! AND Nrank MUST BE PROVIDED (IN THE INPUT FILE "InptAXSYM.dat") IF                 !
! ((DoConvTest = f) OR (DS = t AND autgenDS = f)). BECAUSE THE SIGNIFICANCE OF      !
! THESE PARAMETERS IS AS ABOVE, THE MAIN PROGRAM WILL IGNORE THE IRRELEVANT DATA    !
! INFORMATIONS.                                                                     !
!                                                                                   !
! - zRe, zIm (real arrays: zX(1), zX(2),...,zX(Nrank), X = Re, Im) - coordinates    !
!   of the distributed sources for the expansion order Nrank. These parameters      !
!   are used if the coordinates of the distributed sources are user-defined         !
!   (DS = t and autGenDS = f). The dimension of the arrays zRe and zIm is NrankPD   !
!   and the inequality Nrank <= NrankPD must hold. The integer parameter NrankPD is !
!   specified in the routine "Parameters.f90" and has the value NrankPD = 200. If   !
!   Nrank > NrankPD, the execution is automatically terminated.                     !
!                                                                                   !
! - zRe1, zIm1 (real arrays: zX1(1), zX1(2),...,zX1(Nrank-1), X = Re, Im) -         !
!   coordinates of the distributed sources for the expansion order Nrank - 1.       !
!   These parameters are used if the coordinates of the distributed sources are     !
!   user-defined and the expansion order test is performed (DS = t and autGenDS = f !
!   and TypeConvTest = 2). As before, the dimension of the arrays zRe1 and zIm1     !
!   is NrankPD.                                                                     !
!                                                                                   !
! NOTE: IN ORDER TO SIMPLIFY THE ROUTINE FOR READING THE DATA, THE REAL ARRAYS      !
! zRe, zIm AND zRe1, zIm1 MUST BE SPECIFIED (IN THE INPUT FILE "InptAXSYM.dat") IF  !
! (DS = t AND autGenDS = f). FURTHER NOTE THAT THE INPUT ARRAYS MUST BE SEPARATED   !
! BY A BLANK LINE, AND THAT THE INPUT ARRAYS zRe1 AND zIm1 MUST BE SPECIFIED AS     !
! VECTORS WITH Nrank - 1 COMPONENTS.                                                !
!                                                                                   !
! - epsNint (real) - error tolerance for the integration test.                      !
!                                                                                   !
! - epsNrank (real) - error tolerance for the expansion order test.                 !
!                                                                                   !
! - epsMrank (real) - error tolerance for the azimuthal order test.                 !
!                                                                                   !
! - dNint (integer) - number of division points for the integration test and        !
!   Mishchenko's convergence procedure. Note that the scattering problem is solved  !
!   for Nint and Nint + dNint.                                                      ! 
!                                                                                   !
! - dNintMrank (integer) - number of division points for azimuthal mode             !
!   calculation. This parameter is used if the distributed sources are situated     !
!   in the complex plane (DS = t and ComplexPlane = t). At each azimuthal mode      !
!   calculation, the number of integration points increases with dNintMrank.        !
!                                                                                   !
! - FileTmat (character(80)) - name of the file to which the T matrix is written.   !
!                                                                                   !
! - PrnProgress (logical) - if PrnProgress = t, the progress of calculation         !
!   is printed.                                                                     !
!                                                                                   !
! Note that all input parameters specifying lengths must be provided in the same    !
! units of lengths.                                                                 !
!                                                                                   !
! 7. Logical Scheme                                                                 !
! ------------------                                                                !  
! The organization of the code is as follows:                                       !
! 1.  < read input data >                                                           !
! 2.  < T-matrix calculation >                                                      !
!                                                                                   !
!    if ( read geometry from file ) then                                            !
!       < do not use Mishchenko's convergence procedure >                           !
!       < do not use automatic sources generation >                                 !
!    end if                                                                         !
!    if ( chiral particle ) then                                                    !
!       < do not use Mishchenko's convergence procedure >                           !
!    end if                                                                         !
!    if ( use localized sources ) then                                              !
!                                                                                   !
!       if ( do convergence test) then                                              !
!          if ( use Mishchenko's convergence procedure ) then                       !
!             < the code prompts for the integer parameter Ndgs and computes        !
!               the estimated values of Nint and Nrank by using Mishchenko's        !
!               convergence procedure >                                             !
!          else                                                                     !
!             < the code computes an estimate of Nrank by using                     !
!               Wiscombe's truncation criterion >                                   !
!          end if                                                                   !  
!          if ( .not. read geometry from file) then                                 !
!            < the code prompts for the estimated values of Nint and Nrank >        !
!            < the code prompts for the type of convergence test:                   !
!              1 - over Nint, 2 - over Nrank or 3 - over Mrank >                    !
!          else                                                                     !
!            < the code prompts for the estimated value of Nrank >                  !
!            < the code prompts for the type of convergence test:                   !
!              2 - over Nrank or 3 - over Mrank >                                   !           
!          end if                                                                   !
!       else if ( .not. do convergence test) then                                   !
!          if ( .not. read geometry from file) then                                 !
!             < the input file provides the values of Nint and Nrank >              !
!          else                                                                     ! 
!             < the input file provides the value of Nrank >                        !
!          end if                                                                   !
!          type of convergence test = 3 (convergence test over Mrank)               !
!       end if                                                                      !
!                                                                                   !
!    else if ( use distributed sources ) then                                       !
!                                                                                   !
!       if ( use automatic sources generation ) then                                !
!          if ( do convergence test) then                                           !
!             if ( use Mishchenko's convergence procedure ) then                    !
!                < the code prompts for the integer parameter Ndgs and computes     !
!                  the estimated values of Nint and Nrank by using Mishchenko's     !
!                  convergence procedure >                                          ! 
!             else                                                                  !
!                < the code computes an estimate of Nrank by using                  !
!                  Wiscombe's truncation criterion >                                !
!             end if                                                                !
!             < the code prompts for the estimated values of Nint and Nrank >       !
!             < the code generates the coordinates of the distributed sources       !
!               zRe and zIm corresponding to Nrank >                                !
!             < the code prompts for the type of convergence test:                  !
!               1 - over Nint, 2 - over Nrank or 3 - over Mrank >                   !
!             if ( do maximum expansion order test ) then                           !
!                < the code generate the coordinates of the distributed sources     !
!                  zRe1 and zIm1 corresponding to Nrank - 1 >                       !
!             end if                                                                !
!          else if ( .not. do convergence test) then                                !
!             < the input file provides the values of Nint and Nrank >              !
!             < the code generate the coordinates of the distributed sources        !
!               zRe and zIm corresponding to Nrank >                                !
!             type of convergence test = 3 (convergence test over Mrank)            ! 
!          end if                                                                   !
!       else if ( .not. use automatic sources generation ) then                     !
!          if ( do convergence test) then                                           !
!             < the input file provides the value of Nrank >                        !
!             < the input file provides the coordinates of the distributed sources  !
!               zRe and zIm corresponding to Nrank >                                !
!             if ( .not. read geometry from file ) then                             !
!                < the code prompts for the estimated value of Nint >               !
!                < the code prompts for the type of convergence test:               !
!                  1 - over Nint, 2 - over Nrank or 3 - over Mrank >                !
!             else                                                                  !
!                < the code prompts for the type of convergence test:               !
!                  2 - over Nrank or 3 - over Mrank >                               !
!             end if                                                                !
!             if ( do expansion order test ) then                                   !
!                < the input file provides the coordinates of the distributed       !
!                  sources zRe1 and zIm1 corresponding to Nrank - 1 >               !
!             end if                                                                !
!          else if ( .not. do convergence test) then                                !
!             if ( .not. read geometry from file ) then                             !
!                < the input file provides the values of Nint and Nrank >           !
!             else                                                                  !
!                < the input file provides the value of Nrank >                     !
!             end if                                                                ! 
!             < the input file provides the coordinates of the distributed sources  !
!               zRe and zIm corresponding to Nrank >                                !
!             type of convergence test = 3 (convergence test over Mrank)            !
!          end if                                                                   !
!       end if                                                                      !
!                                                                                   !
!    end if                                                                         !
!    if ( do integration test, i.e., type of convergence test = 1 ) then            !
!       < the code computes the DSCS for Nint and Nint + dNint and                  !
!         write the results to the file "Output.dat" >                              !
!       < the execution is terminated >                                             !
!    end if                                                                         !
!    if ( do expansion order test, i.e., type of convergence test = 2 ) then        !
!       < the code computes the DSCS for Nrank and Nrank - 1 and                    !
!         write the results to the file "Output.dat" >                              !
!       < the execution is terminated >                                             !
!    end if                                                                         !
!    if ( do azimuthal order test, i.e., type of convergence test = 3 ) then        !
!       < the code computes the DSCS for increasing m values and                    !
!         write the results to the file "Output.dat" >                              !
!       < the T matrix is stored in the file FileTmat and the T-matrix information  !
!         file is created >                                                         !
!       < Mrank and Nrank are printed to the screen and to the T-matrix             !
!         information file >                                                        !
!       < go to Step 3 >                                                            !
!    end if                                                                         !
! 3. < scattering characteristics calculation >                                     !
!------------------------------------------------------------------------------------
  use parameters  
  implicit none 
  integer       :: TypeGeom, Nsurf, Nparam, TypeConvTest, dNint, Nrank, Nint,       &
                   Nrank1, dNintMrank, Ndgs, NrankMax, NrankW, Nface                     
  real(O)       :: k, ind_refMed, wavelength, anorm, surf(NsurfPD), snorm,          &
                   kb, epsNint, epsNrank, epsMrank, zRe(NrankPD), zIm(NrankPD),     &
                   zRe1(NrankPD), zIm1(NrankPD), Rcirc, x, delta, Cscat1, Cext1,    &
                   epsZReIm, rp(2,NfacePD), np(2,NfacePD), area(NfacePD)                          
  complex(O)    :: ind_refRel
  logical       :: FileGeom, miror, perfectcond, DoConvTest, DS, chiral, autGenDS,  &
                   ComplexPlane, MishConvTest, PrnProgress
  character(80) :: FileTmat, FileFEM
! -----------------------------------------------------------------------------------
!                               Read the input file                                 ! 
! -----------------------------------------------------------------------------------       
  call readinputAXSYM ( wavelength, ind_refMed, ind_refRel, perfectcond,            &
       chiral, kb, FileGeom, TypeGeom, FileFEM, Nsurf, surf, Nparam, anorm,         &
       Rcirc, miror, DoConvTest, MishConvTest, DS, autGenDS, ComplexPlane,          &
       epsZReIm, Nint, Nrank, zRe, zIm, zRe1, zIm1, epsNint, epsNrank, epsMrank,    &
       dNint, dNintMrank, FileTmat, PrnProgress, k, snorm, Nface, rp, np, area )                   
! -----------------------------------------------------------------------------------
!         Select the type of convergence test and the values of Nint and Nrank      !
! -----------------------------------------------------------------------------------
  x = k * Rcirc
  NrankW = int(x + 4.05_O * x**0.33_O + 2._O)
  if (.not. DS) then
    if (DoConvTest) then                      
      if (MishConvTest) then                         
        print "(/,2x, a)",                                                          &
       'Estimates of Nint and Nrank Using Mishchenko''s Convergence Procedure' 
        print "(  2x, a)",                                                          &
       '---------------------------------------------------------------------'                                         
        call estimateNrankMishchenko (TypeGeom, k, ind_refRel, Nsurf, surf,         &
             zRe, zIm, Nparam, miror, perfectcond, DS, ComplexPlane,                &
             epsZReIm, x, delta, Ndgs, Nint, Nrank, NrankMax, Cscat1, Cext1)
        call estimateNintMishchenko (TypeGeom, k, ind_refRel, Nsurf, surf,          &
             zRe, zIm, Nparam, miror, perfectcond, DS, x, delta, Ndgs, Nint,        &
             dNint, Nrank, NrankMax, Cscat1, Cext1)
        print "(/,2x,'Convergence Test for an Axisymmetric Particle')"
        print "(  2x,'---------------------------------------------')"	       
        print "(/,2x,'- enter the estimated values of Nint and Nrank;')"            
        call read_integer2 (Nint, Nrank)                                
      else 
        print "(/,2x,'Convergence Test for an Axisymmetric Particle')"
        print "(  2x,'---------------------------------------------')"             
        print "(/,2x,'Nrank estimate:')"                                                            
        print "(  2x, a, i3, a)",                                                   &  
       'the estimated value of Nrank from Wiscombe''s criterion is ', NrankW, ';'
        if (.not. FileGeom) then
          print "(/,2x, a)",                                                        &
         '- enter the estimated values of Nint and Nrank, where Nint = Ndgs * Nrank'
          print "(  2x,'  and Ndgs = 3,4,...;')"
          call read_integer2 (Nint, Nrank)                                                                      
        else
          print "(/,2x,'- enter the estimated value of Nrank;')"              
          call read_integer (Nrank)     
        end if  
      end if
      if (.not. FileGeom) then        
        print "(/,2x, a)",                                                          &
       '- enter the type of convergence test: 1 - Nint, 2 - Nrank, 3 - Mrank;' 
        call read_integerbound (TypeConvTest, 1, 3)
      else
        print "(/,2x,'- enter the type of convergence test: 2 - Nrank, 3 - Mrank;')"
        call read_integerbound (TypeConvTest, 2, 3)
      end if
    else
      print "(/,2x,'Convergence Test for an Axisymmetric Particle over Mrank')" 
      print "(  2x,'--------------------------------------------------------')"
      print "(/,2x,'Input values:')"
      if (.not. FileGeom) then
        print "(  2x, a, i4, a, i4, a)",                                            & 
       'the input values of Nint and Nrank are ', Nint, ' and ', Nrank,             &
       ', respectively,'  
        print "(  2x, a, i3, a)",                                                   &
       'while the estimated value of Nrank from Wiscombe''s criterion is ', NrankW,';'
      else
        print "(  2x,'the input value of Nrank is ', i4,', while')", Nrank
        print "(  2x, a, i3, a)",                                                   &
       'the estimated value of Nrank from Wiscombe''s criterion is ', NrankW, ';' 
      end if                                                                          
      TypeConvTest = 3      
    end if
    Nrank1 = Nrank - 1 ! redundant            
  else
    if (autGenDS) then
      if (DoConvTest) then                        
        if (MishConvTest) then           
          print "(/,2x, a)",                                                        &
         'Estimates of Nint and Nrank Using Mishchenko''s Convergence Procedure'
          print "(  2x, a)",                                                        &
         '---------------------------------------------------------------------'	  	 	 	                    
          call estimateNrankMishchenko (TypeGeom, k, ind_refRel, Nsurf, surf,       &
               zRe, zIm, Nparam, miror, perfectcond, DS, ComplexPlane,              &
               epsZReIm, x, delta, Ndgs, Nint, Nrank, NrankMax, Cscat1, Cext1)
          call estimateNintMishchenko (TypeGeom, k, ind_refRel, Nsurf, surf,        &
               zRe, zIm, Nparam, miror, perfectcond, DS, x, delta, Ndgs, Nint,      &
               dNint, Nrank, NrankMax, Cscat1, Cext1)   
          print "(/,2x,'Convergence Test for an Axisymmetric Particle')"
          print "(  2x,'---------------------------------------------')"	       
          print "(/,2x,'- enter the estimated values of Nint and Nrank;')"           
          call read_integer2 (Nint, Nrank)                               
        else
          print "(/,2x,'Convergence Test for an Axisymmetric Particle')"
          print "(  2x,'---------------------------------------------')"	
          print "(/,2x,'Nrank estimate:')"                                                                
          print "(  2x, a, i3, a)",                                                 &
         'the estimated value of Nrank from Wiscombe''s criterion is ', NrankW, ';'
          print "(/,2x, a)",                                                        &
         '- enter the estimated values of Nint and Nrank, where Nint = Ndgs * Nrank'
          print "(  2x,'  and Ndgs = 5,6,...;')"
          call read_integer2 (Nint, Nrank)                                                                                 
        end if      
        call check_MaxNrank (Nrank)             
        call zDSAXSYM (TypeGeom, Nsurf, surf, Nrank, ComplexPlane, epsZReIm, zRe, zIm)     
        print "(/,2x, a)",                                                          &
       '- enter the type of convergence test: 1 - Nint, 2 - Nrank, 3 - Mrank;'
        call read_integerbound (TypeConvTest, 1, 3)
        if (TypeConvTest == 2) then
          Nrank1 = Nrank - 1
          call zDSAXSYM (TypeGeom, Nsurf, surf, Nrank1, ComplexPlane, epsZReIm,     &
               zRe1, zIm1)         
        end if
      else
        print "(/,2x,'Convergence Test for an Axisymmetric Particle over Mrank')" 
        print "(  2x,'--------------------------------------------------------')"
        print "(/,2x,'Input values:')"
        print "(  2x, a, i4, a, i4, a)",                                            &
       'the input values of Nint and Nrank are ', Nint, ' and ', Nrank,             &
       ', respectively,' 
        print "(  2x, a, i3, a)",                                                   &
       'while the estimated value of Nrank from Wiscombe''s criterion is ', NrankW,';'         
        call check_MaxNrank (Nrank)
        call zDSAXSYM (TypeGeom, Nsurf, surf, Nrank, ComplexPlane, epsZReIm, zRe, zIm) 
        TypeConvTest = 3    
      end if
      Nrank1 = Nrank - 1 ! redundant  
    else 
      if (DoConvTest) then      
        print "(/,2x,'Convergence Test for an Axisymmetric Particle')"
        print "(  2x,'---------------------------------------------')"
        print "(/,2x,'Input values:')"
        print "(  2x,'the input value of Nrank is ', i4,', while')", Nrank
        print "(  2x, a, i3, a)",                                                   &
       'the estimated value of Nrank from Wiscombe''s criterion is ', NrankW, ';'
        if (.not. FileGeom) then                                            
          print "(/,2x, a)",                                                        &
         '- enter the estimated value of Nint, where Nint = Ndgs * Nrank'
          print "(  2x,'  and Ndgs = 5,6,...;')"
          call read_integer (Nint) 
          print "(/,2x, a)",                                                        &
         '- enter the type of convergence test: 1 - Nint, 2 - Nrank, 3 - Mrank;'
          call read_integerbound (TypeConvTest, 1, 3)
        else
          print "(/,2x,'- enter the type of convergence test: 2 - Nrank, 3 - Mrank;')"
          call read_integerbound (TypeConvTest, 2, 3)
        end if
        if (TypeConvTest == 2) Nrank1 = Nrank - 1
      else
        print "(/,2x,'Convergence Test for an Axisymmetric Particle over Mrank')" 
        print "(  2x,'--------------------------------------------------------')" 
        print "(/,2x,'Input values:')" 
        if (.not. FileGeom) then                  
          print "(  2x, a, i4, a, i4, a)",                                          &
         'the input values of Nint and Nrank are ', Nint, ' and ', Nrank,           &
         ', respectively,' 
          print "(  2x, a, i3, a)",                                                 &
         'while the estimated value of Nrank from Wiscombe''s criterion is ',       &
          NrankW,';' 
        else
          print "(  2x,'the input value of Nrank is ', i4,', while')", Nrank
          print "(  2x, a, i3, a)",                                                 &
         'the estimated value of Nrank from Wiscombe''s criterion is ', NrankW, ';' 
        end if
        TypeConvTest = 3              
      end if
      Nrank1 = Nrank - 1 ! redundant          
    end if
  end if                                                                            
! -----------------------------------------------------------------------------------
!                               Convergence test                                    !
! -----------------------------------------------------------------------------------
  open (unit = iOutput, file = FileOutput, status = "replace") 
  call printinputAXSYM (TypeConvTest, FileGeom, TypeGeom, FileFEM, Nsurf, Nparam,   &
       Nrank, Nrank1, dNint, dNintMrank, ind_refMed, wavelength, anorm, Rcirc,      &
       surf, kb, epsNint, epsNrank, epsMrank, zRe, zIm, zRe1, zIm1, ind_refRel,     &
       miror, perfectcond, DS, chiral, autGenDS)                     
  if (DoConvTest) then              
    if (TypeConvTest == 1) then
      if (.not. DS) then                  
        call convergence_NintAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,       &
             Nsurf, surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint,       &
             dNint, miror, perfectcond, DS, chiral, kb, epsNint, PrnProgress)
      else 
        call convergence_NintDSAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,     &
             Nsurf, surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint,       &
             dNint, miror, perfectcond, DS, chiral, kb, epsNint, PrnProgress)
      end if
    else if (TypeConvTest == 2) then
      if (.not. DS) then        
        call convergence_NrankAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,      &
             Nsurf, surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint,       &
             miror, perfectcond, DS, chiral, kb, epsNrank, PrnProgress)
      else      
        call convergence_NrankDSAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,    &
             Nsurf, surf, rp, np, area, Nface, zRe, zIm, zRe1, zIm1, Nparam, Nrank, &
             Nrank1, Nint, miror, perfectcond, DS, chiral, kb, epsNrank,            &
             PrnProgress)
      end if
    else 
      if (.not. DS) then    
        call convergence_MrankAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,      &
             Nsurf, surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint,       &
             miror, perfectcond, DS, chiral, kb, epsMrank, FileTmat, PrnProgress)
      else 
        call convergence_MrankDSAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,    &
             Nsurf, surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint,       &
             miror, perfectcond, DS, chiral, kb, epsMrank, dNintMrank, FileTmat,    &
             PrnProgress)
      end if
    end if  
  else      
    if (.not. DS) then    
      call convergence_MrankAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm, Nsurf, &
           surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, miror,         &
           perfectcond, DS, chiral, kb, epsMrank, FileTmat, PrnProgress)
    else          
      call convergence_MrankDSAXSYM (FileGeom, TypeGeom, k, ind_refRel, snorm,      &
           Nsurf, surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, miror,  &
           perfectcond, DS, chiral, kb, epsMrank, dNintMrank, FileTmat, PrnProgress)
    end if  
  end if 
  close (unit = iOutput)
end program TAXSYM
!************************************************************************************
subroutine readinputAXSYM ( wavelength, ind_refMed, ind_refRel, perfectcond,        &
           chiral, kb, FileGeom, TypeGeom, FileFEM, Nsurf, surf, Nparam, anorm,     &
           Rcirc, miror, DoConvTest, MishConvTest, DS, autGenDS, ComplexPlane,      &
           epsZReIm, Nint, Nrank, zRe, zIm, zRe1, zIm1, epsNint, epsNrank,          &
           epsMrank, dNint, dNintMrank, FileTmat, PrnProgress, k, snorm, Nface,     &
           rp, np, area )
  use parameters
  use derived_parameters
  implicit none 
  integer       :: TypeGeom, Nsurf, Nparam, dNint, Nrank, Nint, i, dNintMrank, ios, &
                   Nface, j                     
  real(O)       :: k, ind_refMed, wavelength, anorm, surf(NsurfPD), xpart, snorm,   &
                   kb, epsNint, epsNrank, epsMrank, zRe(NrankPD), zIm(NrankPD),     &
                   zRe1(NrankPD), zIm1(NrankPD), Rcirc, epsZReIm, rp(2,NfacePD),    &
                   np(2,NfacePD), area(NfacePD), dp                          
  complex(O)    :: ind_refRel
  logical       :: FileGeom, miror, perfectcond, DoConvTest, DS, chiral, autGenDS,  &
                   ComplexPlane, InputDS, MishConvTest, PrnProgress, XFindPar
  character(80) :: FileTmat, FileFEM, string       
! -----------------------------------------------------------------------------------
!                        Read the input file FileInputAXSYM                         ! 
! -----------------------------------------------------------------------------------    
  call DrvParameters  
  open (unit = iInputAXSYM, file = FileInputAXSYM, status = "old",                  &
        position = "rewind")   
  wavelength = 0.1_O * 2._O * Pi  
  ind_refMed = 1._O                                                                 
  ind_refRel = (1.5_O,0._O) 
  string     = 'OptProp'    
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) wavelength
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable wavelength;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) ind_refMed
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable ind_refMed;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) ind_refRel
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable ind_refRel;')"
      stop
    end if      
  else
    print "(/,2x,'Group name OptProp not found;')"
    stop  
  end if
  call check_ind_ref (ind_refRel)
  k = 2._O * Pi * ind_refMed / wavelength 
!
  perfectcond = .false.  
  chiral = .false.
  kb     = 0._O  
  string = 'MatProp'
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) perfectcond
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable perfectcond;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) chiral
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable chiral;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) kb
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable kb;')"
      stop
    end if      
  else
    print "(/,2x,'Group name MatProp not found;')"
    stop  
  end if      
  call check_MatPropAXSYM (perfectcond, chiral, kb)   
  if (chiral) call check_chirality (kb)
!
  FileGeom = .false.
  FileFEM  = ' '  
  TypeGeom = 1  
  Nsurf    = 2
  do i = 1, NsurfPD
    surf(i)= 1._O
  end do
  Nparam = 1
  anorm  = 1._O
  Rcirc  = 1._O 
  miror  = .false.
  string = 'GeomProp'
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) FileGeom
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable FileGeom;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) FileFEM
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable FileFEM;')"
      stop
    end if       
    read (iInputAXSYM, *, iostat = ios) TypeGeom
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable TypeGeom;')"
      stop
    end if       
    read (iInputAXSYM, *, iostat = ios) Nsurf
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable Nsurf;')"
      stop
    end if
    if (Nsurf > NsurfPD) then
      print "(/,2x,'Input error: Nsurf exceeds NsurfPD;')"                                    
      stop
    end if            
    do i = 1, Nsurf
      read (iInputAXSYM, *, iostat = ios) surf(i)
      if (ios /= 0) then
        print "(/,2x,'Error by reading the input variable surf;')"
        stop
      end if
    end do    
    read (iInputAXSYM, *, iostat = ios) Nparam
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable Nparam;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) anorm
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable anorm;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) Rcirc
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable Rcirc;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) miror
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable miror;')"
      stop
    end if                                                
  else
    print "(/,2x,'Group name GeomProp not found;')"
    stop  
  end if                          
  call check_geomAXSYM (TypeGeom, Nsurf, Nparam)
  call check_geomAXSYMOblate (TypeGeom, Nsurf, surf)  
  call check_anorm (anorm)
  xpart = k * anorm
  snorm = Pi * xpart * xpart 
  Nface = 1
  do i = 1, NfacePD
    do j = 1, 2
      rp(j,i) = 0._O
      np(j,i) = 0._O
    end do
    area(i) = 0._O
  end do   
  if (FileGeom) then    
    call read_FileFEMAxsym (FileFEM, Nface, rp, np, area)     
    Rcirc = 0._O    
    do i = 1, Nface
      dp = sqrt(rp(1,i)**2 + rp(2,i)**2)
      if (dp > Rcirc) Rcirc = dp
    end do    
  end if          
!
  DoConvTest   = .true.
  MishConvTest = .true.
  string       = 'ConvTest'
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) DoConvTest
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable DoConvTest;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) MishConvTest
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable MishConvTest;')"
      stop
    end if         
  else
    print "(/,2x,'Group name ConvTest not found;')"
    stop  
  end if   
  if (chiral)   MishConvTest = .false.     
  if (FileGeom) MishConvTest = .false.  
!
  DS = .false.
  autGenDS = .true.
  string   = 'Sources'
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) DS
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable DS;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) autGenDS
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable autGenDS;')"
      stop
    end if         
  else
    print "(/,2x,'Group name Sources not found;')"
    stop  
  end if          
  call check_inputAXSYM (miror, chiral, DS)
  if (FileGeom) autGenDS = .false.  
  InputDS = .false.
  if (DS .and. .not. autGenDS) InputDS = .true. 
!
  ComplexPlane = .false.
  epsZReIm = 0.95_O 
  if (DS .and. autGenDS) then
    string = 'SourcePosAut'
    if (XFindPar (iInputAXSYM, string)) then
      read (iInputAXSYM, *, iostat = ios) ComplexPlane
      if (ios /= 0) then
        print "(/,2x,'Error by reading the input variable ComplexPlane;')"
        stop
      end if
      read (iInputAXSYM, *, iostat = ios) epsZReIm
      if (ios /= 0) then
        print "(/,2x,'Error by reading the input variable epsZReIm;')"
        stop
      end if         
    else
      print "(/,2x,'Group name SourcePosAut not found;')"
      stop  
    end if              
  end if
!
  Nint   = 100
  Nrank  =  17 
  if (.not. DoConvTest .or. InputDS) then       
    string = 'NintNrank'
    if (XFindPar (iInputAXSYM, string)) then
      read (iInputAXSYM, *, iostat = ios) Nint
      if (ios /= 0) then
        print "(/,2x,'Error by reading the input variable Nint;')"
        stop
      end if
      read (iInputAXSYM, *, iostat = ios) Nrank
      if (ios /= 0) then
        print "(/,2x,'Error by reading the input variable Nrank;')"
        stop
      end if         
    else
      print "(/,2x,'Group name NintNrank not found;')"
      stop  
    end if                              
  end if    
!
  do i = 1, NrankPD
    zRe(i)  = 0._O
    zIm(i)  = 0._O
    zRe1(i) = 0._O
    zIm1(i) = 0._O
  end do
  if (InputDS) then   
    call check_MaxNrank (Nrank) 
    string = 'SourcePosInp'
    if (XFindPar (iInputAXSYM, string)) then
      do i = 1, Nrank
        read (iInputAXSYM, *, iostat = ios) zRe(i), zIm(i)
        if (ios /= 0) then
          print "(/,2x,'Error by reading the input variables zRe and zIm;')"
          stop
        end if
      end do      
      read (iInputAXSYM, *)
      do i = 1, Nrank - 1
        read (iInputAXSYM, *, iostat = ios) zRe1(i), zIm1(i)
        if (ios /= 0) then
          print "(/,2x,'Error by reading the input variables zRe1 and zIm1;')"
          stop
        end if
      end do
    else
      print "(/,2x,'Group name SourcePosInp not found;')"
      stop  
    end if                       
  end if         
!
  epsNint  = 5.e-2_O
  epsNrank = 5.e-2_O
  epsMrank = 5.e-2_O
  dNint    = 4
  dNintMrank = 10
  string   = 'Errors'
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) epsNint
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable epsNint;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) epsNrank
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable epsNrank;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) epsMrank
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable epsMrank;')"
      stop
    end if 
    read (iInputAXSYM, *, iostat = ios) dNint
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable dNint;')"
      stop
    end if
    read (iInputAXSYM, *, iostat = ios) dNintMrank
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable dNintMrank;')"
      stop
    end if         
  else
    print "(/,2x,'Group name Errors not found;')"
    stop  
  end if
!
  FileTmat = '../TMATFILES/T.dat'
  string   = 'Tmat' 
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) FileTmat
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable FileTmat;')"
      stop
    end if             
  else
    print "(/,2x,'Group name Tmat not found;')"
    stop  
  end if   
!
  PrnProgress = .true.
  string   = 'PrintProgress' 
  if (XFindPar (iInputAXSYM, string)) then
    read (iInputAXSYM, *, iostat = ios) PrnProgress
    if (ios /= 0) then
      print "(/,2x,'Error by reading the input variable PrnProgress;')"
      stop
    end if             
  else
    print "(/,2x,'Group name PrintProgress not found;')"
    stop  
  end if       
  close (unit = iInputAXSYM) 
end subroutine readinputAXSYM   
!************************************************************************************
subroutine printinputAXSYM (ic, FileGeom, TypeGeom, FileFEM, Nsurf, Nparam, Nrank,  &
           Nrank1, dNint, dNintMrank,ind_refMed, wavelength, anorm, Rcirc, surf,    &
           kb, epsNint, epsNrank, epsMrank, zRe, zIm, zRe1, zIm1, ind_refRel,       &
           miror, perfectcond, DS, chiral, autGenDS)
  use parameters
  implicit none
  integer       :: ic, TypeGeom, Nsurf, Nparam, Nrank, Nrank1, dNint, dNintMrank,   &
                   i, LenString                     
  real(O)       :: ind_refMed, wavelength, anorm, Rcirc, surf(Nsurf), kb, epsNint,  &
                   epsNrank, epsMrank, zRe(Nrank), zIm(Nrank), zRe1(Nrank1),        &
                   zIm1(Nrank1)
  complex(O)    :: ind_refRel
  character(80) :: FileFEM, FileFEMWrite
  logical       :: FileGeom, miror, perfectcond, DS, chiral, autGenDS  
!
  write (iOutput,"(/,2x,'Input Parameters of the Scattering Problem:',/)")
  write (iOutput,"(2x,'wavelength of the free space, wavelength = ',1pe13.4,';')")  &
         wavelength
  write (iOutput,"(2x, a, 1pe10.3, a)")                                             &
 'refractive index of the ambient medium, ind_refMed = ', ind_refMed, ';'
  write (iOutput,"(2x, a, 1pe10.3, ',', 1pe10.3, a)")                               &
 'relative refractive index of the particle, ind_refRel = (', ind_refRel, ');' 
  write (iOutput,*)
  if (FileGeom) then
    FileFEMWrite = FileFEM(14:LenString(FileFEM))
    write (iOutput,"(2x, a, a30)")                                                  &
   'name of the file containing the particle geometry, FileFEM = ', FileFEMWrite
  else
    write (iOutput,"(2x,'index of the particle geometry, TypeGeom = ',i2,';')")     &
           TypeGeom
    if (TypeGeom == 1) then
      write (iOutput,"(2x,'spheroid;')")        
    else if (TypeGeom == 2) then
      write (iOutput,"(2x,'cylinder;')")        
    else if (TypeGeom == 3) then
      write (iOutput,"(2x,'rounded oblate cylinder;')")
    end if
    write (iOutput,"(2x,'number of surface parameters, Nsurf = ',i2,';')") Nsurf
    write (iOutput,"(2x,'surface parameters:')")
    do i = 1, Nsurf
      write (iOutput,"(2x,'surf(',i2,') = ',1pe10.3,',')") i, surf(i)
    end do
    if (TypeGeom == 1) then
      write (iOutput,"(2x,'where surf(1) is the semi-axis along the symmetry axis,')")
      write (iOutput,"(2x,'and   surf(2) is the second semi-axis;')")
    else if (TypeGeom == 2 .or. TypeGeom == 3) then
      write (iOutput,"(2x,'where surf(1) is the half-length of the cylinder')") 
      write (iOutput,"(2x,'and   surf(2) is the cylinder radius;')")
    end if               
    write (iOutput,"(2x,'number of integration surfaces, Nparam = ',i2,';')") Nparam
  end if  
  write (iOutput,"(2x,a, 1pe10.3, a)")                                              &
 'characteristic length of the particle, anorm = ', anorm, ';'
  write (iOutput,"(2x, a, 1pe10.3, a)")                                             &
 'radius of the circumscribing sphere, Rcirc = ', Rcirc, ';'
  if (miror) write (iOutput,"(2x,'mirror symmetric particle;')")  
  write (iOutput,*)
  if (perfectcond) then
    write (iOutput,"(2x,'perfectly conducting particle;')")
  else if (chiral) then
    write (iOutput,"(2x,'chiral particle;')")
    write (iOutput,"(2x,'characteristic of chirality, kb = ',1pe10.3,';')") kb  
  else 
    write (iOutput,"(2x,'dielectric particle;')")
  end if 
  write (iOutput,*)
  if (.not.DS) then
    write (iOutput,"(2x,'computation with localized sources;')")
  else
    write (iOutput,"(2x,'computation with distributed sources;')")
    if (autGenDS) then
      write (iOutput,"(2x,'the sources are generated automatically;')") 
    else
      write (iOutput,"(2x,'the sources are user-defined;')")
    end if                      
    write (iOutput,*)       
    write (iOutput,"(2x,'z - coordinates of the sources:')")
    write (iOutput,"(2x,'first configuration:')")
    do i = 1, Nrank
      if (i /= Nrank) then
        write (iOutput,"(2x,'zRe(',i3,') = ',1pe10.3,', zIm(',i3,') = ',1pe10.3,',')")&
               i, zRe(i), i, zIm(i)
      else
        write (iOutput,"(2x,'zRe(',i3,') = ',1pe10.3,', zIm(',i3,') = ',1pe10.3,';')")&
               i, zRe(i), i, zIm(i)
      end if
    end do
    if (ic == 2) then
      write (iOutput,*)
      write (iOutput,"(2x,'second configuration:')")
      do i = 1,Nrank1
        if (i /= Nrank1) then
          write (iOutput,"(2x,'zRe(',i3,') = ',1pe10.3,', zIm(',i3,') = ',1pe10.3,',')")&
                 i, zRe1(i), i, zIm1(i)
        else
          write (iOutput,"(2x,'zRe(',i3,') = ',1pe10.3,', zIm(',i3,') = ',1pe10.3,';')")&
                 i, zRe1(i), i, zIm1(i)
        end if
      end do
    end if
  end if
  write (iOutput,*)
  write (iOutput,"(2x,'integration tolerance, epsNint = ',1pe10.3,';')") epsNint
  write (iOutput,"(2x, a, 1pe10.3, a)")                                             &
 'maximum expansion order tolerance, epsNrank = ', epsNrank, ';'
  write (iOutput,"(2x, a, 1pe10.3, a)")                                             &
 'maximum azimuthal order tolerance, epsMrank = ', epsMrank, ';'          
  write (iOutput,"(2x,'integration step, dNint = ',i3,'.')") dNint
  if (DS) then
    write (iOutput,"(2x, a, i3, a)")                                                &
   'integration step for Mrank calculation, dNintMrank = ',     dNintMrank, '.'
  end if
  write (iOutput,"(/)")                       
end subroutine printinputAXSYM
!***********************************************************************************
subroutine convergence_NintAXSYM (FileGeom, TypeGeom, k, ind_ref, snorm, Nsurf,     &
           surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, dNint, miror,  &
           perfectcond, DS, chiral, kb, epsNint, PrnProgress)
  use parameters                                                                           
  implicit none 
  integer    :: TypeGeom, Nsurf, Nface, Nparam, Nrank, Nint, dNint
  real(O)    :: k, surf(Nsurf), snorm, epsNint, kb, zRe(Nrank), zIm(Nrank),         &
                rp(2,NfacePD), np(2,NfacePD), area(NfacePD)
  complex(O) :: ind_ref
  logical    :: FileGeom, miror, perfectcond, DS, chiral, PrnProgress
!      
  integer    :: Nteta, Mstart, Mrank, Nmax, Nmaxmax, i, m, iNint, NthetaConv,       &
                iprog, Nprog
  real(O)    :: alfa, beta, gama, alfap, tetaGI, phiGI, phiGS, Cscat, Qscat,        &
                Cext, Qext
  integer,allocatable    :: Nintparam(:)
  real(O),allocatable    :: paramG(:,:), weightsG(:,:), h(:), v(:), oldh(:), oldv(:)
  complex(O),allocatable :: a(:,:), b(:,:), c(:), c1(:), cc(:)
!
  tetaGI = 0._O
  phiGI  = 0._O
  phiGS  = 0._O
  Nteta  = 10
  alfa   = 0._O
  beta   = 0._O
  gama   = 0._O
  alfap  = Pi / 4._O  
  Mstart = 1
  Mrank  = 1
  Nmax   = Nrank        
  m = 1            
  call write_TypeConvHead (1)
  allocate (a(2*Nrank,2*Nrank), b(2*Nrank,2*Nrank), c(2*Nrank), c1(2*Nrank))
  Nmaxmax = Nrank + Mrank * (2 * Nrank - Mrank + 1)
  allocate (cc(2*Nmaxmax))
  allocate (h(Nteta), v(Nteta), oldh(Nteta), oldv(Nteta))  
  do i = 1, Nteta
    oldh(i) = 0._O
    oldv(i) = 0._O
  end do
  if (.not. chiral) then
    Nprog = 7
    iprog = 3
  else
    Nprog = 13
    iprog =  6
  end if
  if (PrnProgress) call write_progress (.true., 1, Nprog)
  do iNint = 1, 2         
    allocate (paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
    call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,              &
         Nintparam, paramG, weightsG, miror)       
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 2+iprog*(iNint-1), Nprog)
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, b, Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 3+iprog*(iNint-1), Nprog)
    call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress (.false., 4+iprog*(iNint-1), Nprog)
    call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank,     &
         Nmax, c)
    call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
    call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)
    if (.not. chiral) then
      call matrix_m_negativ (Nmax, Nmax, b, Nrank, Nrank)
    else 
      call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,   &
           area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, &
           weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
      if (PrnProgress) call write_progress (.false., 5+iprog*(iNint-1), Nprog)
      call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,   &
           area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, &
           weightsG, miror, perfectcond, DS, chiral, kb, b, Nrank, Nrank)
      if (PrnProgress) call write_progress (.false., 6+iprog*(iNint-1), Nprog)
      call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
      if (PrnProgress) call write_progress (.false., 7+iprog*(iNint-1), Nprog)
    end if
    call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,    &
         Nmax, c)
    call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
    call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)
    call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm, &
        .false.,.true., h, v)    
    call delta_DSCS (Nteta, h, v, oldh, oldv, epsNint, NthetaConv)
    call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
    call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,         &
         alfap, k, snorm, Cext, Qext)
    call write_3ConvParam (Nint, Nrank, m)
    call write_DSCS(Nteta,.false., h, v)
    call write_Effic (Qscat, Qext)  
    Nint = Nint + dNint
    deallocate (paramG, weightsG, Nintparam)
  end do  
  call write_NintConvRes (NthetaConv, Nteta, epsNint)                 
  deallocate (a, b, c, c1, cc, h, v, oldh, oldv)
end subroutine convergence_NintAXSYM 
!***********************************************************************************
subroutine convergence_NrankAXSYM (FileGeom, TypeGeom, k, ind_ref, snorm, Nsurf,    &
           surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, miror,         &
           perfectcond, DS, chiral, kb, epsNrank, PrnProgress)                  
  use parameters
  implicit none  
  integer    :: TypeGeom, Nsurf, Nface, Nparam, Nrank, Nint
  real(O)    :: k, surf(Nsurf), snorm, epsNrank, kb, zRe(Nrank), zIm(Nrank),        &
                rp(2,NfacePD), np(2,NfacePD), area(NfacePD)
  complex(O) :: ind_ref
  logical    :: FileGeom, miror, perfectcond, DS, chiral, PrnProgress
!      
  integer    :: Nteta, Mstart, Mrank, Nmax, Nmaxmax, i, m, NthetaConv, iprog,       &
                Nprog, j   
  real(O)    :: alfa, beta, gama, alfap, tetaGI, phiGI, phiGS, Cscat, Qscat,        &
                Cext, Qext
  integer,allocatable    :: Nintparam(:)
  real(O),allocatable    :: paramG(:,:), weightsG(:,:), h(:), v(:), oldh(:), oldv(:)
  complex(O),allocatable :: a(:,:), b(:,:), c(:), c1(:), cc(:), ap(:,:), bp(:,:),   &
                            am(:,:), bm(:,:)
!
  tetaGI = 0._O
  phiGI  = 0._O
  phiGS  = 0._O
  Nteta  = 10
  alfa   = 0._O
  beta   = 0._O
  gama   = 0._O
  alfap  = Pi / 4._O
  Mstart = 1
  Mrank  = 1
  Nmax   = Nrank    
  m = 1 
  call write_TypeConvHead (2)
  allocate (a(2*Nrank,2*Nrank), b(2*Nrank,2*Nrank), c(2*Nrank), c1(2*Nrank))     
  allocate (ap(2*Nrank,2*Nrank), bp(2*Nrank,2*Nrank))
  allocate (am(2*Nrank,2*Nrank), bm(2*Nrank,2*Nrank))  
  Nmaxmax = Nrank + Mrank * (2 * Nrank - Mrank + 1)
  allocate (cc(2*Nmaxmax))
  allocate (h(Nteta), v(Nteta), oldh(Nteta), oldv(Nteta))  
  allocate (paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
  if (.not. FileGeom) then
    call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,              &
         Nintparam, paramG, weightsG, miror)
  else
    do i = 1, Nparam
      do j = 1, Nint
        paramG(i,j)   = 0._O 
        weightsG(i,j) = 0._O
      end do
      Nintparam(i) = 1
    end do
  end if
  if (.not. chiral) then
    Nprog = 5
  else
    Nprog = 8
  end if
  if (PrnProgress) call write_progress (.true., 1, Nprog)             
! --- Nrank configuration ---                    
  call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np, area, &
       Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG,  &
       miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
  if (PrnProgress) call write_progress (.false., 2, Nprog)
  call copy_matrix (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, ap, 2*Nrank, 2*Nrank)
  call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np, area, &
       Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG,  &
       miror, perfectcond, DS, chiral, kb, b, Nrank, Nrank)
  if (PrnProgress) call write_progress (.false., 3, Nprog)
  call copy_matrix (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, bp, 2*Nrank, 2*Nrank)
  call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
  if (PrnProgress) call write_progress (.false., 4, Nprog)
  iprog = 4
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank,       &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)
  if (.not. chiral) then
    call matrix_m_negativ (Nmax, Nmax, b, Nrank, Nrank)
  else 
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,   &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 4, Nprog)
    call copy_matrix (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, am, 2*Nrank, 2*Nrank)        
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,   &
         weightsG, miror, perfectcond, DS, chiral, kb, b, Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 5, Nprog)
    call copy_matrix (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, bm, 2*Nrank, 2*Nrank)    
    call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress (.false., 6, Nprog)
    iprog = 6
  end if
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,      &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)
  call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm,   &
      .false.,.true., h, v) 
  call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
  call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,           &
       alfap, k, snorm, Cext, Qext)
  do i = 1, Nteta
    oldh(i) = h(i)
    oldv(i) = v(i)
  end do  
  call write_3ConvParam (Nint, Nrank, m)
  call write_DSCS (Nteta,.false., h, v)
  call write_Effic (Qscat, Qext)
! --- (Nrank - 1) configuration ---
  call copy_matrix (2*Nmax, 2*Nmax, ap, 2*Nrank, 2*Nrank, a, 2*Nrank, 2*Nrank)
  call matrix_Nrank_m_left (Nmax, a, Nrank, Nrank)
  call copy_matrix (2*Nmax, 2*Nmax, bp, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank)
  call matrix_Nrank_m (Nmax, b, Nrank, Nrank)
  call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
  if (PrnProgress) call write_progress (.false., iprog+1, Nprog)
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank,       &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)
  if (.not. chiral) then
    call matrix_m_negativ (Nmax, Nmax, b, Nrank, Nrank)
  else 
    call copy_matrix (2*Nmax, 2*Nmax, am, 2*Nrank, 2*Nrank, a, 2*Nrank, 2*Nrank)
    call matrix_Nrank_m_left (Nmax, a, Nrank, Nrank)
    call copy_matrix (2*Nmax, 2*Nmax, bm, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank)        
    call matrix_Nrank_m (Nmax, b, Nrank, Nrank)
    call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress (.false., iprog+2, Nprog)
  end if
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,      &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)
  call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm,   &
      .false.,.true., h, v)
  call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
  call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,           &
       alfap, k, snorm, Cext, Qext)
  call delta_DSCS (Nteta, h, v, oldh, oldv, epsNrank, NthetaConv)  
  call write_3ConvParam (Nint, Nrank - 1, m)
  call write_DSCS (Nteta,.false., h, v)
  call write_Effic (Qscat, Qext)
  call write_NrankConvRes (NthetaConv, Nteta, epsNrank) 
  deallocate (ap, bp, am, bm)
  deallocate (a, b, c, c1, cc, h, v, oldh, oldv, paramG, weightsG, Nintparam)
end subroutine convergence_NrankAXSYM
!***********************************************************************************
subroutine convergence_MrankAXSYM (FileGeom, TypeGeom, k, ind_ref, snorm, Nsurf,    &
           surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, miror,         &
           perfectcond, DS, chiral, kb, epsMrank, FileTmat, PrnProgress)                
  use parameters
  implicit none   
  integer       :: TypeGeom, Nsurf, Nface, Nparam, Nrank, Nint
  real(O)       :: k, surf(Nsurf), snorm, epsMrank, kb, zRe(Nrank), zIm(Nrank),     &
                   rp(2,NfacePD), np(2,NfacePD), area(NfacePD)
  complex(O)    :: ind_ref
  logical       :: FileGeom, miror, perfectcond, DS, chiral, PrnProgress
  character(80) :: FileTmat
!      
  integer       :: Nteta, Mstart, Mrank, Nmax, Nmaxmax, i, m, NthetaConv, Nprog, j
  real(O)       :: alfa, beta, gama, alfap, tetaGI, phiGI, phiGS, Cscat, Qscat,     &
                   Cext, Qext  
  integer,allocatable    :: Nintparam(:)
  real(O),allocatable    :: paramG(:,:), weightsG(:,:), h(:), v(:), oldh(:), oldv(:)
  complex(O),allocatable :: a(:,:), b(:,:), c(:), c1(:), cc(:)
!
  tetaGI = 0._O
  phiGI  = 0._O
  phiGS  = 0._O
  Nteta  = 10
  alfa   = Pi / 4._O
  beta   = Pi / 4._O
  gama   = 0._O
  alfap  = Pi / 4._O
  Mstart = 0
  Mrank  = Nrank      
  open (unit = iTmat, file = FileTmat, status = 'replace')  
  call write_HeadFileTmat (Nrank, Nrank) 
  call write_TypeConvHead (3)
  call write_2ConvParamAxsym (Nint, Nrank)
  allocate (a(2*Nrank,2*Nrank), b(2*Nrank,2*Nrank), c(2*Nrank), c1(2*Nrank))
  Nmaxmax = Nrank + Mrank * (2 * Nrank - Mrank + 1)
  allocate (cc(2*Nmaxmax))
  allocate (h(Nteta), v(Nteta), oldh(Nteta), oldv(Nteta))
  do i = 1, Nteta
    oldh(i) = 0._O
    oldv(i) = 0._O
  end do  
  allocate (paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
  if (.not. FileGeom) then
    call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,              &
         Nintparam, paramG, weightsG, miror)
  else
    do i = 1, Nparam
      do j = 1, Nint
        paramG(i,j)   = 0._O 
        weightsG(i,j) = 0._O
      end do
      Nintparam(i) = 1
    end do
  end if        
  if (.not. chiral) then
    Nprog = 4
  else
    Nprog = 7
  end if
  Mrank = - 1
  do m = Mstart, Nrank    
    call write_1ConvParam (m)
    Mrank = Mrank + 1
    if (m == 0) then
      Nmax = Nrank
    else
      Nmax = Nrank - m + 1
    end if  
    if (PrnProgress) call write_progress_m (.true., m, 1, Nprog)    
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank) 
    if (PrnProgress) call write_progress_m (.false., m, 2, Nprog)       
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, b, Nrank, Nrank) 
    if (PrnProgress) call write_progress_m (.false., m, 3, Nprog)                           
    call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress_m (.false., m, 4, Nprog)                   
    call write_FileTmat (Nrank, Nrank, b)
    call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank,     &
         Nmax, c)
    call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
    call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)       
    if (m /= 0) then
      if (.not. chiral) then
        call matrix_m_negativ (Nmax, Nmax, b, Nrank, Nrank)     
      else 
        call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np, &
             area, Nface, zRe, zIm, -m, Nrank,Nmax, Nint, Nparam, Nintparam,        &
             paramG, weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
        if (PrnProgress) call write_progress_m (.false., m, 5, Nprog)                     
        call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np, &
             area, Nface, zRe, zIm, -m, Nrank,Nmax, Nint, Nparam, Nintparam,        &
             paramG, weightsG, miror, perfectcond, DS, chiral, kb, b, Nrank, Nrank)    
        if (PrnProgress) call write_progress_m (.false., m, 6, Nprog)
        call LU_SYSTEM (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nmax)       
        if (PrnProgress) call write_progress_m (.false., m, 7, Nprog)
        call write_FileTmat (Nrank, Nrank, b)   
      end if
      call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,  &
           Nmax, c) 
      call product_matrix_vector (2*Nmax, 2*Nmax, b, 2*Nrank, 2*Nrank, c, c1)
      call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)     
    end if
    call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm, &
        .false.,.true., h, v)
    call delta_DSCS (Nteta, h, v, oldh, oldv, epsMrank, NthetaConv)     
    call write_DSCS (Nteta,.false., h, v)
    if (NthetaConv >= int(0.8*Nteta)) exit 
  end do
  close (unit = iTmat) 
  call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
  call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,           &
       alfap, k, snorm, Cext, Qext)
  call write_Effic (Qscat, Qext)
  call write_MrankConvRes (NthetaConv, epsMrank)
  if (NthetaConv >= int(0.8*Nteta)) then
    print "(/,2x,'Convergence criterion for Mrank is satisfied;')"                                              
  else
    print "(/,2x,'Convergence criterion for Mrank is not satisfied;')"
  end if
  call write_InfoFileTmat (FileTmat, Mrank, Nrank, .true., .false., chiral)
  call ScatCharact (k, FileTmat, Mrank, Nrank, .true., .false., chiral)
  print "(/,2x,'T matrix is stored in ',a50)", FileTmat
  print "(  2x,'The dimensions of the T matrix are given by:')"      
  print "(  2x,'- maximum expansion order,   Nrank = ',i3,',')", Nrank
  print "(  2x,'- number of azimuthal modes, Mrank = ',i3,';')", Mrank                     
  deallocate (a, b, c, c1, cc, h, v, oldh, oldv, paramG, weightsG, Nintparam)
end subroutine convergence_MrankAXSYM
!***********************************************************************************
subroutine convergence_NintDSAXSYM (FileGeom, TypeGeom, k, ind_ref, snorm, Nsurf,   &
           surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, dNint, miror,  &
           perfectcond, DS, chiral, kb, epsNint, PrnProgress)
  use parameters                                                                           
  implicit none 
  integer    :: TypeGeom, Nsurf, Nface, Nparam, Nrank, Nint, dNint
  real(O)    :: k, surf(Nsurf), snorm, epsNint, kb, zRe(Nrank), zIm(Nrank),         &
                rp(2,NfacePD), np(2,NfacePD), area(NfacePD)
  complex(O) :: ind_ref
  logical    :: FileGeom, miror, perfectcond, DS, chiral, PrnProgress
!      
  integer    :: Nteta, Mstart, Mrank, Nmax, Nmaxmax, i, m, iNint, NthetaConv,       &
                iprog, Nprog 
  real(O)    :: alfa, beta, gama, alfap, tetaGI, phiGI, phiGS, Cscat, Qscat,        &
                Cext, Qext
  integer,allocatable    :: Nintparam(:)
  real(O),allocatable    :: paramG(:,:), weightsG(:,:), h(:), v(:), oldh(:), oldv(:)
  complex(O),allocatable :: a(:,:), b(:,:), c(:), c1(:), cc(:)
!
  tetaGI = 0._O
  phiGI  = 0._O
  phiGS  = 0._O
  Nteta  = 10
  alfa   = 0._O
  beta   = 0._O
  gama   = 0._O
  alfap  = Pi / 4._O
  Mstart = 1
  Mrank  = 1
  Nmax   = Nrank        
  m = 1           
  call write_TypeConvHead (1)
  allocate (a(2*Nrank,2*Nrank), b(2*Nrank,2*Nrank), c(2*Nrank), c1(2*Nrank))
  Nmaxmax = Nrank + Mrank * (2 * Nrank - Mrank + 1)
  allocate (cc(2*Nmaxmax))
  allocate (h(Nteta), v(Nteta), oldh(Nteta), oldv(Nteta))  
  do i = 1, Nteta
    oldh(i) = 0._O
    oldv(i) = 0._O
  end do
  if (.not. chiral) then
    Nprog = 9
    iprog = 4
  else
    Nprog = 17
    iprog =  8
  end if
  if (PrnProgress) call write_progress (.true., 1, Nprog)
  do iNint = 1, 2         
    allocate(paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
    call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,              &
         Nintparam, paramG, weightsG, miror)       
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 2+iprog*(iNint-1), Nprog)
    call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area, Nface,& 
         zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG, b,    &
         Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 3+iprog*(iNint-1), Nprog)
    call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress (.false., 4+iprog*(iNint-1), Nprog)
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    call product_matrices (2*Nmax, 2*Nrank, 2*Nmax, a, 2*Nrank, 2*Nrank, b, 2*Nrank,&
         2*Nrank)    
    if (PrnProgress) call write_progress (.false., 5+iprog*(iNint-1), Nprog)
    call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank,     &
         Nmax, c)
    call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
    call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)
    if (.not. chiral) then
      call matrix_m_negativ (Nmax, Nmax, a, Nrank, Nrank)
    else 
      call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,   &
           area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, &
           weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
      if (PrnProgress) call write_progress (.false., 6+iprog*(iNint-1), Nprog)
      call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area,     &
           Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,       &
           weightsG, b, Nrank, Nrank)
      if (PrnProgress) call write_progress (.false., 7+iprog*(iNint-1), Nprog)
      call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank,     &
           2*Nmax)
      if (PrnProgress) call write_progress (.false., 8+iprog*(iNint-1), Nprog)
      call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,   &
           area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, &
           weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)    
      call product_matrices (2*Nmax, 2*Nrank, 2*Nmax, a, 2*Nrank, 2*Nrank,          &
           b, 2*Nrank, 2*Nrank)
      if (PrnProgress) call write_progress (.false., 9+iprog*(iNint-1), Nprog)
    end if
    call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,    &
         Nmax, c)
    call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
    call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)
    call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm, &
        .false.,.true., h, v)
    call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
    call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,         &
         alfap, k, snorm, Cext, Qext)    
    call delta_DSCS (Nteta, h, v, oldh, oldv, epsNint, NthetaConv)
    call write_3ConvParam (Nint, Nrank, m)
    call write_DSCS (Nteta,.false., h, v)
    call write_Effic (Qscat, Qext)
    Nint = Nint + dNint
    deallocate (paramG, weightsG, Nintparam)
  end do
  call write_NintConvRes (NthetaConv, Nteta, epsNint)                 
  deallocate (a, b, c, c1, cc, h, v, oldh, oldv)
end subroutine convergence_NintDSAXSYM
!***********************************************************************************
subroutine convergence_NrankDSAXSYM (FileGeom, TypeGeom, k, ind_ref, snorm, Nsurf,  &
           surf, rp, np, area, Nface, zRe, zIm, zRe1, zIm1, Nparam, Nrank, Nrank1,  &
           Nint, miror, perfectcond, DS, chiral, kb, epsNrank, PrnProgress)              
  use parameters
  implicit none  
  integer    :: TypeGeom, Nsurf, Nface, Nparam, Nrank, Nrank1, Nint
  real(O)    :: k, surf(Nsurf), snorm, epsNrank, kb, zRe(Nrank), zIm(Nrank),        &
                zRe1(Nrank1), zIm1(Nrank1), rp(2,NfacePD), np(2,NfacePD),           &
                area(NfacePD)
  complex(O) :: ind_ref
  logical    :: FileGeom, miror, perfectcond, DS, chiral, PrnProgress
!      
  integer    :: Nteta, Mstart, Mrank, Nmax, Nmaxmax, i, m, NthetaConv,              &
                iprog, Nprog, j
  real(O)    :: alfa, beta, gama, alfap, tetaGI, phiGI, phiGS, Cscat, Qscat,        &
                Cext, Qext
  integer,allocatable    :: Nintparam(:)
  real(O),allocatable    :: paramG(:,:), weightsG(:,:), h(:), v(:), oldh(:), oldv(:)
  complex(O),allocatable :: a(:,:), b(:,:), c(:), c1(:), cc(:)
!
  tetaGI = 0._O
  phiGI  = 0._O
  phiGS  = 0._O
  Nteta  = 10
  alfa   = 0._O
  beta   = 0._O
  gama   = 0._O
  alfap  = Pi / 4._O
  Mstart = 1
  Mrank  = 1
  Nmax   = Nrank  
  m = 1
  call write_TypeConvHead (2)
  allocate (a(2*Nrank,2*Nrank), b(2*Nrank,2*Nrank), c(2*Nrank), c1(2*Nrank))
  Nmaxmax = Nrank + Mrank * (2 * Nrank - Mrank + 1)
  allocate (cc(2*Nmaxmax))
  allocate (h(Nteta), v(Nteta), oldh(Nteta), oldv(Nteta))  
  allocate (paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
  if (.not. FileGeom) then
    call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,              &
         Nintparam, paramG, weightsG, miror)
  else
    do i = 1, Nparam
      do j = 1, Nint
        paramG(i,j)   = 0._O 
        weightsG(i,j) = 0._O
      end do
      Nintparam(i) = 1
    end do
  end if         
  if (.not. chiral) then
    Nprog = 9
  else
    Nprog = 17
  end if
  if (PrnProgress) call write_progress (.true., 1, Nprog)
! --- Nrank configuration ---                    
  call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np, area, &
       Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG,  &
       miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
  if (PrnProgress) call write_progress (.false., 2, Nprog)
  call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area, Nface,  &
       zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG, b,      &
       Nrank, Nrank)                              
  if (PrnProgress) call write_progress (.false., 3, Nprog)
  call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank, 2*Nmax)
  if (PrnProgress) call write_progress (.false., 4, Nprog)
  call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np, area, &
       Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG,  &
       miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
  call product_matrices (2*Nmax, 2*Nrank, 2*Nmax, a, 2*Nrank, 2*Nrank, b, 2*Nrank,  &
       2*Nrank)    
  if (PrnProgress) call write_progress (.false., 5, Nprog)
  iprog = 5
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank, Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)
  if (.not. chiral) then
    call matrix_m_negativ (Nmax, Nmax, a, Nrank, Nrank)
  else 
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,   &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 6, Nprog)
    call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area, Nface,&
         zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG, b,   &
         Nrank, Nrank)
    if (PrnProgress) call write_progress (.false., 7, Nprog)
    call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress (.false., 8, Nprog)
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,   &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    call product_matrices (2*Nmax, 2*Nrank, 2*Nmax, a, 2*Nrank, 2*Nrank, b, 2*Nrank,&
         2*Nrank) 
    if (PrnProgress) call write_progress (.false., 9, Nprog)
        iprog = 9
  end if
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,      &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)  
  call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm,   &
      .false.,.true., h, v)
  call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
  call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,           &
       alfap, k, snorm, Cext, Qext)
  do i = 1, Nteta
    oldh(i) = h(i)
    oldv(i) = v(i)
  end do  
  call write_3ConvParam (Nint, Nrank, m)
  call write_DSCS (Nteta,.false., h, v)
  call write_Effic (Qscat, Qext)
! --- Nrank1 configuration ---
  Nmax   = Nrank1
  Nmaxmax= Nrank1 + Mrank*(2*Nrank1 - Mrank + 1)  
  call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np, area, &
       Nface, zRe1, zIm1, m, Nrank1, Nmax, Nint, Nparam, Nintparam, paramG,         &
       weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
  if (PrnProgress) call write_progress (.false., iprog+1, Nprog)
  call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area, Nface,  &
       zRe1, zIm1, m, Nrank1, Nmax, Nint, Nparam, Nintparam, paramG, weightsG, b,   &
       Nrank, Nrank)
  if (PrnProgress) call write_progress (.false., iprog+2, Nprog)
  call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank1, 2*Nmax)
  if (PrnProgress) call write_progress (.false., iprog+3, Nprog)
  call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np, area, &
       Nface, zRe1, zIm1, m, Nrank1, Nmax, Nint, Nparam, Nintparam, paramG,         &
       weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
  call product_matrices (2*Nmax, 2*Nrank1, 2*Nmax, a, 2*Nrank, 2*Nrank, b, 2*Nrank, &
       2*Nrank)    
  if (PrnProgress) call write_progress (.false., iprog+4, Nprog)
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank1,      &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_positive (c1, cc, m, Mstart, Nrank1, Nmax, Nmaxmax)  
  if (.not. chiral) then 
    call matrix_m_negativ (Nmax, Nmax, a, Nrank, Nrank)
  else 
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe1, zIm1, -m, Nrank1, Nmax, Nint, Nparam, Nintparam,        &
         paramG, weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)    
    if (PrnProgress) call write_progress (.false., iprog+5, Nprog)
    call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area, Nface,& 
         zRe1, zIm1, -m, Nrank1, Nmax, Nint, Nparam, Nintparam, paramG, weightsG,   &
         b, Nrank, Nrank)    
    if (PrnProgress) call write_progress (.false., iprog+6, Nprog)
    call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank1,      &
         2*Nmax)    
    if (PrnProgress) call write_progress (.false., iprog+7, Nprog)
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe1, zIm1, -m, Nrank1, Nmax, Nint, Nparam, Nintparam,        &
         paramG, weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)    
    call product_matrices (2*Nmax, 2*Nrank1, 2*Nmax, a, 2*Nrank, 2*Nrank,           &
         b, 2*Nrank, 2*Nrank)       
    if (PrnProgress) call write_progress (.false., iprog+8, Nprog)
  end if
  call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank1,     &
       Nmax, c)
  call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
  call extend_vector_negative (c1, cc, m, Nrank1, Nmax, Nmaxmax)  
  call DSCS (cc, Mrank, Nrank1, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm,  &
      .false.,.true., h, v)
  call CQscat (cc, Mrank, Nrank1, Nmaxmax, k, snorm, Cscat, Qscat)
  call CQext (cc, Mrank, Nrank1, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,          &
       alfap, k, snorm, Cext, Qext)
  call delta_DSCS (Nteta, h, v, oldh, oldv, epsNrank, NthetaConv)  
  call write_3ConvParam (Nint, Nrank1, m)
  call write_DSCS (Nteta,.false., h, v)
  call write_Effic (Qscat, Qext)
  call write_NrankConvRes (NthetaConv, Nteta, epsNrank)
  deallocate (a, b, c, c1, cc, h, v, oldh, oldv, paramG, weightsG, Nintparam)
end subroutine convergence_NrankDSAXSYM 
!***********************************************************************************
subroutine convergence_MrankDSAXSYM (FileGeom, TypeGeom, k, ind_ref, snorm, Nsurf,  &
           surf, rp, np, area, Nface, zRe, zIm, Nparam, Nrank, Nint, miror,         &
           perfectcond, DS, chiral, kb, epsMrank, dNintMrank, FileTmat, PrnProgress)            
  use parameters
  implicit none   
  integer       :: TypeGeom, Nsurf, Nface, Nparam, Nrank, Nint, dNintMrank
  real(O)       :: k, surf(Nsurf), snorm, epsMrank, kb, zRe(Nrank), zIm(Nrank),     &
                   rp(2,NfacePD), np(2,NfacePD), area(NfacePD)
  complex(O)    :: ind_ref
  logical       :: FileGeom, miror, perfectcond, DS, chiral, PrnProgress
  character(80) :: FileTmat
!      
  integer       :: Nteta, Mstart, Mrank, Nmax, Nmaxmax, i, m, NthetaConv, Nprog, j
  real(O)       :: alfa, beta, gama, alfap, tetaGI, phiGI, phiGS, Cscat, Qscat,     &
                   Cext, Qext  
  logical       :: ComplexPlane
  integer,allocatable    :: Nintparam(:)
  real(O),allocatable    :: paramG(:,:), weightsG(:,:), h(:), v(:), oldh(:), oldv(:)
  complex(O),allocatable :: a(:,:), b(:,:), c(:), c1(:), cc(:)
!
  tetaGI = 0._O
  phiGI  = 0._O
  phiGS  = 0._O
  Nteta  = 10
  alfa   = Pi / 4._O
  beta   = Pi / 4._O
  gama   = 0._O
  alfap  = Pi / 4._O
  Mstart = 0
  Mrank  = Nrank      
  open (unit = iTmat, file = FileTmat, status = 'replace') 
  call write_HeadFileTmat (Nrank, Nrank) 
  call write_TypeConvHead (3)
  call write_2ConvParamAxsym (Nint, Nrank)
  allocate (a(2*Nrank,2*Nrank), b(2*Nrank,2*Nrank), c(2*Nrank), c1(2*Nrank))
  Nmaxmax = Nrank + Mrank * (2 * Nrank - Mrank + 1)
  allocate (cc(2*Nmaxmax))
  allocate (h(Nteta), v(Nteta), oldh(Nteta), oldv(Nteta))
  do i = 1, Nteta
    oldh(i) = 0._O
    oldv(i) = 0._O
  end do  
  allocate (paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
  if (.not. FileGeom) then
    call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,              &
         Nintparam, paramG, weightsG, miror)
  else
    do i = 1, Nparam
      do j = 1, Nint
        paramG(i,j)   = 0._O 
        weightsG(i,j) = 0._O
      end do
      Nintparam(i) = 1
    end do
  end if       
  ComplexPlane = .false.        
  do i = 1, Nrank                  
    if (zIm(i) /= 0._O) ComplexPlane = .true.
  end do
  if (.not. chiral) then
    Nprog = 5
  else
    Nprog = 9
  end if                        
  Mrank = - 1
  do m = Mstart, Nrank          
    call write_1ConvParam (m)
    Mrank = Mrank + 1
    if (m == 0) then
      Nmax = Nrank
    else
      Nmax = Nrank - m + 1
    end if  
    if (ComplexPlane) then
      deallocate (paramG, weightsG, Nintparam)
      Nint = Nint + dNintMrank
      allocate (paramG(Nparam,Nint), weightsG(Nparam,Nint), Nintparam(Nparam))
      call interpolation_listAXSYM (TypeGeom, Nsurf, surf, Nint, Nparam,            &
           Nintparam, paramG, weightsG, miror)          
    end if 
    if (PrnProgress) call write_progress_m (.true., m, 1, Nprog)  
    call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    if (PrnProgress) call write_progress_m (.false., m, 2, Nprog) 
    call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area, Nface,&
         zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG, weightsG, b,    &
         Nrank, Nrank)
    if (PrnProgress) call write_progress_m (.false., m, 3, Nprog)
    call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank, 2*Nmax)
    if (PrnProgress) call write_progress_m (.false., m, 4, Nprog)
    call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np,     &
         area, Nface, zRe, zIm, m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,    &
         weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
    call product_matrices (2*Nmax, 2*Nrank, 2*Nmax, a, 2*Nrank, 2*Nrank, b, 2*Nrank,&
         2*Nrank)   
    if (PrnProgress) call write_progress_m (.false., m, 5, Nprog)
    call write_FileTmat (Nrank, Nrank, a)
    call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, m, Nrank,     &
         Nmax, c)           
    call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
    call extend_vector_positive (c1, cc, m, Mstart, Nrank, Nmax, Nmaxmax)       
    if (m /= 0) then
      if (.not. chiral) then
        call matrix_m_negativ (Nmax, Nmax, a, Nrank, Nrank)
      else 
        call matrix_Q_m (FileGeom, TypeGeom, 3, 1, k, ind_ref, Nsurf, surf, rp, np, &
             area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam,       &
             paramG, weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
        if (PrnProgress) call write_progress_m (.false., m, 6, Nprog)
        call incident_matrix_m (FileGeom, TypeGeom, k, Nsurf, surf, rp, np, area,   &
             Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam, paramG,     &
             weightsG, b, Nrank, Nrank)
        if (PrnProgress) call write_progress_m (.false., m, 7, Nprog)
        call LU_SYSTEM_DIRECT (a, 2*Nrank, 2*Nrank, b, 2*Nrank, 2*Nrank, 2*Nrank,   &
             2*Nmax)
        if (PrnProgress) call write_progress_m (.false., m, 8, Nprog)
        call matrix_Q_m (FileGeom, TypeGeom, 1, 1, k, ind_ref, Nsurf, surf, rp, np, &
             area, Nface, zRe, zIm, -m, Nrank, Nmax, Nint, Nparam, Nintparam,       &
             paramG, weightsG, miror, perfectcond, DS, chiral, kb, a, Nrank, Nrank)
        call product_matrices (2*Nmax, 2*Nrank, 2*Nmax, a, 2*Nrank, 2*Nrank,        &
             b, 2*Nrank, 2*Nrank)               
        if (PrnProgress) call write_progress_m (.false., m, 9, Nprog)
        call write_FileTmat (Nrank, Nrank, a)   
      end if
      call PWcoefficients_ab_m (tetaGI, phiGI, alfa, beta, gama, alfap, -m, Nrank,  &
           Nmax, c)
      call product_matrix_vector (2*Nmax, 2*Nmax, a, 2*Nrank, 2*Nrank, c, c1)
      call extend_vector_negative (c1, cc, m, Nrank, Nmax, Nmaxmax)
    end if
    call DSCS (cc, Mrank, Nrank, Nmaxmax, Nteta, phiGS, alfa, beta, gama, k, snorm, &
        .false.,.true., h, v)
    call delta_DSCS (Nteta, h, v, oldh, oldv, epsMrank, NthetaConv)     
    call write_DSCS (Nteta,.false., h, v)
    if (NthetaConv >= int(0.8*Nteta)) exit 
  end do
  close (unit = iTmat)
  call CQscat (cc, Mrank, Nrank, Nmaxmax, k, snorm, Cscat, Qscat)
  call CQext (cc, Mrank, Nrank, Nmaxmax, tetaGI, phiGI, alfa, beta, gama,           &
       alfap, k, snorm, Cext, Qext)
  call write_Effic (Qscat, Qext)
  call write_MrankConvRes (NthetaConv, epsMrank)
  if (NthetaConv >= int(0.8*Nteta)) then
    print "(/,2x,'Convergence criterion for Mrank is satisfied;')"                                   
  else
    print "(/,2x,'Convergence criterion for Mrank is not satisfied;')"
  end if
  call write_InfoFileTmat (FileTmat, Mrank, Nrank, .true., .false., chiral)     
  call ScatCharact (k, FileTmat, Mrank, Nrank, .true., .false., chiral) 
  print "(/,2x,'T matrix is stored in ',a50)", FileTmat
  print "(  2x,'The dimensions of the T matrix are given by:')"
  print "(  2x,'- maximum expansion order,   Nrank = ',i3,',')", Nrank 
  print "(  2x,'- number of azimuthal modes, Mrank = ',i3,';')", Mrank             
  deallocate (a, b, c, c1, cc, h, v, oldh, oldv, paramG, weightsG, Nintparam)
end subroutine convergence_MrankDSAXSYM
