/*========================================================================= Program: Visualization Toolkit Module: vtkQuadratureSchemeDefinition.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 "vtkQuadratureSchemeDefinition.h" #include "vtkObjectFactory.h" #include "vtkInformationQuadratureSchemeDefinitionVectorKey.h" #include "vtkInformationStringKey.h" #include "vtkCellType.h" #include "vtkXMLDataElement.h" #include using std::ostringstream; using std::istringstream; #include using std::string; vtkStandardNewMacro(vtkQuadratureSchemeDefinition); //----------------------------------------------------------------------------- vtkInformationKeyMacro( vtkQuadratureSchemeDefinition, DICTIONARY, QuadratureSchemeDefinitionVector); vtkInformationKeyMacro( vtkQuadratureSchemeDefinition, QUADRATURE_OFFSET_ARRAY_NAME, String); //----------------------------------------------------------------------------- vtkQuadratureSchemeDefinition::vtkQuadratureSchemeDefinition() { this->ShapeFunctionWeights=nullptr; this->QuadratureWeights=nullptr; this->Clear(); } //----------------------------------------------------------------------------- vtkQuadratureSchemeDefinition::~vtkQuadratureSchemeDefinition() { this->Clear(); } //----------------------------------------------------------------------------- int vtkQuadratureSchemeDefinition::DeepCopy(const vtkQuadratureSchemeDefinition *other) { this->ShapeFunctionWeights=nullptr; this->QuadratureWeights=nullptr; this->Clear(); // this->CellType=other->CellType; this->QuadratureKey=other->QuadratureKey; this->NumberOfNodes=other->NumberOfNodes; this->NumberOfQuadraturePoints=other->NumberOfQuadraturePoints; // this->SecureResources(); // this->SetShapeFunctionWeights(other->GetShapeFunctionWeights()); this->SetQuadratureWeights(other->GetQuadratureWeights()); // return 1; } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::Clear() { this->ReleaseResources(); this->CellType=-1; this->QuadratureKey=-1; this->NumberOfNodes=0; this->NumberOfQuadraturePoints=0; } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::Initialize( int cellType, int numberOfNodes, int numberOfQuadraturePoints, double *shapeFunctionWeights) { this->ReleaseResources(); // this->CellType=cellType; this->QuadratureKey=-1; this->NumberOfNodes=numberOfNodes; this->NumberOfQuadraturePoints=numberOfQuadraturePoints; // this->SecureResources(); // this->SetShapeFunctionWeights(shapeFunctionWeights); } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::Initialize( int cellType, int numberOfNodes, int numberOfQuadraturePoints, double *shapeFunctionWeights, double *quadratureWeights) { this->ReleaseResources(); // this->CellType=cellType; this->QuadratureKey=-1; this->NumberOfNodes=numberOfNodes; this->NumberOfQuadraturePoints=numberOfQuadraturePoints; // this->SecureResources(); // this->SetShapeFunctionWeights(shapeFunctionWeights); this->SetQuadratureWeights(quadratureWeights); } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::ReleaseResources() { delete [] this->ShapeFunctionWeights; this->ShapeFunctionWeights=nullptr; delete [] this->QuadratureWeights; this->QuadratureWeights=nullptr; } //----------------------------------------------------------------------------- int vtkQuadratureSchemeDefinition::SecureResources() { if ((this->NumberOfQuadraturePoints<=0) || (this->NumberOfNodes<=0)) { vtkWarningMacro("Failed to allocate. Invalid buffer size."); return 0; } // Delete weights if they have been allocated this->ReleaseResources(); // Shape function weights, one vector for each quad point. this->ShapeFunctionWeights = new double [this->NumberOfQuadraturePoints*this->NumberOfNodes]; for (int i = 0; i < this->NumberOfQuadraturePoints*this->NumberOfNodes; i++) { this->ShapeFunctionWeights[i] = 0.0; } // Quadrature weights, one double for each quad point this->QuadratureWeights = new double [this->NumberOfQuadraturePoints]; for (int i = 0; i < this->NumberOfQuadraturePoints; i++) { this->QuadratureWeights[i] = 0.0; } return 1; } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::SetShapeFunctionWeights(const double *W) { if ((this->NumberOfQuadraturePoints<=0) || (this->NumberOfNodes<=0) || (this->ShapeFunctionWeights==nullptr) || !W) { return; } // Copy int n=this->NumberOfQuadraturePoints*this->NumberOfNodes; for (int i=0; iShapeFunctionWeights[i]=W[i]; } } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::SetQuadratureWeights(const double *W) { if ((this->NumberOfQuadraturePoints<=0) || (this->NumberOfNodes<=0) || (this->QuadratureWeights==nullptr) || !W) { return; } // Copy for (int i=0; iNumberOfQuadraturePoints; ++i) { this->QuadratureWeights[i]=W[i]; } } //----------------------------------------------------------------------------- void vtkQuadratureSchemeDefinition::PrintSelf(ostream &sout, vtkIndent indent) { vtkObject::PrintSelf(sout,indent); double *pSfWt=this->ShapeFunctionWeights; for (int ptId=0; ptIdNumberOfQuadraturePoints; ++ptId) { sout << indent << "(" << pSfWt[0]; ++pSfWt; for (int nodeId=1; nodeIdNumberOfNodes; ++nodeId) { sout << indent << ", " << pSfWt[0]; ++pSfWt; } sout << ")" << endl; } } //NOTE: These are used by XML readers/writers. //----------------------------------------------------------------------------- ostream &operator<<(ostream &sout, const vtkQuadratureSchemeDefinition &def) { /* stream will have this space delimited format: [cell type][number of cell nodes][number quadrature points][Qp1 ... QpN][Qwt1...QwtN] */ // Size of arrays int nQuadPts=def.GetNumberOfQuadraturePoints(); int nNodes=def.GetNumberOfNodes(); // Write header sout << def.GetCellType() << " " << nNodes << " " << nQuadPts; if ((nNodes>0) && (nQuadPts>0)) { sout.setf(ios::floatfield, ios::scientific); sout.precision(16); const double *pWt; // Write shape function weights pWt=def.GetShapeFunctionWeights(); for (int ptId=0; ptId>(istream &sin, vtkQuadratureSchemeDefinition &def) { /* stream will have this space delimited format: [cell type][number of cell nodes][number quadrature points][Qp1 ... QpN][Qwt1...QwtN] */ // read the header int cellType, nNodes, nQuadPts; sin >> cellType >> nNodes >> nQuadPts; double *SfWt=nullptr,*QWt=nullptr,*pWt=nullptr; if ((nNodes>0) && (nQuadPts>0)) { // read shape function weights SfWt=new double [nQuadPts*nNodes]; pWt=SfWt; for (int ptId=0; ptId> pWt[0]; ++pWt; } } // Write quadrature weights QWt=new double [nQuadPts]; pWt=QWt; for (int nodeId=0; nodeId> pWt[0]; ++pWt; } } else { vtkGenericWarningMacro("Empty definition found in stream."); } // initialize the object def.Initialize(cellType,nNodes,nQuadPts,SfWt,QWt); // clean up delete [] SfWt; delete [] QWt; return sin; } //----------------------------------------------------------------------------- int vtkQuadratureSchemeDefinition::SaveState(vtkXMLDataElement *root) { // Quick sanity check, we're not nesting rather treating // this as a root, to be nested by the caller as needed. if (root->GetName()!=nullptr || root->GetNumberOfNestedElements()>0) { vtkWarningMacro("Can't save state to non-empty element."); return 0; } root->SetName("vtkQuadratureSchemeDefinition"); vtkXMLDataElement *e; e=vtkXMLDataElement::New(); e->SetName("CellType"); e->SetIntAttribute("value",this->CellType); root->AddNestedElement(e); e->Delete(); e=vtkXMLDataElement::New(); e->SetName("NumberOfNodes"); e->SetIntAttribute("value",this->NumberOfNodes); root->AddNestedElement(e); e->Delete(); e=vtkXMLDataElement::New(); e->SetName("NumberOfQuadraturePoints"); e->SetIntAttribute("value",this->NumberOfQuadraturePoints); root->AddNestedElement(e); e->Delete(); vtkXMLDataElement *eShapeWts=vtkXMLDataElement::New(); eShapeWts->SetName("ShapeFunctionWeights"); eShapeWts->SetCharacterDataWidth(4); root->AddNestedElement(eShapeWts); eShapeWts->Delete(); vtkXMLDataElement *eQuadWts=vtkXMLDataElement::New(); eQuadWts->SetName("QuadratureWeights"); eQuadWts->SetCharacterDataWidth(4); root->AddNestedElement(eQuadWts); eQuadWts->Delete(); if ((this->NumberOfNodes>0) && (this->NumberOfQuadraturePoints>0)) { // Write shape function weights ostringstream ssShapeWts; ssShapeWts.setf(ios::floatfield, ios::scientific); ssShapeWts.precision(16); ssShapeWts << this->ShapeFunctionWeights[0]; int nIds=this->NumberOfNodes*this->NumberOfQuadraturePoints; for (int id=1; idShapeFunctionWeights[id]; } string sShapeWts=ssShapeWts.str(); eShapeWts->SetCharacterData(sShapeWts.c_str(),static_cast(sShapeWts.size())); // Write quadrature weights ostringstream ssQuadWts; ssQuadWts.setf(ios::floatfield, ios::scientific); ssQuadWts.precision(16); ssQuadWts << this->QuadratureWeights[0]; for (int id=1; idNumberOfQuadraturePoints; ++id) { ssQuadWts << " " << this->QuadratureWeights[id]; } string sQuadWts=ssQuadWts.str(); eQuadWts->SetCharacterData(sQuadWts.c_str(),static_cast(sQuadWts.size())); } else { vtkGenericWarningMacro("Empty definition written to stream."); return 0; } return 1; } //----------------------------------------------------------------------------- int vtkQuadratureSchemeDefinition::RestoreState(vtkXMLDataElement *root) { // A quick sanity check to be sure we have the correct tag. if (strcmp(root->GetName(),"vtkQuadratureSchemeDefinition")!=0) { vtkWarningMacro("Attempting to restore the state in " << root->GetName() << " into vtkQuadratureSchemeDefinition."); return 0; } vtkXMLDataElement *e; const char *value; // Transfer state from XML hierarchy. e=root->FindNestedElementWithName("CellType"); if (e==nullptr) { vtkWarningMacro("Expected nested element \"CellType\" " "is not present."); return 0; } value=e->GetAttribute("value"); this->CellType=atoi(value); // e=root->FindNestedElementWithName("NumberOfNodes"); if (e==nullptr) { vtkWarningMacro("Expected nested element \"NumberOfNodes\" " "is not present."); return 0; } value=e->GetAttribute("value"); this->NumberOfNodes=atoi(value); // e=root->FindNestedElementWithName("NumberOfQuadraturePoints"); if (e==nullptr) { vtkWarningMacro("Expected nested element \"NumberOfQuadraturePoints\" " "is not present."); return 0; } value=e->GetAttribute("value"); this->NumberOfQuadraturePoints=atoi(value); // Extract the weights. if (this->SecureResources()) { istringstream issWts; // e=root->FindNestedElementWithName("ShapeFunctionWeights"); if (e==nullptr) { vtkWarningMacro("Expected nested element \"ShapeFunctionWeights\" " "is not present."); return 0; } value=e->GetCharacterData(); if (value==nullptr) { vtkWarningMacro("Character data in nested element" " \"ShapeFunctionWeights\" is not present."); return 0; } issWts.str(value); int nWts=this->NumberOfNodes*this->NumberOfQuadraturePoints; for (int id=0; id> this->ShapeFunctionWeights[id]; } // e=root->FindNestedElementWithName("QuadratureWeights"); if (e==nullptr) { vtkWarningMacro("Expected element \"QuadratureWeights\" " "is not present."); return 0; } value=e->GetCharacterData(); if (value==nullptr) { vtkWarningMacro("Character data in expected nested element" " \"QuadratureWeights\" is not present."); return 0; } issWts.str(value); for (int id=0; idNumberOfQuadraturePoints; ++id) { if (!issWts.good()) { vtkWarningMacro("Character data for \"QuadratureWeights\" " "is short."); return 0; } issWts >> this->QuadratureWeights[id]; } } return 1; }