Exemple #1
0
Node*
Mesh::newNode(int tag, const Vector& crds)
{
    // check ndf
    if (ndf <= 0) return 0;

    // craete new node
    Node* node = 0;
    if (crds.Size() == 1) {
        node = new Node(tag, ndf, crds(0));
    } else if (crds.Size() == 2) {
        node = new Node(tag, ndf, crds(0), crds(1));
    } else if (crds.Size() == 3) {
        node = new Node(tag, ndf, crds(0), crds(1), crds(2));
    }

    return node;
}
Exemple #2
0
int
TriMesh::mesh(double alpha, const ID& rtags2, const ID& rtags)
{
    // get all regions
    int numregions = rtags.Size()+rtags2.Size();
    int numpoints = 0;
    std::vector<MeshRegion*> regions(numregions);
    for(int i=0; i<rtags.Size(); i++) {
	MeshRegion* region = theDomain->getRegion(rtags(i));
	if(region == 0) {
	    opserr<<"WARNING: region "<<rtags(i)<<" is not defined\n";
	    return -1;
	}
	numpoints += region->getNodes().Size();
	regions[i] = region;
    }
    for(int i=0; i<rtags2.Size(); i++) {
	MeshRegion* region = theDomain->getRegion(rtags2(i));
	if(region == 0) {
	    opserr<<"WARNING: region "<<rtags2(i)<<" is not defined\n";
	    return -1;
	}
	numpoints += region->getNodes().Size();
	regions[i+rtags.Size()] = region;

	// remove elements
	const ID& eles = region->getExtraEles();
	for (int j=0; j<eles.Size(); j++) {
	    Element* ele = theDomain->removeElement(eles(j));
	    if (ele != 0) {
		delete ele;
	    }
	}

    }

    // get all points
    ID ptreg(0,numpoints), ptnode(0,numpoints);
    for(int i=0; i<numregions; i++) {
	const ID& nodes = regions[i]->getNodes();
	for(int j=0; j<nodes.Size(); j++) {
	    int index = ptreg.Size();
	    ptreg[index] = i;
	    ptnode[index] = nodes(j);
	}
    }

    // calling mesh generator
    TriangleMeshGenerator gen;
    for(int i=0; i<ptnode.Size(); i++) {
	// get node
	Node* theNode = theDomain->getNode(ptnode(i));
	if(theNode == 0) {
	    opserr<<"WARNING: node "<<ptnode(i)<<" is not defined\n";
	    return -1;
	}
	const Vector& crds = theNode->getCrds();
	const Vector& disp = theNode->getTrialDisp();
	if(crds.Size() < 2 || disp.Size() < 2) {
	    opserr<<"WARNING: ndm < 2 or ndf < 2\n";
	    return -1;
	}
	
	// add point
	gen.addPoint(crds(0)+disp(0), crds(1)+disp(1));
    }

    // meshing
    gen.remesh(alpha);

    // get elenodes
    std::vector<ID> regelenodes(rtags2.Size());
    for(int i=0; i<gen.getNumTriangles(); i++) {
	int p1,p2,p3;
	gen.getTriangle(i,p1,p2,p3);

	// if all connected to fixed regions
	int numfix = rtags.Size();
	if(ptreg(p1)<numfix && ptreg(p2)<numfix && ptreg(p3)<numfix) {
	    continue;
	}
	
	// which region it belongs to
	int reg = ptreg(p1);
	if(reg<numfix || (reg>ptreg(p2) && ptreg(p2)>=numfix)) reg = ptreg(p2);
	if(reg<numfix || (reg>ptreg(p3) && ptreg(p3)>=numfix)) reg = ptreg(p3);
	reg -= numfix;

	// elenodes
	int index = regelenodes[reg].Size();
	regelenodes[reg][index++] = ptnode(p1);
	regelenodes[reg][index++] = ptnode(p2);
	regelenodes[reg][index++] = ptnode(p3);
    }

    // all elenodes
    ID allelenodes;
    for(int i=0; i<(int)regelenodes.size(); i++) {
	int num = allelenodes.Size();
	int num1 = regelenodes[i].Size();
	allelenodes.resize(num+num1);
	for (int j=0; j<num1; j++) {
	    allelenodes(num+j) = regelenodes[i](j);
	}
    }

    // create elements
    std::string eletype = OPS_GetString();
    ID eletags;
    if (eletype=="PFEMElement2D") {
	if (OPS_PFEMElement2D(*theDomain,allelenodes,eletags) < 0) {
	    return -1;
	}
    } else if (eletype=="PFEMElement2DQuasi") {
	if (OPS_PFEMElement2DCompressible(*theDomain,allelenodes,eletags) < 0) {
	    return -1;
	}
    } else if (eletype=="PFEMElement2DBubble") {
	if (OPS_PFEMElement2DBubble(*theDomain,allelenodes,eletags) < 0) {
	    return -1;
	}

    }  else if (eletype=="tri31") {
	if (OPS_Tri31(*theDomain,allelenodes,eletags) < 0) {
	    return -1;
	}

    } else {
	opserr<<"WARNING: element "<<eletype.c_str()<<" can't be used for tri mesh at this time\n";
	return -1;
    }

    // add to region
    int num = 0;

    for(int i=rtags.Size(); i<numregions; i++) {
	int num1 = regelenodes[i-rtags.Size()].Size()/3;
	ID eletag(num1);
	for (int j=0; j<num1; j++) {
	    eletag(j) = eletags(num+j);
	}
	num += num1;
	regions[i]->setExtraEles(eletag);
    }
    return 0;
}
Exemple #3
0
int
TriMesh::mesh(int rtag, double size, const ID& nodes,const ID& bound)
{
    // check
    if(size <= 0) {
	opserr<<"WARNING: mesh size <= 0\n";
	return -1;
    }
    if(nodes.Size() < 3) {
	opserr<<"WARNING: input number of nodes < 3\n";
	return -1;
    }
    if(bound.Size() < nodes.Size()) {
	opserr<<"WARNING: the number of boundary ID < number of nodes\n";
	return -1;
    }
    
    // calling mesh generator
    TriangleMeshGenerator gen;
    for(int i=0; i<nodes.Size(); i++) {
	// get node
	Node* theNode = theDomain->getNode(nodes(i));
	if(theNode == 0) {
	    opserr<<"WARNING: node "<<nodes(i)<<" is not defined\n";
	    return -1;
	}
	const Vector& crds = theNode->getCrds();
	if(crds.Size() < 2) {
	    opserr<<"WARNING: ndm < 2\n";
	    return -1;
	}
	// add point
	gen.addPoint(crds(0), crds(1));

	// add segment
	int p1 = i;
	int p2;
	if(i==nodes.Size()-1) {
	    p2 = 0;
	} else {
	    p2 = i+1;
	}
	if(bound(i) == 0) {
	    gen.addSegment(p1,p2,-1);
	} else {
	    gen.addSegment(p1,p2,0);
	}
    }

    // meshing
    gen.mesh(size*size*0.5);

    // get node tag
    NodeIter& theNodes = theDomain->getNodes();
    Node* theNode = theNodes();
    int currtag = 0;
    if(theNode != 0) currtag = theNode->getTag();

    // get nodes
    ID regnodes(0,gen.getNumPoints());
    ID ptmark(gen.getNumPoints());
    ID ptnode(gen.getNumPoints());
    int index = 0;
    for(int i=0; i<nodes.Size(); i++) {
	int j = i-1;
	if(i==0) j = nodes.Size()-1;
	if(bound(i)!=0 && bound(j)!=0) {
	    regnodes[index++] = nodes(i);
	    ptmark(i) = 0;
	} else {
	    ptmark(i) = -1;
	}
	ptnode(i) = nodes(i);
    }
    for(int i=nodes.Size(); i<gen.getNumPoints(); i++) {
	// get point
	double x, y;
	int mark = 0;
	gen.getPoint(i,x,y,mark);

	// if on unwanted boundary
	if(mark == -1) {
	    ptmark(i) = -1;
	    continue;
	} else {
	    ptmark(i) = 0;
	}

	// create node
	Node* node = new Node(--currtag,ndf,x,y);
	if(node == 0) {
	    opserr<<"run out of memory for creating Node\n";
	    return -1;
	}
	if(theDomain->addNode(node) == false) {
	    opserr<<"Failed to add node to domain\n";
	    delete node;
	    return -1;
	}

	// add to region
	regnodes[index++] = currtag;
	ptnode(i) = currtag;
    }

    // get elenodes
    ID regelenodes(0,gen.getNumTriangles());
    index = 0;
    for(int i=0; i<gen.getNumTriangles(); i++) {
	int p1,p2,p3;
	gen.getTriangle(i,p1,p2,p3);
	if(ptmark(p1)==0 && ptmark(p2)==0 && ptmark(p3)==0) {
	    regelenodes[index++] = ptnode(p1);
	    regelenodes[index++] = ptnode(p2);
	    regelenodes[index++] = ptnode(p3);
	}
    }

    // get region
    MeshRegion* theRegion = theDomain->getRegion(rtag);
    if(theRegion == 0) {
	theRegion = new MeshRegion(rtag);
	if(theDomain->addRegion(*theRegion) < 0) {
	    opserr<<"WARNING: failed to add region\n";
	    return -1;
	}
    }

    // add to region
    theRegion->setNodes(regnodes);
    
    return 0;
}
void ServiceSystemUI::on_startAutoButton_clicked()
{
    QGraphicsScene * scene = new QGraphicsScene(ui->graphicsView);
    QPen pen(Qt::red);
    pen.setWidth(2);

    ServiceSystem::Results res;

    double p0 = 0, p1 = 0, diff = 0, precision = 0.1;
    int N = 10;

    struct result
    {
        double x, y;
        result()
            : x(0), y(0)
        {}
        result(double x_, double y_)
            : x(x_), y(y_)
        {}
    };

    std::vector<result> results;

    ui->max_y->setText("1");

    do
    {
        ServiceSystem s_system(ui->srcAmountText->text().toUInt(),
                               ui->buffSizeText->text().toUInt(),
                               ui->rcvAmountText->text().toUInt(),
                               ui->srcLambda->text().toDouble(),
                               ui->rcvLambda->text().toDouble());
        p0 = p1;
        //scene->clear();
        Coordinates crds(0, N, 0, 1);
        crds.draw(scene);
        pen.setColor(QColor(255 * N / 11000, 255 - 255 * N / 11000, 0));
        int step = std::round(N / 300);
        if (step == 0) {
            step = 1;
        }
        for (int i = 0; i < N; ++i)
        {
            s_system.make_step();
            ServiceSystem::Results lres = s_system.get_results();
            double p = 0;
            switch (ui->graphList->currentIndex())
            {
                case 0:
                {
                    p = 1. - ((double)lres.accepted / (double)lres.generated);
                    break;
                }
                case 1:
                {
                    p = lres.downtime / (ui->rcvAmountText->text().toUInt() * lres.final_time);
                    break;
                }
            }

            int px = std::round(i * crds.get_x_prop());
            int py = std::round(p * crds.get_y_prop());
            if (i % step == 0) {
                scene->addLine(px, py, px, py, pen);
            }
        }
        ui->graphicsView->setScene(scene);
        ui->graphicsView->update();

        res = s_system.get_results();
        switch (ui->graphList->currentIndex())
        {
            case 0:
            {
                p1 = 1. - ((double)res.accepted / (double)res.generated);
                break;
            }
            case 1:
            {
                p1 = res.downtime / (ui->rcvAmountText->text().toUInt() * res.final_time);
                break;
            }
        }
        results.push_back(result(N, p1));

        std::cout << "N = " << N << std::endl;
        std::cout << "P_0 = " << p0 << std::endl;
        std::cout << "P_1 = " << p1 << std::endl;
        if (p1 == 0) {
            break;
        }
        N = std::round((1.643 * 1.643 * (1 - p1)) / (p1 * precision * precision));
        if (N > 20000) {
            N = 20000;
        }
        std::cout << "New N = " << N << std::endl;
        diff = std::abs(p0 - p1);
    }
    while (diff >= precision * p0);

    Coordinates crds(0, N, 0, 1);
    pen.setWidth(10);
    int px = std::round(N * crds.get_x_prop());
    int py = std::round(p1 * crds.get_y_prop());
    scene->addLine(px, py, px, py, pen);
    scene->addLine(0, py, 0, py, pen);
    ui->graphicsView->setScene(scene);
    ui->max_x->setText(QString::number(N));

    ui->finalValue->setText("Refusal: " +
                            QString::number(1. - (double)res.accepted / (double)res.generated)
                            + "\nError: " + QString::number(std::abs(p0 - p1))
                            + "\nDowntime: " +
                            QString::number(res.downtime / (ui->rcvAmountText->text().toUInt()*res.final_time))
                            + "\nFinal time: " + QString::number(res.final_time));

    ui->finalValue->setStyleSheet("color: rgb(" + QString::number(pen.color().red())
                                  + "," + QString::number(pen.color().green())
                                  + "," + QString::number(pen.color().blue()) + ");");
}
Exemple #5
0
GSA_Recorder::GSA_Recorder(Domain &theDom, 
			   const char *fileName, 
			   const char *title1,
			   const char *title2,
			   const char *title3,
			   const char *jobno,
			   const char *initials,
			   const char *spec,
			   const char *currency,
			   const char *length,
			   const char *force,
			   const char *temp,
			   double dT)
: Recorder(RECORDER_TAGS_GSA_Recorder),
  theDomain(&theDom), ndm(3), ndf(6), counter(0), deltaT(dT), nextTimeStampToRecord(0.0)
{
  // open file 
  if (theFile.setFile(fileName, OVERWRITE) < 0) {
    opserr << "WARNING - GSA_Recorder::GSA_Recorder()";
    opserr << " - could not open file " << fileName << endln;
    exit(-1);
  } 

  // spit out header data
  if (title1 != 0)
    theFile << "TITLE\t" << title1;
  else
    theFile << "TITLE\t" << "No Title";


  if (title2 != 0)
    theFile << "\t" << title2;
  else
    theFile << "\t" << "BLANK";


  if (title3 != 0)
    theFile << "\t" << title3;
  else
    theFile << "\t" << "BLANK";  


  if (jobno != 0)
    theFile << "\t" << jobno;
  else
    theFile << "\t" << "0000";


  if (initials != 0)
    theFile<< "\t" << initials << endln;
  else
    theFile << "\t" << "ANOTHER\n";  


  if (spec != 0)
    theFile << "SPEC\t" << spec << endln;


  if (currency != 0)
    theFile << "CURRENCY\t" << currency << endln;


  if (length != 0)
    theFile << "UNIT_DATA\tLENGTH\t" << length << endln; 


  if (force != 0)
    theFile << "UNIT_DATA\tFORCE\t" << force << endln;


  if (temp != 0)
    theFile << "UNIT_DATA\tTEMP\t" << temp << endln;


  // spit out nodal data
  NodeIter &theNodes = theDomain->getNodes();
  Node *theNode;
  while ((theNode=theNodes()) != 0) {
    int nodeTag = theNode->getTag();
    theFile << "NODE\t" << nodeTag;
    const Vector &crds = theNode->getCrds();
    if (crds.Size() != ndm) {
      opserr << "WARNING - GSA_Recorder::GSA_Recorder() - node: " <<  nodeTag ;
      opserr << " has invalid number of coordinates, expecting: " << ndm << " got: " << crds.Size() << endln;
      exit(-1);
    }
    const Vector &disp = theNode->getTrialDisp();
    if (disp.Size() != ndf) {
      opserr << "WARNING - GSA_Recorder::GSA_Recorder() - node: " <<  nodeTag ;
      opserr << " has invalid number of dof, expecting: " << ndf << " got: " << disp.Size() << endln;
      exit(-1);
    }
    for (int i=0; i<ndm; i++)
      theFile << "\t" << crds(i);
    theFile << endln;
  }
  
  
  // open file and spit out the initial data
  SP_ConstraintIter &theSPs = theDomain->getSPs();
  SP_Constraint *theSP;
  ID theConstrainedNodes(0,6);
  ID theSpMatrix(0, 6*ndf);
  int numNodesWithSP = 0;
  while ((theSP=theSPs()) != 0) {
    int nodeTag =  theSP->getNodeTag();
    int location = theConstrainedNodes.getLocation(nodeTag);
    if (location < 0) {
      theConstrainedNodes[numNodesWithSP] = nodeTag;
      for (int i=0; i<ndf; i++)
	theSpMatrix[numNodesWithSP*ndf+i] = 0;	  
      location = numNodesWithSP++;
    }
    int id = theSP->getDOF_Number();
    theSpMatrix[location*ndf + id] = 1;
  }
  
  for (int j=0; j<numNodesWithSP; j++) {
    theFile << "SPC\t" <<  theConstrainedNodes[j] << "\t0";
    for (int i=0; i<ndf; i++)
      theFile << "\t" << theSpMatrix[j*ndf+i];
    theFile << endln;
  }
  
  ElementIter &theElements = theDomain->getElements();
  Element *theElement;
  while ((theElement=theElements()) != 0) {
    theElement->Print(theFile, -1);
  }

}
Exemple #6
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;
}
Exemple #7
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;
}