Beispiel #1
0
Mesh::~Mesh()
{
    Domain* domain = OPS_GetDomain();
    if (domain == 0) return;

    clearEles();
    clearNodes();
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
  }
}