void Mesh::writeMSH(const char *filename) { FILE *f = fopen(filename, "w"); fprintf(f, "$MeshFormat\n"); fprintf(f, "2.2 0 8\n"); fprintf(f, "$EndMeshFormat\n"); fprintf(f, "$Nodes\n"); fprintf(f, "%d\n", nVert()); for (int i = 0; i < nVert(); i++) fprintf(f, "%d %22.15E %22.15E %22.15E\n", i + 1, _xyz[i].x(), _xyz[i].y(), _xyz[i].z()); fprintf(f, "$EndNodes\n"); fprintf(f, "$Elements\n"); fprintf(f, "%d\n", nEl()); for (int iEl = 0; iEl < nEl(); iEl++) { fprintf(f, "%d %d 2 0 0", _el[iEl]->getNum(), _el[iEl]->getTypeForMSH()); for (size_t iVEl = 0; iVEl < _el2V[iEl].size(); iVEl++) fprintf(f, " %d", _el2V[iEl][iVEl] + 1); fprintf(f, "\n"); } fprintf(f, "$EndElements\n"); fclose(f); }
void Mesh::updateGEntityPositions() { for (int iV = 0; iV < nVert(); iV++) _vert[iV]->setXYZ(_xyz[iV].x(),_xyz[iV].y(),_xyz[iV].z()); for (int iFV = 0; iFV < nFV(); iFV++) _paramFV[iFV]->exportParamCoord(_uvw[iFV]); }
void Mesh::updateGEntityPositions(const std::vector<SPoint3> &xyz, const std::vector<SPoint3> &uvw) { for (int iV = 0; iV < nVert(); iV++) _vert[iV]->setXYZ(xyz[iV].x(),xyz[iV].y(),xyz[iV].z()); for (int iFV = 0; iFV < nFV(); iFV++) _paramFV[iFV]->exportParamCoord(uvw[iFV]); }
void Mesh::getGEntityPositions(std::vector<SPoint3> &xyz, std::vector<SPoint3> &uvw) { xyz.resize(nVert()); uvw.resize(nFV()); for (int iV = 0; iV < nVert(); iV++) xyz[iV] = SPoint3(_vert[iV]->x(),_vert[iV]->y(),_vert[iV]->z()); for (int iFV = 0; iFV < nFV(); iFV++){ MVertex *v = _freeVert[iFV]; if (v->onWhat()->dim() == 1){ double t; v->getParameter(0,t); uvw[iFV] = SPoint3(t,0,0); } if (v->onWhat()->dim() == 2){ double uu,vv; v->getParameter(0,uu); v->getParameter(1,vv); uvw[iFV] = SPoint3(uu,vv,0); } } }
Mesh::Mesh(const std::map<MElement*,GEntity*> &element2entity, const std::set<MElement*> &els, std::set<MVertex*> &toFix, bool fixBndNodes, bool fastJacEval) : _fastJacEval(fastJacEval) { _dim = (*els.begin())->getDim(); // Initialize elements, vertices, free vertices and element->vertices // connectivity const int nElements = els.size(); _nPC = 0; _el.resize(nElements); _el2FV.resize(nElements); _el2V.resize(nElements); _nBezEl.resize(nElements); _nNodEl.resize(nElements); _indPCEl.resize(nElements); int iEl = 0; bool nonGeoMove = false; for(std::set<MElement*>::const_iterator it = els.begin(); it != els.end(); ++it, ++iEl) { _el[iEl] = *it; const JacobianBasis *jac = _el[iEl]->getJacobianFuncSpace(); _nBezEl[iEl] = _fastJacEval ? jac->getNumJacNodesFast() : jac->getNumJacNodes(); _nNodEl[iEl] = jac->getNumMapNodes(); for (int iVEl = 0; iVEl < jac->getNumMapNodes(); iVEl++) { MVertex *vert = _el[iEl]->getVertex(iVEl); GEntity *ge = vert->onWhat(); const int vDim = ge->dim(); const bool hasParam = ge->haveParametrization(); int iV = addVert(vert); _el2V[iEl].push_back(iV); if ((vDim > 0) && (toFix.find(vert) == toFix.end()) && (!fixBndNodes || vDim == _dim)) { // Free vertex? ParamCoord *param; if (vDim == 3) param = new ParamCoordPhys3D(); else if (hasParam) param = new ParamCoordParent(vert); else { if (vDim == 2) param = new ParamCoordLocalSurf(vert); else param = new ParamCoordLocalLine(vert); nonGeoMove = true; } int iFV = addFreeVert(vert,iV,vDim,param,toFix); _el2FV[iEl].push_back(iFV); for (int i=_startPCFV[iFV]; i<_startPCFV[iFV]+vDim; i++) _indPCEl[iEl].push_back(i); } else _el2FV[iEl].push_back(-1); } } if (nonGeoMove) Msg::Info("WARNING: Some vertices will be moved along local lines " "or planes, they may not remain on the exact geometry"); // Initial coordinates _ixyz.resize(nVert()); for (int iV = 0; iV < nVert(); iV++) _ixyz[iV] = _vert[iV]->point(); _iuvw.resize(nFV()); for (int iFV = 0; iFV < nFV(); iFV++) _iuvw[iFV] = _paramFV[iFV]->getUvw(_freeVert[iFV]); // Set current coordinates _xyz = _ixyz; _uvw = _iuvw; // Set normals to 2D elements (with magnitude of inverse Jacobian) or initial // Jacobians of 3D elements if (_dim == 2) { _scaledNormEl.resize(nEl()); for (int iEl = 0; iEl < nEl(); iEl++) calcScaledNormalEl2D(element2entity,iEl); } else { _invStraightJac.resize(nEl(),1.); double dumJac[3][3]; for (int iEl = 0; iEl < nEl(); iEl++) _invStraightJac[iEl] = 1. / fabs(_el[iEl]->getPrimaryJacobian(0.,0.,0.,dumJac)); } }
void Mesh::approximationErrorAndGradients(int iEl, double &f, std::vector<double> &gradF, double eps, simpleFunction<double> &fct) { std::vector<SPoint3> _xyz_temp; for (int iV = 0; iV < nVert(); iV++){ _xyz_temp.push_back(SPoint3( _vert[iV]->x(), _vert[iV]->y(), _vert[iV]->z())); _vert[iV]->setXYZ(_xyz[iV].x(),_xyz[iV].y(),_xyz[iV].z()); } MElement *element = _el[iEl]; f = approximationError (fct, element); // FIME // if (iEl < 1)printf("approx error elem %d = %g\n",iEl,f); int currentId = 0; // compute the size of the gradient // depends on how many dofs exist per vertex (0,1,2 or 3) for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) {// some free coordinates currentId += _nPCFV[_el2FV[iEl][i]]; } } gradF.clear(); gradF.resize(currentId, 0.); currentId = 0; for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) {// some free coordinates MVertex *v = element->getVertex(i); // vertex classified on a model edge if (_nPCFV[_el2FV[iEl][i]] == 1){ double t = _uvw[_el2FV[iEl][i]].x(); GEdge *ge = (GEdge*)v->onWhat(); SPoint3 p (v->x(),v->y(),v->z()); GPoint d = ge->point(t+eps); v->setXYZ(d.x(),d.y(),d.z()); double f_d = approximationError (fct, element); gradF[currentId++] = (f_d-f)/eps; if (iEl < 1)printf("df = %g\n",(f_d-f)/eps); v->setXYZ(p.x(),p.y(),p.z()); } else if (_nPCFV[_el2FV[iEl][i]] == 2){ double uu = _uvw[_el2FV[iEl][i]].x(); double vv = _uvw[_el2FV[iEl][i]].y(); GFace *gf = (GFace*)v->onWhat(); SPoint3 p (v->x(),v->y(),v->z()); GPoint d = gf->point(uu+eps,vv); v->setXYZ(d.x(),d.y(),d.z()); double f_u = approximationError (fct, element); gradF[currentId++] = (f_u-f)/eps; d = gf->point(uu,vv+eps); v->setXYZ(d.x(),d.y(),d.z()); double f_v = approximationError (fct, element); gradF[currentId++] = (f_v-f)/eps; v->setXYZ(p.x(),p.y(),p.z()); // if (iEl < 1)printf("df = %g %g\n",(f_u-f)/eps,(f_v-f)/eps); } } } for (int iV = 0; iV < nVert(); iV++) _vert[iV]->setXYZ(_xyz_temp[iV].x(),_xyz_temp[iV].y(),_xyz_temp[iV].z()); }