void
MAST::OrthotropicProperty3D::
ThermalExpansionMatrix::derivative (   const MAST::FunctionBase& f,
                                    const libMesh::Point& p,
                                    const Real t,
                                    RealMatrixX& m) const {
    
    RealMatrixX
    dm   = RealMatrixX::Zero(6, 6),
    mat  = RealMatrixX::Zero(6, 1),
    dmat = RealMatrixX::Zero(6, 1),
    A    = RealMatrixX::Zero(3, 3),
    dA   = RealMatrixX::Zero(3, 3),
    Tinv = RealMatrixX::Zero(6, 6),
    dTinv= RealMatrixX::Zero(6, 6);
    
    _material_stiffness  (p, t, m);
    _material_stiffness.derivative( f, p, t, dm);
    _material_expansion (p, t, mat);
    _material_expansion.derivative( f, p, t, dmat);
    _orient              (p, t, A);
    _orient.stress_strain_transformation_matrix(A.transpose(), Tinv);
    _orient.derivative    (f, p, t, dA);
    _orient.stress_strain_transformation_matrix_sens(A.transpose(),
                                                      dA.transpose(),
                                                      dTinv);
    
    m =
    dTinv *  m *  mat +
    Tinv  * dm *  mat +
    Tinv  *  m * dmat;
}
void
MAST::OrthotropicProperty3D::
ThermalExpansionMatrix::operator() (const libMesh::Point& p,
                                    const Real t,
                                    RealMatrixX& m) const {
    RealMatrixX
    mat  = RealMatrixX::Zero(6,1),
    A    = RealMatrixX::Zero(3, 3),
    Tinv = RealMatrixX::Zero(6, 6);
    
    _material_stiffness  (p, t, m);
    _material_expansion  (p, t, mat);
    _orient              (p, t, A);
    _orient.stress_strain_transformation_matrix(A.transpose(), Tinv);
    
    //    epsilon' = T^{-T} epsilon
    //    epsilon  = T^T epsilon'
    //    C = Tinv C' T^{-T}
    //    epsilon_delta_T = C epsilon
    //                    = Tinv C' T^{-T} T^T epsilon'
    //                    = Tinv C' alpha' delta_temp
    //    hence,
    //    mat = Tinv C' alpha'
    m =  Tinv * m * mat;
}
void
MAST::OrthotropicProperty3D::
StiffnessMatrix::operator() (const libMesh::Point& p,
                             const Real t,
                             RealMatrixX& m) const {
    RealMatrixX
    A    = RealMatrixX::Zero(3, 3),
    Tinv = RealMatrixX::Zero(6, 6);
    
    _material_stiffness (p, t, m);
    _orient             (p, t, A);
    _orient.stress_strain_transformation_matrix(A.transpose(), Tinv);
    
    //    vk'  = vj ej.ek' = vj Ajk = A^T v
    //    v = A vk'
    //    sij' = skl ek.ei' el.ej' = skl Aki Alj = A^T s A
    //    s' = T s
    //    s = Tinv s'
    //    s' = C' e'
    //    T s = C' Rinv T R s
    //    s = Tinv C Rinv T R e
    //    C = Tinv C Rinv T R
    //    T R scales last three columns by 1/2
    //    Rinv T scales last three rows by 2
    //    therefore, Rinv T R scales top right 3x3 block by 1/2,
    //    and bottom left 3x3 block by 2.
    //    Also, Rinv T R = T^{-T}
    m =  Tinv * m * Tinv.transpose();
}
void
MAST::OrthotropicProperty3D::ThermalConductanceMatrix::
operator() (const libMesh::Point& p,
            const Real t,
            RealMatrixX& m) const {
    
    RealMatrixX
    A    = RealMatrixX::Zero(3, 3);
    
    _mat_cond (p, t, m);
    _orient   (p, t, A);

    m = A.transpose() * m * A;
}
void
MAST::OrthotropicProperty3D::ThermalConductanceMatrix::derivative (                                         const MAST::FunctionBase& f,
                                                                          const libMesh::Point& p,
                                                                          const Real t,
                                                                          RealMatrixX& m) const {
    RealMatrixX
    dm    = RealMatrixX::Zero(3, 3),
    A     = RealMatrixX::Zero(3, 3),
    dA    = RealMatrixX::Zero(3, 3);
    
    _mat_cond    (p, t, m);
    _orient      (p, t, A);
    _mat_cond.derivative( f, p, t, dm);
    _orient.derivative  ( f, p, t, dA);
    
    m =
    dA.transpose() *  m * A +
    A.transpose()  * dm * A +
    A.transpose()  *  m * dA;
}
Пример #6
0
std::vector<double>
OBSpectrophore::GetSpectrophore(OpenBabel::OBMol* mol)
{
   // Clear the return variable
   _spectro.clear();

   // Atoms
   _nAtoms = mol->NumAtoms();
   if (_nAtoms < 3)
   {
      std::cerr << "OBSpectrophore::GetSpectrophore() error: not enough atoms in molecule" << std::endl;;
      return _spectro;
   }

   // Coordinate and property arrays
   _oricoor = new double*[_nAtoms];
   _coor = new double*[_nAtoms];
   double** REF1 = new double*[_nAtoms];
   double** REF2 = new double*[_nAtoms];
   _property = new double*[_nAtoms];
   for (unsigned int i = 0; i < _nAtoms; ++i)
   {
      _oricoor[i] = new double[3];
      _coor[i] = new double[3];
      REF1[i] = new double[3];
      REF2[i] = new double[3];
      _property[i] = new double[N_PROPERTIES];
   }

    // Atom radii and coordinates
   _radii = new double[_nAtoms];
   _getMoleculeData(mol);

   // Atom properties
   _calculateProperties(mol);

   // Shift molecule to its center of gravity and orient it in a standard way
   _orient();

   // Calculate the first spectrum to initiate values
   unsigned int sphoreSize(N_PROPERTIES * _numberOfProbes);
   std::vector<double> ENERGY(sphoreSize);
   std::vector<double> SPHORE(sphoreSize);

   // Properties
   _getBox(_oricoor);
   _getEnergies(_oricoor, &(ENERGY[0]));
   _initiateSpectrophore(&(ENERGY[0]), &(SPHORE[0]));

   // Rotate
   double psi;
   double cos_psi;
   double sin_psi;
   double theta;
   double cos_theta;
   double sin_theta;
   double phi;
   double cos_phi;
   double sin_phi;

   for (unsigned int i = 0; i < _rotationStepList.size(); ++i)
   {
      int rotationStep(_rotationStepList[i]);

      for (int iTheta = 0; iTheta < 180; iTheta += rotationStep)
      {
         theta = 0.017453292519943 * iTheta;
         cos_theta = cos(theta);
         sin_theta = sin(theta);
         _rotateY(_oricoor, REF1, cos_theta, sin_theta);

         for (int iPsi = 0; iPsi < 360; iPsi += rotationStep)
         {
            psi = 0.017453292519943 * iPsi;
            cos_psi = cos(psi);
            sin_psi = sin(psi);
            _rotateZ(REF1, REF2, cos_psi, sin_psi);

            for (int iPhi = 0; iPhi < 360; iPhi += rotationStep)
            {
               phi = 0.017453292519943 * iPhi;
               cos_phi = cos(phi);
               sin_phi = sin(phi);
               _rotateX(REF2, _coor, cos_phi, sin_phi);

               // Calculate energies
               _getBox(_coor);
               _getEnergies(_coor, &(ENERGY[0]));
               _updateSpectrophore(&(ENERGY[0]), &(SPHORE[0]));
            }
         }
      }
   }


   // Cleanup
   for (unsigned int i = 0; i < _nAtoms; ++i)
   {
      delete[] _property[i];
      delete[] _oricoor[i];
      delete[] REF1[i];
      delete[] REF2[i];
      delete[] _coor[i];
      _property[i] = NULL;
      _oricoor[i] = NULL;
      REF1[i] = NULL;
      REF2[i] = NULL;
      _coor[i] = NULL;
   }
   delete[] _radii;
   _radii = NULL;


   // Modify the actual sphore data
   _spectro.resize(sphoreSize);
   for (unsigned int i = 0; i < sphoreSize; ++i)
   {
      _spectro[i] = -100 * SPHORE[i];
   }

   // Normalisation
   double mean[N_PROPERTIES];
   double std[N_PROPERTIES];
   unsigned int m;
   for (unsigned int i(0); i < N_PROPERTIES; ++i)
   {
      mean[i] = 0.0;
      for (unsigned int n(0); n < 12; ++n)
      {
         m = (i * 12) + n;
         mean[i] += _spectro[m];
      }
      mean[i] /= 12.0;
      std[i] = 0.0;
      for (unsigned int n(0); n < 12; ++n)
      {
         m = (i * 12) + n;
         std[i] += (_spectro[m] - mean[i]) * (_spectro[m] - mean[i]);
      }
      std[i] /= 11.0;
      std[i] = sqrt(std[i]);
   }
   if ((_normalization == OBSpectrophore::NormalizationTowardsZeroMean) ||
       (_normalization == OBSpectrophore::NormalizationTowardsZeroMeanAndUnitStd))
   {
      for (unsigned int i(0); i < N_PROPERTIES; ++i)
      {
         for (unsigned int n(0); n < 12; ++n)
         {
            m = (i * 12) + n;
            _spectro[m] -= mean[i];
         }
      }
   }
   if ((_normalization == OBSpectrophore::NormalizationTowardsUnitStd) ||
       (_normalization == OBSpectrophore::NormalizationTowardsZeroMeanAndUnitStd))
   {
      for (unsigned int i(0); i < N_PROPERTIES; ++i)
      {
         for (unsigned int n(0); n < 12; ++n)
         {
            m = (i * 12) + n;
            _spectro[m] /= std[i];
         }
      }
   }

   // Return
   return _spectro;
}