예제 #1
0
PcbXML::PcbXML( const QDomElement & pcbDocument ) 
{
	// TODO: need some execption handling for bad elements missing attrs, etc.
	m_svg = new SVGDomDocument();
	m_svgroot = m_svg->documentElement();
	
	// FIXME: what happens when there is no mark - should be 0
	m_markx = pcbDocument.attribute("MX").toInt();
	m_marky = pcbDocument.attribute("MY").toInt();
	m_units = pcbDocument.attribute("units");
	
	m_minx = m_markx;
	m_miny = m_marky;
	m_maxx = m_markx;
	m_maxy = m_marky;
	m_pinCount = 0;
	m_padCount = 0;
    
	m_silkscreen = m_svg->createGroup("silkscreen");
	m_copper = m_svg->createGroup("copper0");
	m_keepout = m_svg->createGroup("keepout");
	m_mask = m_svg->createGroup("soldermask");  
	m_outline = m_svg->createGroup("outline");  
    
	QDomNodeList tagList = pcbDocument.childNodes();
	
	//TODO: eventually need to support recursing into the tree here
	//TODO: support footprints with multiple root elements (module style)
	for(uint i = 0; i < tagList.length(); i++){
		drawNode(tagList.item(i));
	}

	m_svg->setHeight(m_maxy-m_miny, m_units);
	m_svg->setWidth(m_maxx-m_minx, m_units);
	m_svg->setViewBox(0,0,m_maxx-m_minx,m_maxy-m_miny);
	
	shiftCoordinates();

	m_svgFile = QDir::tempPath () + "/footprint.svg";
	DebugDialog::debug(QString("temp path %1").arg(QDir::tempPath () + "/test.svg" ) );
	m_svg->save(m_svgFile);
}
예제 #2
0
//------------------------------
void MolState::align()
{
  // Shift center of mass to the origin:
  shiftCoordinates( getCenterOfMass() );

  // Aligh moment of inertia principal axes:
  KMatrix MOI_tensor(3,3), MOI_eigenValues(3,1), MOI_eigenVectors(3,3);
  MOI_tensor = getMomentOfInertiaTensor();
  //MOI_tensor.Print("Moment of inertia tensor");
  MOI_eigenVectors=MOI_tensor.Herm_Diag(MOI_eigenValues, true); // true=>eigen vals in the descending order; eigen vectors in ROWS.
  // MOI_eigenVectors.Print("MOI eigen vectors");
  // MOI_eigenValues.Print("MOI eigen values");
  
  // compute the determinant of MOI matrix:
  double det_tmp =  MOI_eigenVectors.Determinant();
  // if determinant is = 1 than it is a proper rotation; 
  // if it is = -1 than it is rotation+reflection (switch from left handed to the right handed coord.system); swap x&y axes:
  if (det_tmp < 0)
    MOI_eigenVectors.SwapRows(0,1);

  transformCoordinates(MOI_eigenVectors); // rotate coordinates using matrix of the MOI eigen vectors 

  std::cout << "Coordinate axes were aligned with MOI principal axes; center mass was shifted to the origin.\n";
}
예제 #3
0
//------------------------------
bool MolState::Read()
{
  int i,j,k,l;
  char tmpCh;
  std::string tmp_str, tmp_atomName;
  std::istringstream tmp_iStr;
  Atom tmp_atom;

  //------------ Read IP (if provided) ----------------------------------

  if ( xmlF.CheckSubNode("ip") )
    {
      xmlF.node("ip");
      energy = xmlF.getDoubleValue();
      xmlF.stepBack();
    }
  //------------ Read the Geometry --------------------------------------
  
  xmlF.node("geometry");
  
  int tmp_nAtoms, tmp_nNormMds;
  tmp_nAtoms=xmlF.getIntValue("number_of_atoms");
 
  std::string units;
  units=xmlF.value("units");

  ifLinear= xmlF.getBoolValue("linear"); 
  if (ifLinear) 
    tmp_nNormMds = (3*tmp_nAtoms - 5);
  else
    tmp_nNormMds = (3*tmp_nAtoms - 6);

  tmp_iStr.str(xmlF.value("text")); 
  tmp_iStr.clear();
  atoms.clear();

  for (i=0; i<tmp_nAtoms; i++)
    {
      tmp_atomName="";
      tmpCh=' ';

      while ( !ifLetterOrNumber(tmpCh) and !(tmp_iStr.fail()) )
	tmp_iStr.get(tmpCh);  

      if (tmp_iStr.fail())
	{
	  std::cout << "\nError: less then "<< tmp_nAtoms <<" atoms found or the format error, \"text\"-s line nuumber "<<i+1<<"\n";
	  xmlF.exitOnFormatError(true);
	}
      
      do {  
	tmp_atomName+=tmpCh; 
	tmp_iStr.get( tmpCh );  
      } while( ifLetterOrNumber(tmpCh) );
      tmp_atom.Name() = tmp_atomName;

      for (k=0; k<CARTDIM; k++)
	{
	  tmp_iStr >> tmp_atom.Coord(k);
	  if (units=="au")
	    tmp_atom.Coord(k)*=AU2ANGSTROM;
	}

      if (tmp_iStr.fail())
	{
	  std::cout << "\nError: less then "<< tmp_nAtoms <<" atoms found or the format error in the atomic coordinates,\n"
		    << "       \"text\"-s line number "<<i+1<<"\n";
	  xmlF.exitOnFormatError(true);
	}
      
      atoms.push_back(tmp_atom);
    }


  
  //------------ Convert atomic names to masses --------------------------

   for (i=0; i<NAtoms(); i++)
    {
      tmp_iStr.str( amuF.reset().node("masses").node(  getAtom(i).Name().c_str()   ).value() ); 
      tmp_iStr.clear();
      tmp_iStr >> getAtom(i).Mass(); 
      amuF.exitOnFormatError(tmp_iStr.fail());
    }

  //------------ Read Normal Modes ---------------------------------------
  NormalMode tmp_normMode(NAtoms(),0); // one temp. norm mode

  normModes.clear();

  xmlF.stepBack();
  xmlF.node("normal_modes");

  tmp_iStr.str(xmlF.value("text")); 
  tmp_iStr.clear();

  for (i=0; i < tmp_nNormMds; i++)
    normModes.push_back( tmp_normMode );
 
  int nModesPerLine=3;  // three number of vib. modes per Line

  int nLines;
  nLines = tmp_nNormMds / nModesPerLine;
  if ( tmp_nNormMds % nModesPerLine != 0)
    nLines++;

  for (k = 0; k < nLines; k++)  // number of blocks with 3 norm.modes. ("lines")
    {
      int current_nModesPerLine = nModesPerLine;
      // for the last entree, nModesPerString may differ from 3
      if (nLines - 1 == k)
  	if ( tmp_nNormMds % nModesPerLine != 0 )
	  current_nModesPerLine = tmp_nNormMds % nModesPerLine;
 
      for (i=0; i < NAtoms(); i++)   
  	for (j=0; j < current_nModesPerLine; j++) 
  	  for (l=0; l < CARTDIM; l++)
	    {
	      tmp_iStr >> normModes[k*nModesPerLine+j].getDisplacement()[i*CARTDIM+l]; 
	      if (tmp_iStr.fail())
		{
		  std::cout << "\nError: less normal modes found than expected or the format error\n";
		  xmlF.exitOnFormatError(true);
		}
	    }
    }
   
  //------------ Read Frequencies ----------------------------------------
  xmlF.stepBack();
  xmlF.node("frequencies");

  tmp_iStr.str(xmlF.value("text")); 
  tmp_iStr.clear();
  
  for (i=0; i < tmp_nNormMds; i++)
    {
      tmp_iStr >> getNormMode(i).getFreq();
      if (tmp_iStr.fail())
	{
	  std::cout << "\nError: format error at frequency #"<<i<< " or less than " << tmp_nNormMds <<" frequencies found\n";
	  xmlF.exitOnFormatError(true);
	}
      if (getNormMode(i).getFreq()<=0)
	{
	  std::cout <<"\nError. The frequency ["<<getNormMode(i).getFreq() <<"] is negative\n";
	  xmlF.exitOnFormatError(true);
	}
    }

  // Now MolState is in a good shape, and some transformations can be performed

  //------------ 1. Un-mass-weight normal modes----------------------------

  xmlF.stepBack();
  xmlF.node("normal_modes");
  bool if_massweighted;
  if_massweighted=xmlF.getBoolValue("if_mass_weighted");

  //------------ 1. mass un-weight normal modes, if needed (QChem-->ACES format; )----------------
  // qchem if_massweighted="true"; aces if_massweighted="false";
  reduced_masses.Adjust(NNormModes(),1);
  reduced_masses.Set(1);
  if (if_massweighted)
    {

      // Read atomic names from "...->normal_modes->atoms"
      std::vector<Atom> normalModeAtoms;

      tmp_iStr.str(xmlF.value("atoms")); 
      tmp_iStr.clear();
      normalModeAtoms.clear();

      for (i=0; i<NAtoms(); i++)
	{
	  tmp_atomName="";
	  tmpCh=' ';

	  while ( !ifLetterOrNumber(tmpCh) and !(tmp_iStr.fail()) )
	    tmp_iStr.get(tmpCh);  

	  xmlF.exitOnFormatError(tmp_iStr.fail());
      
	  do {  
	    tmp_atomName+=tmpCh; 
	    tmp_iStr.get( tmpCh );  
	  } while( ifLetterOrNumber(tmpCh) );
	  tmp_atom.Name() = tmp_atomName;
	  normalModeAtoms.push_back(tmp_atom);
	}
      // Get masses for each atomic name:
      for (i=0; i<NAtoms(); i++)
	{
	  tmp_iStr.str( amuF.reset().node("masses").node(  normalModeAtoms[i].Name().c_str()   ).value() ); 
	  tmp_iStr.clear();
	  tmp_iStr >> normalModeAtoms[i].Mass(); 
	  amuF.exitOnFormatError(tmp_iStr.fail());
	}
      // Mass-un-weight normal modes:
      for (int nm=0; nm<NNormModes(); nm++)
	for (int a=0; a<NAtoms(); a++)
	  for (int i=0; i<CARTDIM; i++ )
	    getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i) *= sqrt(normalModeAtoms[a].Mass());

      // normolize each normal mode (/sqrt(norm) which is also /sqrt(reduced mass)):
      // KMatrix reduced_masses(NNormModes(),1);
      for (int nm=0; nm<NNormModes(); nm++)
	{
	  reduced_masses[nm] = 0;
	  for (int a=0; a<NAtoms(); a++)
	    for (int i=0; i<CARTDIM; i++ )
	      reduced_masses[nm]+= getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i) * getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i);
	}
      // reduced_masses.Print("Reduced masses:");
      // Normalize:
      for (int nm=0; nm<NNormModes(); nm++)
	for (int a=0; a<NAtoms(); a++)
	  for (int i=0; i<CARTDIM; i++ )
	    getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i)/=sqrt(reduced_masses[nm]);

    }
  xmlF.stepBack();

  //------------ 2. Align geometry if requested ----------------------------
  if_aligned_manually=false;
  double man_rot_x, man_rot_y, man_rot_z;
  Vector3D man_shift;
  if ( xmlF.CheckSubNode("manual_coordinates_transformation") )
     {
       xmlF.node("manual_coordinates_transformation");
       
       man_rot_x=xmlF.getDoubleValue("rotate_around_x"); 
       man_rot_y=xmlF.getDoubleValue("rotate_around_y"); 
       man_rot_z=xmlF.getDoubleValue("rotate_around_z"); 

       man_shift.getCoord(0)=-xmlF.getDoubleValue("shift_along_x"); 
       man_shift.getCoord(1)=-xmlF.getDoubleValue("shift_along_y"); 
       man_shift.getCoord(2)=-xmlF.getDoubleValue("shift_along_z"); 
       
       std::cout << "Molecular structure and normal modes of this electronic state\nwill be transformed as requested in the input.\n";

       shiftCoordinates(man_shift);
       rotate(man_rot_x*PI,man_rot_y*PI,man_rot_z*PI);
       applyCoordinateThreshold(COORDINATE_THRESHOLD);
       if_aligned_manually=true;

       xmlF.stepBack();
     }


  //------------ 3. Reorder normal modes if requested --------------------
   if ( xmlF.CheckSubNode("manual_normal_modes_reordering") )
    {
      xmlF.node("manual_normal_modes_reordering");
      if_nm_reordered_manually=false;
      normModesOrder.clear();

      std::cout << "New normal modes order was requested:\n" << xmlF.value("new_order") <<"\n";
      tmp_iStr.str(xmlF.value("new_order")); 
      int tmpInt;
      for (int nm=0; nm < NNormModes(); nm++)
	{
	  tmp_iStr >> tmpInt;
	  //input error check:
	  if (tmp_iStr.fail())
	    {
	      std::cout << "\nFormat error: non numeric symbol or less entries then the number of normal modes\n\n";
	      xmlF.exitOnFormatError(true);
	    }
	  if ( (tmpInt<0) or (tmpInt>=NNormModes()) )
	    {
	      std::cout << "\nError: normal mode number ["<< tmpInt<<"] is out of range [0.."<<NNormModes()-1<<"].\n\n";
	      xmlF.exitOnFormatError(true);
	    }
	  normModesOrder.push_back(tmpInt);
	}
      
      // check if there are duplicates in the list:
      std::vector<int> tmpIntVector, tmpIntVector2;
      tmpIntVector = normModesOrder;
      std::sort( tmpIntVector.begin(), tmpIntVector.end() );
      tmpIntVector2 = tmpIntVector;
      std::vector<int>::const_iterator intVec_iter;
      intVec_iter= unique( tmpIntVector.begin(), tmpIntVector.end() );
      if (intVec_iter != tmpIntVector.end())
	{
	  std::cout << "\nFormat error: there are non unique entries. Check the sorted list:\n";
	  for (std::vector<int>::const_iterator tmp_iter=tmpIntVector2.begin(); tmp_iter!=tmpIntVector2.end(); tmp_iter++)
	    std::cout << ' ' << *tmp_iter;
	  std::cout<<'\n';
	  xmlF.exitOnFormatError(true);
	}
      
      // backup normal modes
      std::vector<NormalMode> oldNormModes;
      oldNormModes.clear();
      for (int nm=0; nm < NNormModes(); nm++)
	{
	  tmp_normMode = getNormMode(nm);
	  oldNormModes.push_back( tmp_normMode );
	}
      
      // copy normal modes using new order
      for (int nm=0; nm < NNormModes(); nm++)
	getNormMode(nm) = oldNormModes[  normModesOrder[nm] ];
      
      std::cout << "Normal modes were reordered accordingly.\n";
      if_nm_reordered_manually=true;

      xmlF.stepBack();
    }