/*******************************************************************************
*                                                                              *
*                                   Viewmol                                    *
*                                                                              *
*                                   M O . C                                    *
*                                                                              *
*                 Copyright (c) Joerg-R. Hill, October 2003                    *
*                                                                              *
********************************************************************************
*
* $Id: mo.c,v 1.6 2003/11/07 11:07:15 jrh Exp $
* $Log: mo.c,v $
* Revision 1.6  2003/11/07 11:07:15  jrh
* Release 2.4
*
* Revision 1.5  2000/12/10 15:12:04  jrh
* Release 2.3
*
* Revision 1.4  1999/05/24 01:26:35  jrh
* Release 2.2.1
*
* Revision 1.3  1999/02/07 21:53:01  jrh
* Release 2.2
*
* Revision 1.2  1998/01/26 00:48:45  jrh
* Release 2.1
*
* Revision 1.1  1996/12/10  18:42:19  jrh
* Initial revision
*
*/
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "viewmol.h"
#include "dialog.h"

/* Prototypes */
double makemo(struct ATOM *, struct ORBITAL *, double, double, double, int,
              int, int, int);
void cnorm(int);
size_t norbs(struct MOLECULE *);
int numberBasisFunctions(struct BASISSET *);
void modcmo(struct MOLECULE *, int);
void assignBasisName(int);
/* void bfnamn(int, int *, int *);
char *bfname(int); */

/* External functions */
extern int messgb(Widget, int, char *, struct PushButtonRow *, int);
extern void GetMessageBoxButton(Widget, XtPointer, caddr_t);
extern void *getmem(size_t, size_t);
extern void fremem(void **);
extern char *getStringResource(Widget, char *);

/* Global variables */
extern struct MOLECULE *molecules;
extern Widget topShell;

/* Local variables */
/*static int *atombasisnames;
static char *basisname;*/
static char basisNames[] = {"s\0p(x)\0p(y)\0p(z)\0d(xx)\0d(yy)\0d(zz)\0d(xy)\0d(xz)\0d(yz)\0f(xxx)\0f(yyy)\0f(zzz)\0f(xxy)\0f(xxz)\0f(yyx)\0f(yyz)\0f(zzx)\0f(zzy)\0f(xyz)\0g(xxxx)\0g(yyyy)\0g(zzzz)\0g(xxxy)\0g(xxxz)\0g(yyyx)\0g(yyyz)\0g(zzzx)\0g(zzzy)\0g(xxyy)\0g(xxzz)\0g(yyzz)\0g(xxyz)\0g(yyxz)\0g(zzxy)"};

double makemo(struct ATOM *atoms, struct ORBITAL *orbital, double xgrid,
              double ygrid, double zgrid, int na, int morb, int nbasfu,
              int imo)
{
  struct BASISSET *p;
  double r, *expnt, *b;
  double result, x, y, z, f;
  register int i, j, k;

  b=(double *)getmem((size_t)morb, sizeof(double));

  k=0;
  for (i=0; i<na; i++)
  {
    x=xgrid-atoms[i].x;
    y=ygrid-atoms[i].y;
    z=zgrid-atoms[i].z;
    r=x*x+y*y+z*z;
    p=atoms[i].basis;
    do
    {
      expnt=p->first;
      f=0.0;
      for (j=0; j<p->nprim; j++)
      {
        f+=exp(-expnt[0]*r)*expnt[1];
        expnt+=2;
      }
      switch (p->ang)
      {
        case 0:  b[k++]=f;
                 break;
        case 1:  b[k++]=x*f;
                 b[k++]=y*f;
                 b[k++]=z*f;
                 break;
        case 2:  b[k++]=x*x*f;
                 b[k++]=y*y*f;
                 b[k++]=z*z*f;
                 b[k++]=x*y*f;
                 b[k++]=x*z*f;
                 b[k++]=y*z*f;
                 break;
        case 3:  b[k++]=x*x*x*f;
                 b[k++]=y*y*y*f;
                 b[k++]=z*z*z*f;
                 b[k++]=x*x*y*f;
                 b[k++]=x*x*z*f;
                 b[k++]=y*y*x*f;
                 b[k++]=y*y*z*f;
                 b[k++]=z*z*x*f;
                 b[k++]=z*z*y*f;
                 b[k++]=x*y*z*f;
                 break;
        case 4:  b[k++]=x*x*x*x*f;
                 b[k++]=y*y*y*y*f; 
                 b[k++]=z*z*z*z*f; 
                 b[k++]=x*x*x*y*f; 
                 b[k++]=x*x*x*z*f; 
                 b[k++]=y*y*y*x*f; 
                 b[k++]=y*y*y*z*f; 
                 b[k++]=z*z*z*x*f; 
                 b[k++]=z*z*z*y*f; 
                 b[k++]=x*x*y*y*f; 
                 b[k++]=x*x*z*z*f; 
                 b[k++]=y*y*z*z*f; 
                 b[k++]=x*x*y*z*f; 
                 b[k++]=y*y*x*z*f; 
                 b[k++]=z*z*x*y*f; 
        default: k+=(p->ang+1)*(p->ang+2)/2;
                 break;
      }
    }
    while ((p=p->next) != NULL);
  }
  result=0.0;
  if (imo == -1)
  {
    for (j=0; j<nbasfu; j++)
    {
      if (orbital[j].occupation != 0.0)
      {
        r=0.0;
        for (i=0; i<morb; i++)
          r+=orbital[j].coeff[i]*b[i];
        result+=orbital[j].occupation*r*r;
      }
    }
  }
  else
  {
    for (i=0; i<morb; i++)
    {
      result+=orbital[imo].coeff[i]*b[i];
    }
  }
  fremem((void **)&b);
  return(result);
}

void cnorm(int imol)
{
/*******************************************************************************
   This function normalizes the basis functions:
                          1/2
   c = N   c  / (Sum(S  ))
    i   ii  i         ij

  with
             3 -1/4  l      (l/2+1/4)
  N   = (2 pi )     2  alpha
   ii                       i

  and
                                             2 (l/2+1/4)
  S   = 2 c c (4 alpha alpha /(alpha +alpha ) )
   ij      i j        i     j       i      j

  (l - angular quantum number plus one)
*******************************************************************************/
  struct BASISSET *shell;
  double sij, nii, fac, *p;
  int ang, *done;
  int i, j, k;

  fac=4.0*atan(1.0);
  fac=pow(2.0*fac*fac*fac, -0.25);

  done=(int *)getmem((size_t)molecules[imol].na, sizeof(int));

  for (i=0; i<molecules[imol].na; i++)
  {
    shell=molecules[imol].atoms[i].basis;
    if (shell && !done[i])
    {
      do
      {
        p=shell->first;
        ang=shell->ang+1;
        if (shell->nprim == 1)
        {
          sij=1.0;
          p[1]=1.0;
        }
        else
        {
          sij=0.0;
          for (j=0; j<shell->nprim; j++)
          {
            sij+=p[2*j+1]*p[2*j+1];
            for (k=0; k<j; k++)
              sij+=2.0*p[2*j+1]*p[2*k+1]*pow(4.0*p[2*j]*p[2*k]
                  /((p[2*j]+p[2*k])*(p[2*j]+p[2*k])), 0.5*ang+0.25);
          }
          sij=1.0/sqrt(sij);
        }
        for (j=0; j<shell->nprim; j++)
        {
          nii=fac*pow(2.0, (double)ang)*pow(p[2*j], 0.5*ang+0.25);
          p[2*j+1]*=nii*sij;
        }
        shell=shell->next;
      } while (shell != NULL);
      done[i]=TRUE;
      for (j=0; j<molecules[imol].na; j++)
      {
        if (molecules[imol].atoms[i].basis == molecules[imol].atoms[j].basis)
          done[j]=TRUE;
      }
    }
  }
  fremem((void **)&done);
}

size_t norbs(struct MOLECULE *mol)
{                                   /* determines the total number  */
  register size_t nmo;              /* of cartesian basis functions */
  register int atom;

  nmo=0;
  for (atom=0; atom<mol->na; atom++)
    nmo+=numberBasisFunctions(mol->atoms[atom].basis);
  return(nmo);
}

int numberBasisFunctions(struct BASISSET *basis)
{
  struct BASISSET *shell;
  int nBasisFunctions;

  nBasisFunctions=0;
  shell=basis;
  if (!shell) return(nBasisFunctions);
  do
  {
    nBasisFunctions+=(shell->ang+1)*(shell->ang+2)/2;
    shell=shell->next;
  } while (shell != NULL);
  return(nBasisFunctions);
}

void modcmo(struct MOLECULE *mol, int gaussian)
{
/*******************************************************************************

  Transform MO coefficients which have been read in with respect to
  "true" basis functions (if pured, puref, or pureg are true) to MO
  coefficients with respect to cartesian basis functions used in the
  calculations (as in moloch). If MO coefficients have been read in
  with respect to cartesian basis functions some renormalization may
  be necessary. The coefficients for s and p functions will not be
  changed. Turbomole uses the following ordering of basis functions
  in the MO vector:
  d functions: (-xx-yy+2zz)/sqrt(12), xz, yz, xy, (xx-yy)/2
  f functions: (-3xxx-3yyy+2zzz)/sqrt(60), (-xxx-xyy+4xzz)/sqrt(40),
               (-yyy-xxy+4yzz)/sqrt(40), xyz, (xxz-yyz)/2, (xxx-3xyy)/sqrt(24),
               (yyy-3xxy)/sqrt(24)        
  g functions: (3xxxx+3yyyy+8zzzz+6xxyy-24xxzz-24yyzz)/sqrt(6720),
               (-3xxxz+4xzzz-3xyyz)/sqrt(168), (-3yyyz+4yzzz-3xxyz)/sqrt(168),
               (-xxxy-xyyy+6xyzz)/sqrt(84), (xxxx-yyyy-6xxzz+6yyzz)/sqrt(336),
               (xxxz-3xyyz)/sqrt(24), (yyyz-3xxyz)/sqrt(24),
               (xxxy-xyyy)/sqrt(12), (xxxx+yyyy-6xxyy)/sqrt(192)
  Gaussian uses:
  d functions: zz, xz, yz, xx-yy, xy
  f functions: ???
  g functions: not available with Gaussian
  After transformation the MO coefficients are ordered in the following
  way:
  d functions: d(xx), d(yy), d(zz), d(xy), d(xz), d(yz)
  f functions: f(xxx), f(yyy), f(zzz), f(xxy), f(xxz), f(yyx), f(yyz),
               f(zzx), f(zzy), f(xyz)
  g functions: g(xxxx), g(yyyy), g(zzzz), g(xxxy), g(xxxz), g(yyyx),
               g(yyyz), g(zzzx), g(zzzy), g(xxyy), g(xxzz), g(yyzz),
               g(xxyz), g(yyxz), g(zzxy)

*******************************************************************************/

  static struct PushButtonRow buttons[] = {{"exit", GetMessageBoxButton, (XtPointer)0, NULL},
                                           {"continue", GetMessageBoxButton, (XtPointer)1, NULL}};

  struct ORBITAL *orbital;
  struct BASISSET *shell;
  double *newmo, *c, help;
  int lmax=(-1), fproblem=FALSE, gproblem=FALSE;
  char line[80], l[4], *p;
  size_t ntotal;
  register int mo, atom, i, j;

  orbital=mol->orbitals;
  ntotal=norbs(mol);
  newmo=(double *)getmem(ntotal*mol->nbasfu, sizeof(double));
  j=0;
  for (mo=0; mo<mol->nbasfu; mo++)
  {
    i=0;
    c=&newmo[j];
    for (atom=0; atom<mol->na; atom++)
    {
      shell=mol->atoms[atom].basis;
      if (shell)
      {
        do
        {
          if (shell->ang > lmax) lmax=shell->ang;
          switch (shell->ang)
          {
            case 0:  newmo[j]=orbital[mo].coeff[i];
                     i++;
                     j++;
                     break;
            case 1:  newmo[j]=orbital[mo].coeff[i];
                     newmo[j+1]=orbital[mo].coeff[i+1];
                     newmo[j+2]=orbital[mo].coeff[i+2];
                     i+=3;
                     j+=3;
                     break;
            case 2:  if (mol->pured)
                     {
                       if (gaussian)
                       {
                         help=orbital[mo].coeff[i+4];
                         orbital[mo].coeff[i+4]=orbital[mo].coeff[i+3];
                         orbital[mo].coeff[i+3]=help;
                       }
                       newmo[j]=-0.5/sqrt(3.)*orbital[mo].coeff[i]
                                +0.5*orbital[mo].coeff[i+4];
                       newmo[j+1]=-0.5/sqrt(3.)*orbital[mo].coeff[i]
                                  -0.5*orbital[mo].coeff[i+4];
                       newmo[j+2]=1.0/sqrt(3.)*orbital[mo].coeff[i];
                       newmo[j+3]=orbital[mo].coeff[i+3];
                       newmo[j+4]=orbital[mo].coeff[i+1];
                       newmo[j+5]=orbital[mo].coeff[i+2];
                       i+=5;
                     }
                     else
                     {
                       if (gaussian)
                       {
                         newmo[j]  =orbital[mo].coeff[i]  /sqrt(3.);
                         newmo[j+1]=orbital[mo].coeff[i+1]/sqrt(3.);
                         newmo[j+2]=orbital[mo].coeff[i+2]/sqrt(3.);
                         newmo[j+3]=orbital[mo].coeff[i+3]/sqrt(3.);
                         newmo[j+4]=orbital[mo].coeff[i+4]/sqrt(3.);
                         newmo[j+5]=orbital[mo].coeff[i+5]/sqrt(3.);
                       }
                       else
                       {
                         newmo[j]=-0.5/sqrt(3.)*orbital[mo].coeff[i]
                                  +0.5*orbital[mo].coeff[i+4]
                                  +1.0/sqrt(15.0)*orbital[mo].coeff[i+5];
                         newmo[j+1]=-0.5/sqrt(3.)*orbital[mo].coeff[i]
                                    -0.5*orbital[mo].coeff[i+4]
                                    +1.0/sqrt(15.0)*orbital[mo].coeff[i+5];
                         newmo[j+2]=1.0/sqrt(3.)*orbital[mo].coeff[i]
                                   +1.0/sqrt(15.0)*orbital[mo].coeff[i+5];
                         newmo[j+3]=orbital[mo].coeff[i+3];
                         newmo[j+4]=orbital[mo].coeff[i+1];
                         newmo[j+5]=orbital[mo].coeff[i+2];
                       }
                       i+=6;
                     }
                     j+=6;
                     break;
            case 3:  if (mol->puref)
                     {
                       if (gaussian)
                       {
                         help=orbital[mo].coeff[i+4];
                         orbital[mo].coeff[i+4]=orbital[mo].coeff[i+3];
                         orbital[mo].coeff[i+3]=help;
                       }
                       newmo[j]=-0.5/sqrt(10.)*orbital[mo].coeff[i+1]
                                +0.5/sqrt(6.)*orbital[mo].coeff[i+5];
                       newmo[j+1]=-0.5/sqrt(10.)*orbital[mo].coeff[i+2]
                                  +0.5/sqrt(6.)*orbital[mo].coeff[i+6];
                       newmo[j+2]=1.0/sqrt(15.)*orbital[mo].coeff[i];
                       newmo[j+3]=-0.5/sqrt(10.)*orbital[mo].coeff[i+2]
                                  -sqrt(3./8.)*orbital[mo].coeff[i+6];
                       newmo[j+4]=-0.5*sqrt(3./5.)*orbital[mo].coeff[i]
                                  +0.5*orbital[mo].coeff[i+4];
                       newmo[j+5]=-0.5/sqrt(10.)*orbital[mo].coeff[i+1]
                                  -sqrt(3./8.)*orbital[mo].coeff[i+5];
                       newmo[j+6]=-0.5*sqrt(3./5.)*orbital[mo].coeff[i]
                                  -0.5*orbital[mo].coeff[i+4];
                       newmo[j+7]=sqrt(2./5.)*orbital[mo].coeff[i+1];
                       newmo[j+8]=sqrt(2./5.)*orbital[mo].coeff[i+2];
                       newmo[j+9]=orbital[mo].coeff[i+3];
                       i+=7;
                     }
                     else
                     {
                       if (gaussian) fproblem=TRUE;
                       else
                       {
                         newmo[j]=-0.5/sqrt(10.)*orbital[mo].coeff[i+1]
                                  +0.5/sqrt(6.)*orbital[mo].coeff[i+5]
                                  +1.0/sqrt(35.)*orbital[mo].coeff[i+8];
                         newmo[j+1]=-0.5/sqrt(10.)*orbital[mo].coeff[i+2]
                                    +0.5/sqrt(6.)*orbital[mo].coeff[i+6]
                                    +1.0/sqrt(35.)*orbital[mo].coeff[i+9];
                         newmo[j+2]=1.0/sqrt(15.)*orbital[mo].coeff[i]
                                   +1.0/sqrt(35.)*orbital[mo].coeff[i+7];
                         newmo[j+3]=-0.5/sqrt(10.)*orbital[mo].coeff[i+2]
                                    -sqrt(3./8.)*orbital[mo].coeff[i+6]
                                    +1.0/sqrt(35.)*orbital[mo].coeff[i+9];
                         newmo[j+4]=-0.5*sqrt(3./5.)*orbital[mo].coeff[i]
                                    +0.5*orbital[mo].coeff[i+4]
                                    +1.0/sqrt(35.)*orbital[mo].coeff[i+7];
                         newmo[j+5]=-0.5/sqrt(10.)*orbital[mo].coeff[i+1]
                                    -sqrt(3./8.)*orbital[mo].coeff[i+5]
                                    +1./sqrt(35.)*orbital[mo].coeff[i+8];
                         newmo[j+6]=-0.5*sqrt(3./5.)*orbital[mo].coeff[i]
                                    -0.5*orbital[mo].coeff[i+4]
                                    +1./sqrt(35.)*orbital[mo].coeff[i+7];
                         newmo[j+7]=sqrt(2./5.)*orbital[mo].coeff[i+1]
                                   +1./sqrt(35.)*orbital[mo].coeff[i+8];
                         newmo[j+8]=sqrt(2./5.)*orbital[mo].coeff[i+2]
                                   +1./sqrt(35.)*orbital[mo].coeff[i+9];
                         newmo[j+9]=orbital[mo].coeff[i+3];
                       }
                       i+=10;
                     }
                     j+=10;
                     break;
            case 4:  if (mol->pureg)
                     {
                       if (gaussian) gproblem=TRUE;
                       else
                       {
                         newmo[j]=0.125*sqrt(3./35.)*orbital[mo].coeff[i]
                                 +0.25/sqrt(21.)*orbital[mo].coeff[i+4]
                                 +0.125/sqrt(3.)*orbital[mo].coeff[i+8];
                         newmo[j+1]=0.125*sqrt(3./35.)*orbital[mo].coeff[i]
                                   -0.25/sqrt(21.)*orbital[mo].coeff[i+4]
                                   +0.125/sqrt(3.)*orbital[mo].coeff[i+8];
                         newmo[j+2]=1./sqrt(105.)*orbital[mo].coeff[i];
                         newmo[j+3]=-0.5/sqrt(21.)*orbital[mo].coeff[i+3]
                                   +0.5/sqrt(3.)*orbital[mo].coeff[i+7];
                         newmo[4]=-0.5*sqrt(3./14.)*orbital[mo].coeff[i+1]
                                  +0.5/sqrt(6.)*orbital[mo].coeff[i+5];
                         newmo[j+5]=-0.5/sqrt(21.)*orbital[mo].coeff[i+3]
                                    -0.5/sqrt(3.)*orbital[mo].coeff[i+7];
                         newmo[j+6]=-0.5*sqrt(3./14.)*orbital[mo].coeff[i+2]
                                    +0.5/sqrt(6.)*orbital[mo].coeff[i+6];
                         newmo[j+7]=sqrt(2./21.)*orbital[mo].coeff[i+1];
                         newmo[j+8]=sqrt(2./21.)*orbital[mo].coeff[i+2];
                         newmo[j+9]=0.25*sqrt(3./35.)*orbital[mo].coeff[i]
                                   -0.25*sqrt(3.)*orbital[mo].coeff[i+8];
                         newmo[j+10]=(-sqrt(3./35.)*orbital[mo].coeff[i]
                                    -0.5*sqrt(3./7.)*orbital[mo].coeff[i+4]);
                         newmo[j+11]=(-sqrt(3./35.)*orbital[mo].coeff[i]
                                    +0.5*sqrt(3./7.)*orbital[mo].coeff[i+4]);
                         newmo[j+12]=(-0.5*sqrt(3./14.)*orbital[mo].coeff[i+2]
                                    -0.5*sqrt(3./2.)*orbital[mo].coeff[i+6]);
                         newmo[j+13]=(-0.5*sqrt(3./14.)*orbital[mo].coeff[i+1]
                                    -0.5*sqrt(3./2.)*orbital[mo].coeff[i+5]);
                         newmo[j+14]=sqrt(3./7.)*orbital[mo].coeff[i+3];
                       }
                       i+=9;
                     }
                     else
                     {
                       if (gaussian) gproblem=TRUE;
                       else
                       {
                         newmo[j]=0.125*sqrt(3./35.)*orbital[mo].coeff[i]
                                 +0.25/sqrt(21.)*orbital[mo].coeff[i+4]
                                 +0.125/sqrt(3.)*orbital[mo].coeff[i+8]
                                 -1./(6.*sqrt(21.))*orbital[mo].coeff[i+9]
                                 +1./(6.*sqrt(7.))*orbital[mo].coeff[i+13]
                                 +1./(3.*sqrt(105.))*orbital[mo].coeff[i+14];
                         newmo[j+1]=0.125*sqrt(3./35.)*orbital[mo].coeff[i]
                                   -0.25/sqrt(21.)*orbital[mo].coeff[i+4]
                                   +0.125/sqrt(3.)*orbital[mo].coeff[i+8]
                                   -1./(6.*sqrt(21.))*orbital[mo].coeff[i+9]
                                   -1./(6.*sqrt(7.))*orbital[mo].coeff[i+13]
                                   +1./(3.*sqrt(105.))*orbital[mo].coeff[i+14];
                         newmo[j+2]=1./sqrt(105.)*orbital[mo].coeff[i]
                                   +1./(3.*sqrt(21.))*orbital[mo].coeff[i+9]
                                   +1./(3.*sqrt(105.))*orbital[mo].coeff[i+14];
                         newmo[j+3]=-0.5/sqrt(21.)*orbital[mo].coeff[i+3]
                                   +0.5/sqrt(3.)*orbital[mo].coeff[i+7]
                                   +1./(3.*sqrt(7.))*orbital[mo].coeff[i+12];
                         newmo[j+4]=-0.5*sqrt(3./14.)*orbital[mo].coeff[i+1]
                                    +0.5/sqrt(6.)*orbital[mo].coeff[i+5]
                                    +1./(3.*sqrt(7.))*orbital[mo].coeff[i+10];
                         newmo[j+5]=-0.5/sqrt(21.)*orbital[mo].coeff[i+3]
                                    -0.5/sqrt(3.)*orbital[mo].coeff[i+7]
                                    +1./(3.*sqrt(7.))*orbital[mo].coeff[i+12];
                         newmo[j+6]=-0.5*sqrt(3./14.)*orbital[mo].coeff[i+2]
                                    +0.5/sqrt(6.)*orbital[mo].coeff[i+6]
                                    +1./(3.*sqrt(7.))*orbital[mo].coeff[i+11];
                         newmo[j+7]=sqrt(2./21.)*orbital[mo].coeff[i+1]
                                   +1./(3.*sqrt(7.))*orbital[mo].coeff[i+10];
                         newmo[j+8]=sqrt(2./21.)*orbital[mo].coeff[i+2]
                                   +1./(3.*sqrt(7.))*orbital[mo].coeff[i+11];
                         newmo[j+9]=0.25*sqrt(3./35.)*orbital[mo].coeff[i]
                                   -0.25*sqrt(3.)*orbital[mo].coeff[i+8]
                                   -1./(3.*sqrt(21.))*orbital[mo].coeff[i+9]
                                   +2./(3.*sqrt(105.))*orbital[mo].coeff[i+14];
                         newmo[j+10]=(-sqrt(3./35.)*orbital[mo].coeff[i]
                                    -0.5*sqrt(3./7.)*orbital[mo].coeff[i+4]
                                    +1./(6.*sqrt(21.))*orbital[mo].coeff[i+9]
                                    +1./(6.*sqrt(7.))*orbital[mo].coeff[i+13]
                                    +2./(3.*sqrt(105.))*orbital[mo].coeff[i+14]);
                         newmo[j+11]=(-sqrt(3./35.)*orbital[mo].coeff[i]
                                    +0.5*sqrt(3./7.)*orbital[mo].coeff[i+4]
                                    +1./(6.*sqrt(21.))*orbital[mo].coeff[i+9]
                                    -1./(6.*sqrt(7.))*orbital[mo].coeff[i+13]
                                    +2./(3.*sqrt(105.))*orbital[mo].coeff[i+14]);
                         newmo[j+12]=-0.5*sqrt(3./14.)*orbital[mo].coeff[i+2]
                                    -0.5*sqrt(3./2.)*orbital[mo].coeff[i+6]
                                    +1./(3.*sqrt(7.))*orbital[mo].coeff[i+11];
                         newmo[j+13]=-0.5*sqrt(3./14.)*orbital[mo].coeff[i+1]
                                    -0.5*sqrt(3./2.)*orbital[mo].coeff[i+5]
                                    +1./(3.*sqrt(7.))*orbital[mo].coeff[i+10];
                         newmo[j+14]=sqrt(3./7.)*orbital[mo].coeff[i+3]
                                    +1./(3.*sqrt(7.))*orbital[mo].coeff[i+12];
                       }
                       i+=15;
                    }
                    j+=15;
                    break;
            default: break;
          }
          shell=shell->next;
        } while (shell != NULL);
      }
    }
    orbital[mo].coeff=c;
  }
  if (fproblem)
  {
    p=getStringResource(topShell, "GaussianProblem");
    sprintf(line, p, 'f');
    if (!messgb(topShell, 3, line, buttons, 2)) exit (-1);
  }
  if (gproblem)
  {
    p=getStringResource(topShell, "GaussianProblem");
    sprintf(line, p, 'g');
    if (!messgb(topShell, 3, line, buttons, 2)) exit(-1);
  }
  if (fproblem || gproblem)
  {
    fremem((void **)&newmo);
    fremem((void **)&orbital);
    return;
  }
  if (lmax > LMAX)
  {
    strcpy(line, "I cannot handle ");
    for (i=LMAX+1; i<lmax; i++)
    {
      sprintf(l, "%c, ", i+'c');
      strcat(line, l);
    }
    sprintf(l, "%c-", lmax+'c');
    if (LMAX+1 != lmax)
    {
      if (lmax-LMAX == 2)
        sprintf(line+strlen(line)-2, "and ");
      else
        strcat(line, "and ");
    }
    strcat(line, l);
    strcat(line, "functions.");
/*  if (messgb(&mx, &my, &one, line, "Continue|Exit programme") == 2) exit(-1);  */
  }
}

void assignBasisName(int imol)
{
  struct MOLECULE *mol;
  struct BASISSET *shell;
  size_t ntotal;
/*char *p;*/
  register int atom, j;

  mol=&molecules[imol];
/*ntotal=norbs(mol);
  if (basisname == NULL)
    basisname=(char *)getmem((size_t)ntotal, 8*sizeof(char));
  if (mol->basisFunctionNames == NULL)
    mol->basisFunctionNames=(char **)getmem((size_t)ntotal, sizeof(char *));
  j=0;
  p=basisname; */
  for (atom=0; atom<mol->na; atom++) /* assign a name for each basis */
  {                                  /* function                     */
/*  atombasisnames[2*atom]=j;*/
    j=0;
    ntotal=numberBasisFunctions(mol->atoms[atom].basis);
    mol->atoms[atom].basisFunctionNames=(char **)getmem((size_t)ntotal, sizeof(char *));
    shell=mol->atoms[atom].basis;
    if (!shell) return;
    do
    {
      switch (shell->ang)
      {
        case 0: /* strcpy(p, "s");
                p+=8; */
		mol->atoms[atom].basisFunctionNames[j]=&basisNames[0];
                j++;
                break;
        case 1: /* strcpy(p,    "p(x)");
                strcpy(p+8,  "p(y)");
                strcpy(p+16, "p(z)");
                p+=24; */
		mol->atoms[atom].basisFunctionNames[j]=&basisNames[2];
		mol->atoms[atom].basisFunctionNames[j+1]=&basisNames[7];
		mol->atoms[atom].basisFunctionNames[j+2]=&basisNames[12];
                j+=3;
                break;
        case 2: /*strcpy(p,    "d(xx)");
                strcpy(p+8,  "d(yy)");
                strcpy(p+16, "d(zz)");
                strcpy(p+24, "d(xy)");
                strcpy(p+32, "d(xz)");
                strcpy(p+40, "d(yz)");
                p+=48; */
		mol->atoms[atom].basisFunctionNames[j]=&basisNames[17];
		mol->atoms[atom].basisFunctionNames[j+1]=&basisNames[23];
		mol->atoms[atom].basisFunctionNames[j+2]=&basisNames[29];
		mol->atoms[atom].basisFunctionNames[j+3]=&basisNames[35];
		mol->atoms[atom].basisFunctionNames[j+4]=&basisNames[41];
		mol->atoms[atom].basisFunctionNames[j+5]=&basisNames[47];
                j+=6;
                break;
        case 3: /*strcpy(p,    "f(xxx)");
                strcpy(p+8,  "f(yyy)");
                strcpy(p+16, "f(zzz)");
                strcpy(p+24, "f(xxy)");
                strcpy(p+32, "f(xxz)");
                strcpy(p+40, "f(yyx)");
                strcpy(p+48, "f(yyz)");
                strcpy(p+56, "f(zzx)");
                strcpy(p+64, "f(zzy)");
                strcpy(p+72, "f(xyz)");
                p+=80;*/
		mol->atoms[atom].basisFunctionNames[j]=&basisNames[53];
		mol->atoms[atom].basisFunctionNames[j+1]=&basisNames[60];
		mol->atoms[atom].basisFunctionNames[j+2]=&basisNames[67];
		mol->atoms[atom].basisFunctionNames[j+3]=&basisNames[74];
		mol->atoms[atom].basisFunctionNames[j+4]=&basisNames[81];
		mol->atoms[atom].basisFunctionNames[j+5]=&basisNames[88];
		mol->atoms[atom].basisFunctionNames[j+6]=&basisNames[95];
		mol->atoms[atom].basisFunctionNames[j+7]=&basisNames[102];
		mol->atoms[atom].basisFunctionNames[j+8]=&basisNames[109];
		mol->atoms[atom].basisFunctionNames[j+9]=&basisNames[116];
                j+=10;
                break;
        case 4: /*strcpy(p,    "g(xxxx)");
                strcpy(p+8,  "g(yyyy)");
                strcpy(p+16, "g(zzzz)");
                strcpy(p+24, "g(xxxy)");
                strcpy(p+32, "g(xxxz)");
                strcpy(p+40, "g(yyyx)");
                strcpy(p+48, "g(yyyz)");
                strcpy(p+56, "g(zzzx)");
                strcpy(p+64, "g(zzzy)");
                strcpy(p+72, "g(xxyy)");
                strcpy(p+80, "g(xxzz)");
                strcpy(p+88, "g(yyzz)");
                strcpy(p+96, "g(xxyz)");
                strcpy(p+104,"g(yyxz)");
                strcpy(p+112,"g(zzxy)");
                p+=120;*/
		mol->atoms[atom].basisFunctionNames[j]=&basisNames[123];
		mol->atoms[atom].basisFunctionNames[j+1]=&basisNames[131];
		mol->atoms[atom].basisFunctionNames[j+2]=&basisNames[139];
		mol->atoms[atom].basisFunctionNames[j+3]=&basisNames[147];
		mol->atoms[atom].basisFunctionNames[j+4]=&basisNames[155];
		mol->atoms[atom].basisFunctionNames[j+5]=&basisNames[163];
		mol->atoms[atom].basisFunctionNames[j+6]=&basisNames[171];
		mol->atoms[atom].basisFunctionNames[j+7]=&basisNames[179];
		mol->atoms[atom].basisFunctionNames[j+8]=&basisNames[187];
		mol->atoms[atom].basisFunctionNames[j+9]=&basisNames[195];
		mol->atoms[atom].basisFunctionNames[j+10]=&basisNames[203];
		mol->atoms[atom].basisFunctionNames[j+11]=&basisNames[211];
		mol->atoms[atom].basisFunctionNames[j+12]=&basisNames[219];
		mol->atoms[atom].basisFunctionNames[j+13]=&basisNames[227];
		mol->atoms[atom].basisFunctionNames[j+14]=&basisNames[235];
                j+=15;
                break;
      }
      shell=shell->next;
    } while (shell != NULL);
    mol->atoms[atom].nBasisFunctions=j;
/*  atombasisnames[2*atom+1]=j-1;*/
  }
}
/*
void bfnamn(int atom, int *start, int *end)
{
  *start=atombasisnames[2*atom];
  *end=atombasisnames[2*atom+1];
}

char *bfname(int ibasfu)
{
  return(basisname+8*ibasfu);
}*/
