Mesh::~Mesh() { Domain* domain = OPS_GetDomain(); if (domain == 0) return; clearEles(); clearNodes(); }
int Mesh::clearEles() { Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; // clear elements for (int i=0; i<eletags.Size(); ++i) { Element* ele = domain->removeElement(eletags(i)); if (ele != 0) { delete ele; } } eletags = ID(); elenodes = ID(); return 0; }
int Mesh::nextEleTag() { Domain* domain = OPS_GetDomain(); if (domain == 0) { opserr << "WARNING: domain is not created\n"; return -1; } ElementIter& eles = domain->getElements(); Element* ele = 0; int etag = 0; while((ele = eles()) != 0) { etag = ele->getTag(); } return etag+1; }
int Mesh::nextNodeTag() { Domain* domain = OPS_GetDomain(); if (domain == 0) { opserr << "WARNING: domain is not created\n"; return -1; } NodeIter& nodes = domain->getNodes(); Node* node = 0; int ndtag = 0; while((node = nodes()) != 0) { ndtag = node->getTag(); } return ndtag+1; }
int Mesh::clearNodes() { Domain* domain = OPS_GetDomain(); return 0; // clear nodes for (int i=0; i<newndtags.Size(); ++i) { Node* node = domain->removeNode(newndtags(i)); if (node != 0) { delete node; } Pressure_Constraint* pc = domain->removePressure_Constraint(newndtags(i)); if (pc != 0) { delete pc; } } newndtags=ID(); return 0; }
int Mesh::newElements(const ID& elends) { Domain* domain = OPS_GetDomain(); if (domain == 0) { opserr << "WARNING: domain is not created\n"; return -1; } // if no element, no new elements if (eleType == 0) return 0; if (elends.Size() < numelenodes) { return 0; } // function to call void* (*OPS_Func)(const ID& info) = 0; switch (eleType) { case ELE_TAG_ElasticBeam2d: OPS_Func = OPS_ElasticBeam2d; break; case ELE_TAG_ForceBeamColumn2d: OPS_Func = OPS_ForceBeamColumn2d; break; case ELE_TAG_DispBeamColumn2d: OPS_Func = OPS_DispBeamColumn2d; break; case ELE_TAG_PFEMElement2DBubble: OPS_Func = OPS_PFEMElement2DBubble; break; case ELE_TAG_PFEMElement3DBubble: OPS_Func = OPS_PFEMElement3DBubble; break; case ELE_TAG_PFEMElement2Dmini: OPS_Func = OPS_PFEMElement2Dmini; break; case ELE_TAG_PFEMElement2DCompressible: OPS_Func = OPS_PFEMElement2DCompressible; break; case ELE_TAG_Tri31: OPS_Func = OPS_Tri31; break; case ELE_TAG_FourNodeTetrahedron: OPS_Func = OPS_FourNodeTetrahedron; break; case ELE_TAG_ShellMITC4: OPS_Func = OPS_ShellMITC4; break; default: OPS_Func = OPS_ElasticBeam2d; } int eletag = this->nextEleTag(); int nodetag = this->nextNodeTag(); // create elements ID neweletags(elends.Size()/numelenodes); std::vector<Element*> neweles(neweletags.Size()); #pragma omp parallel for for (int i=0; i<neweletags.Size(); ++i) { // element tag neweletags(i) = eletag+i; // info ID info(numelenodes+4); info(0) = 2; // load data info(1) = this->getTag(); // mesh tag info(2) = neweletags(i); // ele tag for (int j=0; j<numelenodes; ++j) { // get elenode info(3+j) = elends(numelenodes*i+j); } info(numelenodes+3) = nodetag+i; // create element neweles[i] = (Element*)OPS_Func(info); } // add elements to domain for (unsigned int i=0; i<neweles.size(); ++i) { if (neweles[i] == 0) { opserr<<"WARING: run out of memory for creating element\n"; return -1; } if (domain->addElement(neweles[i]) == false) { opserr<<"WARNING: failed to add element to domain\n"; delete neweles[i]; return -1; } } this->addEleTags(neweletags); return 0; }
int TetMesh::remesh(double alpha) { int ndm = OPS_GetNDM(); if (ndm != 3) { opserr << "WARNING: TetMesh::remesh is only for 3D problem\n"; return -1; } Domain* domain = OPS_GetDomain(); if (domain == 0) { opserr << "WARNING: domain is not created\n"; return -1; } // get all nodes std::map<int, std::vector<int> > ndinfo; TaggedObjectIter& meshes = OPS_getAllMesh(); ID nodetags; Mesh* msh = 0; while((msh = dynamic_cast<Mesh*>(meshes())) != 0) { int id = msh->getID(); int mtag = msh->getTag(); if (id == 0) continue; // get bound nodes const ID& tags = msh->getNodeTags(); for (int i=0; i<tags.Size(); ++i) { std::vector<int>& info = ndinfo[tags(i)]; info.push_back(mtag); info.push_back(id); nodetags.insert(tags(i)); } // get internal nodes const ID& newtags = msh->getNewNodeTags(); for (int i=0; i<newtags.Size(); ++i) { std::vector<int>& info = ndinfo[newtags(i)]; info.push_back(mtag); info.push_back(id); nodetags.insert(newtags(i)); } } if (nodetags.Size() == 0) return 0; // calling mesh generator TetMeshGenerator gen; int nodecounter = nextNodeTag(); for(int i=0; i<nodetags.Size(); ++i) { // get node Node* theNode = domain->getNode(nodetags(i)); if(theNode == 0) { opserr<<"WARNING: node "<<nodetags(i)<<" is not defined\n"; return -1; } const Vector& crds = theNode->getCrds(); const Vector& disp = theNode->getTrialDisp(); if(crds.Size() < ndm || disp.Size() < ndm) { opserr<<"WARNING: ndm < 3 or ndf < 3\n"; return -1; } // create pc if not Pressure_Constraint* thePC = domain->getPressure_Constraint(nodetags(i)); if(thePC != 0) { thePC->setDomain(domain); } else { // create pressure node Node* pnode = 0; pnode = new Node(nodecounter++, 1, crds(0), crds(1), crds(2)); if (pnode == 0) { opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n"; return -1; } if (domain->addNode(pnode) == false) { opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n"; delete pnode; return -1; } thePC = new Pressure_Constraint(nodetags(i), pnode->getTag()); if(thePC == 0) { opserr<<"WARNING: no enough memory for Pressure_Constraint\n"; return -1; } if (domain->addPressure_Constraint(thePC) == false) { opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n"; delete thePC; return -1; } } // add point gen.addPoint(crds(0)+disp(0), crds(1)+disp(1), crds(2)+disp(2), 0); } // meshing gen.remesh(alpha); // get elenodes std::map<int,ID> meshelenodes; for(int i=0; i<gen.getNumTets(); i++) { // get points int p1,p2,p3,p4; gen.getTet(i,p1,p2,p3,p4); // get nodes int nds[4]; nds[0] = nodetags(p1); nds[1] = nodetags(p2); nds[2] = nodetags(p3); nds[3] = nodetags(p4); // check if all nodes in same mesh std::vector<int>& info1 = ndinfo[nds[0]]; int mtag = 0, id = 0; bool same = false; for (int k=0; k<(int)info1.size()/2; ++k) { // check if any mesh of node 1 is same for another three nodes mtag = info1[2*k]; id = info1[2*k+1]; int num = 0; for (int j=1; j<4; ++j) { std::vector<int>& infoj = ndinfo[nds[j]]; for (int kj=0; kj<(int)infoj.size()/2; ++kj) { int mtagj = infoj[2*kj]; if (mtag == mtagj) { ++num; break; } } } if (num == 3) { same = true; break; } } // nodes in different mesh if (!same) { mtag = 0; id = 0; for (int j=0; j<4; ++j) { std::vector<int>& info = ndinfo[nds[j]]; for (int k=0; k<(int)info.size()/2; ++k) { if (info[2*k+1] < id) { if (dynamic_cast<TetMesh*>(OPS_getMesh(info[2*k])) != 0) { mtag = info[2*k]; id = info[2*k+1]; } } } } } // if all connected to structure if (id >= 0) continue; // add elenodes to its mesh ID& elenodes = meshelenodes[mtag]; for (int j=0; j<4; ++j) { elenodes[elenodes.Size()] = nds[j]; } } // creat elements for (std::map<int,ID>::iterator it=meshelenodes.begin(); it!=meshelenodes.end(); ++it) { int mtag = it->first; ID& elenodes = it->second; msh = OPS_getMesh(mtag); if (msh != 0) { int id = msh->getID(); // remove mesh for id<0 if (id < 0) { if (msh->clearEles() < 0) { opserr << "WARNING: failed to clear element in mesh"<<mtag<<"\n"; return -1; } if (msh->newElements(elenodes) < 0) { opserr << "WARNING: failed to create new elements in mesh"<<mtag<<"\n"; return -1; } } } } return 0; }
int TetMesh::mesh() { Domain* domain = OPS_GetDomain(); if (domain == 0) { opserr << "WARNING: domain is not created\n"; return -1; } // check double size = this->getMeshsize(); if(size <= 0) { opserr<<"WARNING: mesh size <= 0\n"; return -1; } if (mtags.Size() == 0) return 0; // get nodes and elements from boundary mesh ID ndtags; std::vector<TetMeshGenerator::Facet> facets; for (int i=0; i<mtags.Size(); ++i) { // get mesh Mesh* mesh = OPS_getMesh(mtags(i)); if (mesh == 0) { opserr << "WARNING: mesh "<<mtags(i)<<" does not exist\n"; return -1; } // get nodes const ID& tags = mesh->getNodeTags(); for (int j=0; j<tags.Size(); ++j) { ndtags.insert(tags(j)); } const ID& newtags = mesh->getNewNodeTags(); for (int j=0; j<newtags.Size(); ++j) { ndtags.insert(newtags(j)); } // get polygons int numelenodes = mesh->getNumEleNodes(); const ID& elends = mesh->getEleNodes(); TetMeshGenerator::Facet facet; for (int j=0; j<elends.Size()/numelenodes; ++j) { TetMeshGenerator::Polygon polygon(numelenodes); for (int k=0; k<numelenodes; ++k) { polygon[k] = elends(numelenodes*j+k); } facet.push_back(polygon); } // add the mesh as a facet facets.push_back(facet); } if(ndtags.Size() < 4) { opserr<<"WARNING: input number of nodes < 4\n"; return -1; } if(facets.size() < 4) { opserr<<"WARNING: input number of facets < 4\n"; return -1; } this->setNodeTags(ndtags); // get correct index for factes for (unsigned int i=0; i<facets.size(); ++i) { for (unsigned int j=0; j<facets[i].size(); ++j) { for (unsigned int k=0; k<facets[i][j].size(); ++k) { facets[i][j][k] = ndtags.getLocationOrdered(facets[i][j][k]); if (facets[i][j][k] < 0) { opserr << "WARNING: failed to get a node in a facet -- Tetmesh::mesh\n"; return -1; } } } } // calling mesh generator TetMeshGenerator gen; int nodecounter = nextNodeTag(); for(int i=0; i<ndtags.Size(); i++) { // get node Node* theNode = domain->getNode(ndtags(i)); if(theNode == 0) { opserr<<"WARNING: node "<<ndtags(i)<<" is not defined\n"; return -1; } Vector crds = theNode->getCrds(); const Vector& disp = theNode->getTrialDisp(); if(crds.Size() != 3) { opserr<<"WARNING: ndm != 3\n"; return -1; } if (disp.Size() >= crds.Size()) { for (int j=0; j<crds.Size(); ++j) { crds(j) += disp(j); } } // add point gen.addPoint(crds(0), crds(1), crds(2), 0); // add pc if (this->isFluid()) { // create pressure constraint Pressure_Constraint* thePC = domain->getPressure_Constraint(ndtags(i)); if(thePC != 0) { thePC->setDomain(domain); } else { // create pressure node Node* pnode = 0; pnode = new Node(nodecounter++, 1, crds[0], crds[1], crds[2]); if (pnode == 0) { opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n"; return -1; } if (domain->addNode(pnode) == false) { opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n"; delete pnode; return -1; } thePC = new Pressure_Constraint(ndtags(i), pnode->getTag()); if(thePC == 0) { opserr<<"WARNING: no enough memory for Pressure_Constraint\n"; return -1; } if (domain->addPressure_Constraint(thePC) == false) { opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n"; delete thePC; return -1; } } } } for (unsigned int i=0; i<facets.size(); ++i) { gen.addFacet(facets[i],0); } // meshing gen.mesh(size*size*size/(6.0*1.414),false); // get points and create nodes int nump = gen.getNumPoints(); if (nump == 0) { opserr << "WARNING: no nodes is meshed\n"; return -1; } ID newndtags(nump-ndtags.Size()); ID allndtags(nump); for (int i=0; i<ndtags.Size(); ++i) { allndtags(i) = ndtags(i); } for (int i=ndtags.Size(); i<nump; ++i) { // get point Vector crds(3); int mark = 0; gen.getPoint(i,crds(0),crds(1),crds(2),mark); Node* node = newNode(nodecounter++,crds); if (node == 0) { opserr << "WARING: failed to create node\n"; return -1; } if (domain->addNode(node) == false) { opserr << "WARNING: failed to add node to domain\n"; delete node; return -1; } allndtags(i) = node->getTag(); newndtags(i-ndtags.Size()) = node->getTag(); // add pc if (this->isFluid()) { // create pressure constraint Pressure_Constraint* thePC = domain->getPressure_Constraint(node->getTag()); if(thePC != 0) { thePC->setDomain(domain); } else { // create pressure node Node* pnode = 0; pnode = new Node(nodecounter++, 1, crds(0), crds(1), crds(2)); if (pnode == 0) { opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n"; return -1; } if (domain->addNode(pnode) == false) { opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n"; delete pnode; return -1; } thePC = new Pressure_Constraint(node->getTag(), pnode->getTag()); if(thePC == 0) { opserr<<"WARNING: no enough memory for Pressure_Constraint\n"; return -1; } if (domain->addPressure_Constraint(thePC) == false) { opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n"; delete thePC; return -1; } } } } this->setNewNodeTags(newndtags); // get tetrahedrons int numtet = gen.getNumTets(); if (numtet == 0) return 0; ID elenodes(numtet*4); for(int i=0; i<numtet; i++) { int p1,p2,p3,p4; gen.getTet(i,p1,p2,p3,p4); elenodes(4*i) = allndtags(p1); elenodes(4*i+1) = allndtags(p2); elenodes(4*i+2) = allndtags(p3); elenodes(4*i+3) = allndtags(p4); } this->setEleNodes(elenodes); // create elemnts if (this->newElements(elenodes) < 0) { opserr << "WARNING: failed to create elements\n"; return -1; } return 0; }
void * OPS_RotationShearCurve(void) { if (shearCurveCount == 0) { opserr << "RotationShearCurve limit curve - Written by MRL UT Austin Copyright 2012 - Use at your Own Peril \n"; shearCurveCount++; } int argc = OPS_GetNumRemainingInputArgs(); if (!(argc == 9 || argc == 23)) { opserr << "WARNING RotationShearCurve -- insufficient arguments\n"; opserr << "For direct input of shear curve parameters and degrading slope want:\n\n"; opserr << "limitCurve RotationShearCurve crvTag? eleTag? \n"; opserr << "ndI? ndJ? rotAxis? Vn? Vr? Kdeg? rotLim? \n" << endln; opserr << "OR for calibrated shear curve and degrading slope want:\n\n"; opserr << "limitCurve RotationShearCurve crvTag? eleTag?\n"; opserr << "ndI? ndJ? rotAxis? Vn? Vr? Kdeg? defType?\n"; opserr << "b? d? h? L? st? As? Acc? ld? db? rhot? f'c?\n"; opserr << "fy? fyt? delta?\n" << endln; return 0; } int iTagData[2]; int iNodeData[3]; double dKdegData[3]; double dRotLimData[1]; int iTypeData[1]; double dPropData[14]; int numData; numData = 2; if (OPS_GetIntInput(&numData, iTagData) != 0) { opserr << "WARNING RotationShearCurve -- invalid crvTag? eleTag?\n" << endln; return 0; } int eleTag = iTagData[1]; Domain *theDomain = 0; theDomain = OPS_GetDomain(); if (theDomain == 0) { opserr << "WARNING RotationShearCurve -- Pointer to Domain was not returned\n" << endln; return 0; } Element *theElement = 0; theElement = theDomain->getElement(eleTag); if (theElement == 0) { opserr << "WARNING RotationShearCurve -- Element with tag " << iTagData[1] << " does not exist for shear curve tag " << iTagData[0] << endln << endln; return 0; } numData = 3; if (OPS_GetIntInput(&numData, iNodeData) != 0) { opserr << "WARNING RotationShearCurve -- invalid ndI? ndJ? rotAxis?\n" << endln; return 0; } Node *theNodeI = 0; theNodeI = theDomain->getNode(iNodeData[0]); if (theNodeI == 0) { opserr << "WARNING RotationShearCurve -- Node with tag " << iNodeData[0] << " does not exist for shear curve tag " << iTagData[0] << endln << endln; return 0; } Node *theNodeJ = 0; theNodeJ = theDomain->getNode(iNodeData[1]); if (theNodeJ == 0) { opserr << "WARNING RotationShearCurve -- Node with tag " << iNodeData[1] << " does not exist for shear curve tag " << iTagData[0] << endln << endln; return 0; } if (iNodeData[2] < 3 || iNodeData[2] > 6) { opserr << "WARNING RotationShearCurve -- rotAxis is invalid\n"; opserr << "rotAxis = 3 -- Rotation about z-axis - 2D\n"; opserr << "rotAxis = 4 -- Rotation about x-axis - 3D\n"; opserr << "rotAxis = 5 -- Rotation about y-axis - 3D\n"; opserr << "rotAxis = 6 -- Rotation about z-axis - 3D\n" << endln; return 0; } if (argc == 9) { numData = 3; if (OPS_GetDoubleInput(&numData, dKdegData) != 0) { opserr << "WARNING RotationShearCurve -- invalid Vn? Vr? Kdeg?\n" << endln; return 0; } if (dKdegData[0] != -1 && !(dKdegData[0] > 0)) { opserr << "WARNING RotationShearCurve -- Vn input is invalid\n"; opserr << "Vn = -1 -- Shear critical limit is not used\n"; opserr << "Vn > 0 -- Shear critical limit is the input value\n" << endln; return 0; } if (dKdegData[1] < -1) { opserr << "WARNING RotationShearCurve -- Vr input is invalid\n"; opserr << "Vr = -1 -- Residual shear strength = 0.2*(maximum shear at failure)\n"; opserr << "-1 < Vr < 0 -- Residual shear strength = Vr*(maximum shear at failure)\n"; opserr << "Vr >= 0 -- Residual shear strength is the input value\n" << endln; return 0; } if (dKdegData[2] >= 0) { opserr << "WARNING RotationShearCurve -- Kdeg input is invalid\n"; opserr << "The degrading slope must be less than zero\n" << endln; return 0; } numData = 1; if (OPS_GetDoubleInput(&numData, dRotLimData) != 0) { opserr << "WARNING RotationShearCurve -- invalid rotLim?\n" << endln; return 0; } if (dRotLimData[0] <= 0) { opserr << "WARNING RotationShearCurve -- rotLim input must be greater than zero\n" << endln; return 0; } LimitCurve *theCurve = 0; theCurve = new RotationShearCurve(iTagData[0], iTagData[1], iNodeData[0], iNodeData[1], iNodeData[2], dKdegData[0], dKdegData[1], dKdegData[2], dRotLimData[0], 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, theDomain, theElement, theNodeI, theNodeJ); if (theCurve == 0) { opserr << "WARNING RotationShearCurve -- could not create limitCurve with constructor " << iTagData[0] << endln << endln; return 0; } return theCurve; } else { numData = 3; if (OPS_GetDoubleInput(&numData, dKdegData) != 0) { opserr << "WARNING RotationShearCurve -- invalid Vn? Vr? Kdeg?\n" << endln; return 0; } if (dKdegData[0] != -1 && !(dKdegData[0] >= 0)) { opserr << "WARNING RotationShearCurve -- Vn input is invalid\n"; opserr << "Vn = -1 -- Shear critical limit is not used\n"; opserr << "Vn = 0 -- Shear critical limit is calculated using ASCE 41 Eq. 6-4\n"; opserr << "Vn > 0 -- Shear critical limit is the input value\n" << endln; return 0; } if (dKdegData[1] < -1) { opserr << "WARNING RotationShearCurve -- Vr input is invalid\n"; opserr << "Vr = -1 -- Residual shear strength from regression\n"; opserr << "-1 < Vr < 0 -- Residual shear strength = Vr*(maximum shear at failure)\n"; opserr << "Vr >= 0 -- Residual shear strength is the input value\n" << endln; return 0; } if (dKdegData[2] > 0) { opserr << "WARNING RotationShearCurve -- Kdeg input is invalid\n"; opserr << "Kdeg = 0 -- Degrading slope calculated by regressions\n"; opserr << "Kdeg < 0 -- Degrading slope is the input value\n" << endln; return 0; } numData = 1; if (OPS_GetIntInput(&numData, iTypeData) != 0) { opserr << "WARNING RotationShearCurve -- invalid defType?\n" << endln; return 0; } if (iTypeData[0] > 5 || iTypeData[0] <= 0) { opserr << "WARNING RotationShearCurve -- invalid defType input?\n" << endln; opserr << "1 -- Flexure-Shear capacity based on theta_f rotation capacity\n"; opserr << "2 -- Flexure-Shear capacity based on theta_total rotation capacity\n"; opserr << "3 -- Flexure-Shear capacity based on theta_flexural rotation capacity\n"; opserr << "4 -- Flexure-Shear capacity based on theta_total-plastic rotation capacity\n"; opserr << "5 -- Flexure-Shear capacity based on theta_flexural-plastic rotation capacity\n" << endln; return 0; } numData = 14; if (OPS_GetDoubleInput(&numData, dPropData) != 0) { opserr << "WARNING RotationShearCurve -- invalid b? d? h? L? st? As? Acc? ld? db? rhot? f'c? fy? fyt? delta?\n" << endln; return 0; } LimitCurve *theCurve = 0; theCurve = new RotationShearCurve(iTagData[0], iTagData[1], iNodeData[0], iNodeData[1], iNodeData[2], dKdegData[0], dKdegData[1], dKdegData[2], 0.0, iTypeData[0], fabs(dPropData[0]), fabs(dPropData[1]), fabs(dPropData[2]), fabs(dPropData[3]), fabs(dPropData[4]), fabs(dPropData[5]), fabs(dPropData[6]), fabs(dPropData[7]), fabs(dPropData[8]), fabs(dPropData[9]), fabs(dPropData[10]), fabs(dPropData[11]), fabs(dPropData[12]), dPropData[13], theDomain, theElement, theNodeI, theNodeJ); if (theCurve == 0) { opserr << "WARNING RotationShearCurve -- could not create limitCurve with constructor " << iTagData[0] << endln << endln; return 0; } return theCurve; } }