TABLE OF CONTENTS


ABINIT/m_paw_gaussfit [ Modules ]

[ Top ] [ Modules ]

NAME

  m_paw_gaussfit

FUNCTION

  Module to fit PAW related data to sums of gaussians

COPYRIGHT

  Copyright (C) 2012-2018 ABINIT group (T. Rangel)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

NOTES

  FOR DEVELOPPERS: in order to preserve the portability of libPAW library,
  please consult ~abinit/src/??_libpaw/libpaw-coding-rules.txt

SOURCE

21 #include "libpaw.h"
22 
23 module m_paw_gaussfit
24 
25  USE_DEFS
26  USE_MSG_HANDLING
27  USE_MPI_WRAPPERS
28  USE_MEMORY_PROFILING
29 
30  use m_paw_numeric, only : paw_splint, paw_spline
31  use m_pawrad,      only : pawrad_type, pawrad_init, pawrad_deducer0, pawrad_free, pawrad_ifromr
32 
33  implicit none
34 
35  private
36 
37  public:: gaussfit_projector !fit non-local projectors to a sum of gaussians
38  public:: gaussfit_main !main routine to fit
39 !Routines related to MPI:
40  private:: gaussfit_mpi_set_weight
41  private:: gaussfit_mpi_remove_item
42  private:: gaussfit_mpi_add_item
43  private:: gaussfit_mpi_assign
44  private:: gaussfit_mpi_main
45  private:: gaussfit_mpi_calc_deviation
46  private:: gaussfit_mpi_swap
47 !Routines related to fitting:
48  private:: gaussfit_fit !fit a function to gaussians
49  private:: gaussfit_calc_deriv_r  !calc. derivatives for real gauss.
50  private:: gaussfit_calc_deriv_c  !calc. derivatives for cplex. gauss. of form 1
51  private:: gaussfit_calc_deriv_c2 !calc. derivatives for cplex. gauss. of form 2
52  private:: gaussfit_calc_deriv_c3 !calc. derivatives for cplex. gauss. of form 3
53  private:: gaussfit_calc_deriv_c4 !calc. derivatives for cplex. gauss. of form 4
54  private:: gaussfit_rlsf !retreined least squares fit
55  private:: gaussfit_chisq_alpha_beta
56 !set parameters for LSF (for 5 different forms of gauss. sums):
57  private:: gaussfit_set_param1
58  private:: gaussfit_set_param2
59  private:: gaussfit_set_param3
60  private:: gaussfit_set_param4
61  private:: gaussfit_set_param5
62  private:: gaussfit_constrains_init !initialize constrains
63  private:: gaussfit_apply_constrains !apply cons. to get new params.

gaussfit_set_param2/gaussfit_param2_findsign [ Functions ]

[ Top ] [ gaussfit_set_param2 ] [ Functions ]

NAME

  gaussfit_param2_findsign

FUNCTION

  Finds the value of y at a given point
  This was taken out of gaussfit_set_param2 to make the code more
  readable.

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2084  subroutine gaussfit_param2_findsign()
2085 
2086 !Arguments -------------------------------
2087 !Local variables-------------------------------
2088 
2089 !This section has been created automatically by the script Abilint (TD).
2090 !Do not modify the following lines by hand.
2091 #undef ABI_FUNC
2092 #define ABI_FUNC 'gaussfit_param2_findsign'
2093 !End of the abilint section
2094 
2095  integer::ix,minx
2096  real(dp)::dist,mindist,xx,yy
2097 
2098 ! *********************************************************************
2099 
2100    mindist=rpaw
2101    do ix=1,nx
2102      xx=x(ix)
2103      dist=abs(raux-xx)
2104      if(dist<mindist) then
2105        mindist=dist
2106        minx=ix
2107      end if
2108    end do
2109    yy=y(minx)
2110    sig=yy
2111 
2112  end subroutine gaussfit_param2_findsign
2113 
2114 end subroutine gaussfit_set_param2

m_paw_gaussfit/gaussfit_apply_constrains [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_apply_constrains

FUNCTION

  Apply constrains to get new set of parameters

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2399 subroutine gaussfit_apply_constrains(const,limit,nparam,ioparams)
2400 
2401 
2402 !This section has been created automatically by the script Abilint (TD).
2403 !Do not modify the following lines by hand.
2404 #undef ABI_FUNC
2405 #define ABI_FUNC 'gaussfit_apply_constrains'
2406 !End of the abilint section
2407 
2408  implicit none
2409 
2410 !Arguments -------------------------------
2411  integer,intent(in):: nparam
2412  integer,intent(in):: const(nparam)
2413  real(dp),intent(in):: limit(nparam)
2414  real(dp),intent(inout):: ioparams(nparam)
2415 
2416 !Local variables-------------------------------
2417  integer::ii
2418 
2419 ! *********************************************************************
2420 
2421  do ii=1,nparam
2422    if(const(ii)==restricted .or. const(ii)==restricted_and_positive) then
2423      if(ioparams(ii)<limit(ii)) ioparams(ii)=limit(ii)
2424    end if
2425    if(const(ii)==positive .or. const(ii)==restricted_and_positive ) ioparams(ii)=abs(ioparams(ii))
2426 
2427  end do
2428 
2429 end subroutine gaussfit_apply_constrains

m_paw_gaussfit/gaussfit_calc_deriv_c [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_calc_deriv_c

FUNCTION

  Calculate expressions and derivatives for Gaussians fitting.
   The Gaussians expressions are defined in the comments of "gaussfit_main"

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1349 subroutine gaussfit_calc_deriv_c(nparam,nterm,nx,opt,param,x,y_out,&
1350 & deriv) ! optional
1351 
1352 
1353 !This section has been created automatically by the script Abilint (TD).
1354 !Do not modify the following lines by hand.
1355 #undef ABI_FUNC
1356 #define ABI_FUNC 'gaussfit_calc_deriv_c'
1357 !End of the abilint section
1358 
1359  implicit none
1360 
1361 !Arguments -------------------------------
1362  integer,intent(in)::nparam !number of parameters
1363  integer,intent(in)::nterm !number of gaussian expressions
1364  integer,intent(in)::nx     !number of point in the x grid
1365  integer,intent(in)::opt    !option:
1366                             !1) calculate only f(x)
1367                             !2) calculate f(x) and its derivatives
1368  real(dp),intent(in)::param(nparam) !parameters
1369  real(dp),intent(in)::x(nx) !xgrid
1370  real(dp),intent(out)::y_out(nx) !f(x)
1371  real(dp),optional,intent(out)::deriv(nx,nparam) !derivatives
1372 
1373 !Local variables-------------------------------
1374  integer::iexp,ii
1375  real(dp)::alpha1(nterm),alpha2(nterm),alpha3(nterm)
1376  real(dp)::alpha4(nterm),alpha5(nterm),alpha6(nterm)
1377  real(dp)::aux1(nx),aux2(nx)
1378  real(dp)::cos1(nx,nterm),cos2(nx,nterm),sin1(nx,nterm),sin2(nx,nterm)
1379  real(dp)::term1(nx,nterm),term2(nx,nterm)
1380 
1381 ! *********************************************************************
1382 
1383 !
1384 !Initialize
1385 !
1386  y_out(:)=0.d0
1387 !
1388 !Get parameters from param array:
1389 !
1390  alpha1(:)=param(1:nterm)
1391  alpha2(:)=param(nterm+1:2*nterm)
1392  alpha3(:)=param(2*nterm+1:3*nterm)
1393  alpha4(:)=param(3*nterm+1:4*nterm)
1394  alpha5(:)=param(4*nterm+1:5*nterm)
1395  alpha6(:)=param(5*nterm+1:6*nterm)
1396 !
1397 !calculate useful quantities
1398 !
1399  do iexp=1,nterm
1400    aux1(:)=-alpha2(iexp)*x(:)**2
1401    term1(:,iexp)=alpha1(iexp)*exp(aux1(:))
1402  end do
1403 !
1404  do iexp=1,nterm
1405    aux1(:)=alpha4(iexp)*x(:)**2
1406    sin1(:,iexp)=sin(aux1(:))
1407 !
1408    aux1(:)=alpha6(iexp)*x(:)**2
1409    sin2(:,iexp)=sin(aux1(:))
1410 !
1411    aux1(:)=alpha4(iexp)*x(:)**2
1412    cos1(:,iexp)=cos(aux1(:))
1413 !
1414    aux1(:)=alpha6(iexp)*x(:)**2
1415    cos2(:,iexp)=cos(aux1(:))
1416  end do
1417 !
1418  do iexp=1,nterm
1419    aux1(:)=alpha3(iexp)*sin1(:,iexp)
1420    aux2(:)=alpha5(iexp)*cos2(:,iexp)
1421    term2(:,iexp)=aux1(:)+aux2(:)
1422    y_out(:)=y_out(:)+term1(:,iexp)*term2(:,iexp)
1423  end do
1424 !
1425 !Calculate derivatives:
1426 !
1427  if(opt==2) then
1428 !
1429 !  alpha1
1430 !
1431    do iexp=1,nterm
1432      aux1(:)=term1(:,iexp)/alpha1(iexp)
1433      aux2(:)=aux1(:)*term2(:,iexp)
1434      deriv(:,iexp)=aux2(:)
1435    end do
1436 !
1437 !  alpha2
1438 !
1439    do iexp=1,nterm
1440      ii=nterm+iexp
1441      aux1(:)=-term1(:,iexp)*term2(:,iexp)
1442      aux2(:)=aux1(:)*x(:)**2
1443      deriv(:,ii)=aux2(:)
1444    end do
1445 !
1446 !  alpha3
1447 !
1448    do iexp=1,nterm
1449      ii=2*nterm+iexp
1450      aux1(:)=term1(:,iexp)*sin1(:,iexp)
1451      deriv(:,ii)=aux1(:)
1452    end do
1453 !
1454 !  alpha4
1455 !
1456    do iexp=1,nterm
1457      ii=3*nterm+iexp
1458      aux1(:)=term1(:,iexp)*alpha3(iexp)
1459      aux2(:)=cos1(:,iexp)*x(:)**2
1460      deriv(:,ii)=aux2(:)*aux1(:)
1461    end do
1462 !
1463 !  alpha5
1464 !
1465    do iexp=1,nterm
1466      ii=4*nterm+iexp
1467      aux1(:)=term1(:,iexp)*cos2(:,iexp)
1468      deriv(:,ii)=aux1(:)
1469    end do
1470 !
1471 !  alpha6
1472 !
1473    do iexp=1,nterm
1474      ii=5*nterm+iexp
1475      aux1(:)=-term1(:,iexp)*alpha5(iexp)
1476      aux2(:)=sin2(:,iexp)*x(:)**2
1477      deriv(:,ii)=aux1(:)*aux2(:)
1478    end do
1479  end if
1480 
1481 end subroutine gaussfit_calc_deriv_c

m_paw_gaussfit/gaussfit_calc_deriv_c2 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_calc_deriv_c2

FUNCTION

  Calculate expressions and derivatives for Gaussians fitting.
   The Gaussians expressions are defined in the comments of "gaussfit_main"

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1219 subroutine gaussfit_calc_deriv_c2(nparam,nterm,nx,opt,param,x,y_out,&
1220 & deriv) ! optional
1221 
1222 
1223 !This section has been created automatically by the script Abilint (TD).
1224 !Do not modify the following lines by hand.
1225 #undef ABI_FUNC
1226 #define ABI_FUNC 'gaussfit_calc_deriv_c2'
1227 !End of the abilint section
1228 
1229  implicit none
1230 
1231 !Arguments -------------------------------
1232  integer,intent(in)::nparam !number of param
1233  integer,intent(in)::nterm  !number of gaussian expressions
1234  integer,intent(in)::nx     !number of point in the x grid
1235  integer,intent(in)::opt    !option:
1236                             !1) calculate only f(x)
1237                             !2) calculate f(x) and its derivatives
1238  real(dp),intent(in)::param(nparam) !parameters
1239  real(dp),intent(in)::x(nx) !xgrid
1240  real(dp),intent(out)::y_out(nx) !f(x)
1241  real(dp),optional,intent(out)::deriv(nx,nparam) !derivatives
1242 
1243 !Local variables-------------------------------
1244  integer::iexp,ii
1245  real(dp)::alpha1(nterm),alpha2(nterm),alpha3(nterm)
1246  real(dp)::alpha4(nterm)
1247  real(dp)::term1(nx,nterm)
1248  real(dp)::sin1(nx,nterm),sin2(nx,nterm),cos1(nx,nterm),cos2(nx,nterm)
1249  real(dp)::aux1(nx),aux2(nx)
1250 
1251 ! *********************************************************************
1252 
1253 !
1254 !Initialize
1255 !
1256  y_out(:)=0.d0
1257 !
1258 !Get param from param array:
1259 !
1260  alpha1(:)=param(1:nterm)
1261  alpha2(:)=param(nterm+1:2*nterm)
1262  alpha3(:)=param(2*nterm+1:3*nterm)
1263  alpha4(:)=param(3*nterm+1:4*nterm)
1264 !
1265 !calculate useful quantities
1266 !
1267 !
1268  do iexp=1,nterm
1269    aux1(:)=alpha2(iexp)*x(:)**2
1270    sin1(:,iexp)=sin(aux1(:))
1271 !
1272    aux1(:)=alpha4(iexp)*x(:)**2
1273    sin2(:,iexp)=sin(aux1(:))
1274 !
1275    aux1(:)=alpha2(iexp)*x(:)**2
1276    cos1(:,iexp)=cos(aux1(:))
1277 !
1278    aux1(:)=alpha4(iexp)*x(:)**2
1279    cos2(:,iexp)=cos(aux1(:))
1280  end do
1281 !
1282  do iexp=1,nterm
1283    aux1(:)=alpha1(iexp)*sin1(:,iexp)
1284    aux2(:)=alpha3(iexp)*cos2(:,iexp)
1285    term1(:,iexp)=aux1(:)+aux2(:)
1286    y_out(:)=y_out(:)+term1(:,iexp)
1287  end do
1288 !
1289 !Calculate derivatives:
1290 !
1291  if(opt==2) then
1292 !
1293 !  alpha1
1294 !
1295    do iexp=1,nterm
1296      deriv(:,iexp)=sin1(:,iexp)
1297    end do
1298 !
1299 !  alpha2
1300 !
1301    do iexp=1,nterm
1302      ii=nterm+iexp
1303      aux1(:)=alpha1(iexp)*cos1(:,iexp)*x(:)**2
1304      deriv(:,ii)=aux1(:)
1305    end do
1306 !
1307 !  alpha3
1308 !
1309    do iexp=1,nterm
1310      ii=2*nterm+iexp
1311      deriv(:,ii)=cos2(:,iexp)
1312    end do
1313 !
1314 !  alpha4
1315 !
1316    do iexp=1,nterm
1317      ii=3*nterm+iexp
1318      aux1(:)=-alpha3(iexp)*sin2(:,iexp)*x(:)**2
1319      deriv(:,ii)=aux1(:)
1320    end do
1321  end if
1322 
1323 end subroutine gaussfit_calc_deriv_c2

m_paw_gaussfit/gaussfit_calc_deriv_c3 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_calc_deriv_c3

FUNCTION

  Calculate expressions and derivatives for Gaussians fitting.
   The Gaussians expressions are defined in the comments of "gaussfit_main"

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1109 subroutine gaussfit_calc_deriv_c3(nparam,nterm,nx,opt,param,x,y_out,&
1110 & deriv) ! optional
1111 
1112 
1113 !This section has been created automatically by the script Abilint (TD).
1114 !Do not modify the following lines by hand.
1115 #undef ABI_FUNC
1116 #define ABI_FUNC 'gaussfit_calc_deriv_c3'
1117 !End of the abilint section
1118 
1119  implicit none
1120 
1121 !Arguments -------------------------------
1122  integer,intent(in)::nparam !number of parameters
1123  integer,intent(in)::nterm !number of gaussian expressions
1124  integer,intent(in)::nx     !number of point in the x grid
1125  integer,intent(in)::opt    !option:
1126                             !1) calculate only f(x)
1127                             !2) calculate f(x) and its derivatives
1128  real(dp),intent(in)::param(nparam) !parameters
1129  real(dp),intent(in)::x(nx) !xgrid
1130  real(dp),intent(out)::y_out(nx) !f(x)
1131  real(dp),optional,intent(out)::deriv(nx,nparam) !derivatives
1132 
1133 !Local variables-------------------------------
1134  integer::iexp,ii
1135  real(dp)::sep
1136  real(dp)::alpha1(nterm),alpha2(nterm),alpha3(nterm)
1137  real(dp)::term1(nx,nterm)
1138  real(dp)::sin1(nx,nterm),cos1(nx,nterm)
1139  real(dp)::aux1(nx),aux2(nx)
1140 
1141 ! *********************************************************************
1142 
1143 !
1144 !Initialize
1145 !
1146  y_out(:)=0.d0
1147 !
1148  sep=1.2d0
1149 !
1150 !Get param from param array:
1151 !
1152  alpha1(:)=param(1:nterm)
1153  alpha2(:)=param(nterm+1:2*nterm)
1154 !
1155  do ii=1,nterm
1156    alpha3(ii)=sep**(ii)
1157  end do
1158 !
1159 !calculate useful quantities
1160 !
1161  do iexp=1,nterm
1162    aux1(:)=alpha3(iexp)*x(:)**2
1163 !
1164    sin1(:,iexp)=sin(aux1(:))
1165    cos1(:,iexp)=cos(aux1(:))
1166  end do
1167 !
1168  do iexp=1,nterm
1169    aux1(:)=alpha1(iexp)*sin1(:,iexp)
1170    aux2(:)=alpha2(iexp)*cos1(:,iexp)
1171    term1(:,iexp)=aux1(:)+aux2(:)
1172    y_out(:)=y_out(:)+term1(:,iexp)
1173  end do
1174 !
1175 !Calculate derivatives:
1176 !
1177  if(opt==2) then
1178 !
1179 !  alpha1
1180 !
1181    do iexp=1,nterm
1182      deriv(:,iexp)=sin1(:,iexp)
1183    end do
1184 !
1185 !  alpha2
1186 !
1187    do iexp=1,nterm
1188      ii=nterm+iexp
1189      deriv(:,ii)=cos1(:,iexp)
1190    end do
1191  end if
1192 
1193 end subroutine gaussfit_calc_deriv_c3

m_paw_gaussfit/gaussfit_calc_deriv_c4 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_calc_deriv_c4

FUNCTION

  Calculate expressions and derivatives for Gaussians fitting.
   The Gaussians expressions are defined in the comments of "gaussfit_main"

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1507 subroutine gaussfit_calc_deriv_c4(nparam,nterm,nx,opt,param,x,y_out,&
1508 & deriv) ! optional
1509 
1510 
1511 !This section has been created automatically by the script Abilint (TD).
1512 !Do not modify the following lines by hand.
1513 #undef ABI_FUNC
1514 #define ABI_FUNC 'gaussfit_calc_deriv_c4'
1515 !End of the abilint section
1516 
1517  implicit none
1518 
1519 !Arguments -------------------------------
1520  integer,intent(in)::nparam !number of parameters
1521  integer,intent(in)::nterm !number of gaussian expressions
1522  integer,intent(in)::nx     !number of point in the x grid
1523  integer,intent(in)::opt    !option:
1524                             !1) calculate only f(x)
1525                             !2) calculate f(x) and its derivatives
1526  real(dp),intent(in)::param(nparam) !parameters
1527  real(dp),intent(in)::x(nx) !xgrid
1528  real(dp),intent(out)::y_out(nx) !f(x)
1529  real(dp),optional,intent(out)::deriv(nx,nparam) !derivatives
1530 
1531 !Local variables-------------------------------
1532  integer::iexp,ii
1533  real(dp)::raux,sep
1534  real(dp)::alpha1(nterm),alpha2(nterm),alpha3(nterm)
1535  real(dp)::alpha4(nterm),alpha5(nterm)
1536  real(dp)::aux1(nx),aux2(nx)
1537  real(dp)::cos1(nx,nterm),sin1(nx,nterm)
1538  real(dp)::term1(nx,nterm),term2(nx,nterm)
1539 
1540 ! *********************************************************************
1541 
1542 !
1543 !Initialize
1544 !
1545  sep=1.1d0
1546  y_out(:)=0.d0
1547 
1548 !Get parameters from param array:
1549 !
1550  alpha1(:)=param(1:nterm)
1551  alpha2(:)=param(nterm+1:2*nterm)
1552  alpha3(:)=param(2*nterm+1:3*nterm)
1553  alpha4(:)=param(3*nterm+1:4*nterm)
1554 !
1555 !
1556  raux=(2.d0*pi)/real(nterm,dp)
1557  do ii=1,nterm
1558    alpha5(ii)=sep**(ii)
1559 !  alpha5(ii)=raux*real(ii-1,dp)
1560  end do
1561 !
1562 !calculate useful quantities
1563 !
1564  do iexp=1,nterm
1565    aux1(:)=-alpha2(iexp)*x(:)**2
1566    term1(:,iexp)=alpha1(iexp)*exp(aux1(:))
1567  end do
1568 !
1569  do iexp=1,nterm
1570    aux1(:)=alpha5(iexp)*x(:)**2
1571 !
1572    sin1(:,iexp)=sin(aux1(:))
1573    cos1(:,iexp)=cos(aux1(:))
1574  end do
1575 !
1576  do iexp=1,nterm
1577    aux1(:)=alpha3(iexp)*sin1(:,iexp)
1578    aux2(:)=alpha4(iexp)*cos1(:,iexp)
1579    term2(:,iexp)=aux1(:)+aux2(:)
1580    y_out(:)=y_out(:)+term1(:,iexp)*term2(:,iexp)
1581  end do
1582 !
1583 !Calculate derivatives:
1584 !
1585  if(opt==2) then
1586 !
1587 !  alpha1
1588 !
1589    do iexp=1,nterm
1590      aux1(:)=term1(:,iexp)/alpha1(iexp)
1591      aux2(:)=aux1(:)*term2(:,iexp)
1592      deriv(:,iexp)=aux2(:)
1593    end do
1594 !
1595 !  alpha2
1596 !
1597    do iexp=1,nterm
1598      ii=nterm+iexp
1599      aux1(:)=-term1(:,iexp)*term2(:,iexp)
1600      aux2(:)=aux1(:)*x(:)**2
1601      deriv(:,ii)=aux2(:)
1602    end do
1603 !
1604 !  alpha3
1605 !
1606    do iexp=1,nterm
1607      ii=2*nterm+iexp
1608      aux1(:)=term1(:,iexp)*sin1(:,iexp)
1609      deriv(:,ii)=aux1(:)
1610    end do
1611 !
1612 !  alpha4
1613 !
1614    do iexp=1,nterm
1615      ii=3*nterm+iexp
1616      aux1(:)=term1(:,iexp)*cos1(:,iexp)
1617      deriv(:,ii)=aux1(:)
1618    end do
1619  end if
1620 
1621 end subroutine gaussfit_calc_deriv_c4

m_paw_gaussfit/gaussfit_calc_deriv_r [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_calc_deriv_r

FUNCTION

  Calculate derivatives for Gaussians
   Only relevant for fitting Gaussians algorithm.
   The Gaussians expressions are defined in the comments of "gaussfit_main"

INPUTS

OUTPUT

PARENTS

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

 988 subroutine gaussfit_calc_deriv_r(nterm,nparam,nx,opt,param,x,y_out,&
 989 & deriv) ! optional
 990 
 991 
 992 !This section has been created automatically by the script Abilint (TD).
 993 !Do not modify the following lines by hand.
 994 #undef ABI_FUNC
 995 #define ABI_FUNC 'gaussfit_calc_deriv_r'
 996 !End of the abilint section
 997 
 998  implicit none
 999 
1000 !Arguments -------------------------------
1001  integer,intent(in)::nx     !number of point in the x grid
1002  integer,intent(in)::nparam !number of parameters
1003  integer,intent(in)::nterm !number of gaussian expressions
1004  integer,intent(in)::opt    !option:
1005                             !1) calculate only f(x)
1006                             !2) calculate f(x) and its derivatives
1007  real(dp),intent(in)::param(nparam) !parameters
1008  real(dp),intent(in)::x(nx) !xgrid
1009  real(dp),intent(out)::y_out(nx) !f(x)
1010  real(dp),optional,intent(out)::deriv(nx,nparam) !derivatives
1011 
1012 !Local variables-------------------------------
1013  integer::iexp,ii
1014  real(dp)::alpha1(nterm),alpha2(nterm),alpha3(nterm)
1015  real(dp)::term1(nx,nterm)
1016  real(dp)::aux1(nx)
1017  !real(dp)::step
1018 
1019 ! *********************************************************************
1020 
1021 !
1022 !Initialize
1023 !
1024  y_out(:)=0.d0
1025 !
1026 !Get parameters from parameters array:
1027 !
1028  alpha1(:)=param(1:nterm)
1029  alpha2(:)=param(nterm+1:2*nterm)
1030  alpha3(:)=param(2*nterm+1:3*nterm)
1031 !
1032 !alpha3
1033 !set to constant values of x
1034 !step=rpaw/real(nterm,dp)
1035 !do ii=1,nterm
1036 !raux=step*real(ii,dp)
1037 !alpha3(ii)=raux
1038 !end do
1039 !
1040 !
1041 !
1042 !calculate useful quantities
1043 !
1044  do iexp=1,nterm
1045    aux1(:)=-alpha2(iexp)*(x(:)-alpha3(iexp))**2
1046    term1(:,iexp)=alpha1(iexp)*exp(aux1(:))
1047  end do
1048 !
1049  do iexp=1,nterm
1050    y_out(:)=y_out(:)+term1(:,iexp)
1051  end do
1052 !
1053 !Calculate derivatives:
1054 !
1055  if(opt==2) then
1056 !
1057 !  alpha1
1058 !
1059    do iexp=1,nterm
1060      aux1(:)=term1(:,iexp)/alpha1(iexp)
1061      deriv(:,iexp)=aux1(:)
1062    end do
1063 !
1064 !  alpha2
1065 !
1066    do iexp=1,nterm
1067      ii=nterm+iexp
1068      aux1(:)=-term1(:,iexp)*(x(:)-alpha3(iexp))
1069      deriv(:,ii)=aux1(:)
1070      deriv(:,ii)=0.1d0
1071    end do
1072 !
1073 !  alpha3
1074 !
1075    do iexp=1,nterm
1076      ii=2*nterm+iexp
1077      aux1(:)=term1(:,iexp)*2.d0*alpha2(iexp)
1078      aux1(:)=aux1(:)*(x(:)-alpha3(iexp))
1079      deriv(:,ii)=aux1(:)
1080    end do
1081  end if
1082 
1083 end subroutine gaussfit_calc_deriv_r

m_paw_gaussfit/gaussfit_chisq_alpha_beta [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_chisq_alpha_beta

FUNCTION

  Finds chisq, alpha and beta parameters for LSF using the Levenberg-Marquardt algorithm.

COPYRIGHT

  Copyright (C) 2011-2018 ABINIT group (T. Rangel)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .
  The original Levemberg Marquardt routines were written by Armando Sole
  These were modified for the ARPUS spectra in the BigDFT code by A. Mirone.
  These were re-writen in Fortran and further modified in ABINIT for our particular needs.

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1847 subroutine gaussfit_chisq_alpha_beta(alpha,beta,chisq,&
1848 & nparam,nterm,nx,option,parameters,x,y)
1849 
1850 
1851 !This section has been created automatically by the script Abilint (TD).
1852 !Do not modify the following lines by hand.
1853 #undef ABI_FUNC
1854 #define ABI_FUNC 'gaussfit_chisq_alpha_beta'
1855 !End of the abilint section
1856 
1857  implicit none
1858 
1859 !Arguments -------------------------------
1860  integer,intent(in)::nparam,nterm,nx
1861  integer,intent(in)::option
1862  real(dp),intent(out)::chisq
1863  real(dp),intent(in)::parameters(nparam),x(nx),y(nx)
1864  real(dp),intent(out)::alpha(nparam,nparam),beta(nparam)
1865 
1866 !Local variables-------------------------------
1867  integer::ii,jj,kk
1868  real(dp)::deltax,help1
1869  !arrays
1870  real(dp)::deltay(nx),deriv(nx,nparam),derivi(nx)
1871  real(dp)::yfit(nx)
1872  real(dp)::help0(nx),help2(nx),help3(nparam)
1873 
1874 ! *********************************************************************
1875 
1876  deltax=x(2)-x(1) !we assume a linear grid
1877 !
1878  if(option==1) then
1879    call gaussfit_calc_deriv_c2(nparam,nterm,nx,2,parameters,x,yfit,deriv)
1880  elseif(option==2) then
1881    call gaussfit_calc_deriv_c(nparam,nterm,nx,2,parameters,x,yfit,deriv)
1882  elseif(option==3) then
1883    call gaussfit_calc_deriv_c3(nparam,nterm,nx,2,parameters,x,yfit,deriv)
1884  elseif(option==4) then
1885    call gaussfit_calc_deriv_c4(nparam,nterm,nx,2,parameters,x,yfit,deriv)
1886  end if
1887  deltay=y-yfit
1888  help0=deltay
1889 !
1890  do ii=1,nparam
1891    derivi(:)=deriv(:,ii)
1892    help1=0.d0
1893    do jj=1,nx
1894      help1=help1+help0(jj)*derivi(jj)
1895    end do
1896    beta(ii)=help1
1897 !  help1 = innerproduct(deriv,weight*derivi)
1898 !  below I use help3 instead for the array dimenstions
1899    help3=0.d0
1900    do kk=1,nparam
1901      do jj=1,nx
1902        help3(kk)=help3(kk)+deriv(jj,kk)*derivi(jj)
1903      end do
1904    end do
1905 !  !
1906    alpha(:,ii)=help3(:)
1907  end do
1908 !
1909  help2(:)=help0(:)*deltay(:)
1910  chisq=sum(help2)
1911  chisq=chisq*deltax
1912 
1913 end subroutine gaussfit_chisq_alpha_beta

m_paw_gaussfit/gaussfit_constrains_init [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_constrains_init

FUNCTION

  Initialise constrains for LSF.
  It will constrain the Gaussians width
  It will also constraint the Delta use in the LSF algorithm, to jump slowly at each step.

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2314 subroutine gaussfit_constrains_init(cons1,cons2,limit,nparam,nterm,nx,option,rpaw,y)
2315 
2316 
2317 !This section has been created automatically by the script Abilint (TD).
2318 !Do not modify the following lines by hand.
2319 #undef ABI_FUNC
2320 #define ABI_FUNC 'gaussfit_constrains_init'
2321 !End of the abilint section
2322 
2323  implicit none
2324 
2325 !Arguments -------------------------------
2326  integer,intent(in)::nterm,option,nparam,nx
2327  integer,intent(out)::cons2(nparam)
2328  real(dp),intent(in)::rpaw
2329  real(dp),intent(in)::y(nx)
2330  real(dp),intent(out)::cons1(nparam),limit(nparam)
2331 
2332 !Local variables-------------------------------
2333  integer :: ix
2334  real(dp)::rc,a1,mm,raux
2335 
2336 ! *********************************************************************
2337 
2338 !
2339 !DEFAULT: no weight
2340  cons1(:)=1.d0
2341  limit(:)=0.d0
2342  cons2=1
2343 !
2344  if(option==4) then
2345      cons1(1:nterm)=0.2d0
2346      cons1(nterm+1:nterm*2)=0.3d0
2347  end if
2348 !
2349  if(option==4) then
2350 !  parameters
2351 
2352 !  a1=maxval( y(:),nx)/real(nterm,dp)
2353 !  maxval gives problems in some architectures:
2354    a1=-9999999
2355    do ix=1,nx
2356      if(a1<y(ix)) a1=y(ix)
2357    end do
2358    a1=a1/real(nterm,dp)
2359 
2360    mm=0.01
2361 !
2362    rc=1.7d0*rpaw
2363    raux=log(a1/mm)/rc**2
2364 !
2365 !  Constraint exponential of gaussians to be positive (multiplied by -1),
2366 !  so that it decays to zero.
2367 !  Constraint as well its value, so that it does not get too big
2368 !  and it decays soon,
2369 !  This prevents that a gaussian grows at a very large x value.
2370    cons2(nterm+1:nterm*2)=restricted_and_positive
2371    limit(nterm+1:nterm*2)=raux
2372  end if
2373 
2374 end subroutine gaussfit_constrains_init

m_paw_gaussfit/gaussfit_fit [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_fit

FUNCTION

  Fits a given input function f(r) to a sum of gaussians

INPUTS

  chisq= It measures how good is the fitting.
   It is defined here as sum_i^N_i f(x_i)-y(x_i)/N_i
  constrains= constraints for Gaussians
  limit(nparam)= it limits the widths of Gaussians
  maxiter=maximum number of iterations
  nparam= number of parameters (a constant times nterm)
         if(option==1)nparam=nterm*4
         if(option==2)nparam=nterm*6
         if(option==3)nparam=nterm*2
         if(option==4)nparam=nterm*4
  nterm= number of Gaussians
  nx=number of points along the x axis
  option=1 fit to a1 cos(a2 x^2)+ a3 sin( a4 x^2)
         2 fit to a1 exp(-a2 x^2)*(a3 cos (a4 x^2) + a5 sin (a6 x^2) )
         3 fit to a1 cos (k x^2) + a2 sin (k x^2)
         4 fit to a1 exp(-a2 x^2)* (a3 cos(k x^2)+ a4 sin (k x^2))
  outfile= filename for output (only written if verbosity>1)
  verbosity= controls output volume
  weight(nparam)= weights for the fitting procedure
  x(nx)= points along the x axis
  y(nx)= function to be fitted
  rpaw ,optional= paw radius

OUTPUT

 y_out(nx)= fitted function

SIDE EFFECTS

 if(verbosity>1) output files are written with y(x) and y_out(x)

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

896 subroutine gaussfit_fit(chisq,constrains,&
897 & limit,maxiter,nparam,nterm,nx,option,outfile,param,&
898 & verbosity,weight,x,y,y_out)
899 
900 
901 !This section has been created automatically by the script Abilint (TD).
902 !Do not modify the following lines by hand.
903 #undef ABI_FUNC
904 #define ABI_FUNC 'gaussfit_fit'
905 !End of the abilint section
906 
907  implicit none
908 
909 !Arguments ------------------------------------
910  integer, intent(in) :: maxiter,nparam
911  integer,intent(in)  :: nterm,nx,option,verbosity
912  !real(dp),optional,intent(in)::rpaw
913  !arrays
914  integer,intent(in)::constrains(nparam)
915  real(dp),intent(in)::limit(nparam),weight(nparam)
916  real(dp),intent(in)::x(nx),y(nx)
917  real(dp),intent(inout)::param(nparam)
918  real(dp),intent(out)::chisq,y_out(nx)
919  character(80),intent(in)::outfile
920 
921 !Local variables ------------------------------
922  integer, parameter :: wfn_unit=1007
923  integer::ix
924  real(dp)::rerror
925  real(dp),allocatable::sy(:)
926 
927 ! *************************************************************************
928 
929  LIBPAW_ALLOCATE(sy,(nx))
930 
931  sy(:)=1.0d0
932 
933  call gaussfit_rlsf(&
934 & chisq,constrains,limit,maxiter,&
935 & nterm,nparam,nx,option,param(1:nparam),&
936 & verbosity,weight,x,y)
937 !
938  if(verbosity>=1) then
939    if(option==1) then
940      call gaussfit_calc_deriv_c2(nparam,nterm,nx,1,param,x,y_out)
941    elseif(option==2) then
942      call gaussfit_calc_deriv_c(nparam,nterm,nx,1,param,x,y_out)
943    elseif(option==3) then
944      call gaussfit_calc_deriv_c3(nparam,nterm,nx,1,param,x,y_out)
945    elseif(option==4) then
946      call gaussfit_calc_deriv_c4(nparam,nterm,nx,1,param,x,y_out)
947    end if
948 !
949 !
950    open(wfn_unit,file=outfile,form='formatted',status='unknown')
951 !  per_error=0.d0
952    do ix=1, nx
953      rerror=abs(y(ix)-y_out(ix))
954      write(wfn_unit,'(6(e20.12,1x))')x(ix),y(ix),y_out(ix),rerror
955    end do
956    close(wfn_unit)
957 
958  end if
959 
960  LIBPAW_DEALLOCATE(sy)
961 
962 end subroutine gaussfit_fit

m_paw_gaussfit/gaussfit_main [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_main

FUNCTION

  Fits a given input function f(r) to a sum of gaussians

INPUTS

  nterm_bounds= sets the minimum and maximum number of terms to be taken into account.
  mparam= maximum number of parameters
         if(option==1)mparam=nterm_bounds(2)*4
         if(option==2)mparam=nterm_bounds(2)*6
         if(option==3)mparam=nterm_bounds(2)*2
         if(option==4)mparam=nterm_bounds(2)*4
  nr= number of real space points
  pawrad= pawrad type
  option=1 fit to a1 cos(a2 x^2)+ a3 sin( a4 x^2)
         2 fit to a1 exp(-a2 x^2)*(a3 cos (a4 x^2) + a5 sin (a6 x^2) )
         3 fit to a1 cos (k x^2) + a2 sin (k x^2)
         4 fit to a1 exp(-a2 x^2)* (a3 cos(k x^2)+ a4 sin (k x^2))
  Given these definitions, the number of complex gaussians are:
    ngauss=4*nterm (for option=1,2)
    ngauss=2*nterm (for option=3,4)
  outfile= filename to write out fitted functions.
  rpaw=paw radius
  y(nr)= function to fit

OUTPUT

 nparam_out= number of parameters found.
 param_out(nparam_out)= parameters (coefficients and factors of complex gaussians).

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

115  subroutine gaussfit_main(mparam,nparam_out,nterm_bounds,nr,&
116 &           param_out,pawrad,option,outfile,rpaw,y,comm_mpi)
117 
118 
119 !This section has been created automatically by the script Abilint (TD).
120 !Do not modify the following lines by hand.
121 #undef ABI_FUNC
122 #define ABI_FUNC 'gaussfit_main'
123 !End of the abilint section
124 
125  implicit none
126 
127 !Arguments ------------------------------------
128  integer,intent(in)::mparam,nr,nterm_bounds(2)
129  integer,intent(in)::option
130  integer,intent(in),optional:: comm_mpi
131  real(dp),intent(in)::rpaw
132  real(dp),intent(inout)::y(nr)
133  character(80),intent(in)::outfile
134  type(pawrad_type),intent(in) :: pawrad
135  integer,intent(out)::nparam_out
136  real(dp),intent(out)::param_out(mparam)
137 
138 !Local variables-------------------------------
139 !scalars
140  logical,parameter::modify_y=.false. !used only for plotting purposes
141  integer :: ichisq,ierr,ii,jj
142  integer :: master,me
143  integer :: maxiter,minterm,my_chisq_size,counts_all
144  integer :: ngauss,nparam,nproc,nterm
145  integer :: verbosity
146  real(dp) :: chisq,chisq_min
147 !real(dp) :: T1,T2 !uncomment for timming
148  !arrays
149  integer::constrains(mparam)
150  integer::proc_dist(nterm_bounds(1):nterm_bounds(2))
151  integer,allocatable::counts(:),disp(:),map_nterm(:)
152  real(dp)::limit(mparam),param_tmp(mparam),weight(mparam)
153  real(dp),allocatable::chisq_array(:),recv_buf(:),send_buf(:)
154  real(dp),allocatable::y_out(:)
155  character(len=500) :: msg
156 
157 ! *************************************************************************
158 
159 !initialize variables
160  maxiter=200
161 !
162 !initialize mpi quantities:
163  master=0; me=0; nproc=1; proc_dist=1;
164  if(present(comm_mpi)) then
165    me=xmpi_comm_rank(comm_mpi)
166    nproc=xmpi_comm_size(comm_mpi)
167  end if
168  if(nproc>1) then
169 !  Find distribution (master)
170    if(me==master) then
171      call gaussfit_mpi_main(nproc,nterm_bounds,proc_dist)
172    end if
173 !  send distribution to all processors
174    call xmpi_bcast(proc_dist(nterm_bounds(1):nterm_bounds(2)),&
175 &    master,comm_mpi,ierr)
176  end if
177 !Set size of chisq treated by each proc
178  my_chisq_size=nterm_bounds(2)-nterm_bounds(1)+1 !all terms
179  if(nproc>1 .and. .not. me==master) then
180    do nterm=nterm_bounds(1),nterm_bounds(2)
181      if(.not. proc_dist(nterm)==me+1) cycle
182      my_chisq_size=my_chisq_size+1
183    end do
184  end if
185 
186 !
187 !Allocate objects
188 !
189  LIBPAW_ALLOCATE(y_out,(nr))
190  LIBPAW_ALLOCATE(chisq_array,(my_chisq_size))
191  if(master==me ) then
192    LIBPAW_BOUND1_ALLOCATE(map_nterm,BOUNDS(nterm_bounds(1),nterm_bounds(2)))
193    jj=1
194    do ii=1,nproc
195      do nterm=nterm_bounds(1),nterm_bounds(2)
196        if(proc_dist(nterm)==ii) then
197          map_nterm(nterm)=jj
198          jj=jj+1
199        end if
200      end do
201    end do
202  end if
203 !
204 !fill with zeros
205 !
206  chisq_array=zero
207  nparam_out=0
208  y_out=0.d0
209  verbosity=1 !print the minimum at the terminal
210 !
211  ichisq=0
212  do nterm=nterm_bounds(1),nterm_bounds(2)
213 !  mpi distribution
214    if(.not. proc_dist(nterm)==me+1) cycle
215    ichisq=ichisq+1
216 
217 !   call CPU_TIME(T1)
218 
219    if(option==1) nparam=nterm*4
220    if(option==2) nparam=nterm*6
221    if(option==3) nparam=nterm*2
222    if(option==4) nparam=nterm*4
223 !  set initial guess
224 !   if(option==1) then
225 !     call gaussfit_set_param3(nterm,nparam,param_tmp(1:nparam),sep(ii))
226 !   elseif(option==2) then
227 !     call gaussfit_set_param1(nterm,nparam,nr,&
228 !&     param_tmp(1:nparam),sep(ii),pawrad%rad(1:nr),y)
229    if(option==3) then
230      call gaussfit_set_param4(nparam,param_tmp(1:nparam))
231    elseif(option==4) then
232      call gaussfit_set_param5(nterm,nparam,nr,&
233 &     param_tmp(1:nparam),rpaw,y)
234    end if
235 !
236 !
237    call gaussfit_constrains_init(weight(1:nparam),constrains(1:nparam),&
238 &   limit(1:nparam),nparam,nterm,nr,option,rpaw,y)
239 !
240    call gaussfit_fit(chisq,constrains(1:nparam),&
241 &   limit(1:nparam),maxiter,nparam,nterm,nr,option,outfile,param_tmp,&
242 &   verbosity,weight(1:nparam),pawrad%rad(1:nr),y,y_out)
243 
244 !  if there was an error, set chisq to very high
245 !  if there is an NaN, for instance:
246    if(abs(chisq+1.d0)<tol8) chisq=99999
247    if(abs(chisq)==chisq*chisq) chisq=99999
248    if(chisq .ne. chisq) chisq=99999
249 !
250    chisq_array(ichisq)=chisq
251 
252 !   call CPU_TIME(T2)
253 !   print *, 'Time for fit ', T2-T1, 'seconds.'
254 
255  end do !nterm
256 
257 !mpicast results
258 !send distribution to master
259  if(nproc>1) then
260 !  Prepare communications:
261    LIBPAW_ALLOCATE(counts,(nproc))
262    counts(:)=0
263    do nterm=nterm_bounds(1),nterm_bounds(2)
264      counts(proc_dist(nterm))=counts(proc_dist(nterm))+1
265    end do
266    counts_all=sum(counts)
267    LIBPAW_ALLOCATE(send_buf,(counts(me+1)))
268    send_buf(:)=chisq_array(1:counts(me+1))
269    if(me==master) then
270      LIBPAW_ALLOCATE(recv_buf,(counts_all))
271    else
272      LIBPAW_ALLOCATE(recv_buf,(1))
273    end if
274    LIBPAW_ALLOCATE(disp,(nproc))
275    disp(1)=0
276    do ii=2,nproc
277      disp(ii)=disp(ii-1)+counts(ii-1)
278    end do
279 !  communicate all info to master
280    call xmpi_gatherv(send_buf,counts(me+1),recv_buf,&
281 &    counts,disp,master,comm_mpi,ierr)
282 !  fill in chisq_array with all received info:
283    if(master==me) then
284      do ii=1,counts_all
285        chisq_array(ii)=recv_buf(ii)
286      end do
287    end if
288 !  Deallocate MPI arrays:
289    LIBPAW_DEALLOCATE(recv_buf)
290    LIBPAW_DEALLOCATE(counts)
291    LIBPAW_DEALLOCATE(disp)
292    LIBPAW_DEALLOCATE(send_buf)
293  end if
294 
295 !Print out info:
296  if(me==master) then
297    write(msg,'(3a)')'Preliminary results (with only 200 iter.):',ch10,'   ngauss    chisq'
298    call wrtout(std_out,msg,'COLL')
299    do nterm=nterm_bounds(1),nterm_bounds(2)
300      if(option==1) ngauss=nterm*4
301      if(option==2) ngauss=nterm*4
302      if(option==3) ngauss=nterm*2
303      if(option==4) ngauss=nterm*2
304      write(msg,'(i4,2x,e13.6,1x)')ngauss,&
305 &     chisq_array(map_nterm(nterm))
306      call wrtout(std_out,msg,'COLL')
307    end do
308  end if
309 
310 !get minterm for best accuracy:
311  if(me==master) then
312    chisq_min=999999999
313    do nterm=nterm_bounds(1),nterm_bounds(2)
314      if(chisq_array(map_nterm(nterm))<chisq_min) then
315        chisq_min=chisq_array(map_nterm(nterm))
316        minterm=nterm
317      end if
318    end do
319 
320 !run again with the best parameters
321    nterm=minterm
322    if(option==1)nparam=4*nterm
323    if(option==2)nparam=6*nterm
324    if(option==3)nparam=2*nterm
325    if(option==4)nparam=4*nterm
326 
327 !  set initial guess
328    if (option==3) then
329      call gaussfit_set_param4(nparam,param_tmp(1:nparam))
330    elseif (option==4) then
331      call gaussfit_set_param5(nterm,nparam,nr,&
332 &     param_tmp(1:nparam),rpaw,y)
333    end if
334 !
335    call gaussfit_constrains_init(weight(1:nparam),constrains(1:nparam),&
336 &   limit(1:nparam),nparam,nterm,nr,option,rpaw,y)
337 !
338    verbosity=1;
339    maxiter=1000 !this time we do more iterations
340    call gaussfit_fit(chisq,constrains(1:nparam),&
341 &   limit(1:nparam),maxiter,nparam,nterm,nr,option,outfile,param_tmp,&
342 &   verbosity,weight(1:nparam),pawrad%rad(1:nr),y,y_out)
343 
344 !  Write out best solution
345    write(msg,'(3a)')"Best solution (with more iterations):",ch10,"   ngauss    chisq"
346    call wrtout(std_out,msg,'COLL')
347    if(option==1) ngauss=nterm*4
348    if(option==2) ngauss=nterm*4
349    if(option==3) ngauss=nterm*2
350    if(option==4) ngauss=nterm*2
351    write(msg,'(i4,2x,e13.6,1x)')ngauss,chisq
352    call wrtout(std_out,msg,'COLL')
353  end if
354 
355 !Fill output variables
356 !and communicate results to all procs:
357  if(option==1) then
358    nparam_out=minterm*4
359  elseif (option==2) then
360    nparam_out=minterm*6
361  elseif (option==3) then
362    nparam_out=minterm*2
363  elseif (option==4) then
364    nparam_out=minterm*4
365  end if
366 
367 !communicate
368  if(nproc>1) then
369    call xmpi_bcast(nparam_out,master,comm_mpi,ierr)
370    call xmpi_bcast(param_tmp(1:nparam_out),master,comm_mpi,ierr)
371  end if !nproc>1
372 
373  param_out(:)=param_tmp
374 
375  if(modify_y) then
376 !   call xmpi_scatterv(y_out,nr,mpi_displ,y_out,nr,0,comm_mpi,ierr)
377    y=y_out !at output modify y for the fitted y
378  end if
379 
380  LIBPAW_DEALLOCATE(y_out)
381  LIBPAW_DEALLOCATE(chisq_array)
382  if(me==master) then
383    LIBPAW_DEALLOCATE(map_nterm)
384  end if
385 
386 end subroutine gaussfit_main

m_paw_gaussfit/gaussfit_mpi_add_item [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_add_item

FUNCTION

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

519  subroutine gaussfit_mpi_add_item(iterm,pload)
520 
521 
522 !This section has been created automatically by the script Abilint (TD).
523 !Do not modify the following lines by hand.
524 #undef ABI_FUNC
525 #define ABI_FUNC 'gaussfit_mpi_add_item'
526 !End of the abilint section
527 
528  implicit none
529 
530 !Arguments ------------------------------------
531  integer,intent(in)::iterm
532  integer,intent(inout)::pload
533 
534 !Local variables ------------------------------
535  integer:: f_i
536 
537 !************************************************************************
538 
539  call gaussfit_mpi_set_weight(f_i,iterm)
540  pload=pload+f_i
541 
542  end subroutine gaussfit_mpi_add_item

m_paw_gaussfit/gaussfit_mpi_assign [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_assign

FUNCTION

  Set task to a processor

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

697  subroutine gaussfit_mpi_assign(iterm,nproc,nterm_bounds,&
698 & proc_dist,proc_load)
699 
700 
701 !This section has been created automatically by the script Abilint (TD).
702 !Do not modify the following lines by hand.
703 #undef ABI_FUNC
704 #define ABI_FUNC 'gaussfit_mpi_assign'
705 !End of the abilint section
706 
707  implicit none
708 
709 !Arguments ------------------------------------
710  integer,intent(in)::iterm,nproc,nterm_bounds(2)
711  integer,intent(inout)::proc_dist(nterm_bounds(1):nterm_bounds(2)),proc_load(nproc)
712 
713 !Local variables ------------------------------
714  integer:: iproc,jproc,dev
715  integer:: deviation(nproc),mindev
716  character(len=100) :: msg
717 
718 !************************************************************************
719 
720  do iproc=1,nproc
721   !add this term to iproc
722   call gaussfit_mpi_add_item(iterm,proc_load(iproc))
723   !calculate the deviation for this configuration
724   call gaussfit_mpi_calc_deviation(dev,nproc,proc_load)
725   deviation(iproc)=dev
726   !remove this term from iproc
727   call gaussfit_mpi_remove_item(iterm,proc_load(iproc))
728  end do
729 
730 !assign to jproc, the proc with minimal deviation above:
731  jproc=-1; mindev=999999999
732  do iproc=1,nproc
733    if(deviation(iproc)<mindev) then
734      mindev=deviation(iproc)
735      jproc=iproc
736    end if
737  end do
738  if(jproc==-1) then
739 !  One should not get here!
740    msg = 'error in accomodate_mpi'
741    MSG_BUG(msg)
742  end if
743 
744 !assign this term for jproc
745  proc_dist(iterm)=jproc
746  call gaussfit_mpi_add_item(iterm,proc_load(jproc))
747 
748  end subroutine gaussfit_mpi_assign

m_paw_gaussfit/gaussfit_mpi_calc_deviation [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_calc_deviation

FUNCTION

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

566  subroutine gaussfit_mpi_calc_deviation(deviation,nproc,proc_load)
567 
568 
569 !This section has been created automatically by the script Abilint (TD).
570 !Do not modify the following lines by hand.
571 #undef ABI_FUNC
572 #define ABI_FUNC 'gaussfit_mpi_calc_deviation'
573 !End of the abilint section
574 
575  implicit none
576 
577 !Arguments ------------------------------------
578  integer,intent(in)::nproc
579  integer,intent(in)::proc_load(nproc)
580  integer,intent(out)::deviation
581 
582 !Local variables ------------------------------
583  integer:: jproc,kproc,kload,jload
584 
585 !************************************************************************
586 
587 ! deviation=0
588 ! do jproc=1,nproc
589 !   deviation=deviation+abs(proc_load(jproc)-ideal)
590 ! end do
591 
592  deviation=0
593  do jproc=1,nproc
594    jload=proc_load(jproc)
595    do kproc=1,jproc
596      kload=proc_load(kproc)
597      deviation=deviation+abs(kload-jload)
598    end do
599  end do
600 
601  end subroutine gaussfit_mpi_calc_deviation

m_paw_gaussfit/gaussfit_mpi_main [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_main

FUNCTION

  Set charge for each processor

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

773  subroutine gaussfit_mpi_main(nproc,nterm_bounds,proc_dist)
774 
775 
776 !This section has been created automatically by the script Abilint (TD).
777 !Do not modify the following lines by hand.
778 #undef ABI_FUNC
779 #define ABI_FUNC 'gaussfit_mpi_main'
780 !End of the abilint section
781 
782  implicit none
783 
784 !Arguments ------------------------------------
785  integer,intent(in)::nproc,nterm_bounds(2)
786  integer,intent(out)::proc_dist(nterm_bounds(1):nterm_bounds(2))
787 
788 !Local variables ------------------------------
789  integer:: dev1,dev2,ii
790  integer:: iproc,iterm,jterm,ngauss,weight
791  integer:: proc_load(nproc)
792  character(len=500) :: msg
793 
794 !************************************************************************
795 
796  proc_load=0; proc_dist=0 !initializations
797 
798 !1) get a first-trial distribution:
799  do iterm=nterm_bounds(2),nterm_bounds(1),-1
800      call gaussfit_mpi_assign(iterm,nproc,nterm_bounds,proc_dist,proc_load)
801  end do
802 
803 !Do the following 20 times
804  do ii=1,20
805 !  Calculate initial state
806    call gaussfit_mpi_calc_deviation(dev1,nproc,proc_load)
807 !  Try to swap tasks between two processors:
808    do iterm=nterm_bounds(2),nterm_bounds(1),-1
809      do jterm=nterm_bounds(2),nterm_bounds(1),-1
810        call gaussfit_mpi_swap(iterm,jterm,&
811 &       nproc,nterm_bounds,proc_dist,proc_load)
812      end do
813    end do
814 !!  Try to reassign tasks to different processors
815    do iterm=nterm_bounds(2),nterm_bounds(1),-1
816      iproc=proc_dist(iterm)
817 !    Remove this job from this node
818      call gaussfit_mpi_remove_item(iterm,proc_load(iproc))
819 !    Accomodate this again:
820      call gaussfit_mpi_assign(iterm,nproc,nterm_bounds,proc_dist,proc_load)
821    end do
822 !  Calculate final state
823    call gaussfit_mpi_calc_deviation(dev2,nproc,proc_load)
824 !  If final state equals initial state, exit:
825    if(dev2 == dev1) exit
826 !   write(*,'(a)')'Deviation: ',dev2
827  end do
828 
829 !Write down distribution:
830  write(msg,'(3a)') 'MPI distribution',ch10,'N. gauss, iproc, weight '
831  call wrtout(std_out,msg,'COLL')
832  do iterm=nterm_bounds(2),nterm_bounds(1),-1
833      ngauss=iterm*2
834      call gaussfit_mpi_set_weight(weight,iterm)
835      write(msg,'(3(i4,1x))') ngauss,proc_dist(iterm),weight
836      call wrtout(std_out,msg,'COLL')
837  end do
838  write(msg,'(a)') 'Load per processor: '
839  call wrtout(std_out,msg,'COLL')
840  do iproc=1,nproc
841    write(msg,'(i5,1x,i10)') iproc,proc_load(iproc)
842    call wrtout(std_out,msg,'COLL')
843  end do
844 
845  end subroutine gaussfit_mpi_main

m_paw_gaussfit/gaussfit_mpi_remove_item [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_remove_item

FUNCTION

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

472  subroutine gaussfit_mpi_remove_item(iterm,pload)
473 
474 
475 !This section has been created automatically by the script Abilint (TD).
476 !Do not modify the following lines by hand.
477 #undef ABI_FUNC
478 #define ABI_FUNC 'gaussfit_mpi_remove_item'
479 !End of the abilint section
480 
481  implicit none
482 
483 !Arguments ------------------------------------
484  integer,intent(in)::iterm
485  integer,intent(inout)::pload
486 
487 !Local variables ------------------------------
488  integer:: f_i
489 
490 !***********************************************************************
491 
492  call gaussfit_mpi_set_weight(f_i,iterm)
493  pload=pload-f_i
494 
495  end subroutine gaussfit_mpi_remove_item

m_paw_gaussfit/gaussfit_mpi_set_weight [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_set_weight

FUNCTION

 It sets a weight to the number of
 Gaussians used.
 This was calculated by measuring the time
 it takes to fit a projector with different
 number of gaussians.

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

415  subroutine gaussfit_mpi_set_weight(f,x)
416 
417 
418 !This section has been created automatically by the script Abilint (TD).
419 !Do not modify the following lines by hand.
420 #undef ABI_FUNC
421 #define ABI_FUNC 'gaussfit_mpi_set_weight'
422 !End of the abilint section
423 
424  implicit none
425 
426 !Arguments ------------------------------------
427  integer,intent(in)::x
428  integer,intent(out)::f
429 
430 !Local variables ------------------------------
431  real(dp)::a,b,c,d,ff,xx
432 
433 !************************************************************************
434 
435  !The following parameters were obtained
436  !from the time (in seconds)
437  !it takes to fit a given projector
438  !using from 1 to 100 gaussians.
439  a               = -0.374137d0      !  +/- 2.013        (538.1%)
440  b               = 0.207854d0       !  +/- 0.3385       (162.8%)
441  c               = 0.0266371d0      !  +/- 0.01534      (57.59%)
442  d               = 0.000152476d0    !  +/- 0.0001978    (129.7%)
443 
444  xx=real(x,dp)
445  ff=a+b*xx+c*xx**2+d*xx**3
446  f=max(1,ceiling(ff))
447 
448  end subroutine gaussfit_mpi_set_weight

m_paw_gaussfit/gaussfit_mpi_swap [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_mpi_swap

FUNCTION

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

625  subroutine gaussfit_mpi_swap(iterm,jterm,&
626 &           nproc,nterm_bounds,proc_dist,proc_load)
627 
628 
629 !This section has been created automatically by the script Abilint (TD).
630 !Do not modify the following lines by hand.
631 #undef ABI_FUNC
632 #define ABI_FUNC 'gaussfit_mpi_swap'
633 !End of the abilint section
634 
635  implicit none
636 
637 !Arguments ------------------------------------
638  integer,intent(in)::iterm,jterm,nproc,nterm_bounds(2)
639  integer,intent(inout)::proc_dist(nterm_bounds(1):nterm_bounds(2)),proc_load(nproc)
640 
641 !Local variables ------------------------------
642  integer:: deviation1,deviation2
643  integer:: iproc,jproc
644 
645 !************************************************************************
646 
647 !Calculate initial state
648  call gaussfit_mpi_calc_deviation(deviation1,nproc,proc_load)
649  iproc=proc_dist(iterm)
650  jproc=proc_dist(jterm)
651 !Swap terms:
652  call gaussfit_mpi_add_item(jterm,proc_load(iproc))
653  call gaussfit_mpi_remove_item(iterm,proc_load(iproc))
654  call gaussfit_mpi_add_item(iterm,proc_load(jproc))
655  call gaussfit_mpi_remove_item(jterm,proc_load(jproc))
656 !Calculate final state
657  call gaussfit_mpi_calc_deviation(deviation2,nproc,proc_load)
658 !Swap them only if final state is better than the initial one
659  if(deviation2<deviation1) then
660    proc_dist(iterm)=jproc
661    proc_dist(jterm)=iproc
662  else
663 !  Return work load to initial state
664    call gaussfit_mpi_add_item(iterm,proc_load(iproc))
665    call gaussfit_mpi_remove_item(jterm,proc_load(iproc))
666    call gaussfit_mpi_add_item(jterm,proc_load(jproc))
667    call gaussfit_mpi_remove_item(iterm,proc_load(jproc))
668 !   write(*,*)'Back initial state'
669 !   write(*,*)'proc_load',proc_load(:)
670  end if
671 
672  end subroutine gaussfit_mpi_swap

m_paw_gaussfit/gaussfit_projector [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_projector

FUNCTION

 Fit tproj to Gaussians

INPUTS

  basis_size= size of the PAW basis
  orbitals= indicates the l quantum number for all orbitals.
  rpaw= PAW radius
  pawrad <type(pawrad_type)>=paw radial mesh and related data
  tproj= projectors
  maxterm= maximum number of terms used to fit the projectors.
  mparam= maximum number of parameters (Gaussian coefficients and factors) used.

OUTPUT

  nparam_array= number of parameters found.
  param = parameters found  (Gaussian coefficients and factors).

NOTES

 chisq=accuracy_p= sum_x abs(f(x)-y(x))/nx.
    nx is the number of points, f(x) and y(x) are the fitted and original functions.

PARENTS

      m_pawpsp

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2467 subroutine gaussfit_projector(basis_size,mparam,nparam_array,nterm_bounds,orbitals,param,pawrad,&
2468 & rpaw,tproj,comm_mpi)
2469 
2470 
2471 !This section has been created automatically by the script Abilint (TD).
2472 !Do not modify the following lines by hand.
2473 #undef ABI_FUNC
2474 #define ABI_FUNC 'gaussfit_projector'
2475 !End of the abilint section
2476 
2477  implicit none
2478 
2479 !Arguments ------------------------------------
2480  integer,intent(in) :: basis_size
2481  integer,intent(in) :: orbitals(basis_size)
2482  integer, optional,intent(in) :: comm_mpi
2483  real(dp),intent(in) :: rpaw
2484  type(pawrad_type),intent(in) :: pawrad
2485  real(dp),intent(in) :: tproj(:,:)
2486  integer,intent(in) :: mparam,nterm_bounds(2)
2487  integer,intent(out) :: nparam_array(basis_size)
2488  real(dp),intent(out) :: param(mparam,basis_size)
2489  type(pawrad_type)::mesh_tmp
2490 
2491 !Local variables ------------------------------
2492  integer :: ibasis,ierr,il,ir
2493  integer :: msz1,msz2,option
2494  real(dp) :: raux(1),rr(1)
2495  real(dp),allocatable :: d2(:),tproj_tmp1(:),tproj_tmp2(:)
2496  character(len=500) :: msg
2497  character(80) :: outfile
2498  !debug: uncomment
2499  !integer::i,nterm ,unitp
2500  !real(dp),allocatable::y(:)
2501  !end debug
2502 
2503 !************************************************************************
2504 
2505  if(size(tproj,2)<basis_size) then
2506    msg = 'wrong size for tproj in gaussfit_projector!'
2507    MSG_BUG(msg)
2508  end if
2509 
2510  option=4  !see gaussfit_main
2511  nparam_array(:)=0
2512  msz1=min(pawrad_ifromr(pawrad,rpaw)+2,size(tproj,1))
2513  !msz1=pawrad%mesh_size
2514 
2515 !Augment the mesh size
2516 !this is to make the Gaussians go to zero after paw_radius
2517 !This is done by creating a new pawrad objet: mesh_tmp
2518 !Change to a linear grid:
2519  mesh_tmp%mesh_type=1 !linear grid
2520  mesh_tmp%rstep=0.0005 !very fine grid
2521  msz2=ceiling(pawrad%rmax*two/mesh_tmp%rstep)
2522  mesh_tmp%lstep=zero !only needed for log grids
2523  call pawrad_init(mesh_tmp,mesh_size=msz2,mesh_type=mesh_tmp%mesh_type,&
2524 & rstep=mesh_tmp%rstep,lstep=mesh_tmp%lstep)
2525 
2526  LIBPAW_ALLOCATE(tproj_tmp1,(msz1))
2527  LIBPAW_ALLOCATE(d2,(msz1))
2528  LIBPAW_ALLOCATE(tproj_tmp2,(msz2))
2529 
2530  do ibasis=1,basis_size
2531 
2532    write(msg,'(a," - Fitting wfn ",i4," to Gaussians")')ch10,ibasis
2533    call wrtout(std_out,  msg,'COLL')
2534 
2535    tproj_tmp1=zero; d2=zero; tproj_tmp2=zero
2536 
2537 !  take out r^il factor:
2538 !  il=psps%indlmn(1,ilmn,itypat)
2539    il=orbitals(ibasis)
2540 
2541    tproj_tmp1(2:msz1)=tproj(2:msz1,ibasis)/((pawrad%rad(2:msz1)+tol8)**(il))
2542 
2543 !  take out 1/r factor from eq.(3) of M. Torrent CMS 42, 337 (2008)
2544 !  since: <phi|proj>=1 from atompaw, and phi=phi*r, alors proj=proj/r
2545 
2546    tproj_tmp1(2:msz1)=tproj_tmp1(2:msz1)/(pawrad%rad(2:msz1))
2547    call pawrad_deducer0(tproj_tmp1(1:msz1),msz1,pawrad)
2548 
2549 !  splint to a different mesh:
2550 !  get second derivative of tproj and store it
2551    call paw_spline(pawrad%rad,tproj_tmp1(:),msz1,&
2552 &   zero,zero,d2)
2553 
2554    do ir=2,msz2
2555      rr=mesh_tmp%rad(ir)
2556      if( rr(1)-rpaw > tol8 ) then
2557        !after rpaw projectors are zero
2558        raux=zero
2559      else
2560        call paw_splint(msz1,pawrad%rad,&
2561 &       tproj_tmp1(:),d2(:),&
2562 &       1,rr,raux,ierr=ierr)
2563      end if
2564      tproj_tmp2(ir)=raux(1)
2565    end do
2566 
2567 !  Obtain the name for the output file
2568    if(ibasis<10) then
2569      write(outfile,'("wfn",i1,".fit")')ibasis
2570    elseif(ibasis<100) then
2571      write(outfile,'("wfn",i2,".fit")')ibasis
2572      write(msg,'(a,a,a,a)')ch10,&
2573 &     "ib (basis index) is too big!",ch10,&
2574 &     "Action: check your pseudopotentials"
2575      MSG_BUG(msg)
2576    end if
2577 
2578    if(present(comm_mpi)) then
2579      call gaussfit_main(mparam,nparam_array(ibasis),nterm_bounds,msz2,&
2580 &     param(:,ibasis),mesh_tmp,option,outfile,rpaw,tproj_tmp2,comm_mpi)
2581    else
2582      call gaussfit_main(mparam,nparam_array(ibasis),nterm_bounds,msz2,&
2583 &     param(:,ibasis),mesh_tmp,option,outfile,rpaw,tproj_tmp2)
2584    end if
2585 
2586 !  check
2587 !  LIBPAW_ALLOCATE(y,(mesh_tmp%mesh_size))
2588 !  nterm=nparam_array(ibasis)/4
2589 !  call calcgaussc4(nparam_array(ibasis),nterm,mesh_tmp%mesh_size,1,param(:,ibasis),&
2590 !  &  mesh_tmp%rad,y)
2591 !  ! unitp=600+ibasis
2592 !  ! do ir=1,mesh_tmp%mesh_size
2593 !  !  write(unitp,'(2(f16.7,x,f16.7))')mesh_tmp%rad(ir),y(ir)
2594 !  ! end do
2595 !  LIBPAW_DEALLOCATE(y)
2596 
2597  end do
2598 
2599 !Deallocate
2600  call pawrad_free(mesh_tmp)
2601  LIBPAW_DEALLOCATE(tproj_tmp1)
2602  LIBPAW_DEALLOCATE(tproj_tmp2)
2603  LIBPAW_DEALLOCATE(d2)
2604 
2605 end subroutine gaussfit_projector

m_paw_gaussfit/gaussfit_rlsf [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_rlsf

FUNCTION

  Fits a given function to a sum of Gaussians.
  Uses the Levenberg-Marquardt algorithm.

COPYRIGHT

  Copyright (C) 2011-2018 ABINIT group (T. Rangel)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .
  The original Levemberg Marquardt routines were written by Armando Sole
  These were modified for the ARPUS spectra in the BigDFT code by A. Mirone.
  These were re-writen in Fortran and further modified in ABINIT for our particular needs.

INPUTS

  option=1 fit to a1 cos(a2 x^2)+ a3 sin( a4 x^2)
         2 fit to a1 exp(-a2 x^2)*(a3 cos (a4 x^2) + a5 sin (a6 x^2) )
         3 fit to a1 cos (k x^2) + a2 sin (k x^2)
         4 fit to a1 exp(-a2 x^2)* (a3 cos(k x^2)+ a4 sin (k x^2))
  if(option==1)mparam=nterm_bounds(2)*4
  if(option==2)mparam=nterm_bounds(2)*6
  if(option==3)mparam=nterm_bounds(2)*2
  if(option==4)mparam=nterm_bounds(2)*4

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1664 subroutine gaussfit_rlsf(&
1665 &chisq,constrains,limit,maxiter,&
1666 &nterm,nparam,nx,option,parameters,&
1667 &verbosity,weight,x,y)
1668 
1669 
1670 !This section has been created automatically by the script Abilint (TD).
1671 !Do not modify the following lines by hand.
1672 #undef ABI_FUNC
1673 #define ABI_FUNC 'gaussfit_rlsf'
1674 !End of the abilint section
1675 
1676  implicit none
1677 
1678 !Arguments -------------------------------
1679  real(dp),parameter::deltachi=tol10
1680  integer, intent(in) ::maxiter,nparam,nterm,nx
1681  integer, intent(in) ::option ,verbosity
1682  integer, intent(in) ::constrains(nparam)
1683  real(dp),intent(out)::chisq
1684  !arrays
1685  real(dp),intent(in)::limit(nparam),weight(nparam)
1686  real(dp),intent(inout)::parameters(nparam)
1687  real(dp),intent(in)::x(nx),y(nx)
1688 
1689 !Local variables-------------------------------
1690  integer::flag,ii,info,iter,jj,niter
1691  real(dp):: deltax
1692  real(dp)::chisq0,flambda,eta,lastdeltachi
1693  integer::ipvt(nparam)
1694  real(dp)::alpha(nparam,nparam)
1695  real(dp)::alpha0(nparam,nparam),beta(nparam)
1696  real(dp)::deltapar(nparam)
1697  real(dp)::tmp1(nparam,nparam)
1698  real(dp)::work(nparam)
1699  real(dp)::workpar(nparam)
1700  real(dp)::yfit(nx)
1701  character(len=500) :: msg
1702 
1703 ! *********************************************************************
1704 
1705 !
1706  !flambda=1e-6
1707  flambda=1e-7
1708 !iter=maxiter !later it is changed
1709  niter=0
1710  deltax=x(2)-x(1) !we assume this is a linear grid
1711 !
1712  iter_loop: do iter=1,maxiter
1713 !
1714    call gaussfit_chisq_alpha_beta(alpha0,beta,chisq0,&
1715 &   nparam,nterm,nx,option,parameters,x,y)
1716 !
1717    flag=0
1718    lastdeltachi=chisq0
1719 !
1720 !
1721    while_flag: do
1722      if(flag .ne. 0) exit while_flag
1723 !
1724      tmp1=0.d0
1725      do ii=1,nparam
1726        tmp1(ii,ii)=1.d0*flambda  !identity matrix * flambda
1727      end do
1728      alpha=alpha0+tmp1*alpha0
1729 !    Invert alpha matrix
1730      tmp1=alpha
1731      call dgetrf(nparam,nparam,tmp1,nparam,ipvt,info)
1732      if (.not.info==0) then
1733        if(verbosity>1) then
1734          write(msg,'(a)')'Matrix is singular'
1735          call wrtout(std_out,msg,'COLL')
1736        end if
1737        chisq=-1.d0
1738        exit iter_loop
1739      end if
1740      call dgetri(nparam,tmp1,nparam,ipvt,work,nparam,info)
1741      deltapar=0.d0
1742      if (.not.info==0) then
1743        if(verbosity>2) then
1744          write(msg,'(a)')'Matrix is singular'
1745          call wrtout(std_out,msg,'COLL')
1746        end if
1747        chisq=-1.d0
1748        exit iter_loop
1749      end if
1750 !
1751      if(tmp1(1,1) .ne. tmp1(1,1)) then !If is NaN
1752        chisq=-1.d0
1753        exit iter_loop
1754      end if
1755      if(abs(tmp1(1,1)) == tmp1(1,1)*tmp1(1,1)) then !If is infinity
1756        chisq=-1.d0
1757        exit iter_loop
1758      end if
1759 !
1760      do ii=1,nparam
1761        do jj=1,nparam
1762          deltapar(ii)=deltapar(ii)+beta(jj)*tmp1(jj,ii)
1763        end do
1764      end do
1765 !    apply constrains
1766      workpar(1:nparam)=parameters(1:nparam)+deltapar(1:nparam)*weight(1:nparam)
1767      call gaussfit_apply_constrains(constrains,limit,nparam,workpar)
1768 !
1769      if(option==1) then
1770        call gaussfit_calc_deriv_c2(nparam,nterm,nx,1,workpar,x,yfit)
1771      elseif(option==2) then
1772        call gaussfit_calc_deriv_c(nparam,nterm,nx,1,workpar,x,yfit)
1773      elseif(option==3) then
1774        call gaussfit_calc_deriv_c3(nparam,nterm,nx,1,workpar,x,yfit)
1775      elseif(option==4) then
1776        call gaussfit_calc_deriv_c4(nparam,nterm,nx,1,workpar,x,yfit)
1777      end if
1778      chisq=0.d0
1779      do ii=1,nx
1780        chisq=chisq + ((y(ii)-yfit(ii)))**2
1781      end do
1782      chisq=chisq*deltax
1783 !
1784 !    write(*,'("chisq ",f12.5,"  chisq0 ",f12.5)')chisq,chisq0
1785 !
1786      if(chisq > chisq0) then
1787        flambda=flambda*2.0d0
1788        if( flambda > 1000.d0) then
1789          flag=1
1790 !        iter=0
1791          if(verbosity>2) then
1792            write(msg,'(a)')'flambda > 1000.d0'
1793            call wrtout(std_out,msg,'COLL')
1794          end if
1795          exit iter_loop
1796        end if
1797      else
1798        flag=1
1799        parameters=workpar
1800        eta=0.d0
1801        lastdeltachi=(chisq0-chisq) !/(chisq0+eta)
1802        if(lastdeltachi<deltachi) cycle
1803        chisq0=chisq
1804        flambda=flambda/2.d0
1805        if(verbosity>2) then
1806          write(msg,'("iter = ",i4," chisq = ",e15.6)')iter,chisq
1807          call wrtout(std_out,msg,'COLL')
1808        end if
1809      end if
1810    end do while_flag
1811  end do iter_loop
1812 
1813 end subroutine gaussfit_rlsf

m_paw_gaussfit/gaussfit_set_param1 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_set_param1

FUNCTION

  Sets parameters for LSF

INPUTS

OUTPUT

PARENTS

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

1937 subroutine gaussfit_set_param1(nterm,nparam,nx,param,sep,x,y)
1938 
1939 
1940 !This section has been created automatically by the script Abilint (TD).
1941 !Do not modify the following lines by hand.
1942 #undef ABI_FUNC
1943 #define ABI_FUNC 'gaussfit_set_param1'
1944 !End of the abilint section
1945 
1946  implicit none
1947 
1948 !Arguments -------------------------------
1949  integer,intent(in)::nterm,nparam,nx
1950  real(dp),intent(in)::sep
1951  real(dp),intent(in)::x(nx),y(nx)
1952  real(dp),intent(out)::param(nparam)
1953 
1954 !Local variables-------------------------------
1955  integer::ii,jj
1956  real(dp)::raux
1957 
1958 ! *********************************************************************
1959 
1960 !
1961  param(:)=1.0d0
1962 !exps=1.0/(x(nx)**2)
1963 !
1964 !alpha1
1965 
1966 !raux=maxval( y(:),nx )
1967 !maxval gives problems in some architectures:
1968  raux=-9999999
1969  do ii=1,nx
1970    if(raux<y(ii)) raux=y(ii)
1971  end do
1972  param(1:nterm)=raux
1973 !
1974 !alpha2
1975 !
1976 !y(r_c)=e^{-\alpha1 r_c}
1977  raux=-log(abs(y(nx))+tol10)/(x(nx)**2)
1978  param(nterm+1:nterm+2)=raux
1979 !
1980 !raux=0.5d0*pi/real(nterm,dp)
1981  do jj=1,nterm
1982    ii=jj+3*nterm
1983    param(ii)=sep**(jj)
1984 !  param(ii)=raux*real(jj,dp)
1985  end do
1986 !
1987  do jj=1,nterm
1988    ii=jj+5*nterm
1989    param(ii)=sep**(jj)
1990 !  param(ii)=raux*real(jj,dp)
1991  end do
1992 
1993 end subroutine gaussfit_set_param1

m_paw_gaussfit/gaussfit_set_param2 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_set_param2

FUNCTION

  Sets parameters for LSF

INPUTS

OUTPUT

PARENTS

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2017 subroutine gaussfit_set_param2(nterm,nparam,nx,param,rpaw,x,y)
2018 
2019 
2020 !This section has been created automatically by the script Abilint (TD).
2021 !Do not modify the following lines by hand.
2022 #undef ABI_FUNC
2023 #define ABI_FUNC 'gaussfit_set_param2'
2024 !End of the abilint section
2025 
2026  implicit none
2027 
2028 !Arguments -------------------------------
2029  integer,intent(in)::nterm,nparam,nx
2030  real(dp),intent(in)::rpaw
2031  real(dp),intent(in)::x(nx),y(nx)
2032  real(dp),intent(out)::param(nparam)
2033 
2034 !Local variables-------------------------------
2035  integer::ii,jj
2036  real(dp)::exps,raux,sig,step
2037 
2038 ! *************************************************************************
2039 
2040  step=rpaw/real(nterm-1,dp)
2041 !exps=1.0/(rpaw/(real(nterm,dp)/2.d0))**2
2042  exps=1.0/(step*1.0d0)**2
2043 !alpha2 (width of gaussians)
2044 !Set to exps*real(nterm,dp)**2, for a good guess
2045  param(nterm+1:2*nterm)=exps !*real(nterm,dp)**2
2046 !
2047  do jj=1,nterm
2048 !  alpha3
2049 !  set to constant values of x
2050    ii=jj+2*nterm
2051    raux=step*real(jj-1,dp)
2052    param(ii)=raux
2053 !  alpha1
2054 !  set to the value of y at that point
2055    call gaussfit_param2_findsign()
2056    param(jj)=sig
2057  end do
2058 !
2059  contains

m_paw_gaussfit/gaussfit_set_param3 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_set_param3

FUNCTION

  Sets parameters for LSF

INPUTS

OUTPUT

PARENTS

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2138 subroutine gaussfit_set_param3(nterm,nparam,param,sep)
2139 
2140 
2141 !This section has been created automatically by the script Abilint (TD).
2142 !Do not modify the following lines by hand.
2143 #undef ABI_FUNC
2144 #define ABI_FUNC 'gaussfit_set_param3'
2145 !End of the abilint section
2146 
2147  implicit none
2148 
2149 !Arguments -------------------------------
2150  integer,intent(in)::nterm,nparam
2151  real(dp),intent(in)::sep
2152  !real(dp),intent(in)::x(nx),y(nx)
2153  real(dp),intent(out)::param(nparam)
2154 
2155 !Local variables-------------------------------
2156  integer::ii,jj
2157 
2158 ! *********************************************************************
2159 
2160  param(:)=1.0d0
2161 !
2162  do jj=1,nterm
2163    ii=jj+nterm
2164    param(ii)=sep**(jj)
2165 !  param(ii)=raux*real(i,dp)
2166  end do
2167 !
2168  do jj=1,nterm
2169    ii=jj+3*nterm
2170    param(ii)=sep**(jj)
2171 !  param(ii)=raux*real(i,dp)
2172  end do
2173 
2174 end subroutine gaussfit_set_param3

m_paw_gaussfit/gaussfit_set_param4 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_set_param4

FUNCTION

  Sets parameters for LSF

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2199 subroutine gaussfit_set_param4(nparam,param)
2200 
2201 
2202 !This section has been created automatically by the script Abilint (TD).
2203 !Do not modify the following lines by hand.
2204 #undef ABI_FUNC
2205 #define ABI_FUNC 'gaussfit_set_param4'
2206 !End of the abilint section
2207 
2208  implicit none
2209 
2210 !Arguments -------------------------------
2211  integer,intent(in)::nparam
2212  real(dp),intent(out)::param(nparam)
2213 
2214 !Local variables-------------------------------
2215 
2216 ! *********************************************************************
2217 
2218  param(:)=1.0d0
2219 
2220 end subroutine gaussfit_set_param4

m_paw_gaussfit/gaussfit_set_param5 [ Functions ]

[ Top ] [ m_paw_gaussfit ] [ Functions ]

NAME

  gaussfit_set_param5

FUNCTION

  Sets parameters for LSF

INPUTS

OUTPUT

PARENTS

      m_paw_gaussfit

CHILDREN

      gaussfit_main,paw_spline,paw_splint,pawrad_deducer0,pawrad_free
      pawrad_init,wrtout

SOURCE

2245 subroutine gaussfit_set_param5(nterm,nparam,nx,param,rpaw,y)
2246 
2247 
2248 !This section has been created automatically by the script Abilint (TD).
2249 !Do not modify the following lines by hand.
2250 #undef ABI_FUNC
2251 #define ABI_FUNC 'gaussfit_set_param5'
2252 !End of the abilint section
2253 
2254  implicit none
2255 
2256 !Arguments -------------------------------
2257  integer,intent(in)::nterm,nparam,nx
2258  real(dp),intent(in)::rpaw
2259  real(dp),intent(in)::y(nx)
2260  real(dp),intent(out)::param(nparam)
2261 
2262 !Local variables-------------------------------
2263  integer::ix
2264  real(dp)::raux,a1,r_c,m
2265 
2266 ! *********************************************************************
2267 
2268  param(:)=1.0d0
2269 !
2270 !alpha1
2271 !a1=maxval( y(:),nx )
2272 !maxval gives problems in some architectures:
2273  a1=-9999999
2274  do ix=1,nx
2275    if(a1<y(ix)) a1=y(ix)
2276  end do
2277  param(1:nterm)=a1
2278 !
2279 !alpha2
2280 !
2281  r_c=rpaw+0.5d0 !paw sphere + a bit more.
2282 !this is not arbitrary since it is an initial guess
2283  m=0.01d0
2284  raux=log(a1/m)/r_c**2
2285  param(nterm+1:nterm*2)=raux
2286 
2287 end subroutine gaussfit_set_param5