static void drawElementLabels(drawContext *ctx, GEntity *e, std::vector<T*> &elements, int forceColor=0, unsigned int color=0) { unsigned col = forceColor ? color : getColorByEntity(e); glColor4ubv((GLubyte *) & col); int labelStep = CTX::instance()->mesh.labelSampling; if(labelStep <= 0) labelStep = 1; for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; if(!isElementVisible(ele)) continue; if(i % labelStep == 0) { SPoint3 pc = ele->barycenter(); char str[256]; if(CTX::instance()->mesh.labelType == 4) sprintf(str, "(%g,%g,%g)", pc.x(), pc.y(), pc.z()); else if(CTX::instance()->mesh.labelType == 3) sprintf(str, "%d", ele->getPartition()); else if(CTX::instance()->mesh.labelType == 2){ int np = e->physicals.size(); int p = np ? e->physicals[np - 1] : 0; sprintf(str, "%d", p); } else if(CTX::instance()->mesh.labelType == 1) sprintf(str, "%d", e->tag()); else sprintf(str, "%d", ele->getNum()); glRasterPos3d(pc.x(), pc.y(), pc.z()); ctx->drawString(str); } } }
PView *elasticitySolver::buildElasticEnergyView(const std::string postFileName) { std::cout << "build Elastic Energy View"<< std::endl; std::map<int, std::vector<double> > data; GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad); for (unsigned int i = 0; i < elasticFields.size(); ++i) { if(elasticFields[i]._E == 0.) continue; SolverField<SVector3> Field(pAssembler, LagSpace); IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu); BilinearTermToScalarTerm Elastic_Energy_Term(Eterm); ScalarTermConstant<double> One(1.0); for (groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double energ; double vol; IntPt *GP; int npts=Integ_Bulk.getIntPoints(e,&GP); Elastic_Energy_Term.get(e,npts,GP,energ); One.get(e,npts,GP,vol); std::vector<double> vec; vec.push_back(energ/vol); data[e->getNum()]=vec; } } PView *pv = new PView (postFileName, "ElementData", pModel, data, 0.0); return pv; }
PView *elasticitySolver::buildStrainView(const std::string postFileName) { std::cout << "build strain view" << std::endl; std::map<int, std::vector<double> > data; for(std::size_t i = 0; i < elasticFields.size(); ++i) { SolverField<SVector3> Field(pAssembler, LagSpace); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; int nbVertex = e->getNumVertices(); std::vector<SVector3> val(nbVertex); double valx[256]; double valy[256]; double valz[256]; for(int k = 0; k < nbVertex; k++) { MVertex *v = e->getVertex(k); MPoint p(v); Field.f(&p, 0, 0, 0, val[k]); valx[k] = val[k](0); valy[k] = val[k](1); valz[k] = val[k](2); } double gradux[3]; double graduy[3]; double graduz[3]; double u = 0.33, v = 0.33, w = 0.0; e->interpolateGrad(valx, u, v, w, gradux); e->interpolateGrad(valy, u, v, w, graduy); e->interpolateGrad(valz, u, v, w, graduz); std::vector<double> vec(9); vec[0] = gradux[0]; vec[4] = graduy[1]; vec[8] = graduy[2]; vec[1] = vec[3] = 0.5 * (gradux[0] + graduy[1]); vec[2] = vec[6] = 0.5 * (gradux[0] + graduz[2]); vec[5] = vec[7] = 0.5 * (gradux[1] + graduz[2]); data[e->getNum()] = vec; } } PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0); return pv; }
PView *elasticitySolver::buildErrorView(const std::string postFileName, simpleFunction<double> *f0, simpleFunction<double> *f1, simpleFunction<double> *f2) { std::cout << "build Error View" << std::endl; std::map<int, std::vector<double> > data; SolverField<SVector3> solField(pAssembler, LagSpace); for(std::size_t i = 0; i < elasticFields.size(); ++i) { for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; int npts; IntPt *GP; double jac[3][3]; int integrationOrder = 2 * (e->getPolynomialOrder() + 5); e->getIntegrationPoints(integrationOrder, &npts, &GP); double val = 0.0; for(int j = 0; j < npts; j++) { double u = GP[j].pt[0]; double v = GP[j].pt[1]; double w = GP[j].pt[2]; double weight = GP[j].weight; double detJ = fabs(e->getJacobian(u, v, w, jac)); SPoint3 p; e->pnt(u, v, w, p); SVector3 FEMVALUE; solField.f(e, u, v, w, FEMVALUE); SVector3 sol((*f0)(p.x(), p.y(), p.z()), (*f1)(p.x(), p.y(), p.z()), (*f2)(p.x(), p.y(), p.z())); double diff = normSq(sol - FEMVALUE); val += diff * detJ * weight; } std::vector<double> vec; vec.push_back(sqrt(val)); data[e->getNum()] = vec; } } PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0, 1); return pv; }
PView *elasticitySolver::buildVolumeView(const std::string postFileName) { std::cout << "build Volume View"; std::map<int, std::vector<double> > data; double voltot = 0; double length = 0; GaussQuadrature Integ_Vol(GaussQuadrature::Val); for(std::size_t i = 0; i < elasticFields.size(); ++i) { ScalarTermConstant<double> One(1.0); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double vol; IntPt *GP; int npts = Integ_Vol.getIntPoints(e, &GP); One.get(e, npts, GP, vol); voltot += vol; std::vector<double> vec; vec.push_back(vol); data[e->getNum()] = vec; } } for(std::size_t i = 0; i < LagrangeMultiplierFields.size(); ++i) { ScalarTermConstant<double> One(1.0); for(groupOfElements::elementContainer::const_iterator it = LagrangeMultiplierFields[i].g->begin(); it != LagrangeMultiplierFields[i].g->end(); ++it) { MElement *e = *it; double l; IntPt *GP; int npts = Integ_Vol.getIntPoints(e, &GP); One.get(e, npts, GP, l); length += l; } std::cout << " : length " << LagrangeMultiplierFields[i]._tag << " = " << length; length = 0; } PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0, 1); std::cout << " / total vol = " << voltot << std::endl; return pv; }
int GModel::writeKEY(const std::string &name, int saveAll, int saveGroupsOfNodes, double scalingFactor) { FILE *fp = Fopen(name.c_str(), "w"); if(!fp) { Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } if(noPhysicalGroups()) saveAll = 0x51; indexMeshVertices(saveAll & 0x51); std::vector<GEntity *> entities; getEntities(entities); fprintf(fp, "$# LS-DYNA Keyword file created by Gmsh\n*KEYWORD\n*TITLE\n"); fprintf(fp, " %s\n", name.c_str()); fprintf(fp, "*NODE\n"); for(std::size_t i = 0; i < entities.size(); i++) for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++) entities[i]->mesh_vertices[j]->writeKEY(fp, scalingFactor); if(!(saveAll & 0x2)) // save or ignore Vertex, not in GUI for(viter it = firstVertex(); it != lastVertex(); ++it) { writeElementsKEY(fp, *it, (*it)->points, saveAll & 0x1); } if(!(saveAll & 0x8)) // save or ignore line for(eiter it = firstEdge(); it != lastEdge(); ++it) { writeElementsKEY(fp, *it, (*it)->lines, saveAll & 0x4); } if(!(saveAll & 0x20)) // save or ignore surface for(fiter it = firstFace(); it != lastFace(); ++it) { writeElementsKEY(fp, *it, (*it)->triangles, saveAll & 0x10); writeElementsKEY(fp, *it, (*it)->quadrangles, saveAll & 0x10); } if(!(saveAll & 0x80)) // save or ignore surface for(riter it = firstRegion(); it != lastRegion(); ++it) { writeElementsKEY(fp, *it, (*it)->tetrahedra, saveAll & 0x40); writeElementsKEY(fp, *it, (*it)->hexahedra, saveAll & 0x40); writeElementsKEY(fp, *it, (*it)->prisms, saveAll & 0x40); writeElementsKEY(fp, *it, (*it)->pyramids, saveAll & 0x40); } std::map<int, std::vector<GEntity *> > groups[4]; getPhysicalGroups(groups); int setid = 0; // save elements sets for each physical group if(saveGroupsOfNodes & 0x2) { for(int dim = 0; dim <= 3; dim++) { if(saveAll & (0x2 << (2 * dim))) continue; // elements are ignored for(std::map<int, std::vector<GEntity *> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++) { std::vector<GEntity *> &entities = it->second; int n = 0; for(std::size_t i = 0; i < entities.size(); i++) { for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) { MElement *e = entities[i]->getMeshElement(j); if(!n) { const char *str = (e->getDim() == 3) ? "SOLID" : (e->getDim() == 2) ? "SHELL" : (e->getDim() == 1) ? "BEAM" : "NODE"; fprintf(fp, "*SET_%s_LIST\n$# %s\n%d", str, physicalName(this, dim, it->first).c_str(), ++setid); } if(!(n % 8)) fprintf(fp, "\n%lu", e->getNum()); else fprintf(fp, ", %lu", e->getNum()); n++; } } if(n) fprintf(fp, "\n"); } } } // save node sets for each physical group, for easier load/b.c. if(saveGroupsOfNodes & 0x1) { for(int dim = 1; dim <= 3; dim++) { for(std::map<int, std::vector<GEntity *> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++) { std::set<MVertex *> nodes; std::vector<GEntity *> &entities = it->second; for(std::size_t i = 0; i < entities.size(); i++) { for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) { MElement *e = entities[i]->getMeshElement(j); for(std::size_t k = 0; k < e->getNumVertices(); k++) nodes.insert(e->getVertex(k)); } } fprintf(fp, "*SET_NODE_LIST\n$# %s\n%d", physicalName(this, dim, it->first).c_str(), ++setid); int n = 0; for(std::set<MVertex *>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++) { if(!(n % 8)) fprintf(fp, "\n%ld", (*it2)->getIndex()); else fprintf(fp, ", %ld", (*it2)->getIndex()); n++; } if(n) fprintf(fp, "\n"); } } } fprintf(fp, "*END\n"); fclose(fp); return 1; }
PView *elasticitySolver::buildStressesView(const std::string postFileName) { double sti[6] = {0., 0., 0., 0., 0., 0.}; double str[6] = {0., 0., 0., 0., 0., 0.}; double volTot = 0.; std::cout << "build stresses view" << std::endl; std::map<int, std::vector<double> > data; for(std::size_t i = 0; i < elasticFields.size(); ++i) { double E = elasticFields[i]._e; double nu = elasticFields[i]._nu; SolverField<SVector3> Field(pAssembler, LagSpace); for(groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) { MElement *e = *it; double vol = e->getVolume() * e->getVolumeSign(); int nbVertex = e->getNumVertices(); std::vector<SVector3> val(nbVertex); double valx[256]; double valy[256]; double valz[256]; for(int k = 0; k < nbVertex; k++) { MVertex *v = e->getVertex(k); MPoint p(v); Field.f(&p, 0, 0, 0, val[k]); valx[k] = val[k](0); valy[k] = val[k](1); valz[k] = val[k](2); } double gradux[3]; double graduy[3]; double graduz[3]; SPoint3 center = e->barycenterUVW(); double u = center.x(), v = center.y(), w = center.z(); e->interpolateGrad(valx, u, v, w, gradux); e->interpolateGrad(valy, u, v, w, graduy); e->interpolateGrad(valz, u, v, w, graduz); double eps[6] = {gradux[0], graduy[1], graduz[2], 0.5 * (gradux[1] + graduy[0]), 0.5 * (gradux[2] + graduz[0]), 0.5 * (graduy[2] + graduz[1])}; double A = E / (1. + nu); double B = A * (nu / (1. - 2 * nu)); double trace = eps[0] + eps[1] + eps[2]; double sxx = A * eps[0] + B * trace; double syy = A * eps[1] + B * trace; double szz = A * eps[2] + B * trace; double sxy = A * eps[3]; double sxz = A * eps[4]; double syz = A * eps[5]; std::vector<double> vec(9); vec[0] = sxx; vec[1] = sxy; vec[2] = sxz; vec[3] = sxy; vec[4] = syy; vec[5] = syz; vec[6] = sxz; vec[7] = syz; vec[8] = szz; data[e->getNum()] = vec; for(int k = 0; k < 6; k++) str[k] += eps[k] * vol; sti[0] += sxx * vol; sti[1] += syy * vol; sti[2] += szz * vol; sti[3] += sxy * vol; sti[4] += sxz * vol; sti[5] += syz * vol; volTot += vol; } } for(int i = 0; i < 6; i++) { str[i] = str[i] / volTot; sti[i] = sti[i] / volTot; } printf("effective stiffn = "); for(int i = 0; i < 6; i++) printf("%g ", sti[i]); printf("\n"); printf("effective strain = "); for(int i = 0; i < 6; i++) printf("%g ", str[i]); printf("\n"); PView *pv = new PView(postFileName, "ElementData", pModel, data, 0.0); return pv; }
int GModel::writeINP(const std::string &name, bool saveAll, bool saveGroupsOfNodes, double scalingFactor) { FILE *fp = Fopen(name.c_str(), "w"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } if(noPhysicalGroups()) saveAll = true; indexMeshVertices(saveAll); std::vector<GEntity*> entities; getEntities(entities); fprintf(fp, "*Heading\n"); fprintf(fp, " %s\n", name.c_str()); fprintf(fp, "*Node\n"); for(unsigned int i = 0; i < entities.size(); i++) for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++) entities[i]->mesh_vertices[j]->writeINP(fp, scalingFactor); for(viter it = firstVertex(); it != lastVertex(); ++it){ writeElementsINP(fp, *it, (*it)->points, saveAll); } for(eiter it = firstEdge(); it != lastEdge(); ++it){ writeElementsINP(fp, *it, (*it)->lines, saveAll); } for(fiter it = firstFace(); it != lastFace(); ++it){ writeElementsINP(fp, *it, (*it)->triangles, saveAll); writeElementsINP(fp, *it, (*it)->quadrangles, saveAll); } for(riter it = firstRegion(); it != lastRegion(); ++it){ writeElementsINP(fp, *it, (*it)->tetrahedra, saveAll); writeElementsINP(fp, *it, (*it)->hexahedra, saveAll); writeElementsINP(fp, *it, (*it)->prisms, saveAll); writeElementsINP(fp, *it, (*it)->pyramids, saveAll); } std::map<int, std::vector<GEntity*> > groups[4]; getPhysicalGroups(groups); // save elements sets for each physical group for(int dim = 0; dim <= 3; dim++){ for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++){ std::vector<GEntity *> &entities = it->second; fprintf(fp, "*ELSET,ELSET=%s\n", physicalName(this, dim, it->first).c_str()); int n = 0; for(unsigned int i = 0; i < entities.size(); i++){ for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ MElement *e = entities[i]->getMeshElement(j); if(n && !(n % 10)) fprintf(fp, "\n"); fprintf(fp, "%d, ", e->getNum()); n++; } } fprintf(fp, "\n"); } } // save node sets for each physical group if(saveGroupsOfNodes){ for(int dim = 1; dim <= 3; dim++){ for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin(); it != groups[dim].end(); it++){ std::set<MVertex*> nodes; std::vector<GEntity *> &entities = it->second; for(unsigned int i = 0; i < entities.size(); i++){ for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){ MElement *e = entities[i]->getMeshElement(j); for (int k = 0; k < e->getNumVertices(); k++) nodes.insert(e->getVertex(k)); } } fprintf(fp, "*NSET,NSET=%s\n", physicalName(this, dim, it->first).c_str()); int n = 0; for(std::set<MVertex*>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++){ if(n && !(n % 10)) fprintf(fp, "\n"); fprintf(fp, "%d, ", (*it2)->getIndex()); n++; } fprintf(fp, "\n"); } } } fclose(fp); return 1; }