Path: blob/devel/ElmerGUI/netgen/libsrc/interface/writejcm.cpp
3206 views
//1// Write JCMwave file2// 07.07.2005, Sven Burger, ZIB Berlin3//456#include <mystdlib.h>7#include <myadt.hpp>8#include <linalg.hpp>9#include <csg.hpp>10#include <meshing.hpp>11#include <sys/stat.h>1213namespace netgen14{15#include "writeuser.hpp"1617void WriteJCMFormat (const Mesh & mesh,18const CSGeometry & geom,19const string & filename)20{21if (mesh.GetDimension() != 3)22{23cout <<"\n Error: Dimension 3 only supported by this output format!"<<endl;24return;25}2627int bc_at_infinity = 0;28int i, j, jj, ct(0), counter;29double dx1, dx2, dx3, dy1, dy2, dy3, dz1, dz2, dz3, vol;3031// number of points32int np = mesh.GetNP();3334// Identic points35ARRAY<int,1> identmap1, identmap2, identmap3;36mesh.GetIdentifications().GetMap(1, identmap1);37mesh.GetIdentifications().GetMap(2, identmap2);38mesh.GetIdentifications().GetMap(3, identmap3);3940// number of volume elements41int ne = mesh.GetNE();42int ntets = 0;43int nprisms = 0;44for (i = 1; i <= ne; i++)45{46Element el = mesh.VolumeElement(i);47if (el.GetNP() == 4)48{49ntets++;50// Check that no two points on a tetrahedron are identified with each other51for (j = 1; j <= 4; j++)52for (jj = 1; jj <=4; jj++)53{54if (identmap1.Elem(el.PNum(j)) == el.PNum(jj))55{56cout << "\n Error: two points on a tetrahedron identified (1) with each other"57<< "\n REFINE MESH !" << endl;58return;59}60if (identmap2.Elem(el.PNum(j)) == el.PNum(jj))61{62cout << "\n Error: two points on a tetrahedron identified (2) with each other"63<< "\n REFINE MESH !" << endl;64return;65}66if (identmap3.Elem(el.PNum(j)) == el.PNum(jj))67{68cout << "\n Error: two points on a tetrahedron identified (3) with each other"69<< "\n REFINE MESH !" << endl;70return;71}72}7374}75else if (el.GetNP() == 6)76nprisms++;77}78if ( ne != (ntets+nprisms))79{80cout<< "\n Error in determining number of volume elements!\n"81<< "\n Prisms and tetrahedra only implemented in the JCMwave format!\n"<<endl;82return;83}8485if (nprisms > 0)86cout << " Please note: Boundaries at infinity have to carry the bc-attribute '-bc="87<< bc_at_infinity <<"'."<<endl;8889// number of surface elements90int nse = mesh.GetNSE();91// number of boundary triangles92int nbtri = 0;93// number of boundary quadrilaterals94int nbquad = 0;95// array with 1 if point on any tetra, 0 else96// this is needed in order to arrange the prism points in the right order97ARRAY<int,1> pointsOnTetras;98pointsOnTetras.SetSize (mesh.GetNP());99pointsOnTetras = 0;100for (i = 1; i <= ne; i++)101{102Element el = mesh.VolumeElement(i);103if (el.GetNP() == 4)104{105for (j = 1; j <= 4; j++)106pointsOnTetras.Set(el.PNum(j).GetInt(),1);107}108}109110// number of boundary triangles and boundary quadrilaterals111for (i = 1; i <= nse; i++)112{113Element2d el = mesh.SurfaceElement(i);114if (el.GetNP() == 3 &&115( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 ||116mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) )117nbtri++;118else if (el.GetNP() == 4 &&119( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 ||120mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) )121nbquad++;122}123124ofstream outfile (filename.c_str());125outfile.precision(6);126outfile.setf (ios::fixed, ios::floatfield);127outfile.setf (ios::showpoint);128129outfile << "/* <BLOBHead>\n";130outfile << "__BLOBTYPE__=Grid\n";131outfile << "__OWNER__=JCMwave\n";132outfile << "<I>SpaceDim=3\n";133outfile << "<I>ManifoldDim=3\n";134outfile << "<I>NRefinementSteps=0\n";135outfile << "<I>NPoints="<<np<<"\n";136outfile << "<I>NTetrahedra="<<ntets<<"\n";137outfile << "<I>NPrisms="<<nprisms<<"\n";138outfile << "<I>NBoundaryTriangles="<<nbtri<<"\n";139outfile << "<I>NBoundaryQuadrilaterals="<<nbquad<<"\n";140outfile << "*/\n";141outfile << "\n";142outfile << "# output from Netgen\n\n";143int nDomains=mesh.GetNDomains();144for (i=1; i<=nDomains; i++)145{146if (mesh.GetMaterial(i))147outfile << "#" << mesh.GetMaterial(i)148<< ": Material ID = "149<< i << "\n";150}151152outfile << "# Points\n";153cout << " Please note: The unit of length in the .geo file is assumed to be 'microns'."<<endl;154for (i = 1; i <= np; i++)155{156const Point<3> & p = mesh.Point(i);157outfile << i << "\n";158outfile << p(0) << "e-6\n";159outfile << p(1) << "e-6\n";160outfile << p(2) << "e-6\n\n";161}162163outfile << "\n";164outfile << "# Tetrahedra\n";165counter = 0;166for (i = 1; i <= ne; i++)167{168Element el = mesh.VolumeElement(i);169if (el.GetNP() == 4)170{171counter++;172dx1 = mesh.Point(el.PNum(2))(0) - mesh.Point(el.PNum(1))(0);173dx2 = mesh.Point(el.PNum(3))(0) - mesh.Point(el.PNum(1))(0);174dx3 = mesh.Point(el.PNum(4))(0) - mesh.Point(el.PNum(1))(0);175dy1 = mesh.Point(el.PNum(2))(1) - mesh.Point(el.PNum(1))(1);176dy2 = mesh.Point(el.PNum(3))(1) - mesh.Point(el.PNum(1))(1);177dy3 = mesh.Point(el.PNum(4))(1) - mesh.Point(el.PNum(1))(1);178dz1 = mesh.Point(el.PNum(2))(2) - mesh.Point(el.PNum(1))(2);179dz2 = mesh.Point(el.PNum(3))(2) - mesh.Point(el.PNum(1))(2);180dz3 = mesh.Point(el.PNum(4))(2) - mesh.Point(el.PNum(1))(2);181vol = (dy1*dz2-dz1*dy2)*dx3 + (dz1*dx2-dx1*dz2)*dy3 + (dx1*dy2-dy1*dx2)*dz3;182183if ( vol > 0 )184for (j = 1; j <= 4; j++)185outfile << el.PNum(j)<<"\n";186else187{188for (j = 2; j >= 1; j--)189outfile << el.PNum(j)<<"\n";190for (j = 3; j <= 4; j++)191outfile << el.PNum(j)<<"\n";192}193outfile << el.GetIndex() << "\n\n";194}195}196if ( counter != ntets)197{198cout<< "\n Error in determining number of tetras!\n"<<endl;199return;200}201202outfile << "\n";203outfile << "# Prisms\n";204counter = 0;205for (i = 1; i <= ne; i++)206{207Element el = mesh.VolumeElement(i);208if (el.GetNP() == 6)209{210counter++;211dx1 = mesh.Point(el.PNum(2))(0) - mesh.Point(el.PNum(1))(0);212dx2 = mesh.Point(el.PNum(3))(0) - mesh.Point(el.PNum(1))(0);213dx3 = mesh.Point(el.PNum(4))(0) - mesh.Point(el.PNum(1))(0);214dy1 = mesh.Point(el.PNum(2))(1) - mesh.Point(el.PNum(1))(1);215dy2 = mesh.Point(el.PNum(3))(1) - mesh.Point(el.PNum(1))(1);216dy3 = mesh.Point(el.PNum(4))(1) - mesh.Point(el.PNum(1))(1);217dz1 = mesh.Point(el.PNum(2))(2) - mesh.Point(el.PNum(1))(2);218dz2 = mesh.Point(el.PNum(3))(2) - mesh.Point(el.PNum(1))(2);219dz3 = mesh.Point(el.PNum(4))(2) - mesh.Point(el.PNum(1))(2);220vol = (dy1*dz2-dz1*dy2)*dx3 + (dz1*dx2-dx1*dz2)*dy3 + (dx1*dy2-dy1*dx2)*dz3;221222if (pointsOnTetras.Get(el.PNum(1)) &&223pointsOnTetras.Get(el.PNum(2)) &&224pointsOnTetras.Get(el.PNum(3)))225{226if (vol > 0)227for (j = 1; j <= 6; j++)228outfile << el.PNum(j)<<"\n";229else230{231for (j = 3; j >= 1; j--)232outfile << el.PNum(j)<<"\n";233for (j = 6; j >= 4; j--)234outfile << el.PNum(j)<<"\n";235}236}237else if ( pointsOnTetras.Get(el.PNum(4)) &&238pointsOnTetras.Get(el.PNum(5)) &&239pointsOnTetras.Get(el.PNum(6)) )240{241if ( vol < 0 )242{243for (j = 4; j <= 6; j++)244outfile << el.PNum(j)<<"\n";245for (j = 1; j <= 3; j++)246outfile << el.PNum(j)<<"\n";247}248else249{250for (j = 6; j >= 4; j--)251outfile << el.PNum(j)<<"\n";252for (j = 3; j >= 1; j--)253outfile << el.PNum(j)<<"\n";254}255}256else257{258cout << "\n Error in determining prism point numbering!\n"<<endl;259return;260}261outfile << el.GetIndex() << "\n\n";262}263}264if ( counter != nprisms)265{266cout<< "\n Error in determining number of prisms!\n"<<endl;267return;268}269270int npid1 = 0;271int npid2 = 0;272int npid3 = 0;273for (i=1; i<=np; i++)274{275if (identmap1.Elem(i))276npid1++;277if (identmap2.Elem(i))278npid2++;279if (identmap3.Elem(i))280npid3++;281}282283outfile << "\n";284outfile << "# Boundary triangles\n";285outfile << "# Number of identified points in 1-direction: " << npid1 << "\n";286outfile << "# Number of identified points in 2-direction: " << npid2 << "\n";287outfile << "# Number of identified points in 3-direction: " << npid3 << "\n";288for (i = 1; i <= nse; i++)289{290Element2d el = mesh.SurfaceElement(i);291if (el.GetNP() == 3292&& (mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0293|| mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0))294{295outfile <<"# T\n";296for (j = 1; j <= 3; j++)297outfile << el.PNum(j)<<"\n";298if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty()==bc_at_infinity)299outfile << 1000 << "\n";300else301outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << "\n";302if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() == bc_at_infinity)303outfile << "-2\n\n";304else if (identmap1.Elem(el.PNum(1))305&&identmap1.Elem(el.PNum(2))306&&identmap1.Elem(el.PNum(3)))307{308outfile << "-1\n";309for (j = 1; j <= 3; j++)310outfile << identmap1.Elem(el.PNum(j))<<"\n";311outfile << "\n";312}313else if (identmap2.Elem(el.PNum(1))314&&identmap2.Elem(el.PNum(2))315&&identmap2.Elem(el.PNum(3)))316{317outfile << "-1\n";318for (j = 1; j <= 3; j++)319outfile << identmap2.Elem(el.PNum(j))<<"\n";320outfile << "\n";321}322else if (identmap3.Elem(el.PNum(1))323&&identmap3.Elem(el.PNum(2))324&&identmap3.Elem(el.PNum(3)))325{326outfile << "-1\n";327for (j = 1; j <= 3; j++)328outfile << identmap3.Elem(el.PNum(j))<<"\n";329outfile << "\n";330}331else332outfile << "1\n\n";333334}335}336337outfile << "\n";338outfile << "# Boundary quadrilaterals\n";339for (i = 1; i <= nse; i++)340{341Element2d el = mesh.SurfaceElement(i);342343if (el.GetNP() == 4344&& (mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0345|| mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0))346{347if (pointsOnTetras.Get(el.PNum(1)) &&348pointsOnTetras.Get(el.PNum(2)))349ct = 0;350else if (pointsOnTetras.Get(el.PNum(2)) &&351pointsOnTetras.Get(el.PNum(3)))352ct = 1;353else if (pointsOnTetras.Get(el.PNum(3)) &&354pointsOnTetras.Get(el.PNum(4)))355ct = 2;356else if (pointsOnTetras.Get(el.PNum(4)) &&357pointsOnTetras.Get(el.PNum(1)))358ct = 3;359else360cout << "\nWarning: Quadrilateral with inconsistent points found!"<<endl;361362for (j = 1; j <= 4; j++)363{364jj = j + ct;365if ( jj >= 5 )366jj = jj - 4;367outfile << el.PNum(jj)<<"\n";368}369outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << "\n";370if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() == bc_at_infinity)371{372outfile << "-2\n\n";373cout << "\nWarning: Quadrilateral at infinity found (this should not occur)!"<<endl;374}375else if ( identmap1.Elem(el.PNum(1)) &&376identmap1.Elem(el.PNum(2)) &&377identmap1.Elem(el.PNum(3)) &&378identmap1.Elem(el.PNum(4)) )379{380outfile << "-1\n";381for (j = 1; j <= 4; j++)382{383jj = j + ct;384if ( jj >= 5 )385jj = jj - 4;386outfile << identmap1.Elem(el.PNum(jj))<<"\n";387}388outfile << "\n";389}390else if ( identmap2.Elem(el.PNum(1)) &&391identmap2.Elem(el.PNum(2)) &&392identmap2.Elem(el.PNum(3)) &&393identmap2.Elem(el.PNum(4)) )394{395outfile << "-1\n";396for (j = 1; j <= 4; j++)397{398jj = j + ct;399if ( jj >= 5 )400jj = jj - 4;401outfile << identmap2.Elem(el.PNum(jj))<<"\n";402}403outfile << "\n";404}405else if ( identmap3.Elem(el.PNum(1)) &&406identmap3.Elem(el.PNum(2)) &&407identmap3.Elem(el.PNum(3)) &&408identmap3.Elem(el.PNum(4)) )409{410outfile << "-1\n";411for (j = 1; j <= 4; j++)412{413jj = j + ct;414if ( jj >= 5 )415jj = jj - 4;416outfile << identmap3.Elem(el.PNum(jj))<<"\n";417}418outfile << "\n";419}420else421outfile << "1\n\n";422}423}424425cout << " JCMwave grid file written." << endl;426}427428}429430431432