📄 mortar.cpp
字号:
// ORIG-DATE: Dec 2002 // -*- Mode : c++ -*-//// SUMMARY : Mortar model ( not used)// USAGE : LGPL // ORG : LJLL Universite Pierre et Marie Curi, Paris, FRANCE // AUTHOR : Frederic Hecht// E-MAIL : frederic.hecht@ann.jussieu.fr///* This file is part of Freefem++ Freefem++ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Freefem++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Freefem++; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Thank to the ARN () FF2A3 grant ref:ANR-07-CIS7-002-01 */#include <cmath>#include <cstdlib>#include <cassert>#include <iostream>#include <fstream>//#include <strstream.h>//using namespace std; //introduces namespace std#include "RNM.hpp"#include "rgraph.hpp"#include "fem.hpp"#include "FQuadTree.hpp"inline int NbOfSubTriangle(int k){ assert(k>0); return k*k;}inline int NbOfSubInternalVertices(int k){ assert(k>0); int r= (k+2)*(k+1)/2; assert(r>=0); return r;}// for the mortar elements Mesh::Mesh(const Mesh & Th,int * split,bool WithMortar) { // routine complique // count the number of elements area=Th.area; BoundaryAdjacencesHead=0; BoundaryAdjacencesLink=0; BoundaryEdgeHeadLink=0; quadtree =0; NbMortars=0; mortars=0; TheAdjacencesLink =0; quadtree =0; bedges=0; neb =0; R2 Pmin,Pmax; Th.BoundingBox(Pmin,Pmax); nt=0; for (int i=0;i<Th.nt;i++) nt += NbOfSubTriangle(split[i]); triangles = new Triangle[nt]; assert(triangles); // computation of thee numbers of vertices // on decoupe tous betement // et on recolle le points ensuite // avec le quadtree qui sont sur les aretes ou les sommets // calcul du magorant du nombre de sommets int nvmax=Th.nv;// attention il faut supprime les aretes frontiere interne for (int ieb=0,jj;ieb<Th.neb;ieb++) neb += split[Th.BoundaryElement(ieb,jj)]; int nebmax=neb; for (int i=0;i<Th.nt;i++) nvmax += NbOfSubInternalVertices(split[i]) -3; // compute the minimal Hsize of the new mesh R hm = Th[0].h();// cout << " hm " << hm << endl; for (int it=0;it<Th.nt;it++) { assert(split[it]>0 && split[it]<=64);// cout << " it = " <<it << " h " << Th[it].h() << " " << split[it] << " hm = " << hm << endl; hm=Min(hm,Th[it].h()/(R) split[it]); } R seuil=hm/4.0; cout << " seuil = " << seuil << " hmin = " << hm << endl; assert(seuil>1e-15); vertices = new Vertex[nvmax]; assert( vertices && Th.nv <= nvmax); // copy of the old vertices for (int i=0;i<Th.nv;i++) vertices[i] = Th(i); nv = Th.nv; quadtree = new FQuadTree(this,Pmin,Pmax,nv); // put all the old vertices in the quadtree bedges = new BoundaryEdge[nebmax]; assert(bedges);// generation of the boundary edges neb =0; for (int ieb=0,jj;ieb<Th.neb;ieb++) { int kold = Th.BoundaryElement(ieb,jj); int n=split[kold]; int n1=n+1; BoundaryEdge & be(Th.bedges[ieb]); Vertex *pva= vertices + (&be[0]-Th.vertices); Vertex *pvb= vertices + (&be[1]-Th.vertices); Vertex *pv0=pva; R2 A(*pva),B(*pvb); R la = 1,lb=0, delta=1.0/n; for (int j=1;j<n;j++) { la-=delta; lb+=delta; assert(nv<nvmax); Vertex *pv1= vertices + nv; (R2 &) *pv1 = A*la + B*lb; (Reference &) *pv1 = (Reference) be; quadtree->Add(*pv1); nv++; assert(neb<nebmax); bedges[neb].vertices[0]=pv0; bedges[neb].vertices[1]=pv1; (Reference &) bedges[neb]= be; neb++; pv0=pv1; } assert(neb<nebmax); bedges[neb].vertices[0]=pv0; bedges[neb].vertices[1]=pvb; (Reference &) bedges[neb]= be; neb++; } assert(neb==nebmax); // create the new vertices and the new triangle int kerr=0,kt=0; for (int K=0;K<Th.nt;K++) { // cout << K << endl; Triangle &T(Th[K]); R2 A(T[0]); R2 B(T[1]); R2 C(T[2]); long N=split[K]; long N2=N*N; int vt[3]; for (int n=0;n<N2;n++,kt++) // loop on all sub triangle { //(Reference&) triangles[kt] = (Reference&) T; for(int j=0;j<3;j++) // Loop on the 3 vertices { R2 PTj=SubTriangle(N,n,j); R la=1-PTj.x-PTj.y,lb=PTj.x,lc=PTj.y; R2 Pj= A*la+B*lb+C*lc; Vertex *pV; pV=quadtree->ToClose(Pj,seuil); if(!pV) { // new vertex // cout << " -- " << nv << " New Vertices " << Pj << " n=" << n << " j=" << j << " " << PTj << endl; assert(nv<nvmax); vertices[nv]=Pj; (Reference&) vertices[nv]=0; // Internal vertices pV = vertices + nv; quadtree->Add(*pV); nv++; } // end of new vertex vt[j]=number(pV); // triangles[kt].SetVertex(j,pV); } // for(int j=0;j<3;j++) // cout << kt << " " << n << endl; R2 A=vertices[vt[0]]; R2 B=vertices[vt[1]]; R2 C=vertices[vt[2]]; R a = (( B-A)^(C-A))*0.5; if (a>0) triangles[kt] = Triangle(vertices,vt[0],vt[1],vt[2],T.ref); else triangles[kt] = Triangle(vertices,vt[0],vt[2],vt[1],T.ref); } // end loop on all sub triangle } // end cout << " -- Nb of vertices " << nv << endl; cout << " -- Nb of triangle " << nt << endl; cout << " -- Nb of boundary edges " << neb << endl; // if (!WithMortar) { // long nba = neb; // long nbsd = 1; // bofbof // faux just pour un test long *sd; nbsd=1; sd=new long[2*nbsd]; sd[0]=-1; sd[1]=Th[0].ref; long nbs=nv; long nbsmax=nv; long err = 0, nbsold = nbs; long *c = 0; long *tri = 0; long *nu = 0; long *reft = 0; float *cr = 0; float *h = 0; long nbtmax = 2 * nbsmax; long * arete = new long[2*nba]; nu = new long[6*nbtmax]; c = new long[2*nbsmax]; tri = new long[(4 * nbsmax + 2 * nbsd)]; reft = new long[nbtmax]; cr = new float[(2 * nbsmax + 2)]; h = new float[nbsmax]; for(int i=0,k=0; i<nv; i++) { cr[k++] =vertices[i].x; cr[k++]=vertices[i].y; h[i]=1; } for (int i=0,k=0 ;i<neb;i++) { arete[k++] =number(bedges[i][0])+1; arete[k++] =number(bedges[i][1])+1; } extern int mshptg_ (float *cr, float *h, long *c, long *nu, long *nbs, long nbsmx, long *tri, long *arete, long nba, long *sd, long nbsd, long *reft, long *nbt, float coef, float puis, long *err); long nbt=0; mshptg_ (cr, h, c, nu, &nbs, nbs, tri, arete, nba, (long *) sd, nbsd, reft, &nbt, .25, .75, &err); assert(err==0 && nbt !=0); delete [] triangles; nt = nbt; cout << " Nb Triangles = " << nbt << endl; triangles = new Triangle[nt]; for(int i=0,k=0;i<nt;i++,k+=3) triangles[i]=Triangle(vertices,nu[k]-1,nu[k+1]-1,nu[k+2]-1,reft[i]); delete [] arete; delete [] nu; delete [] c; delete [] tri; delete [] reft; delete [] cr; delete [] h; delete [] sd; } ConsAdjacence();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -