示例#1
0
vector<float> projectVectorOnPlane (vector<float> vec,vector<float> axis1,vector<float> axis2)

{
			float projAxis1;
			float projAxis2;
			vector <float> axis1Norm ;
			vector <float> axis2Norm ;
			vector <float> projAxis1Vec ;
			vector <float> projAxis2Vec ;
			vector <float> projectedVector ;



			projAxis1 = projVector(vec,axis1);
			projAxis2 = projVector(vec,axis2);
			
			axis1Norm = normVector(axis1);
			axis2Norm = normVector(axis2);

			projAxis1Vec =scalarVector(axis1Norm,projAxis1);
			projAxis2Vec =scalarVector(axis2Norm,projAxis2);


			projectedVector = vectorSum(projAxis1Vec,projAxis2Vec);

			return projectedVector;


}
示例#2
0
Vector normalized(const Vector& a)
{
    Vector normVector(a.size, a.orientation);
    double normVal = norm(a);
    for(int i = 0; i < a.size; ++i)
        normVector.values[i] = a.values[i] / normVal;
    
    return normVector;
}
int main (int argc, char **argv) 
{
    /* Matrix data. */

   CRS_MATRIX *M1, *M2;
   double *b1, *x1, *b2, *x2, *r;
   int n;
   int nvals;

   FILE *fp;

   if (argc == 1) {
     fp = stdin;
   }
   else if (argc == 2) {
     fp = fopen (*argv, "r");
   }
   else {
     fprintf (stderr, "Usage: pardisoTestExample [<fileName>]\n");
     exit (1);
   }

   M1 = readCRSMatrix (fp, /*symmetric=*/1);
   n = M1->nrows;
   b1 = readVector (fp, n);
   x1 = (double*)malloc(n*sizeof(double));
   r = (double*)malloc(n*sizeof(double));

   // ja -> M1->colIdxs;
   // a -> M1->vals;
   // ia -> M1->rowOffs

   int      mtype = -2;        /* Real symmetric matrix */
   int      nrhs = 1;          /* Number of right hand sides. */

   /* Internal solver memory pointer pt,                  */
   /* 32-bit: int pt[64]; 64-bit: long int pt[64]         */
   /* or void *pt[64] should be OK on both architectures  */ 
   void    *pt[64]; 

   /* Pardiso control parameters. */
   int      iparm[64];
   int      maxfct, mnum, phase, error, msglvl;

   /* Number of processors. */
   int      num_procs;

   /* Auxiliary variables. */
   char    *var;
   int      i;

   double   ddum;              /* Double dummy */
   int      idum;              /* Integer dummy. */

   double t0, t1;
   
/* -------------------------------------------------------------------- */
/* ..  Setup Pardiso control parameters.                                */
/* -------------------------------------------------------------------- */

   error = 0;
   //solver = 0; /* use sparse direct solver */
   // do we need this, or will init take care of it?
   for (i=0; i<64; i++) {
     pt[i] = (void*)0;
   }
   for (i=0; i<64; i++) {
     iparm[i] = 0;
   }
   iparm[0] = 1; /* Don't use solver default values */
   iparm[1] = 3; /* Fill-in reordering from OpenMP METIS */
   /* Numbers of processors; if 0, defaults to max number or MKL_NUM_THREADS */
   iparm[2] = 0;
   iparm[3] = 0; /* No iterative-direct algorithm */
   iparm[4] = 0; /* No user fill-in reducing permutation */
   iparm[5] = 0; /* Write solution into x */
   iparm[6] = 0; /* Not in use */
   iparm[7] = 0; /* Max numbers of iterative refinement steps */
   iparm[8] = 0; /* Not in use */
   iparm[9] = 13; /* Perturb the pivot elements with 1E-13 */
   iparm[10] = 1; /* Use nonsymmetric permutation and scaling MPS */
   iparm[11] = 0; /* Not in use */
   iparm[12] = 0; /* Maximum weighted matching algorithm is switched-off (default for symmetric). Try iparm[12] = 1 in case of inappropriate accuracy */
   iparm[13] = 0; /* Output: Number of perturbed pivots */
   iparm[14] = 0; /* Not in use */
   iparm[15] = 0; /* Not in use */
   iparm[16] = 0; /* Not in use */
   iparm[17] = -1; /* Output: Number of nonzeros in the factor LU */
   iparm[18] = -1; /* Output: Mflops for LU factorization */
   iparm[19] = 0; /* Output: Numbers of CG Iterations */
   iparm[20] = 1; /* use 1x1 and 2x2 pivoting

   //F77_FUNC(pardisoinit) (pt,  &mtype, &solver, iparm, &error); 

   if (error != 0) 
    {
      if (error == -10 )
	 printf("No license file found \n");
      if (error == -11 )
	 printf("License is expired \n");
      if (error == -12 )
	 printf("Wrong username or hostname \n");
      return 1; 
    }
   else
    { printf("PARDISO license check was successful ... \n");
    }

   /* Numbers of processors, value of OMP_NUM_THREADS */
   var = getenv("OMP_NUM_THREADS");
   if(var != NULL)
      sscanf( var, "%d", &num_procs );
   else {
     printf("Set environment OMP_NUM_THREADS to 1");
     exit(1);
   }
   iparm[2]  = num_procs;
   
   // other special settings
   iparm[1] = 3; // 2 for metis, 0 for AMD
   iparm[9] = 12;
   iparm[10] = 1;
   iparm[12] = 1; // setting this to 2 can cause errors sometimes
   
   maxfct = 1;		/* Maximum number of numerical factorizations.  */
   mnum   = 1;         /* Which factorization to use. */
    
   msglvl = 0;         /* Print statistical information  */
   error  = 0;         /* Initialize error flag */

/* -------------------------------------------------------------------- */
/* ..  Reordering and Symbolic Factorization.  This step also allocates */
/*     all memory that is necessary for the factorization.              */
/* -------------------------------------------------------------------- */
   phase = 11; 

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, &ddum, &ddum, &error);
   t1 = currentTimeUsec();
    
   if (error != 0) {
     printf("ERROR during symbolic factorization: %d\n", error);
     exit(1);
   }
   printf("Analyze: msec=%8.1f\n", (t1-t0)/1000.0);
   printf("Number of nonzeros in factors  = %d\n", iparm[17]);
   printf("Number of factorization MFLOPS = %d\n", iparm[18]);
   
/* -------------------------------------------------------------------- */
/* ..  Numerical factorization.                                         */
/* -------------------------------------------------------------------- */    
   phase = 22;

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, &ddum, &ddum, &error);
   t1 = currentTimeUsec();   

   if (error != 0) {
     printf("ERROR during numerical factorization: %d\n", error);
     exit(2);
   }
   printf("Factor:  msec=%8.1f\n", (t1-t0)/1000.0);

/* -------------------------------------------------------------------- */    
/* ..  Back substitution and iterative refinement.                      */
/* -------------------------------------------------------------------- */    
   phase = 33;

   iparm[7] = 1;       /* Max numbers of iterative refinement steps. */

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, b1, x1, &error);
   t1 = currentTimeUsec();   
   if (error != 0) {
     printf("ERROR during solution: %d\n", error);
     exit(3);
   }

   mulVector (r, M1, x1);
   subVector (r, r, b1, n);
   printf("Solve:   msec=%8.1f\n\n", (t1-t0)/1000.0);
   /* for (i=0; i<n; i++) { */
   /*   printf ("%g ", x1[i]); */
   /* } */
   /* printf ("\n"); */
   printf("residual=%g\n", normVector(r, n));

#if 0
   M2 = readCRSMatrix (fp, /*symmetric=*/1);
   n = M2->nrows;
   b2 = readVector (fp, n);
   x2 = (double*)malloc(n*sizeof(double));

   setVector (x2, x1, n);

   iparm[7] = 1;       /* Max numbers of iterative refinement steps. */
   iparm[3] = 102;

   printf ("maxfct=%d\n", maxfct);
   printf ("mnum=%d\n", mnum);
   printf ("mtype=%d\n", mtype);
   printf ("phase=%d\n", phase);
   printf ("idum=%d\n", idum);
   for (i=0; i<64; i++) {
     printf ("%d ", iparm[i]);
   }
   printf ("\n");

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M2->vals, M2->rowOffs, M2->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, b2, x2, &error);
   t1 = currentTimeUsec();   
   if (error != 0) {
     printf("ERROR during solution: %d\n", error);
     exit(3);
   }
   printf ("num iterations=%d\n", iparm[19]);

   for (i=0; i<n; i++) {
     printf ("%g ", x2[i]);
   }
   printf ("\n");
   printf("Solve:   msec=%8.1f\n\n", (t1-t0)/1000.0);

   mulVector (r, M2, x2);
   subVector (r, r, b2, n);
   printf("residual=%g\n", normVector(r, n));
#endif

/* -------------------------------------------------------------------- */    
/* ..  Termination and release of memory.                               */
/* -------------------------------------------------------------------- */    
   phase = -1;                 /* Release internal memory. */
    
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, &ddum, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, &ddum, &ddum, &error);

   return 0;
} 
示例#4
0
Vector3 normalizeVector(Vector3 a) {
    return divScalarVector(a, normVector(a));
}
示例#5
0
		MStatus MG_dotProduct::compute(const MPlug& plug,MDataBlock& dataBlock)
	{
		MStatus returnStatus;
		if ((plug==dotProductA)||
			(plug==dotProductMax)||
			(plug==proj1on2)||
			(plug==proj2on1)||
			(plug==angleInBetweenAttr)||
			(plug==angleX)||
			(plug==angleY)||
			(plug==angleZ))
			/*get time */
		
		{
				
			//creating handles to the input values

			MDataHandle vector1DataH = dataBlock.inputValue(vector1);
			MFloatPoint vector1V = vector1DataH.asFloatVector();
			
			MDataHandle vector2DataH = dataBlock.inputValue(vector2);
			MFloatPoint vector2V = vector2DataH.asFloatVector();

			MDataHandle xAxisH = dataBlock.inputValue(projAxisX);
			MFloatPoint xAxisData = xAxisH.asFloatVector();

			MDataHandle yAxisH = dataBlock.inputValue(projAxisY);
			MFloatPoint yAxisData = yAxisH.asFloatVector();

			MDataHandle zAxisH = dataBlock.inputValue(projAxisZ);
			MFloatPoint zAxisData = zAxisH.asFloatVector();
			
			MDataHandle normData = dataBlock.inputValue(normalize);
			bool norm =normData.asBool();
			

			//Creating some neededs variables

			float dotResult; // variable that will hold the dot product result
			float maxValue; //variable that will hold the dot product max value 
			float distance1; // variable that will hold the vector 1 lenght 
			float distance2; //variable that will hold the  vector 2 lenght
			float angleDeg;  //variable that will hold the  angle inbetween the two vectors
			//float cosRad ;   //variable that will hold the cosine value in radiants 
				
			//Dot product math 

			float vec1Array[3] = {vector1V[0],vector1V[1],vector1V[2]};
			vector <float> vec1 = makeVector(vec1Array) ;

			float vec2Array[3] = {vector2V[0],vector2V[1],vector2V[2]};
			vector <float> vec2 = makeVector(vec2Array) ;

			dotResult = vecDotProduct(vec1,vec2);
			distance1 = vectorLength(vec1);
			distance2 = vectorLength(vec2);
			maxValue = distance1*distance2;

			
			if (norm == 1) 

			{
				if (maxValue ==0)
				{
					dotResult=0;
				}else{
					dotResult = dotResult/maxValue;
				}
			} 
  
			


				
				

			//Projection v2 on v1

			float projV2=0;  //variable that will hold the value projection of v2 projected on v1
			vector <float> v1Norm; // variable that will hold the normalized v1 vector
			vector<float> v2Vec; // variable that will hold the projected vector

			if (distance1 != 0) 
			{
 
				projV2 = projVector(vec2,vec1);
				

				v1Norm = normVector(vec1);


				v2Vec = scalarVector(v1Norm,projV2);
				
				

			}else{

				//initialize the vector as 0 0 0
				float zeroVec2[3]= {0,0,0};
				v2Vec=makeVector(zeroVec2);
			}


			//Projection v1 on v2

			float projV1=0; //variable that will hold the value projection of v1 projected on v2
			vector <float> v2Norm;// variable that will hold the normalized v2 vector
			vector <float> v1Vec;// variable that will hold the projected vector

			if (distance2 != 0) 
			{
				projV1 = projVector(vec1,vec2);


				v2Norm = normVector(vec2);
				v1Vec = scalarVector(v2Norm,projV1);
			}else{
				//initialize the vector as 0 0 0
				float zeroVec1[3]= {0,0,0};
				v1Vec=makeVector(zeroVec1);
			}

			
			//Angle in between 


			if ((distance2*distance1)!=0)
			{
			angleDeg=angleInbetweenVector(vec1,vec2);
			}else{
				angleDeg=0;

			}

			//Angle inbetween splitted into X,Y,Z world rotation 
			
			//float dotResultV1X;
			// splitting inbetween angle into X Y Z rotation



			//converting axis from node into vector class
			float xAxisArray[3] = {xAxisData[0],xAxisData[1],xAxisData[2]};
			vector<float> xAxisVec = makeVector(xAxisArray) ;
			
			float yAxisArray[3] = {yAxisData[0],yAxisData[1],yAxisData[2]};
			vector<float> yAxisVec = makeVector(yAxisArray) ;

			float zAxisArray[3] = {zAxisData[0],zAxisData[1],zAxisData[2]};
			vector<float> zAxisVec = makeVector(zAxisArray) ;


			float angleProjXYDeg=0 ;
			float angleProjYZDeg=0 ;
			float angleProjXZDeg=0 ;

			// angle Z
			

			vector<float> projectedV1;
			vector<float> projectedV2;

			projectedV1= projectVectorOnPlane(vec1,xAxisVec,yAxisVec);
			projectedV2= projectVectorOnPlane(vec2,xAxisVec,yAxisVec);
			angleProjXYDeg=angleInbetweenVector(projectedV1,projectedV2);



			// angle X
			

			projectedV1= projectVectorOnPlane(vec1,zAxisVec,yAxisVec);
			projectedV2= projectVectorOnPlane(vec2,zAxisVec,yAxisVec);
			angleProjYZDeg=angleInbetweenVector(projectedV1,projectedV2);


			// angle Y
			

			projectedV1= projectVectorOnPlane(vec1,zAxisVec,xAxisVec);
			projectedV2= projectVectorOnPlane(vec2,zAxisVec,xAxisVec);
			angleProjXZDeg=angleInbetweenVector(projectedV1,projectedV2);

















			//Setting output values

			MDataHandle output = dataBlock.outputValue(dotProductA);
			MDataHandle outputMax = dataBlock.outputValue(dotProductMax);
			MDataHandle projV1Output = dataBlock.outputValue(proj1on2);
			MDataHandle projV2Output = dataBlock.outputValue(proj2on1);
			MDataHandle angleInBetweenOutput = dataBlock.outputValue(angleInBetweenAttr);
			MDataHandle angleXout = dataBlock.outputValue(angleX);
			MDataHandle angleYout = dataBlock.outputValue(angleY);
			MDataHandle angleZout = dataBlock.outputValue(angleZ);




			output.set(dotResult);
			outputMax.set(maxValue);
			projV1Output.set(v1Vec[0],v1Vec[1],v1Vec[2]);
			projV2Output.set(v2Vec[0],v2Vec[1],v2Vec[2]);
			angleInBetweenOutput.set(angleDeg);
			angleXout.set(angleProjYZDeg);
			angleYout.set(angleProjXZDeg);
			angleZout.set(angleProjXYDeg);

			//SetClean tells maya attribute is update
			outputMax.setClean();
			output.setClean();
			projV1Output.setClean();
			projV2Output.setClean();
			angleInBetweenOutput.setClean();
			angleXout.setClean();
			angleYout.setClean();
			angleZout.setClean();
		}
		
		return MS::kSuccess;


		}
示例#6
0
/**
 * Get the Wilson's B-matrix
 */
void getBMatrix(Real** cartCoords, int numCartesians,
		bondCoord** bonds, int numBonds,
		angleCoord** angles, int numAngles,
		dihedralCoord** dihedrals, int numDihedrals,
		improperCoord** impropers, int numImpropers,
		Matrix& B) {
#ifdef DEBUG
  cout << "\n\ngetBMatrix - Constructing B Matrix\n";
#endif

  // Constructing B Matrix
  //   follows method in chapter 4 of Molecular Vibrations by Wilson, Decius, and Cross

#ifdef DEBUG  
  int numInternals = numBonds + numAngles + numDihedrals + numImpropers;
  cout << "numBonds: " << numBonds << "\n";
  cout << "numAngles: " << numAngles << "\n";
  cout << "numDihedrals: " << numDihedrals << "\n";
  cout << "numImpropers: " << numImpropers << "\n";
  cout << "numInternals: " << numInternals << "\n";
#endif

  // Load Data
  B = 0.0;
  int i = 0;
  int j = 0;
  int index1 = 0;
  int index2 = 0;
  RowVector tempCoord1(3);
  RowVector tempCoord2(3);
  Real norm = 0.0;
  
  // Bonds
  for (i=0; i<numBonds; i++) {
    index1 = bonds[i]->x1;
    index2 = bonds[i]->x2;
    //norm = bonds[i].val;   // Could calculate this, like below.
#ifdef DEBUG
    cout << "index1=" << index1 << "index2=" << index2 << "\n";
#endif
    for (j=0; j<3; j++) {
      tempCoord1(j+1) = cartCoords[index1][j];
      tempCoord2(j+1) = cartCoords[index2][j];
    }
    tempCoord1 << tempCoord1 - tempCoord2;
    norm = tempCoord1.NormFrobenius();   // XXX - don't delete
    if (norm > 0.0) {
      tempCoord1 << tempCoord1 / norm;
    }
    for (j=1; j<=3; j++) {
      B(i+1,((index1)*3)+j) =  tempCoord1(j);
      B(i+1,((index2)*3)+j) = -tempCoord1(j);
    }
  }
  
#ifdef DEBUG
  cout << "after bonds\n";
  cout << "B:\n";
  cout << setw(9) << setprecision(3) << (B);
  cout << "\n\n";
#endif

  // Angles
  int index3 = 0;
  RowVector tempCoord3(3);
  RowVector tempCoord4(3);
  RowVector tempCoord5(3);
  RowVector r21(3);   // Vector from 2nd to 1st point
  RowVector r23(3);   // Vector from 2nd to 3rd point
  RowVector e21(3);   // Unit vector from 2nd to 1st point
  RowVector e23(3);   // Unit vector from 2nd to 3rd point
  Real norm21;        // Norm of r21
  Real norm23;        // Norm of r23
  Real angle = 0.0;   // Angle in radians
  Real cosAngle123 = 0.0;
  Real sinAngle123 = 0.0;
  //Real pi = 3.14159265;
  Real scaleFactor = 0.529178;   // Scaling factor (0.529178)
  for (i=0; i<numAngles; i++) {
    index1 = angles[i]->x1;
    index2 = angles[i]->x2;
    index3 = angles[i]->x3;
    //angle = angles[i].val * (pi/180.0);   // Convert to radians.
    for (j=0; j<3; j++) {
      tempCoord1(j+1) = cartCoords[index1][j];
      tempCoord2(j+1) = cartCoords[index2][j];
      tempCoord3(j+1) = cartCoords[index3][j];
    }
    r21 << tempCoord1 - tempCoord2;
    r23 << tempCoord3 - tempCoord2;
    norm21 = r21.NormFrobenius();
    norm23 = r23.NormFrobenius();
    e21 << r21;
    if (norm21 > 0.0) {
      e21 << e21 / norm21;
    }
    e23 << r23;
    if (norm23 > 0.0) {
      e23 << e23 / norm23;
    }
    angle = acos(DotProduct(r21,r23) / (norm21 * norm23));
    cosAngle123 = DotProduct(r21,r23) / (norm21 * norm23);
    sinAngle123 = sqrt(1 - (cosAngle123 * cosAngle123));
    
#ifdef DEBUG
    cout << "r21: " << (r21) << "\n";
    cout << "r23: " << (r23) << "\n";
    cout << "norm21: " << norm21 << ", norm23: " << norm23 << "\n\n";
    cout << "e21: " << (e21) << "\n";
    cout << "e23: " << (e23) << "\n";
    cout << "cos(" << angle << "): " << cos(angle) << "\n";
    cout << "sin(" << angle << "): " << sin(angle) << "\n";
    cout << "angle: " << acos(DotProduct(r21,r23) / (norm21 * norm23)) << "\n";
    cout << "cosAngle123: " << cosAngle123 << "\n";
    cout << "sinAngle123: " << sinAngle123 << "\n";
#endif    

    // First elements of coordinate triples
    tempCoord4 << ((cosAngle123 * e21) - e23);
    tempCoord4 << (tempCoord4 * scaleFactor) / (norm21 * sinAngle123);
    for (j=1; j<=3; j++) {
      B(i+numBonds+1,((index1)*3)+j) = tempCoord4(j);
    }
    // Third elements of coordinate triples
    tempCoord5 << ((cosAngle123 * e23) - e21);
    tempCoord5 << (tempCoord5 * scaleFactor) / (norm23 * sinAngle123);
    for (j=1; j<=3; j++) {
      B(i+numBonds+1,((index3)*3)+j) = tempCoord5(j);
    }
    // Second (middle) elements of coordinate triples (depends on 1st and 3rd)
    tempCoord4 << -tempCoord4 - tempCoord5;
    for (j=1; j<=3; j++) {
      B(i+numBonds+1,((index2)*3)+j) = tempCoord4(j);
    }
  }
  
#ifdef DEBUG
  cout << "after angles\n";
  cout << "B:\n";
  cout << setw(9) << setprecision(3) << (B);
  cout << "\n\n";
#endif  

  // Dihedrals
  RowVector r12(3);   // Vector from 1st to 2nd point
  RowVector r32(3);   // Vector from 3rd to 2nd point
  RowVector r34(3);   // Vector from 3rd to 2nd point
  RowVector r43(3);   // Vector from 4th to 3rd point
  RowVector e12(3);   // Unit vector from 1st to 2nd point
  RowVector e32(3);   // Unit vector from 3rd to 2nd point
  RowVector e34(3);   // Unit vector from 3rd to 2nd point
  RowVector e43(3);   // Unit vector from 4th to 3rd point
  Real norm12;        // Norm of r12
  Real norm32;        // Norm of r32
  Real norm34;        // Norm of r34
  Real norm43;        // Norm of r43
  RowVector cross1223(3);   // Cross product of e12 and e23
  RowVector cross4332(3);   // Cross product of e43 and e32
  Real angle123 = 0.0;   // Angle in radians
  Real angle234 = 0.0;   // Angle in radians
  Real cosAngle234 = 0.0;
  Real sinAngle234 = 0.0;
  scaleFactor = 0.529178;   // Scaling factor (0.529178)
  int index4 = 0;
  RowVector tempCoord6(3);
  for (i=0; i<numDihedrals; i++) {
    index1 = dihedrals[i]->x1;
    index2 = dihedrals[i]->x2;
    index3 = dihedrals[i]->x3;
    index4 = dihedrals[i]->x4;
    for (j=0; j<3; j++) {
      tempCoord1(j+1) = cartCoords[index1][j];
      tempCoord2(j+1) = cartCoords[index2][j];
      tempCoord3(j+1) = cartCoords[index3][j];
      tempCoord4(j+1) = cartCoords[index4][j];
    }
    r12 << tempCoord2 - tempCoord1;
    r21 << tempCoord1 - tempCoord2;
    r23 << tempCoord3 - tempCoord2;
    r32 << tempCoord2 - tempCoord3;
    r34 << tempCoord4 - tempCoord3;
    r43 << tempCoord3 - tempCoord4;
    norm12 = r12.NormFrobenius();
    norm21 = r21.NormFrobenius();
    norm23 = r23.NormFrobenius();
    norm32 = r32.NormFrobenius();
    norm34 = r34.NormFrobenius();
    norm43 = r43.NormFrobenius();
#ifdef DEBUG
    cout << "norm12: " << norm12 << "\n";
    cout << "norm21: " << norm21 << "\n";
    cout << "norm23: " << norm23 << "\n";
    cout << "norm32: " << norm32 << "\n";
    cout << "norm34: " << norm34 << "\n";
    cout << "norm43: " << norm43 << "\n";
#endif
    e12 << r12 / norm12;
    e21 << r21 / norm21;
    e23 << r23 / norm23;
    e32 << r32 / norm32;
    e34 << r34 / norm34;
    e43 << r43 / norm43;
    angle123 = acos(DotProduct(r21,r23) / (norm21 * norm23));   // Wilson's angle 2
    angle234 = acos(DotProduct(r32,r34) / (norm32 * norm34));   // Wilson's angle 3
    cosAngle123 = DotProduct(r21,r23) / (norm21 * norm23);
    cosAngle234 = DotProduct(r32,r34) / (norm32 * norm34);
    sinAngle123 = sqrt(1 - (cosAngle123 * cosAngle123));
    sinAngle234 = sqrt(1 - (cosAngle234 * cosAngle234));
#ifdef DEBUG
    cout << "angle123: " << angle123 << ", cos(angle123): " << cos(angle123) << ", sin(angle123): " << sin(angle123) << "\n";
    cout << "angle234: " << angle234 << ", cos(angle234): " << cos(angle234) << ", sin(angle234): " << sin(angle234) << "\n";
    cout << "cosAngle123: " << cosAngle123 << ", sinAngle123: " << sinAngle123 << "\n";
    cout << "cosAngle234: " << cosAngle234 << ", sinAngle234: " << sinAngle234 << "\n";
#endif
    cross1223(1) = (e12(2)*e23(3)) - (e12(3)*e23(2));
    cross1223(2) = (e12(3)*e23(1)) - (e12(1)*e23(3));
    cross1223(3) = (e12(1)*e23(2)) - (e12(2)*e23(1));
    cross4332(1) = (e43(2)*e32(3)) - (e43(3)*e32(2));
    cross4332(2) = (e43(3)*e32(1)) - (e43(1)*e32(3));
    cross4332(3) = (e43(1)*e32(2)) - (e43(2)*e32(1));
#ifdef DEBUG
    cout << "cross1223 (norm " << cross1223.NormFrobenius() << "):\n";
    cout << setw(9) << setprecision(6) << (cross1223);
    cout << "\n\n";
    cout << "cross4332 (norm " << cross4332.NormFrobenius() << "):\n";
    cout << setw(9) << setprecision(6) << (cross4332);
    cout << "\n\n";
#endif
    // First elements of coordinate triples
    tempCoord5 << -((cross1223 * scaleFactor) / (norm12 * sinAngle123 * sinAngle123));
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+1,((index1)*3)+j) = tempCoord5(j);
    }
    // Second elements of coordinate triples
    tempCoord5 << ((norm23 - (norm12 * cosAngle123)) / (norm23 * norm12 * sinAngle123 * sinAngle123)) * (cross1223);
    tempCoord6 << (cosAngle234 / (norm23 * sinAngle234 * sinAngle234)) * (cross4332);
#ifdef DEBUG
    cout << "tempCoord5:\n";
    cout << setw(9) << setprecision(6) << (tempCoord5);
    cout << "tempCoord6:\n";
    cout << setw(9) << setprecision(6) << (tempCoord6);
#endif
    tempCoord5 << (tempCoord5 + tempCoord6) * scaleFactor;
#ifdef DEBUG
    cout << "tempCoord5:\n";
    cout << setw(9) << setprecision(6) << (tempCoord5);
#endif
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+1,((index2)*3)+j) = tempCoord5(j);
    }
    // Third elements of coordinate triples
    tempCoord5 << ((norm32 - (norm43 * cosAngle234)) / (norm32 * norm43 * sinAngle234 * sinAngle234)) * (cross4332);
    tempCoord6 << (cosAngle123 / (norm32 * sinAngle123 * sinAngle123)) * (cross1223);
    tempCoord5 << (tempCoord5 + tempCoord6) * scaleFactor;
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+1,((index3)*3)+j) = tempCoord5(j);
    }
    // Fourth elements of coordinate triples
    tempCoord5 << -((cross4332 * scaleFactor) / (norm43 * sinAngle234 * sinAngle234));
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+1,((index4)*3)+j) = tempCoord5(j);
    }
  }
  
#ifdef DEBUG
  cout << "B:\n";
  cout << setw(9) << setprecision(3) << (B);
  cout << "\n\n";
#endif

  // Impropers
  RowVector r41(3);   // Vector from 4th to 1st point
  RowVector r42(3);   // Vector from 4th to 2nd point
  RowVector e41(3);   // Unit vector from 4th to 1st point
  RowVector e42(3);   // Unit vector from 4th to 2nd point
  RowVector normVector(3);   // Normal to the plane
  Real norm41;        // Norm of r41
  Real norm42;        // Norm of r42
  Real angle142 = 0.0;   // Angle in radians
  Real angle143 = 0.0;   // Angle in radians
  Real angle243 = 0.0;   // Angle in radians
  Real cosAngle142 = 0.0;
  Real cosAngle143 = 0.0;
  Real cosAngle243 = 0.0;
  Real sinAngle142 = 0.0;
  Real sinAngle143 = 0.0;
  Real sinAngle243 = 0.0;
  Real apexCoeff = 0.0;   // Magnitude of central atom displacement
  scaleFactor = -0.352313;   // Scale factor (-0.352313)
  for (i=0; i<numImpropers; i++) {
    index1 = impropers[i]->x1;
    index2 = impropers[i]->x2;
    index3 = impropers[i]->x3;
    index4 = impropers[i]->x4;
    for (j=0; j<3; j++) {
      tempCoord1(j+1) = cartCoords[index1][j];
      tempCoord2(j+1) = cartCoords[index2][j];
      tempCoord3(j+1) = cartCoords[index3][j];
      tempCoord4(j+1) = cartCoords[index4][j];
    }
    r41 << tempCoord1 - tempCoord4;
    r42 << tempCoord2 - tempCoord4;
    r43 << tempCoord3 - tempCoord4;
    norm41 = r41.NormFrobenius();
    norm42 = r42.NormFrobenius();
    norm43 = r43.NormFrobenius();
    e41 << r41 / norm41;
    e42 << r42 / norm42;
    e43 << r43 / norm43;
    angle142 = acos(DotProduct(r41,r42) / (norm41 * norm42));
    angle143 = acos(DotProduct(r41,r43) / (norm41 * norm43));
    angle243 = acos(DotProduct(r42,r43) / (norm42 * norm43));
    cosAngle142 = DotProduct(r41,r42) / (norm41 * norm42);
    cosAngle143 = DotProduct(r41,r43) / (norm41 * norm43);
    cosAngle243 = DotProduct(r42,r43) / (norm42 * norm43);
    sinAngle142 = sqrt(1 - (cosAngle142 * cosAngle142));
    sinAngle143 = sqrt(1 - (cosAngle143 * cosAngle143));
    sinAngle243 = sqrt(1 - (cosAngle243 * cosAngle243));
    normVector(1) = (r41(2)*r42(3)) - (r41(3)*r42(2));
    normVector(2) = (r41(3)*r42(1)) - (r41(1)*r42(3));
    normVector(3) = (r41(1)*r42(2)) - (r41(2)*r42(1));
    normVector << normVector / normVector.NormFrobenius();
    // First elements of coordinate triples
    tempCoord5 << normVector * (scaleFactor / norm41);
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+numDihedrals+1,((index1)*3)+j) = tempCoord5(j);
    }
    // Second elements of coordinate triples
    tempCoord5 << normVector * sinAngle143 * scaleFactor;
    tempCoord5 << tempCoord5 / (norm42 * sinAngle243);
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+numDihedrals+1,((index2)*3)+j) = tempCoord5(j);
    }
    // Third elements of coordinate triples
    tempCoord5 << normVector * sinAngle142 * scaleFactor;
    tempCoord5 << tempCoord5 / (norm43 * sinAngle243);
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+numDihedrals+1,((index3)*3)+j) = tempCoord5(j);
    }
    // Fourth elements of coordinate triples
    apexCoeff = -1.0 / norm42;
    apexCoeff -= sinAngle143 / (norm42 * sinAngle243);
    apexCoeff -= sinAngle142 / (norm43 * sinAngle243);
    tempCoord5 << normVector * apexCoeff * scaleFactor;
    for (j=1; j<=3; j++) {
      B(i+numBonds+numAngles+numDihedrals+1,((index4)*3)+j) = tempCoord5(j);
    }
  }
  
  return;
}
示例#7
0
int testPlane() {
	int numErr = 0;

	logMessage(_T("TESTING  -  class GM_3dPlane ...\n\n"));

	// Default constructor, plane must be invalid
	GM_3dPlane p;
	if (p.isValid()) {
		logMessage(_T("\tERROR - Default constructor creates valid plane\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Default constructor creates invalid plane\n"));
	}

	// Constructor (coeff)
	GM_3dPlane p1(getRandomDouble(), getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPlane pNull(0.0, 0.0, 0.0, getRandomDouble());
	if (!p1.isValid() || pNull.isValid()) {
		logMessage(_T("\tERROR - Coeff. constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Coeff. constructor working\n"));
	}

	// Copy constructor
	GM_3dPlane copyPlane(p1);
	if (!copyPlane.isValid() || copyPlane != p1) {
		logMessage(_T("\tERROR - Copy constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Copy constructor working\n"));
	}

	// Constructor (coeff vector)
	double pointsVect[4];
	for (int i = 0 ; i < 4 ; i++) {
		pointsVect[i] = getRandomDouble();
	}
	GM_3dPlane p2(pointsVect);
	if (!p2.isValid()) {
		logMessage(_T("\tERROR - Coeff. vector constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Coeff. vector constructor working\n"));
	}

	// Constructor (points)
	GM_3dPoint pt1(getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPoint pt2(getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPoint pt3(getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dLine ln(getRandomDouble(), getRandomDouble(), getRandomDouble(),getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPoint ptLn1 = ln.begin();
	GM_3dPoint ptLn2 = ln.center();
	GM_3dPoint ptLn3 = ln.end();
	GM_3dPlane p3(pt1, pt2, pt3);
	GM_3dPlane pLine(ptLn2, ptLn2, ptLn3);
	double distPt1 = pt1.x()*p3[0] + pt1.y()*p3[1] + pt1.z()*p3[2] + p3[3];
	double distPt2 = pt2.x()*p3[0] + pt2.y()*p3[1] + pt2.z()*p3[2] + p3[3];
	double distPt3 = pt3.x()*p3[0] + pt3.y()*p3[1] + pt3.z()*p3[2] + p3[3];
	if (!p3.isValid() || pLine.isValid() || fabs(distPt1) > GM_NULL_TOLERANCE || fabs(distPt2) > GM_NULL_TOLERANCE || fabs(distPt3) > GM_NULL_TOLERANCE) {
		logMessage(_T("\tERROR - Points constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Points constructor working\n"));
	}

	// Point distance
	GM_3dPlane p4(getRandomDouble(), getRandomDouble(), getRandomDouble(),getRandomDouble());
	GM_3dPoint checkPoint(getRandomDouble(), getRandomDouble(), getRandomDouble());
	if (fabs(p4[0]) > GM_NULL_TOLERANCE) {
		checkPoint.x(-(checkPoint.y()*p4[1] + checkPoint.z()*p4[2] + p4[3]) / p4[0]);
	}
	else if (fabs(p4[1]) > GM_NULL_TOLERANCE) {
		checkPoint.y(-(checkPoint.x()*p4[0] + checkPoint.z()*p4[2] + p4[3]) / p4[1]);
	}
	else if (fabs(p4[2]) > GM_NULL_TOLERANCE) {
		checkPoint.z(-(checkPoint.x()*p4[0] + checkPoint.y()*p4[1] + p4[3]) / p4[2]);
	}
	else {
		p4.invalidate();
	}
	double checkSignedDist = getRandomDouble();
	double checkDist = fabs(checkSignedDist);
	GM_3dVector p4Norm = p4.normalVector();
	checkPoint = (GM_3dVector)checkPoint + (p4Norm * checkSignedDist);
	GM_3dPoint checkPointOnPlane1;
	GM_3dPoint checkPointOnPlane2;
	double dist = p4.pointDistance(checkPoint);
	double signedDist = p4.pointDistanceSgn(checkPoint);
	double signedDistOnPlane = p4.pointDistanceSgn(checkPoint, checkPointOnPlane1);
	double distOnPlane = p4.pointDistance(checkPoint, checkPointOnPlane2);
	
	distPt1 = checkPointOnPlane1.x()*p4[0] + checkPointOnPlane1.y()*p4[1] + checkPointOnPlane1.z()*p4[2] + p4[3];
	distPt2 = checkPointOnPlane2.x()*p4[0] + checkPointOnPlane2.y()*p4[1] + checkPointOnPlane2.z()*p4[2] + p4[3];
	
	if (!p4.isValid() || !checkPointOnPlane1.isValid() || !checkPointOnPlane2.isValid() ||
		fabs(distPt1) > GM_NULL_TOLERANCE || fabs(distPt2) > GM_NULL_TOLERANCE ||
		fabs(distOnPlane - checkDist) > GM_NULL_TOLERANCE || fabs(signedDistOnPlane - checkSignedDist) > GM_NULL_TOLERANCE ||
		fabs(dist - checkDist) > GM_NULL_TOLERANCE || fabs(signedDist - checkSignedDist) > GM_NULL_TOLERANCE) {
		logMessage(_T("\tERROR - Point distance computation not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Point distance computation working\n"));
	}

	// XY Angle
	double angle = ((((double)rand()) / ((double)RAND_MAX)) * GM_PI) - (GM_PI / 2.0);
	GM_3dVector normVector(angle/* + GM_HALFPI*/);
	normVector.z(normVector.y());
	normVector.y(0.0);
	GM_3dPlane angleP(normVector, GM_3dPoint(getRandomDouble(), getRandomDouble(), getRandomDouble()));
	double checkAngle = angleP.xyAngle();
	if (checkAngle > GM_PI) {
		checkAngle -= 2.0 * GM_PI;
	}
	if (!angleP.isValid() || fabs(angle - checkAngle) > GM_NULL_TOLERANCE) {
		logMessage(_T("\tERROR - XY angle computation not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - XY angle computation working\n"));
	}


	return numErr;
}