This file is indexed.

/usr/include/sc/chemistry/molecule/coor.h is in libsc-dev 2.3.1-16.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
//
// coor.h
//
// Copyright (C) 1996 Limit Point Systems, Inc.
//
// Author: Curtis Janssen <cljanss@limitpt.com>
// Maintainer: LPS
//
// This file is part of the SC Toolkit.
//
// The SC Toolkit is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// The SC Toolkit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
//
// The U.S. Government is granted a limited license as per AL 91-7.
//

#ifndef _chemistry_molecule_coor_h
#define _chemistry_molecule_coor_h

#ifdef __GNUC__
#pragma interface
#endif

#include <iostream>
#include <vector>

#include <math/scmat/matrix.h>
#include <math/optimize/transform.h>
#include <chemistry/molecule/molecule.h>

namespace sc {

/** The IntCoor abstract class describes an internal coordinate of a
molecule. */
class IntCoor: public SavableState {
  protected:
    // conversion factors from radians, bohr to the preferred units
    static double bohr_conv;
    static double radian_conv;
    char *label_;
    double value_;
  public:
    IntCoor(StateIn&);
    IntCoor(const IntCoor&);
    /** This constructor takes a string containing a label for the
        internal coordinate.  The string is copied. */
    IntCoor(const char* label = 0);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>label</tt><dd> A label for the coordinate using only to
        identify the coordinate to the user in printouts.  The default is
        no label.

        <dt><tt>value</tt><dd> A value for the coordinate.  In the way that
        coordinates are usually used, the default is to compute a value
        from the cartesian coordinates in a Molecule object.

        <dt><tt>unit</tt><dd> The unit in which the value is given.  This
        can be bohr, anstrom, radian, and degree.  The default is bohr for
        lengths and radian for angles.

        </dl> */
    IntCoor(const Ref<KeyVal>&);
    
    virtual ~IntCoor();
    void save_data_state(StateOut&);

    /// Returns the string containing the label for the internal coordinate.
    virtual const char* label() const;
    /// Returns the value of the coordinate in atomic units or radians.
    virtual double value() const;
    /// Sets the value of the coordinate in atomic units or radians.
    virtual void set_value(double);
    /// Returns the value of the coordinate in more familiar units.
    virtual double preferred_value() const;
    /// Returns a string representation of the type of coordinate this is.
    virtual const char* ctype() const = 0;
    /// Print information about the coordinate.
    virtual void print(std::ostream & o=ExEnv::out0()) const;
    virtual void print_details(const Ref<Molecule> &, std::ostream& =ExEnv::out0()) const;
    /** Returns the value of the force constant associated with this
        coordinate. */
    virtual double force_constant(Ref<Molecule>&) = 0;
    /// Recalculate the value of the coordinate.
    virtual void update_value(const Ref<Molecule>&) = 0;
    /// Fill in a row the the B matrix.
    virtual void bmat(const Ref<Molecule>&,RefSCVector&bmat,double coef=1.0) = 0;
    /** Test to see if this internal coordinate is equivalent to that one.
        The definition of equivalence is left up to the individual
        coordinates. */
    virtual int equivalent(Ref<IntCoor>&) = 0;
};

/** SumIntCoor is used to construct linear combinations of internal
coordinates.

The following is a sample ParsedKeyVal input for a SumIntCoor object:
<pre>
  sumintcoor\<SumIntCoor>: (
    coor: [
      \<StreSimpleCo>:( atoms = [ 1 2 ] )
      \<StreSimpleCo>:( atoms = [ 2 3 ] )
      ]
    coef = [ 1.0 1.0 ]
    )
</pre>
*/
class SumIntCoor: public IntCoor {
  private:
    std::vector<double> coef_;
    std::vector<Ref<IntCoor> > coor_;
  public:
    SumIntCoor(StateIn&);
    /** This constructor takes a string containing a label for this
        coordinate. */
    SumIntCoor(const char *);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>coor</tt><dd> A vector of IntCoor objects that define the
        summed coordinates.

        <dt><tt>coef</tt><dd> A vector of floating point numbers that gives
        the coefficients of the summed coordinates.

        </dl> */
    SumIntCoor(const Ref<KeyVal>&);

    ~SumIntCoor();
    void save_data_state(StateOut&);

    /// Returns the number of coordinates in this linear combination.
    int n();
    /** Add a coordinate to the linear combination.  coef is the
        coefficient for the added coordinate. */
    void add(Ref<IntCoor>&,double coef);
    /// This function normalizes all the coefficients.
    void normalize();

    // IntCoor overrides
    /// Returns the value of the coordinate in a.u. and radians.
    double preferred_value() const;
    /// Always returns ``SUM''.
    const char* ctype() const;
    /// Print the individual coordinates in the sum with their coefficients.
    void print_details(const Ref<Molecule> &, std::ostream& =ExEnv::out0()) const;
    /// Returns the weighted sum of the individual force constants.
    double force_constant(Ref<Molecule>&);
    /// Recalculate the value of the coordinate.
    void update_value(const Ref<Molecule>&);
    /// Fill in a row the the B matrix.
    void bmat(const Ref<Molecule>&,RefSCVector&bmat,double coef = 1.0);
    /// Always returns 0.
    int equivalent(Ref<IntCoor>&);
};

/** The SetIntCoor class describes a set of internal coordinates.
It can automatically generate these coordinates using a integral coordinate
generator object (see the IntCoorGen class) or the internal
coordinates can be explicity given.

The following is a sample ParsedKeyVal input for
a SetIntCoor object.
<pre>
  setintcoor<SetIntCoor>: [
    \<SumIntCoor>: (
      coor: [
        \<StreSimpleCo>:( atoms = [ 1 2 ] )
        \<StreSimpleCo>:( atoms = [ 2 3 ] )
        ]
      coef = [ 1.0 1.0 ]
      )
    \<BendSimpleCo>:( atoms = [ 1 2 3 ] )
  ]
</pre>
*/
class SetIntCoor: public SavableState {
  private:
    std::vector<Ref<IntCoor> > coor_;
  public:
    SetIntCoor();
    SetIntCoor(StateIn&);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>generator</tt><dd> A IntCoorGen object that will be used to
        generate the internal coordinates.

        <dt><tt>i</tt><dd> A sequence of integer keywords, all \f$i\f$ for
        \f$0 \leq i < n\f$, can be assigned to IntCoor objects.

        </dl> */
    SetIntCoor(const Ref<KeyVal>&);

    virtual ~SetIntCoor();
    void save_data_state(StateOut&);

    /// Adds an internal coordinate to the set.
    void add(const Ref<IntCoor>&);
    /// Adds all the elements of another set to this one.
    void add(const Ref<SetIntCoor>&);
    /// Removes the last coordinate from this set.
    void pop();
    /// Removes all coordinates from the set.
    void clear();
    /// Returns the number of coordinates in the set.
    int n() const;
    /// Returns a reference to the i'th coordinate in the set.
    Ref<IntCoor> coor(int i) const;
    /// Compute the B matrix by finite displacements.
    virtual void fd_bmat(const Ref<Molecule>&,RefSCMatrix&);
    /// Compute the B matrix the old-fashioned way.
    virtual void bmat(const Ref<Molecule>&, RefSCMatrix&);
    /** Create an approximate Hessian for this set of coordinates.  This
        Hessian is a symmetric matrix whose i'th diagonal is the force
        constant for the i'th coordinate in the set. */
    virtual void guess_hessian(Ref<Molecule>&,RefSymmSCMatrix&);
    /// Print the coordinates in the set.
    virtual void print_details(const Ref<Molecule> &,std::ostream& =ExEnv::out0()) const;
    /// Recalculate the values of the internal coordinates in the set.
    virtual void update_values(const Ref<Molecule>&);
    /// Copy the values of the internal coordinates to a vector.
    virtual void values_to_vector(const RefSCVector&);
};


// ////////////////////////////////////////////////////////////////////////

class BitArrayLTri;

/** IntCoorGen generates a set of simple internal coordinates
    for a molecule. */
class IntCoorGen: public SavableState
{
  protected:
    Ref<Molecule> molecule_;
    
    int linear_bends_;
    int linear_lbends_;
    int linear_tors_;
    int linear_stors_;
    int nextra_bonds_;
    int *extra_bonds_;
    double linear_bend_thres_;
    double linear_tors_thres_;
    double radius_scale_factor_;

    void init_constants();

    double cos_ijk(Molecule& m, int i, int j, int k);
    int hterminal(Molecule& m, BitArrayLTri& bonds, int i);
    int nearest_contact(int i, Molecule& m);

    void add_bonds(const Ref<SetIntCoor>& list, BitArrayLTri& bonds, Molecule& m);
    void add_bends(const Ref<SetIntCoor>& list, BitArrayLTri& bonds, Molecule& m);
    void add_tors(const Ref<SetIntCoor>& list, BitArrayLTri& bonds, Molecule& m);
    void add_out(const Ref<SetIntCoor>& list, BitArrayLTri& bonds, Molecule& m);
  public:
    /** Create an IntCoorGen given a Molecule and, optionally, extra bonds.
        IntCoorGen keeps a reference to extra and deletes it when the
        destructor is called. */
    IntCoorGen(const Ref<Molecule>&, int nextra=0, int *extra=0);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>molecule</tt><dd> A Molecule object.  There is no default.

        <dt><tt>radius_scale_factor</tt><dd> If the distance between two
        atoms is less than the radius scale factor times the sum of the
        atoms' atomic radii, then a bond is placed between the two atoms
        for the purpose of finding internal coordinates.  The default is
        1.1.

        <dt><tt>linear_bend_threshold</tt><dd> A bend angle in degress
        greater than 180 minus this keyword's floating point value is
        considered a linear bend. The default is 1.0.

        <dt><tt>linear_tors_threshold</tt><dd> The angles formed by atoms
        a-b-c and b-c-d are checked for near linearity.  If an angle in
        degrees is greater than 180 minus this keyword's floating point
        value, then the torsion is classified as a linear torsion. The
        default is 1.0.

        <dt><tt>linear_bend</tt><dd> Generate BendSimpleCo objects to
        describe linear bends.  The default is false.

        <dt><tt>linear_lbend</tt><dd> Generate pairs of LinIPSimpleCo and
        LinIPSimpleCo objects to describe linear bends.  The default is
        true.

        <dt><tt>linear_tors</tt><dd> Generate TorsSimpleCo objects to
        described linear torsions.  The default is false.

        <dt><tt>linear_stors</tt><dd> Generate ScaledTorsSimpleCo objects
        to described linear torsions.  The default is true.

        <dt><tt>extra_bonds</tt><dd> This is a vector of atom numbers,
        where elements \f$2 (i-1) + 1\f$ and \f$2 i\f$ specify the atoms
        which are bound in extra bond \f$i\f$.  The extra_bonds keyword
        should only be needed for weakly interacting fragments, otherwise
        all the needed bonds will be found.

        </dl> */
    IntCoorGen(const Ref<KeyVal>&);
    IntCoorGen(StateIn&);

    ~IntCoorGen();

    /// Standard member.
    void save_data_state(StateOut&);

    /// This generates a set of internal coordinates.
    virtual void generate(const Ref<SetIntCoor>&);

    /// Print out information about this.
    virtual void print(std::ostream& out=ExEnv::out0()) const;
};


// ////////////////////////////////////////////////////////////////////////


/** The MolecularCoor abstract class describes the coordinate system used
to describe a molecule.  It is used to convert a molecule's cartesian
coordinates to and from this coordinate system. */
class MolecularCoor: public SavableState
{
  protected:
    Ref<Molecule> molecule_;
    RefSCDimension dnatom3_; // the number of atoms x 3
    Ref<SCMatrixKit> matrixkit_; // used to construct matrices

    int debug_;
  public:
    MolecularCoor(Ref<Molecule>&);
    MolecularCoor(StateIn&);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>molecule</tt><dd> A Molecule object.  There is no default.

        <dt><tt>debug</tt><dd> An integer which, if nonzero, will cause
        extra output.

        <dt><tt>matrixkit</tt><dd> A SCMatrixKit object.  It is usually
        unnecessary to give this keyword.

        <dt><tt>natom3</tt><dd> An SCDimension object for the dimension of
        the vector of cartesian coordinates.  It is usually unnecessary to
        give this keyword.

        </dl> */
    MolecularCoor(const Ref<KeyVal>&);

    virtual ~MolecularCoor();

    void save_data_state(StateOut&);

    /** Returns a smart reference to an SCDimension equal to the
        number of atoms in the molecule times 3. */
    RefSCDimension dim_natom3() { return dnatom3_; }

    /// Returns the molecule.
    Ref<Molecule> molecule() const { return molecule_; }

    /// Print the coordinate.
    virtual void print(std::ostream& =ExEnv::out0()) const = 0;
    virtual void print_simples(std::ostream& =ExEnv::out0()) const = 0;

    /** Returns a smart reference to an SCDimension equal to the number of
        coordinates (be they Cartesian, internal, or whatever) that are
        being optimized. */
    virtual RefSCDimension dim() = 0;
    
    /** Given a set of displaced internal coordinates, update the cartesian
        coordinates of the Molecule contained herein.  This function does
        not change the vector ``internal''. */
    int to_cartesian(const RefSCVector&internal);
    virtual int to_cartesian(const Ref<Molecule>&mol,
                             const RefSCVector&internal) = 0;

    /** Fill in the vector ``internal'' with the current internal
        coordinates.  Note that this member will update the values of the
        variable internal coordinates. */
    virtual int to_internal(RefSCVector&internal) = 0;

    /** Convert the internal coordinate gradients in ``internal'' to
        Cartesian coordinates and copy these Cartesian coordinate gradients
        to ``cartesian''. Only the variable internal coordinate gradients
        are transformed. */
    virtual int to_cartesian(RefSCVector&cartesian,RefSCVector&internal) = 0;

    /** Convert the Cartesian coordinate gradients in ``cartesian'' to
        internal coordinates and copy these internal coordinate gradients
        to ``internal''.  Only the variable internal coordinate gradients
        are calculated. */
    virtual int to_internal(RefSCVector&internal,RefSCVector&cartesian) = 0;

    /** Convert the internal coordinate Hessian ``internal'' to Cartesian
        coordinates and copy the result to ``cartesian''.  Only the variable
        internal coordinate force constants are transformed. */
    virtual int to_cartesian(RefSymmSCMatrix&cartesian,
                              RefSymmSCMatrix&internal) =0;

    /** Convert the Cartesian coordinate Hessian ``cartesian'' to internal
        coordinates and copy the result to ``internal''.  Only the variable
        internal coordinate force constants are calculated. */
    virtual int to_internal(RefSymmSCMatrix&internal,
                             RefSymmSCMatrix&cartesian) = 0;

    /** Calculate an approximate hessian and place the result in
        ``hessian''. */
    virtual void guess_hessian(RefSymmSCMatrix&hessian) = 0;

    /** Given an Hessian, return the inverse of that hessian.  For singular
        matrices this should return the generalized inverse. */
    virtual RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&) = 0;

    /// Returns the number of constrained coordinates.
    virtual int nconstrained();

    /** When this is called, MoleculeCoor may select a new internal
        coordinate system and return a transform to it.  The default action
        is to not change anything and return an IdentityTransform. */
    virtual Ref<NonlinearTransform> change_coordinates();

    Ref<SCMatrixKit> matrixkit() const { return matrixkit_; }
};


/** The IntMolecularCoor abstract class describes a molecule's coordinates
in terms of internal coordinates. */
class IntMolecularCoor: public MolecularCoor
{
  protected:
    Ref<IntCoorGen> generator_;

    void form_K_matrix(RefSCDimension& dredundant,
                       RefSCDimension& dfixed,
                       RefSCMatrix& K,
                       int*& is_totally_symmetric);

    RefSCDimension dim_; // corresponds to the number of variable coordinates
    RefSCDimension dvc_; // the number of variable + constant coordinates

    Ref<SetIntCoor> variable_; // the variable internal coordinates
    Ref<SetIntCoor> constant_; // the constant internal coordinates
    
    Ref<SetIntCoor> fixed_;
    Ref<SetIntCoor> watched_;
    Ref<IntCoor> followed_;

    // these are all of the basic coordinates
    Ref<SetIntCoor> bonds_;
    Ref<SetIntCoor> bends_;
    Ref<SetIntCoor> tors_;
    Ref<SetIntCoor> outs_;
    // these are provided by the user or generated coordinates that
    // could not be assigned to any of the above catagories
    Ref<SetIntCoor> extras_;

    Ref<SetIntCoor> all_;

    // Useful relationships
    // variable_->n() + constant_->n() = 3N-6(5)
    // symm_->n() + asymm_->n() = 3N-6(5)

    int update_bmat_;  // if 1 recompute the b matrix during to_cartesian
    int only_totally_symmetric_; // only coors with tot. symm comp. are varied
    double symmetry_tolerance_; // tol used to find coors with tot. sym. comp.
    double simple_tolerance_; // tol used to see if a simple is included
    double coordinate_tolerance_; // tol used to see if a coor is included
    double cartesian_tolerance_;  // tol used in intco->cart transformation
    double scale_bonds_; // scale factor for bonds
    double scale_bends_; // scale factor for bends
    double scale_tors_;  // scale factor for tors
    double scale_outs_;  // scale factor for outs

    int nextra_bonds_;
    int* extra_bonds_;

    int given_fixed_values_; // if true make molecule have given fixed values

    int decouple_bonds_;
    int decouple_bends_;

    int max_update_steps_;
    double max_update_disp_;

    /** This is called by the constructors of classes derived from
        IntMolecularCoor.  It initialized the lists of simple internal
        coordinates, and then calls the form_coordinates() member. */
    virtual void init();
    /** Allocates memory for the SetIntCoor's used to store the
        simple and internal coordinates. */
    virtual void new_coords();
    /// Reads the KeyVal input.
    virtual void read_keyval(const Ref<KeyVal>&);

    // control whether or not to print coordinates when they are formed
    int form_print_simples_;
    int form_print_variable_;
    int form_print_constant_;
    int form_print_molecule_;
  public:
    IntMolecularCoor(StateIn&);
    IntMolecularCoor(Ref<Molecule>&mol);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>variable</tt><dd> Gives a SetIntCoor object that specifies
        the internal coordinates that can be varied. If this is not given,
        the variable coordinates will be generated.

        <dt><tt>followed</tt><dd> Gives a IntCoor object that specifies a
        coordinate to used as the first coordinate in the variable
        coordinate list.  The remaining coordinates will be automatically
        generated.  The default is no followed coordinate.  This option is
        usually used to set the initial search direction for a transition
        state optimization, where it is used in conjunction with the
        mode_following keyword read by the EFCOpt class.

        <dt><tt>fixed</tt><dd> Gives a SetIntCoor object that specifies the
        internal coordinates that will be fixed.  The default is no fixed
        coordinates.

        <dt><tt>watched</tt><dd> Gives a SetIntCoor object that specifies
        internal coordinates that will be printed out whenever the
        coordinates are changed.  The default is none.

        <dt><tt>have_fixed_values</tt><dd> If true, then values for the
        fixed coordinates must be given in fixed and an attempt will be
        made to displace the initial geometry to the given fixed
        values. The default is false.

        <dt><tt>extra_bonds</tt><dd> This is only read if the generator
        keyword is not given.  It is a vector of atom numbers, where
        elements \f$(i-1)\times 2 + 1\f$ and \f$i\times 2\f$ specify the
        atoms which are bound in extra bond \f$i\f$.  The extra_bonds
        keyword should only be needed for weakly interacting fragments,
        otherwise all the needed bonds will be found.

        <dt><tt>generator</tt><dd> Specifies an IntCoorGen object that
        creates simple, redundant internal coordinates. If this keyword is
        not given, then a vector giving extra bonds to be added is read
        from extra_bonds and this is used to create an IntCoorGen object.

        <dt><tt>decouple_bonds</tt><dd> Automatically generated internal
        coordinates are linear combinations of possibly any mix of simple
        internal coordinates.  If decouple_bonds is true, an attempt will
        be made to form some of the internal coordinates from just stretch
        simple coordinates.  The default is false.

        <dt><tt>decouple_bends</tt><dd> This is like decouple_bonds except
        it applies to the bend-like coordinates.  The default is false.

        <dt><tt>max_update_disp</tt><dd> The maximum displacement to be
        used in the displacement to fixed internal coordinates values.
        Larger displacements will be broken into several smaller
        displacements and new coordinates will be formed for each of these
        displacments. This is only used when fixed and have_fixed_values
        are given.  The default is 0.5.

        <dt><tt>max_update_steps</tt><dd> The maximum number of steps
        permitted to convert internal coordinate displacements to cartesian
        coordinate displacements.  The default is 100.
               
        <dt><tt>update_bmat</tt><dd> Displacements in internal coordinates
        are converted to a cartesian displacements iteratively.  If there
        are large changes in the cartesian coordinates during conversion,
        then recompute the \f$B\f$ matrix, which is using to do the
        conversion.  The default is false.

        <dt><tt>only_totally_symmetric</tt><dd> If a simple test reveals
        that an internal coordinate is not totally symmetric, then it will
        not be added to the internal coordinate list.  The default is true.
               
        <dt><tt>simple_tolerance</tt><dd> The internal coordinates are
        formed as linear combinations of simple, redundant internal
        coordinates.  Coordinates with coefficients smaller then
        simple_tolerance will be omitted. The default is 1.0e-3.

        <dt><tt>cartesian_tolerance</tt><dd> The tolerance for conversion
        of internal coordinate displacements to cartesian displacements.
        The default is 1.0e-12.
               
        <dt><tt>form:print_simple</tt><dd> Print the simple internal
        coordinates.  The default is false.
               
        <dt><tt>form:print_variable</tt><dd> Print the variable internal
        coordinates.  The default is false.
               
        <dt><tt>form:print_constant</tt><dd> Print the constant internal
        coordinates.  The default is false.
               
        <dt><tt>form:print_molecule</tt><dd> Print the molecule when
        forming coordinates.  The default is false.
               
        <dt><tt>scale_bonds</tt><dd> Obsolete.  The default value is 1.0.

        <dt><tt>scale_bends</tt><dd> Obsolete.  The default value is 1.0.
               
        <dt><tt>scale_tors</tt><dd> Obsolete.  The default value is 1.0.

        <dt><tt>scale_outs</tt><dd> Obsolete.  The default value is 1.0.

        <dt><tt>symmetry_tolerance</tt><dd> Obsolete.  The default is 1.0e-5.

        <dt><tt>coordinate_tolerance</tt><dd> Obsolete.  The default is 1.0e-7.

        </dl> */
    IntMolecularCoor(const Ref<KeyVal>&);

    virtual ~IntMolecularCoor();
    void save_data_state(StateOut&);
  
    /** Actually form the variable and constant internal coordinates from
        the simple internal coordinates. */
    virtual void form_coordinates(int keep_variable=0) =0;
    
    /** Like to_cartesians(), except all internal coordinates are
        considered, not just the variable ones. */
    virtual int all_to_cartesian(const Ref<Molecule> &,RefSCVector&internal);
    /** Like to_internal(), except all internal coordinates are
        considered, not just the variable ones. */
    virtual int all_to_internal(const Ref<Molecule> &,RefSCVector&internal);

    /** These implement the virtual functions inherited from
        MolecularCoor. */
    virtual RefSCDimension dim();
    virtual int to_cartesian(const Ref<Molecule> &,const RefSCVector&internal);
    virtual int to_internal(RefSCVector&internal);
    virtual int to_cartesian(RefSCVector&cartesian,RefSCVector&internal);
    virtual int to_internal(RefSCVector&internal,RefSCVector&cartesian);
    virtual int to_cartesian(RefSymmSCMatrix&cart,RefSymmSCMatrix&internal);
    virtual int to_internal(RefSymmSCMatrix&internal,RefSymmSCMatrix&cart);
    virtual void print(std::ostream& =ExEnv::out0()) const;
    virtual void print_simples(std::ostream& =ExEnv::out0()) const;
    virtual void print_variable(std::ostream& =ExEnv::out0()) const;
    virtual void print_constant(std::ostream& =ExEnv::out0()) const;
    int nconstrained();
};

// ///////////////////////////////////////////////////////////////////////

/** The SymmMolecularCoor class derives from IntMolecularCoor.  It provides
a unique set of totally symmetric internal coordinates.  Giving an
MolecularEnergy object a coor is usually the best way to optimize a
molecular structure.  However, for some classes of molecules
SymmMolecularCoor doesn't work very well.  For example, enediyne can cause
problems.  In these cases, cartesian coordinates (obtained by not giving
the MolecularEnergy object the coor keyword) might be better or you can
manually specify the coordinates that the SymmMolecularCoor object uses
with the variable keyword (see the IntMolecularCoor class description).  */
class SymmMolecularCoor: public IntMolecularCoor
{
  protected:
    // true if coordinates should be changed during optimization
    int change_coordinates_;
    // true if hessian should be transformed too (should always be true)
    int transform_hessian_;
    // max value for the condition number if coordinates can be changed
    double max_kappa2_;

    void init();
  public:
    SymmMolecularCoor(Ref<Molecule>&mol);
    SymmMolecularCoor(StateIn&);
    /** The KeyVal constructor.
        <dl>

        <dt><tt>change_coordinates</tt><dd> If true, the quality of the
        internal coordinates will be checked periodically and if they are
        beginning to become linearly dependent a new set of internal
        coordinates will be computed.  The default is false.

        <dt><tt>max_kappa2</tt><dd> A measure of the quality of the
        internal coordinates.  Values of the 2-norm condition,
        \f$\kappa_2\f$, larger than max_kappa2 are considered linearly
        dependent.  The default is 10.0.

        <dt><tt>transform_hessian</tt><dd> If true, the hessian will be
        transformed every time the internal coordinates are formed.  The
        default is true.

        </dl> */
    SymmMolecularCoor(const Ref<KeyVal>&);

    virtual ~SymmMolecularCoor();
    void save_data_state(StateOut&);

    /** Actually form the variable and constant internal coordinates from
        simple internal coordinates. */
    void form_coordinates(int keep_variable=0);

    /// Form the approximate hessian.
    void guess_hessian(RefSymmSCMatrix&hessian);
    /// Invert the hessian.
    RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&);

    /** This overrides MoleculeCoor's change_coordinates
        and might transform to a new set of coordinates. */
    Ref<NonlinearTransform> change_coordinates();

    void print(std::ostream& =ExEnv::out0()) const;
};

// ///////////////////////////////////////////////////////////////////////

/** The RedundMolecularCoor class provides a redundant set of simple
internal coordinates. */
class RedundMolecularCoor: public IntMolecularCoor
{

  public:
    RedundMolecularCoor(Ref<Molecule>&mol);
    RedundMolecularCoor(StateIn&);
    /// The KeyVal constructor.
    RedundMolecularCoor(const Ref<KeyVal>&);

    virtual ~RedundMolecularCoor();
    void save_data_state(StateOut&);

    /** Actually form the variable and constant internal coordinates from
        the simple internal coordinates. */
    void form_coordinates(int keep_variable=0);
    /// Form the approximate hessian.
    void guess_hessian(RefSymmSCMatrix&hessian);
    /// Invert the hessian.
    RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&);
};

// ///////////////////////////////////////////////////////////////////////

/** The CartMolecularCoor class implements Cartesian coordinates in a way
    suitable for use in geometry optimizations. CartMolecularCoor is a
    SavableState has StateIn and KeyVal constructors. CartMolecularCoor is
    derived from MolecularCoor. */
class CartMolecularCoor: public MolecularCoor
{
  private:
  protected:
    RefSCDimension dim_; // the number of atoms x 3

    /// Initializes the dimensions.
    virtual void init();
  public:
    CartMolecularCoor(Ref<Molecule>&mol);
    CartMolecularCoor(StateIn&);
    /// The KeyVal constructor.
    CartMolecularCoor(const Ref<KeyVal>&);

    virtual ~CartMolecularCoor();
  
    void save_data_state(StateOut&);

    /// These implement the virtual functions inherited from MolecularCoor.
    virtual RefSCDimension dim();
    virtual int to_cartesian(const Ref<Molecule>&,const RefSCVector&internal);
    virtual int to_internal(RefSCVector&internal);
    virtual int to_cartesian(RefSCVector&cartesian,RefSCVector&internal);
    virtual int to_internal(RefSCVector&internal,RefSCVector&cartesian);
    virtual int to_cartesian(RefSymmSCMatrix&cart,RefSymmSCMatrix&internal);
    virtual int to_internal(RefSymmSCMatrix&internal,RefSymmSCMatrix&cart);
    virtual void print(std::ostream& =ExEnv::out0()) const;
    virtual void print_simples(std::ostream& =ExEnv::out0()) const;
    void guess_hessian(RefSymmSCMatrix&hessian);
    RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&);
};

}

#endif

// Local Variables:
// mode: c++
// c-file-style: "CLJ"
// End: