/*========================================================================= Program: Visualization Toolkit Module: vtkOpenQubeMoleculeSource.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkOpenQubeMoleculeSource.h" #include "vtkExecutive.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkMolecule.h" #include "vtkObjectFactory.h" #include "vtkOpenQubeElectronicData.h" #include #include #include #include //------------------------------------------------------------------------------ vtkStandardNewMacro(vtkOpenQubeMoleculeSource); //------------------------------------------------------------------------------ vtkOpenQubeMoleculeSource::vtkOpenQubeMoleculeSource() : vtkDataReader() , FileName(nullptr) , CleanUpBasisSet(false) { } //------------------------------------------------------------------------------ vtkOpenQubeMoleculeSource::~vtkOpenQubeMoleculeSource() { this->SetFileName(nullptr); if (this->CleanUpBasisSet) { delete this->BasisSet; this->BasisSet = nullptr; } } //------------------------------------------------------------------------------ vtkMolecule* vtkOpenQubeMoleculeSource::GetOutput() { return vtkMolecule::SafeDownCast(this->GetOutputDataObject(0)); } //------------------------------------------------------------------------------ void vtkOpenQubeMoleculeSource::SetOutput(vtkMolecule* output) { this->GetExecutive()->SetOutputData(0, output); } //------------------------------------------------------------------------------ void vtkOpenQubeMoleculeSource::SetBasisSet(OpenQube::BasisSet* b) { vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting BasisSet to " << b); if (this->BasisSet != b) { if (this->CleanUpBasisSet) { delete this->BasisSet; } this->BasisSet = b; this->CleanUpBasisSetOff(); this->Modified(); } } //------------------------------------------------------------------------------ int vtkOpenQubeMoleculeSource::RequestData( vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector) { vtkMolecule* output = vtkMolecule::SafeDownCast(vtkDataObject::GetData(outputVector)); if (!output) { vtkWarningMacro(<< "vtkOpenQubeMoleculeSource does not have a vtkMolecule " "as output."); return 1; } // Obtain basis set OpenQube::BasisSet* basisSet = 0; if (this->BasisSet) { basisSet = this->BasisSet; } else { if (!this->FileName) { vtkWarningMacro(<< "No FileName or OpenQube::BasisSet specified."); return 1; } // We're creating the BasisSet, so we need to clean it up this->CleanUpBasisSetOn(); // Huge padding, better safe than sorry. char basisName[strlen(this->FileName) + 256]; OpenQube::BasisSetLoader::MatchBasisSet(this->FileName, basisName); if (!basisName[0]) { vtkErrorMacro(<< "OpenQube cannot find matching basis set file for '" << this->FileName << "'"); return 1; } basisSet = OpenQube::BasisSetLoader::LoadBasisSet(basisName); this->BasisSet = basisSet; vtkDebugMacro(<< "Loaded basis set file: " << basisName); } // Populate vtkMolecule const OpenQube::Molecule& oqmol = basisSet->moleculeRef(); this->CopyOQMoleculeToVtkMolecule(&oqmol, output); // Add ElectronicData vtkNew oqed; oqed->SetBasisSet(basisSet); output->SetElectronicData(oqed); return 1; } //------------------------------------------------------------------------------ int vtkOpenQubeMoleculeSource::FillOutputPortInformation(int, vtkInformation* info) { info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMolecule"); return 1; } //------------------------------------------------------------------------------ void vtkOpenQubeMoleculeSource::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "FileName: " << this->FileName << "\n"; } //------------------------------------------------------------------------------ void vtkOpenQubeMoleculeSource::CopyOQMoleculeToVtkMolecule( const OpenQube::Molecule* oqmol, vtkMolecule* mol) { mol->Initialize(); // Copy atoms Eigen::Vector3d pos; for (size_t i = 0; i < oqmol->numAtoms(); ++i) { vtkAtom atom = mol->AppendAtom(); pos = oqmol->atomPos(i); atom.SetPosition(vtkVector3d(pos.data()).Cast().GetData()); atom.SetAtomicNumber(oqmol->atomAtomicNumber(i)); } // TODO copy bonds (OQ doesn't currently have bonds) }