Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/hprefinement.cpp
3206 views
#include <mystdlib.h>1#include "meshing.hpp"2#include "hprefinement.hpp"34namespace netgen5{67#include "hpref_segm.hpp"8#include "hpref_trig.hpp"9#include "hpref_quad.hpp"10#include "hpref_tet.hpp"11#include "hpref_prism.hpp"12#include "hpref_hex.hpp"13#include "hpref_pyramid.hpp"14#include "classifyhpel.hpp"151617void HPRefElement :: Reset(void)18{19np = 8;20for (int i = 0; i < 8; i++)21{22pnums[i] = -1;23param[i][0] = param[i][1] = param[i][2] = 0;24domin=-1; domout=-1; // he:25}26}2728HPRefElement :: HPRefElement ()29{30Reset();31}3233HPRefElement :: HPRefElement(Element & el)34{35//Reset();36np = el.GetNV();37for (int i=0; i<np ; i++)38pnums[i] = el[i];3940index = el.GetIndex();41const Point3d * points =42MeshTopology :: GetVertices (el.GetType());43for(int i=0;i<np;i++)44for(int l=0;l<3;l++)45param[i][l] = points[i].X(l+1);46type = HP_NONE;47domin=-1; domout=-1; // he: needed for segments48}495051HPRefElement :: HPRefElement(Element2d & el)52{53//Reset();54np = el.GetNV();5556for (int i=0; i<np ; i++)57pnums[i] = el[i];5859index = el.GetIndex();60const Point3d * points =61MeshTopology :: GetVertices (el.GetType());62for(int i=0;i<np;i++)63for(int l=0;l<3;l++)64param[i][l] = points[i].X(l+1);65type = HP_NONE;66domin=-1; domout=-1; // he: needed for segments67}6869HPRefElement :: HPRefElement(Segment & el)70{71//Reset();72np = 2;73for (int i=0; i<np ; i++)74pnums[i] = el[i];75const Point3d * points =76MeshTopology :: GetVertices (SEGMENT);77for(int i=0;i<np;i++)78for(int l=0;l<3;l++)79param[i][l] = points[i].X(l+1);8081/*82for (int i=0; i<np; i++)83{84param[i][0] = i;85param[i][1] = -1; param[i][2] = -1;86}87*/8889singedge_left = el.singedge_left;90singedge_right = el.singedge_right;91type = HP_NONE;92// he: needed for orientation!93domin = el.domin;94domout = el.domout;95}9697HPRefElement :: HPRefElement(HPRefElement & el)98{99//Reset();100np = el.np;101for (int i=0; i<np ; i++)102{103pnums[i] = el[i];104for(int l=0; l<3; l++) param[i][l] = el.param[i][l];105}106index = el.index;107levelx = el.levelx;108levely = el.levely;109levelz = el.levelz;110type = el.type;111coarse_elnr = el.coarse_elnr;112singedge_left = el.singedge_left;113singedge_right = el.singedge_right;114domin = el.domin; // he: needed for segments115domout=el.domout;116117}118119void HPRefElement :: SetType( HPREF_ELEMENT_TYPE t)120{121type = t;122switch(type)123{124case HP_SEGM: np=2; break;125case HP_TRIG: np=3; break;126case HP_QUAD: np=4; break;127case HP_TET: np=4; break;128case HP_PRISM: np=6; break;129case HP_PYRAMID: np=5; break;130case HP_HEX: np=8; break;131}132for(int k=0;k<8;k++)133{134pnums[k]=0;135for(int l=0;l<3;l++) param[k][l]=0.;136}137}138139140HPRef_Struct * Get_HPRef_Struct (HPREF_ELEMENT_TYPE type)141{142HPRef_Struct * hps = NULL;143144switch (type)145{146case HP_SEGM:147hps = &refsegm; break;148case HP_SEGM_SINGCORNERL:149hps = &refsegm_scl; break;150case HP_SEGM_SINGCORNERR:151hps = &refsegm_scr; break;152case HP_SEGM_SINGCORNERS:153hps = &refsegm_sc2; break;154155case HP_TRIG:156hps = &reftrig; break;157case HP_TRIG_SINGCORNER:158hps = &reftrig_singcorner; break;159case HP_TRIG_SINGCORNER12:160hps = &reftrig_singcorner12; break;161case HP_TRIG_SINGCORNER123:162hps = &reftrig_singcorner123; break;163case HP_TRIG_SINGCORNER123_2D:164hps = &reftrig_singcorner123_2D; break;165case HP_TRIG_SINGEDGE:166hps = &reftrig_singedge; break;167case HP_TRIG_SINGEDGECORNER1:168hps = &reftrig_singedgecorner1; break;169case HP_TRIG_SINGEDGECORNER2:170hps = &reftrig_singedgecorner2; break;171case HP_TRIG_SINGEDGECORNER12:172hps = &reftrig_singedgecorner12; break;173case HP_TRIG_SINGEDGECORNER3:174hps = &reftrig_singedgecorner3; break;175case HP_TRIG_SINGEDGECORNER13:176hps = &reftrig_singedgecorner13; break;177case HP_TRIG_SINGEDGECORNER23:178hps = &reftrig_singedgecorner23; break;179case HP_TRIG_SINGEDGECORNER123:180hps = &reftrig_singedgecorner123; break;181case HP_TRIG_SINGEDGES:182hps = &reftrig_singedges; break;183case HP_TRIG_SINGEDGES2:184hps = &reftrig_singedges2; break;185case HP_TRIG_SINGEDGES3:186hps = &reftrig_singedges3; break;187case HP_TRIG_SINGEDGES23:188hps = &reftrig_singedges23; break;189case HP_TRIG_3SINGEDGES:190hps = &reftrig_3singedges; break;191192193case HP_QUAD:194hps = &refquad; break;195case HP_DUMMY_QUAD_SINGCORNER:196hps = &refdummyquad_singcorner; break;197case HP_QUAD_SINGCORNER:198hps = &refquad_singcorner; break;199case HP_QUAD_SINGEDGE:200hps = &refquad_singedge; break;201202case HP_QUAD_0E_2VA:203hps = &refquad_0e_2va; break;204case HP_QUAD_0E_2VB:205hps = &refquad_0e_2vb; break;206207case HP_QUAD_0E_3V:208hps = &refquad_0e_3v; break;209case HP_QUAD_0E_4V:210hps = &refquad_0e_4v; break;211212case HP_QUAD_1E_1VA:213hps = &refquad_1e_1va; break;214case HP_QUAD_1E_1VB:215hps = &refquad_1e_1vb; break;216case HP_QUAD_1E_1VC:217hps = &refquad_1e_1vc; break;218case HP_QUAD_1E_1VD:219hps = &refquad_1e_1vd; break;220221case HP_QUAD_1E_2VA:222hps = &refquad_1e_2va; break;223case HP_QUAD_1E_2VB:224hps = &refquad_1e_2vb; break;225case HP_QUAD_1E_2VC:226hps = &refquad_1e_2vc; break;227case HP_QUAD_1E_2VD:228hps = &refquad_1e_2vd; break;229case HP_QUAD_1E_2VE:230hps = &refquad_1e_2ve; break;231case HP_QUAD_1E_2VF:232hps = &refquad_1e_2vf; break;233234case HP_QUAD_1E_3VA:235hps = &refquad_1e_3va; break;236case HP_QUAD_1E_3VB:237hps = &refquad_1e_3vb; break;238case HP_QUAD_1E_3VC:239hps = &refquad_1e_3vc; break;240case HP_QUAD_1E_3VD:241hps = &refquad_1e_3vd; break;242case HP_QUAD_1E_4V:243hps = &refquad_1e_4v; break;244245246case HP_QUAD_2E:247hps = &refquad_2e; break;248case HP_QUAD_2E_1VA:249hps = &refquad_2e_1va; break;250case HP_QUAD_2E_1VB:251hps = &refquad_2e_1vb; break;252case HP_QUAD_2E_1VC:253hps = &refquad_2e_1vc; break;254case HP_QUAD_2E_2VA:255hps = &refquad_2e_2va; break;256case HP_QUAD_2E_2VB:257hps = &refquad_2e_2vb; break;258case HP_QUAD_2E_2VC:259hps = &refquad_2e_2vc; break;260case HP_QUAD_2E_3V:261hps = &refquad_2e_3v; break;262263case HP_QUAD_2EB_0V:264hps = &refquad_2eb_0v; break;265266case HP_QUAD_2EB_1VA:267hps = &refquad_2eb_1va; break;268case HP_QUAD_2EB_1VB:269hps = &refquad_2eb_1vb; break;270271272case HP_QUAD_2EB_2VA:273hps = &refquad_2eb_2va; break;274case HP_QUAD_2EB_2VB:275hps = &refquad_2eb_2vb; break;276case HP_QUAD_2EB_2VC:277hps = &refquad_2eb_2vc; break;278case HP_QUAD_2EB_2VD:279hps = &refquad_2eb_2vd; break;280281case HP_QUAD_2EB_3VA:282hps = &refquad_2eb_3va; break;283case HP_QUAD_2EB_3VB:284hps = &refquad_2eb_3vb; break;285286case HP_QUAD_2EB_4V:287hps = &refquad_2eb_4v; break;288289case HP_QUAD_3E:290hps = &refquad_3e; break;291case HP_QUAD_3E_3VA:292hps = &refquad_3e_3va; break;293case HP_QUAD_3E_3VB:294hps = &refquad_3e_3vb; break;295case HP_QUAD_3E_4V:296hps = &refquad_3e_4v; break;297298299case HP_QUAD_4E:300hps = &refquad_4e; break;301302303case HP_TET:304hps = &reftet; break;305case HP_TET_0E_1V:306hps = &reftet_0e_1v; break;307case HP_TET_0E_2V:308hps = &reftet_0e_2v; break;309case HP_TET_0E_3V:310hps = &reftet_0e_3v; break;311case HP_TET_0E_4V:312hps = &reftet_0e_4v; break;313314case HP_TET_1E_0V:315hps = &reftet_1e_0v; break;316case HP_TET_1E_1VA:317hps = &reftet_1e_1va; break;318case HP_TET_1E_1VB:319hps = &reftet_1e_1vb; break;320321case HP_TET_1E_2VA:322hps = &reftet_1e_2va; break;323case HP_TET_1E_2VB:324hps = &reftet_1e_2vb; break;325case HP_TET_1E_2VC:326hps = &reftet_1e_2vc; break;327case HP_TET_1E_2VD:328hps = &reftet_1e_2vd; break;329330case HP_TET_1E_3VA:331hps = &reftet_1e_3va; break;332case HP_TET_1E_3VB:333hps = &reftet_1e_3vb; break;334case HP_TET_1E_4V:335hps = &reftet_1e_4v; break;336337case HP_TET_2EA_0V:338hps = &reftet_2ea_0v; break;339case HP_TET_2EA_1VB:340hps = &reftet_2ea_1vb; break;341case HP_TET_2EA_1VC:342hps = &reftet_2ea_1vc; break;343case HP_TET_2EA_1VA:344hps = &reftet_2ea_1va; break;345case HP_TET_2EA_2VA:346hps = &reftet_2ea_2va; break;347case HP_TET_2EA_2VB:348hps = &reftet_2ea_2vb; break;349case HP_TET_2EA_2VC:350hps = &reftet_2ea_2vc; break;351case HP_TET_2EA_3V:352hps = &reftet_2ea_3v; break;353354case HP_TET_2EB_0V:355hps = &reftet_2eb_0v; break;356case HP_TET_2EB_1V:357hps = &reftet_2eb_1v; break;358case HP_TET_2EB_2VA:359hps = &reftet_2eb_2va; break;360case HP_TET_2EB_2VB:361hps = &reftet_2eb_2vb; break;362case HP_TET_2EB_2VC:363hps = &reftet_2eb_2vc; break;364case HP_TET_2EB_3V:365hps = &reftet_2eb_3v; break;366case HP_TET_2EB_4V:367hps = &reftet_2eb_4v; break;368369370case HP_TET_3EA_0V:371hps = &reftet_3ea_0v; break;372case HP_TET_3EA_1V:373hps = &reftet_3ea_1v; break;374case HP_TET_3EA_2V:375hps = &reftet_3ea_2v; break;376case HP_TET_3EA_3V:377hps = &reftet_3ea_3v; break;378379case HP_TET_3EB_0V:380hps = &reftet_3eb_0v; break;381case HP_TET_3EB_1V:382hps = &reftet_3eb_1v; break;383case HP_TET_3EB_2V:384hps = &reftet_3eb_2v; break;385case HP_TET_3EC_0V:386hps = &reftet_3ec_0v; break;387case HP_TET_3EC_1V:388hps = &reftet_3ec_1v; break;389case HP_TET_3EC_2V:390hps = &reftet_3ec_2v; break;391392393case HP_TET_1F_0E_0V:394hps = &reftet_1f_0e_0v; break;395case HP_TET_1F_0E_1VA:396hps = &reftet_1f_0e_1va; break;397case HP_TET_1F_0E_1VB:398hps = &reftet_1f_0e_1vb; break;399case HP_TET_1F_1EA_0V:400hps = &reftet_1f_1ea_0v; break;401case HP_TET_1F_1EB_0V:402hps = &reftet_1f_1eb_0v; break;403case HP_TET_2F_0E_0V:404hps = &reftet_2f_0e_0v; break;405406407case HP_PRISM:408hps = &refprism; break;409case HP_PRISM_SINGEDGE:410hps = &refprism_singedge; break;411// case HP_PRISM_SINGEDGE_H1:412// hps = &refprism_singedge_h1; break;413// case HP_PRISM_SINGEDGE_H12:414// hps = &refprism_singedge_h12; break;415case HP_PRISM_SINGEDGE_V12:416hps = &refprism_singedge_v12; break;417418419case HP_PRISM_1FA_0E_0V:420hps = &refprism_1fa_0e_0v; break;421case HP_PRISM_2FA_0E_0V:422hps = &refprism_2fa_0e_0v; break;423case HP_PRISM_1FB_0E_0V:424hps = &refprism_1fb_0e_0v; break;425case HP_PRISM_1FB_1EA_0V:426hps = &refprism_1fb_1ea_0v; break;427428case HP_PRISM_1FA_1E_0V:429hps = &refprism_1fa_1e_0v; break;430case HP_PRISM_2FA_1E_0V:431hps = &refprism_2fa_1e_0v; break;432case HP_PRISM_1FA_1FB_0E_0V:433hps = &refprism_1fa_1fb_0e_0v; break;434case HP_PRISM_2FA_1FB_0E_0V:435hps = &refprism_2fa_1fb_0e_0v; break;436case HP_PRISM_1FA_1FB_1EA_0V:437hps = &refprism_1fa_1fb_1ea_0v; break;438case HP_PRISM_1FA_1FB_1EB_0V:439hps = &refprism_1fa_1fb_1eb_0v; break;440case HP_PRISM_2FA_1FB_1EA_0V:441hps = &refprism_2fa_1fb_1ea_0v; break;442case HP_PRISM_1FB_1EC_0V:443hps = &refprism_1fb_1ec_0v; break;444case HP_PRISM_1FA_1FB_1EC_0V:445hps = &refprism_1fa_1fb_1ec_0v; break;446case HP_PRISM_2FA_1FB_1EC_0V:447hps = &refprism_2fa_1fb_1ec_0v; break;448case HP_PRISM_1FB_2EA_0V:449hps = &refprism_1fb_2ea_0v; break;450case HP_PRISM_1FA_1FB_2EA_0V:451hps = &refprism_1fa_1fb_2ea_0v; break;452case HP_PRISM_2FA_1FB_2EA_0V:453hps = &refprism_2fa_1fb_2ea_0v; break;454case HP_PRISM_1FB_2EB_0V:455hps = &refprism_1fb_2eb_0v; break;456case HP_PRISM_1FA_1FB_2EB_0V:457hps = &refprism_1fa_1fb_2eb_0v; break;458case HP_PRISM_1FA_1FB_2EC_0V:459hps = &refprism_1fa_1fb_2ec_0v; break;460case HP_PRISM_2FA_1FB_2EB_0V:461hps = &refprism_2fa_1fb_2eb_0v; break;462case HP_PRISM_1FB_3E_0V:463hps = &refprism_1fb_3e_0v; break;464case HP_PRISM_1FA_1FB_3E_0V:465hps = &refprism_1fa_1fb_3e_0v; break;466case HP_PRISM_2FA_1FB_3E_0V:467hps = &refprism_2fa_1fb_3e_0v; break;468case HP_PRISM_2FB_0E_0V:469hps = &refprism_2fb_0e_0v; break;470case HP_PRISM_1FA_2FB_0E_0V:471hps = &refprism_1fa_2fb_0e_0v; break;472case HP_PRISM_2FA_2FB_0E_0V:473hps = &refprism_2fa_2fb_0e_0v; break;474case HP_PRISM_2FB_1EC_0V:475hps = &refprism_2fb_1ec_0v; break;476case HP_PRISM_1FA_2FB_1EC_0V:477hps = &refprism_1fa_2fb_1ec_0v; break;478case HP_PRISM_2FA_2FB_1EC_0V:479hps = &refprism_2fa_2fb_1ec_0v; break;480case HP_PRISM_1FA_2FB_1EB_0V:481hps = &refprism_1fa_2fb_1eb_0v; break;482case HP_PRISM_2FB_3E_0V:483hps = &refprism_2fb_3e_0v; break;484case HP_PRISM_1FA_2FB_3E_0V:485hps = &refprism_1fa_2fb_3e_0v; break;486case HP_PRISM_2FA_2FB_3E_0V:487hps = &refprism_2fa_2fb_3e_0v; break;488case HP_PRISM_1FA_2E_0V:489hps = &refprism_1fa_2e_0v; break;490case HP_PRISM_2FA_2E_0V:491hps = &refprism_2fa_2e_0v; break;492case HP_PRISM_3E_0V:493hps = &refprism_3e_0v; break;494case HP_PRISM_1FA_3E_0V:495hps = &refprism_1fa_3e_0v; break;496case HP_PRISM_2FA_3E_0V:497hps = &refprism_2fa_3e_0v; break;498case HP_PRISM_3FB_0V:499hps = &refprism_3fb_0v; break;500case HP_PRISM_1FA_3FB_0V:501hps = &refprism_1fa_3fb_0v; break;502case HP_PRISM_2FA_3FB_0V:503hps = &refprism_2fa_3fb_0v; break;504// case HP_PRISM_3E_4EH:505// hps = &refprism_3e_4eh; break;506507508/*case HP_PRISM_1FB_1EB_0V:509hps = &refprism_1fb_1eb_0v; break;510case HP_PRISM_2F_0E_0V:511hps = &refprism_2f_0e_0v; break;512*/513514515case HP_PYRAMID:516hps = &refpyramid; break;517case HP_PYRAMID_0E_1V:518hps = &refpyramid_0e_1v; break;519case HP_PYRAMID_EDGES:520hps = &refpyramid_edges; break;521case HP_PYRAMID_1FB_0E_1VA:522hps = &refpyramid_1fb_0e_1va; break;523524525case HP_HEX:526hps = &refhex; break;527case HP_HEX_0E_1V:528hps = &refhex_0e_1v; break;529case HP_HEX_1E_1V:530hps = &refhex_1e_1v; break;531case HP_HEX_1E_0V:532hps = &refhex_1e_0v; break;533case HP_HEX_3E_0V:534hps = &refhex_3e_0v; break;535536case HP_HEX_1F_0E_0V:537hps = &refhex_1f_0e_0v; break;538case HP_HEX_1FA_1FB_0E_0V:539hps = &refhex_1fa_1fb_0e_0v; break;540}541542/*543if (type != HP_TET_1E_4V && type != HP_TET_1E_2VD)544{545if (hps->geom == HP_TET)546hps = &reftet;547if (hps->geom == HP_TRIG)548hps = &reftrig;549}550*/551552if (!hps)553{554cout << "Attention hps : hp-refinement not implemented for case " << type << endl;555PrintSysError ("hp-refinement not implemented for case ", type);556}557558return hps;559}560561bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoiclt_dom,562BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,563INDEX_2_HASHTABLE<int> & surf_edges, ARRAY<int, PointIndex::BASE> & facepoint, int & levels, int & act_ref);564565bool ClassifyHPElements (Mesh & mesh, ARRAY<HPRefElement> & elements, int & act_ref, int & levels);566567568void InitHPElements(Mesh & mesh, ARRAY<HPRefElement> & elements)569{570for(ElementIndex i=0;i<mesh.GetNE();i++)571{572HPRefElement hpel(mesh[i]);573hpel.coarse_elnr=i;574575switch (mesh[i].GetType())576{577case PRISM:578hpel.type = HP_PRISM;579break;580case HEX:581hpel.type = HP_HEX;582break;583case TET:584hpel.type = HP_TET;585break;586case PYRAMID:587hpel.type = HP_PYRAMID;588break;589}590elements.Append(hpel);591}592593for(SurfaceElementIndex i=0;i<mesh.GetNSE();i++)594{595HPRefElement hpel(mesh.SurfaceElement(i));596hpel.coarse_elnr = i;597switch(mesh.SurfaceElement(i).GetType())598{599case TRIG:600hpel.type = HP_TRIG;601break;602case QUAD:603hpel.type = HP_QUAD;604break;605}606elements.Append(hpel);607}608609for(int i=1;i<=mesh.GetNSeg();i++)610{611Segment & seg = mesh.LineSegment(i);612HPRefElement hpel(seg);613hpel.coarse_elnr = i-1;614hpel.type = HP_SEGM;615hpel.index = seg.edgenr + 10000*seg.si;616if(seg.edgenr >= 10000)617{618throw NgException("assumption that seg.edgenr < 10000 is wrong");619}620elements.Append(hpel);621622}623}624625626627/* ******************************* DoRefinement *************************************** */628void DoRefinement (Mesh & mesh, ARRAY<HPRefElement> & elements,629Refinement * ref, double fac1)630{631elements.SetAllocSize (5 * elements.Size());632INDEX_2_HASHTABLE<int> newpts(elements.Size()+1);633INDEX_3_HASHTABLE<int> newfacepts(elements.Size()+1);634635// prepare new points636637fac1 = max(0.001,min(0.33,fac1));638cout << " in HP-REFINEMENT with fac1 " << fac1 << endl;639*testout << " in HP-REFINEMENT with fac1 " << fac1 << endl;640641642int oldelsize = elements.Size();643644for (int i = 0; i < oldelsize; i++)645{646HPRefElement & el = elements[i];647HPRef_Struct * hprs = Get_HPRef_Struct (el.type);648649if (!hprs)650{651cout << "Refinementstruct not defined for element " << el.type << endl;652continue;653}654655int j = 0;656while (hprs->splitedges[j][0])657{658INDEX_2 i2(el.pnums[hprs->splitedges[j][0]-1],659el.pnums[hprs->splitedges[j][1]-1]);660if (!newpts.Used (i2))661{662Point<3> np;663for( int l=0;l<3;l++)664np(l) = (1-fac1)*mesh.Point(i2.I1())(l)665+ fac1 * mesh.Point(i2.I2())(l);666667int npi = mesh.AddPoint (np);668newpts.Set (i2, npi);669}670j++;671}672673j = 0;674if (hprs->splitfaces)675while (hprs->splitfaces[j][0])676{677INDEX_3 i3(el.pnums[hprs->splitfaces[j][0]-1],678el.pnums[hprs->splitfaces[j][1]-1],679el.pnums[hprs->splitfaces[j][2]-1]);680681if (i3.I2() > i3.I3()) Swap (i3.I2(), i3.I3());682683if (!newfacepts.Used (i3))684{685Point<3> np;686for( int l=0;l<3;l++)687np(l) = (1-2*fac1)*mesh.Point(i3.I1())(l)688+ fac1*mesh.Point(i3.I2())(l) + fac1*mesh.Point(i3.I3())(l);689int npi = mesh.AddPoint (np);690newfacepts.Set (i3, npi);691}692j++;693}694}695696for (int i = 0; i < oldelsize; i++)697{698HPRefElement el = elements[i];699HPRef_Struct * hprs = Get_HPRef_Struct (el.type);700int newlevel = el.levelx + 1;701702int oldnp(0);703switch (hprs->geom)704{705case HP_SEGM: oldnp = 2; break;706case HP_TRIG: oldnp = 3; break;707case HP_QUAD: oldnp = 4; break;708case HP_TET: oldnp = 4; break;709case HP_PYRAMID: oldnp = 5; break;710case HP_PRISM: oldnp = 6; break;711case HP_HEX: oldnp = 8; break;712}713714715if (el.type == HP_SEGM ||716el.type == HP_TRIG ||717el.type == HP_QUAD ||718el.type == HP_TET ||719el.type == HP_PRISM ||720el.type == HP_HEX ||721el.type == HP_PYRAMID)722newlevel = el.levelx;723724if (!hprs) continue;725726int newpnums[64];727double newparam[64][3];728729int j;730for (j = 0; j < oldnp; j++)731{732newpnums[j] = el.pnums[j];733for (int l = 0; l < 3; l++)734newparam[j][l] = el.param[j][l];735}736737// split edges, incl. transferring curvature738j = 0;739while (hprs->splitedges[j][0])740{741INDEX_2 i2(el.pnums[hprs->splitedges[j][0]-1],742el.pnums[hprs->splitedges[j][1]-1]);743744int npi = newpts.Get(i2);745newpnums[hprs->splitedges[j][2]-1] = npi;746747for (int l = 0; l < 3; l++)748newparam[hprs->splitedges[j][2]-1][l] =749(1-fac1) * el.param[hprs->splitedges[j][0]-1][l] +750fac1 * el.param[hprs->splitedges[j][1]-1][l];751752j++;753}754755// split faces756j = 0;757if (hprs->splitfaces)758while (hprs->splitfaces[j][0])759{760INDEX_3 i3(el.pnums[hprs->splitfaces[j][0]-1],761el.pnums[hprs->splitfaces[j][1]-1],762el.pnums[hprs->splitfaces[j][2]-1]);763if (i3.I2() > i3.I3())764Swap (i3.I2(), i3.I3());765int npi = newfacepts.Get(i3);766newpnums[hprs->splitfaces[j][3]-1] = npi;767768769for (int l = 0; l < 3; l++)770newparam[hprs->splitfaces[j][3]-1][l] =771(1-2*fac1) * el.param[hprs->splitfaces[j][0]-1][l] +772fac1 * el.param[hprs->splitfaces[j][1]-1][l] +773fac1 * el.param[hprs->splitfaces[j][2]-1][l];774j++;775}776// split elements777j = 0;778if (hprs->splitelements)779while (hprs->splitelements[j][0])780{781//int pi1 = el.pnums[hprs->splitelements[j][0]-1];782Point<3> np;783for( int l=0;l<3;l++)784np(l) = (1-3*fac1)* mesh.Point(el.pnums[hprs->splitelements[j][0]-1])(l)785+ fac1* mesh.Point(el.pnums[hprs->splitelements[j][1]-1])(l)786+ fac1* mesh.Point(el.pnums[hprs->splitelements[j][2]-1])(l)787+ fac1* mesh.Point(el.pnums[hprs->splitelements[j][3]-1])(l);788789int npi = mesh.AddPoint (np);790791newpnums[hprs->splitelements[j][4]-1] = npi;792793794for (int l = 0; l < 3; l++)795newparam[hprs->splitelements[j][4]-1][l] =796(1-3*fac1) * el.param[hprs->splitelements[j][0]-1][l] +797fac1 * el.param[hprs->splitelements[j][1]-1][l] +798fac1 * el.param[hprs->splitelements[j][2]-1][l] +799fac1 * el.param[hprs->splitelements[j][3]-1][l];800801j++;802}803804j = 0;805806/*807*testout << " newpnums = ";808for (int hi = 0; hi < 64; hi++)809*testout << newpnums[hi] << " ";810*testout << endl;811*/812813while (hprs->neweltypes[j])814{815HPRef_Struct * hprsnew = Get_HPRef_Struct (hprs->neweltypes[j]);816HPRefElement newel(el);817818newel.type = hprs->neweltypes[j];819820// newel.index = elements[i].index;821// newel.coarse_elnr = elements[i].coarse_elnr;822newel.levelx = newel.levely = newel.levelz = newlevel;823switch(hprsnew->geom)824{825case HP_SEGM: newel.np=2; break;826case HP_QUAD: newel.np=4; break;827case HP_TRIG: newel.np=3; break;828case HP_HEX: newel.np=8; break;829case HP_PRISM: newel.np=6; break;830case HP_TET: newel.np=4; break;831case HP_PYRAMID: newel.np=5; break;832}833834for (int k = 0; k < newel.np; k++)835newel.pnums[k] = newpnums[hprs->newels[j][k]-1];836837/*838*testout << " newel pnums " ;839for (int k = 0; k < newel.np; k++)840*testout << newel.pnums[k] << "\t";841*testout << endl;842*/843844for (int k = 0; k < newel.np; k++)845{846for (int l = 0; l < 3; l++)847{848newel.param[k][l] = newparam[hprs->newels[j][k]-1][l];849// *testout << newel.param[k][l] << " \t ";850}851// *testout << endl;852}853854if (j == 0)855elements[i] = newel; // overwrite old element856else857elements.Append (newel);858j++;859}860}861}862863864865866867868/* ************************** DoRefineDummies ******************************** */869870void DoRefineDummies (Mesh & mesh, ARRAY<HPRefElement> & elements,871Refinement * ref)872{873int oldelsize = elements.Size();874875for (int i = 0; i < oldelsize; i++)876{877HPRefElement el = elements[i];878879HPRef_Struct * hprs = Get_HPRef_Struct (el.type);880if (!hprs) continue;881882if (el.type != HP_DUMMY_QUAD_SINGCORNER &&883el.type != HP_PYRAMID_EDGES &&884el.type != HP_PYRAMID_0E_1V &&885el.type != HP_HEX_0E_1V &&886el.type != HP_HEX_1E_1V &&887el.type != HP_HEX_1E_0V &&888el.type != HP_HEX_3E_0V889) continue;890891int newlevel = el.levelx;892893int newpnums[8];894int j;895for (j = 0; j < 8; j++)896newpnums[j] = el.pnums[j];897898double newparam[8][3];899for (j = 0; j < 8; j++)900for (int k = 0; k < 3; k++)901newparam[j][k] = el.param[j][k];902903j = 0;904while (hprs->neweltypes[j])905{906HPRef_Struct * hprsnew = Get_HPRef_Struct (hprs->neweltypes[j]);907HPRefElement newel(el);908switch(hprsnew->geom)909{910case HP_SEGM: newel.np=2; break;911case HP_QUAD: newel.np=4; break;912case HP_TRIG: newel.np=3; break;913case HP_HEX: newel.np=8; break;914case HP_PRISM: newel.np=6; break;915case HP_TET: newel.np=4; break;916case HP_PYRAMID: newel.np=5; break;917}918newel.type = hprs->neweltypes[j];919for (int k = 0; k < 8; k++)920newel.pnums[k] = newpnums[hprs->newels[j][k]-1];921newel.index = el.index;922newel.coarse_elnr = el.coarse_elnr;923newel.levelx = newel.levely = newel.levelz = newlevel;924925for (int k = 0; k < 8; k++)926for (int l = 0; l < 3; l++)927newel.param[k][l] = newparam[hprs->newels[j][k]-1][l];928929if (j == 0)930elements[i] = newel;931else932elements.Append (newel);933j++;934}935}936}937938939940941942943944void SubdivideDegeneratedHexes (Mesh & mesh, ARRAY<HPRefElement> & elements, double fac1)945{946int oldne = elements.Size();947for (int i = 0; i < oldne; i++)948if (Get_HPRef_Struct (elements[i].type)->geom == HP_HEX)949{950bool common = 0;951for (int j = 0; j < 8; j++)952for (int k = 0; k < j; k++)953if (elements[i].pnums[j] == elements[i].pnums[k])954common = 1;955if (common)956{957958959cout << " Degenerate Hex found " << endl;960*testout << " Degenerate Hex found " << endl;961HPRefElement el = elements[i];962HPRefElement newel = el;963964Point<3> center(0,0,0);965double newparam[3] = { 0, 0, 0 };966967for (int j = 0; j < 8; j++)968{969970971center += 0.125 * Vec<3>(mesh[el.pnums[j]]);972// 0.125 originates form 8 points not from fac1;973974for (int l = 0; l < 3; l++)975newparam[l] += 0.125 * el.param[j][l];976977}978979int npi = mesh.AddPoint (center);980981const ELEMENT_FACE * faces = MeshTopology::GetFaces (HEX);982983for (int j = 0; j < 6; j++)984{985ARRAY<int> pts;986for (int k = 0; k < 4; k++)987{988bool same = 0;989for (int l = 0; l < pts.Size(); l++)990if (el.pnums[pts[l]] == el.pnums[faces[j][k]-1])991same = 1;992if (!same)993pts.Append (faces[j][k]-1);994995}996997998if (pts.Size() == 3) // TrigFace -> TET999{10001001for (int k = 0; k < 3; k++)1002{1003newel.pnums[k] = el.pnums[pts[2-k]];1004for (int l = 0; l < 3; l++)1005newel.param[k][l] = el.param[pts[2-k]][l];1006}1007newel.pnums[3] = npi;1008for (int l = 0; l < 3; l++)1009newel.param[3][l] = newparam[l];10101011newel.type = HP_TET;1012newel.np = 4;1013}1014else1015{1016for (int k = 0; k < 4; k++)1017{1018newel.pnums[k] = el.pnums[pts[3-k]];1019for (int l = 0; l < 3; l++)1020newel.param[k][l] = el.param[pts[3-k]][l];1021}10221023newel.pnums[4] = npi;1024for (int l = 0; l < 3; l++)1025newel.param[4][l] = newparam[l];10261027newel.type = HP_PYRAMID;1028newel.np = 5;1029}10301031if (j == 0)1032elements[i] = newel;1033else1034elements.Append (newel);103510361037}10381039/* const ELEMENT_EDGE * edges = MeshTopology::GetEdges (HEX);10401041for(int k=0;k<12;k++)1042{1043int e[2];1044for(int l=0;l<2;l++) e[l] = edges[k][l]-1;1045if(el.PNum(e[0]+1)!=el.PNum(e[1]+1))1046{1047newel.SetType(HP_SEGM);1048for(int l=0;l<2;l++)1049{1050newel.pnums[0] = el.PNum(e[l]+1);1051newel.pnums[1] = npi;1052for(int j=0;j<3;j++)1053{1054// newel.param[0][j] = el.param[e[l]][j];1055// newel.param[1][j] = newparam[j];1056}10571058elements.Append(newel);1059}1060newel.SetType(HP_TRIG);1061newel.pnums[0] = el.PNum(e[0]+1);1062newel.pnums[1] = el.PNum(e[1]+1);1063newel.pnums[2] = npi;10641065*testout << "DEGHEX TRIG :: newpnums " << newel.pnums[0] << "\t" << newel.pnums[1] << "\t" << newel.pnums[2] << endl;1066cout << "DEGHEX TRIG :: newpnums " << newel.pnums[0] << "\t" << newel.pnums[1] << "\t" << newel.pnums[2] << endl;1067for(int j=0;j<3;j++)1068{1069// newel.param[0][j] = el.param[e[0]][j];1070// newel.param[1][j] = el.param[e[1]][j];1071// newel.param[2][j] = newparam[j];1072}10731074elements.Append(newel);1075}10761077}*/1078}1079}1080}108110821083void CalcStatistics (ARRAY<HPRefElement> & elements)1084{1085return;1086#ifdef ABC1087int i, p;1088int nsegm = 0, ntrig = 0, nquad = 0;1089int nhex = 0, nprism = 0, npyramid = 0, ntet = 0;1090int maxlevel = 0;10911092for (i = 1; i <= elements.Size(); i++)1093{1094const HPRefElement & el = elements.Get(i);1095maxlevel = max2 (el.level, maxlevel);1096switch (Get_HPRef_Struct (el.type)->geom)1097{1098case HP_SEGM:10991100{1101nsegm++;1102break;1103}1104case HP_TRIG:1105{1106ntrig ++;1107break;1108}1109case HP_QUAD:1110{1111nquad++;1112break;1113}1114case HP_TET:1115{1116ntet++;1117break;1118}11191120case HP_PRISM:1121{1122nprism++;1123break;1124}11251126case HP_PYRAMID:1127{1128npyramid++;1129break;1130}11311132case HP_HEX:1133{1134nhex++;1135break;1136}11371138default:1139{1140cerr << "statistics error, unknown element type" << endl;1141}1142}1143}11441145cout << "level = " << maxlevel << endl;1146cout << "nsegm = " << nsegm << endl;1147cout << "ntrig = " << ntrig << ", nquad = " << nquad << endl;1148cout << "ntet = " << ntet << ", npyr = " << npyramid1149<< ", nprism = " << nprism << ", nhex = " << nhex << endl;11501151return;11521153double memcost = 0, cpucost = 0;1154for (p = 1; p <= 20; p++)1155{1156memcost = (ntet + nprism + nhex) * pow (static_cast<double>(p), 6.0);1157cpucost = (ntet + nprism + nhex) * pow (static_cast<double>(p), 9.0);1158cout << "costs for p = " << p << ": mem = " << memcost << ", cpu = " << cpucost << endl;1159}11601161double memcosttet = 0;1162double memcostprism = 0;1163double memcosthex = 0;1164double memcostsctet = 0;1165double memcostscprism = 0;1166double memcostschex = 0;1167double cpucosttet = 0;1168double cpucostprism = 0;1169double cpucosthex = 0;11701171for (i = 1; i <= elements.Size(); i++)1172{1173const HPRefElement & el = elements.Get(i);1174switch (el.type)1175{1176case HP_TET:1177case HP_TET_0E_1V:1178case HP_TET_1E_0V:1179case HP_TET_1E_1VA:1180{1181int p1 = maxlevel - el.level + 1;1182(*testout) << "p1 = " << p1 << ", P1^6 = " << pow (static_cast<double>(p1), 6.0)1183<< " (p1-3)^6 = " << pow ( static_cast<double>(max2(p1-3, 0)), 6.0)1184<< " p1^3 = " << pow ( static_cast<double>(p1), 3.0)1185<< " (p1-3)^3 = " << pow ( static_cast<double>(p1-3), 3.0)1186<< " [p1^3-(p1-3)^3]^2 = " << sqr (pow (static_cast<double>(p1),3.0) - pow ( static_cast<double>(p1-3), 3.0))1187<< endl;11881189p1 /= 2 +1;1190memcosttet += pow (static_cast<double>(p1), 6.0);1191memcostsctet += pow (static_cast<double>(p1), 6.0) - pow ( static_cast<double>(max2(p1-3, 1)), 6.0);1192cpucosttet += pow (static_cast<double>(p1), 9.0);1193break;1194}1195case HP_PRISM:1196case HP_PRISM_SINGEDGE:1197{1198int p1 = maxlevel - el.level + 1;1199p1 /= 2 +1;1200memcostprism += pow (static_cast<double>(p1), 6.0);1201memcostscprism += pow (static_cast<double>(p1), 6.0) - pow ( static_cast<double>(max2(p1-3, 1)), 6.0);1202cpucostprism += pow (static_cast<double>(p1), 9.0);1203break;1204}1205case HP_HEX:1206{1207int p1 = maxlevel - el.level + 1;1208int p2 = maxlevel;1209p1 /= 2 +1;1210p2 /= 2 +1;1211memcosthex += pow (static_cast<double>(p1), 4.0) * pow (static_cast<double>(p2), 2.0);1212memcostschex += pow (static_cast<double>(p1), 6.0) - pow ( static_cast<double>(max2(p1-2, 0)), 6.0);1213cpucosthex += pow (static_cast<double>(p1), 6.0) * pow (static_cast<double>(p2), 3.0);1214break;1215}1216default:1217;1218}1219}1220cout << "TET: hp-memcost = " << memcosttet1221<< ", scmemcost = " << memcostsctet1222<< ", cpucost = " << cpucosttet1223<< endl;1224cout << "PRI: hp-memcost = " << memcostprism1225<< ", scmemcost = " << memcostscprism1226<< ", cpucost = " << cpucostprism << endl;1227cout << "HEX: hp-memcost = " << memcosthex1228<< ", scmemcost = " << memcostschex1229<< ", cpucost = " << cpucosthex << endl;1230#endif1231}1232123312341235void ReorderPoints (Mesh & mesh, ARRAY<HPRefElement> & hpelements)1236{1237ARRAY<int, 1> map (mesh.GetNP());12381239for (int i = 1; i <= mesh.GetNP(); i++)1240map[i] = i;12411242int nwrong(0), nright(0);1243for (int k = 0; k < 5; k++)1244{1245nwrong = nright = 0;1246for (int i = 0; i < hpelements.Size(); i++)1247{1248const HPRefElement & hpel = hpelements[i];12491250if (Get_HPRef_Struct (hpel.type) -> geom == HP_PRISM)1251{1252int minbot = 0, mintop = 0;1253for (int j = 0; j < 3; j++)1254{1255if (map[hpel.pnums[j]] < map[hpel.pnums[minbot]]) minbot = j;1256if (map[hpel.pnums[j+3]] < map[hpel.pnums[mintop+3]]) mintop = j;1257}1258if (minbot != mintop)1259nwrong++;1260else1261nright++;12621263if (minbot != mintop)1264{1265if (map[hpel.pnums[minbot]] < map[hpel.pnums[mintop+3]])1266swap (map[hpel.pnums[3+minbot]], map[hpel.pnums[3+mintop]]);1267else1268swap (map[hpel.pnums[minbot]], map[hpel.pnums[mintop]]);1269}1270}1271}1272// cout << nwrong << " wrong prisms, " << nright << " right prisms" << endl;1273}12741275cout << nwrong << " wrong prisms, " << nright << " right prisms" << endl;127612771278ARRAY<MeshPoint, 1> hpts(mesh.GetNP());12791280for (int i = 1; i <= mesh.GetNP(); i++)1281hpts[map[i]] = mesh.Point(i);12821283for (int i = 1; i <= mesh.GetNP(); i++)1284mesh.Point(i) = hpts[i];12851286for (int i = 0; i < hpelements.Size(); i++)1287{1288HPRefElement & hpel = hpelements[i];1289for (int j = 0; j < hpel.np; j++)1290hpel.pnums[j] = map[hpel.pnums[j]];1291}1292}1293129412951296/* ***************************** HPRefinement ********************************** */12971298void HPRefinement (Mesh & mesh, Refinement * ref, int levels, double fac1, bool setorders, bool reflevels)1299{1300PrintMessage (1, "HP Refinement called, levels = ", levels);130113021303NgLock mem_lock (mem_mutex,1);13041305mesh.coarsemesh = new Mesh;1306*mesh.coarsemesh = mesh;13071308#ifdef CURVEDELEMS_NEW1309const_cast<CurvedElements&> (mesh.coarsemesh->GetCurvedElements() ).1310BuildCurvedElements (ref, mesh.GetCurvedElements().GetOrder());1311#endif131213131314delete mesh.hpelements;1315mesh.hpelements = new ARRAY<HPRefElement>;13161317ARRAY<HPRefElement> & hpelements = *mesh.hpelements;13181319InitHPElements(mesh,hpelements);13201321ARRAY<int> nplevel;1322nplevel.Append (mesh.GetNP());13231324int act_ref=1;1325bool sing = ClassifyHPElements(mesh,hpelements, act_ref, levels);13261327sing = true; // iterate at least once1328while(sing)1329{1330cout << " Start new hp-refinement: step " << act_ref << endl;13311332DoRefinement (mesh, hpelements, ref, fac1);1333DoRefineDummies (mesh, hpelements, ref);13341335nplevel.Append (mesh.GetNP());1336CalcStatistics (hpelements);13371338SubdivideDegeneratedHexes (mesh, hpelements,fac1);13391340ReorderPoints (mesh, hpelements);13411342mesh.ClearSegments();1343mesh.ClearSurfaceElements();1344mesh.ClearVolumeElements();13451346for (int i = 0; i < hpelements.Size(); i++)1347{1348HPRefElement & hpel = hpelements[i];1349if (Get_HPRef_Struct (hpel.type))1350switch (Get_HPRef_Struct (hpel.type) -> geom)1351{1352case HP_SEGM:1353{1354Segment seg;1355seg.p1 = hpel.pnums[0];1356seg.p2 = hpel.pnums[1];1357// NOTE: only for less than 10000 elements (HACK) !!!1358seg.edgenr = hpel.index % 10000;1359seg.si = hpel.index / 10000;13601361/*1362seg.epgeominfo[0].dist = hpel.param[0][0]; // he: war hpel.param[0][0]1363seg.epgeominfo[1].dist = hpel.param[1][0]; // he: war hpel.param[1][0]1364*/13651366const Segment & coarseseg = mesh.coarsemesh->LineSegment(hpel.coarse_elnr+1);1367double d1 = coarseseg.epgeominfo[0].dist;1368double d2 = coarseseg.epgeominfo[1].dist;13691370// seg.epgeominfo[0].dist = hpel.param[0][0]; // he: war hpel.param[0][0]1371// seg.epgeominfo[1].dist = hpel.param[1][0]; // he: war hpel.param[1][0]13721373seg.epgeominfo[0].dist = d1 + hpel.param[0][0] * (d2-d1); // JS, June 081374seg.epgeominfo[1].dist = d1 + hpel.param[1][0] * (d2-d1);137513761377seg.epgeominfo[0].edgenr = seg.edgenr;1378seg.epgeominfo[1].edgenr = seg.edgenr;1379seg.domin = hpel.domin; seg.domout=hpel.domout; // he: needed for segments!1380seg.hp_elnr = i;1381seg.singedge_left = hpel.singedge_left;1382seg.singedge_right = hpel.singedge_right;1383mesh.AddSegment (seg);1384break;1385}13861387case HP_TRIG:1388case HP_QUAD:1389{1390Element2d el(hpel.np);1391for(int j=0;j<hpel.np;j++)1392el.PNum(j+1) = hpel.pnums[j];1393el.hp_elnr = i;1394el.SetIndex(hpel.index);1395if(setorders)1396el.SetOrder(act_ref+1,act_ref+1,0);1397mesh.AddSurfaceElement(el);1398break;1399}1400case HP_HEX:1401case HP_TET:1402case HP_PRISM:1403case HP_PYRAMID:1404{1405Element el(hpel.np);1406for(int j=0;j<hpel.np;j++)1407el.PNum(j+1) = hpel.pnums[j];1408el.SetIndex(hpel.index);1409el.hp_elnr = i;1410if(setorders)1411el.SetOrder(act_ref+1,act_ref+1,act_ref+1);1412mesh.AddVolumeElement(el);1413break;1414}14151416default:1417PrintSysError ("hpref, backconversion failed for element ",1418int(Get_HPRef_Struct (hpel.type) -> geom));1419}1420}1421cout << " Start with Update Topology " << endl;1422mesh.UpdateTopology();1423cout << " Mesh Update Topology done " << endl;14241425act_ref++;14261427sing = ClassifyHPElements(mesh,hpelements, act_ref, levels);1428}14291430cout << " HP-Refinement done with " << --act_ref << " refinement steps." << endl;14311432if(act_ref>=1)1433{1434for(ElementIndex i=0;i<mesh.GetNE(); i++)1435{1436Element el = mesh[i] ;1437HPRefElement & hpel = hpelements[mesh[i].hp_elnr];1438const ELEMENT_EDGE * edges = MeshTopology::GetEdges (mesh[i].GetType());1439double dist[3] = {0,0,0};1440int ord_dir[3] = {0,0,0};1441int edge_dir[12] = {0,0,0,0,0,0,0,0,0,0,0,0};1442int ned = 4;14431444switch (mesh[i].GetType())1445{1446case TET:1447/* cout << " TET " ;1448for(int k=0;k<4;k++) cout << el[k] << "\t" ;1449cout << endl; */1450break;1451case PRISM:1452/* cout << " PRISM " ;1453for(int k=0;k<6;k++) cout << el[k] << "\t" ;1454cout << endl; */1455for(int l=6;l<9;l++) edge_dir[l] = 2;1456ord_dir[2] = 2;1457ned = 9;1458break;1459case HEX:1460/* cout << " HEX " ;1461for(int k=0;k<8;k++) cout << el[k] << "\t" ;1462cout << endl; */1463for(int l=8;l<12; l++) edge_dir[l] = 2;1464edge_dir[2] = edge_dir[3] = edge_dir[6] = edge_dir[7] = 1;1465ord_dir[1] = 1;1466ord_dir[2] = 2;1467ned = 12;1468break;1469case PYRAMID:1470/* cout << " PYRAMID " ;1471for(int k=0;k<5;k++) cout << el[k] << "\t" ;1472cout << endl; */1473for(int l=4;l<8;l++) edge_dir[l] = 2;1474edge_dir[2] = edge_dir[3] = 1;1475ord_dir[1] = 1;1476ord_dir[2] = 2;1477ned = 8;1478break;1479}14801481for (int j=0;j<ned;j++)1482{14831484Vec<3> v(hpel.param[edges[j][0]-1][0]-hpel.param[edges[j][1]-1][0],1485hpel.param[edges[j][0]-1][1]-hpel.param[edges[j][1]-1][1],1486hpel.param[edges[j][0]-1][2]-hpel.param[edges[j][1]-1][2]);1487dist[edge_dir[j]] = max(v.Length(),dist[edge_dir[j]]);1488}14891490int refi[3];1491for(int j=0;j<3;j++)1492refi[j] = int(max(double(floor(log(dist[ord_dir[j]]/sqrt(2.))/log(fac1))),0.));14931494// cout << " ref " << refi[0] << "\t" << refi[1] << "\t" << refi[2] << endl;1495// cout << " order " << act_ref +1 - refi[0] << "\t" << act_ref +1 - refi[1] << "\t" << act_ref +1 - refi[2] << endl;14961497if(setorders)1498mesh[i].SetOrder(act_ref+1-refi[0],act_ref+1-refi[1],act_ref+1-refi[2]);1499}1500for(SurfaceElementIndex i=0;i<mesh.GetNSE(); i++)1501{1502Element2d el = mesh[i] ;1503HPRefElement & hpel = hpelements[mesh[i].hp_elnr];1504const ELEMENT_EDGE * edges = MeshTopology::GetEdges (mesh[i].GetType());1505double dist[3] = {0,0,0};1506int ord_dir[3] = {0,0,0};1507int edge_dir[4] = {0,0,0,0} ;1508int ned = 3;15091510if(mesh[i].GetType() == QUAD)1511{1512/* cout << " QUAD " ;1513for(int k=0;k<4;k++) cout << el[k] << "\t" ;1514cout << endl; */15151516edge_dir[2] = edge_dir[3] = 1;1517ord_dir[1] = 1;1518ned = 4;1519}1520/* else1521{1522cout << " TRIG " ;1523for(int k=0;k<3;k++) cout << el[k] << "\t" ;1524cout << endl;1525} */15261527for (int j=0;j<ned;j++)1528{1529Vec<3> v(hpel.param[edges[j][0]-1][0]-hpel.param[edges[j][1]-1][0],1530hpel.param[edges[j][0]-1][1]-hpel.param[edges[j][1]-1][1],1531hpel.param[edges[j][0]-1][2]-hpel.param[edges[j][1]-1][2]);1532dist[edge_dir[j]] = max(v.Length(),dist[edge_dir[j]]);1533}15341535int refi[3];1536for(int j=0;j<3;j++)1537refi[j] = int(max(double(floor(log(dist[ord_dir[j]]/sqrt(2.))/log(fac1))),0.));15381539if(setorders)1540mesh[i].SetOrder(act_ref+1-refi[0],act_ref+1-refi[1],act_ref+1-refi[2]);15411542// cout << " ref " << refi[0] << "\t" << refi[1] << endl;1543// cout << " order " << act_ref +1 - refi[0] << "\t" << act_ref +1 - refi[1] << endl;1544}1545}1546}15471548bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom,1549BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges,1550INDEX_2_HASHTABLE<int> & surf_edges, ARRAY<int, PointIndex::BASE> & facepoint, int & levels, int & act_ref)1551{1552bool sing=0;1553if (mesh.GetDimension() == 3)1554{1555/*1556// check, if point has as least 3 different surfs:15571558ARRAY<INDEX_3, PointIndex::BASE> surfonpoint(mesh.GetNP());1559surfonpoint = INDEX_3(0,0,0);15601561for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)1562{1563const Element2d & el = mesh[sei];1564int ind = el.GetIndex();1565for (int j = 0; j < el.GetNP(); j++)1566{1567INDEX_3 & i3 = surfonpoint[el[j]];1568if (ind != i3.I1() && ind != i3.I2() && ind != i3.I3())1569{1570i3.I1() = i3.I2();1571i3.I2() = i3.I3();1572i3.I3() = ind;1573}1574}1575}1576for (int i = 1; i <= mesh.GetNP(); i++)1577if (surfonpoint.Get(i).I1())1578cornerpoint.Set(i);1579*/1580cornerpoint.Clear();15811582for (int i = 1; i <= mesh.GetNP(); i++)1583{1584if (mesh.Point(i).Singularity() * levels >= act_ref)1585{1586cornerpoint.Set(i);1587sing = 1;1588}1589}1590cout << endl;15911592for (int i = 1; i <= mesh.GetNSeg(); i++)1593if (mesh.LineSegment(i).singedge_left * levels >= act_ref)1594{1595INDEX_2 i2 (mesh.LineSegment(i).p1,1596mesh.LineSegment(i).p2);15971598/*1599// before1600edges.Set (i2, 1);1601i2.Sort();1602INDEX_2 i2s(i2.I2(), i2.I1());1603edges.Set (i2s, 1);1604*/16051606edges.Set (i2, 1);1607INDEX_2 i2s(i2.I2(), i2.I1());1608edges.Set (i2s, 1);160916101611edgepoint.Set (i2.I1());1612edgepoint.Set (i2.I2());1613sing = 1;1614}16151616// if 2 adjacent edges of an element are singular, the1617// commen point must be a singular point1618for (int i = 1; i <= mesh.GetNE(); i++)1619{1620const Element & el = mesh.VolumeElement(i);1621const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (el.GetType());1622int nedges = MeshTopology::GetNEdges (el.GetType());1623for (int j = 0; j < nedges; j++)1624for (int k = 0; k < nedges; k++)1625if (j != k)1626{1627INDEX_2 ej(el.PNum(eledges[j][0]), el.PNum(eledges[j][1]));1628ej.Sort();1629INDEX_2 ek(el.PNum(eledges[k][0]), el.PNum(eledges[k][1]));1630ek.Sort();1631if (edges.Used(ej) && edges.Used(ek))1632{1633if (ej.I1() == ek.I1()) cornerpoint.Set (ek.I1());1634if (ej.I1() == ek.I2()) cornerpoint.Set (ek.I2());1635if (ej.I2() == ek.I1()) cornerpoint.Set (ek.I1());1636if (ej.I2() == ek.I2()) cornerpoint.Set (ek.I2());1637}1638}1639}16401641edgepoint.Or (cornerpoint);1642(*testout) << "cornerpoint = " << endl << cornerpoint << endl;1643(*testout) << "edgepoint = " << endl << edgepoint << endl;16441645facepoint = 0;1646for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++)1647{1648const Element2d & el = mesh[sei];1649const FaceDescriptor & fd = mesh.GetFaceDescriptor (el.GetIndex());16501651int domnr = 0;1652if (fd.domin_singular * levels < act_ref && fd.domout_singular * levels < act_ref)1653{ domnr=0; continue;}16541655if (fd.domin_singular * levels >= act_ref)1656{1657domnr = fd.DomainIn();1658sing = 1;1659}1660if (fd.domout_singular * levels >= act_ref)1661{1662domnr = fd.DomainOut();1663sing = 1;1664}1665if (fd.domin_singular * levels >= act_ref1666&& fd.domout_singular * levels >= act_ref)1667{1668domnr = -1;1669sing = 1;1670}16711672INDEX_3 i3;1673if (el.GetNP() == 3)1674i3 = INDEX_3::Sort (el[0], el[1], el[2]);1675else1676{1677INDEX_4 i4 (el[0], el[1], el[2], el[3]);1678i4.Sort();1679i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3());1680}1681faces.Set (i3, domnr);16821683for (int j = 0; j < el.GetNP(); j++)1684{1685face_edges.Set (INDEX_2::Sort (el[j], el[(j+1)%el.GetNP()]), domnr);16861687surf_edges.Set (INDEX_2::Sort (el[j], el[(j+1)%el.GetNP()]), fd.SurfNr()+1);16881689facepoint[el[j]] = domnr;1690}16911692}1693(*testout) << "singular faces = " << faces << endl;1694(*testout) << "singular faces_edges = " << face_edges << endl;1695}1696else1697{1698// 2D case16991700// check, if point has as least 3 different surfs:1701ARRAY<INDEX_3, PointIndex::BASE> surfonpoint(mesh.GetNP());17021703for (int i = 1; i <= mesh.GetNP(); i++)1704surfonpoint.Elem(i) = INDEX_3(0,0,0);17051706for (int i = 1; i <= mesh.GetNSeg(); i++)1707{1708const Segment & seg = mesh.LineSegment(i);1709int ind = seg.edgenr;171017111712if (seg.singedge_left * levels >= act_ref)1713{1714INDEX_2 i2 (mesh.LineSegment(i).p1,1715mesh.LineSegment(i).p2);1716edges.Set(i2,1);1717edgepoint.Set(i2.I1());1718edgepoint.Set(i2.I2());1719*testout << " singleft " << endl;1720*testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl;1721*testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl;1722edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I1()), 1);1723edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I2()), 1);1724sing = 1;17251726}17271728if (seg.singedge_right * levels >= act_ref)1729{1730INDEX_2 i2 (mesh.LineSegment(i).p2,1731mesh.LineSegment(i).p1);1732edges.Set (i2, 1);1733edgepoint.Set(i2.I1());1734edgepoint.Set(i2.I2());17351736*testout << " singright " << endl;1737*testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl;1738*testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl;17391740edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I1()), 1);1741edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I2()), 1);1742sing = 1;1743}17441745// (*testout) << "seg = " << ind << ", " << seg.p1 << "-" << seg.p2 << endl;174617471748if (seg.singedge_left * levels >= act_ref1749|| seg.singedge_right* levels >= act_ref)1750{1751for (int j = 0; j < 2; j++)1752{1753int pi = (j == 0) ? seg.p1 : seg.p2;1754INDEX_3 & i3 = surfonpoint.Elem(pi);1755if (ind != i3.I1() &&1756ind != i3.I2())1757{1758i3.I1() = i3.I2();1759i3.I2() = ind;1760}1761}1762}1763}176417651766for (int i = 1; i <= mesh.GetNP(); i++)1767{1768// mark points for refinement that are in corners between two anisotropic edges1769if (surfonpoint.Get(i).I1())1770{1771cornerpoint.Set(i);1772edgepoint.Set(i);1773}17741775// mark points for refinement that are explicity specified in input file1776if (mesh.Point(i).Singularity()*levels >= act_ref)1777{1778cornerpoint.Set(i);1779edgepoint.Set(i);1780sing = 1;1781}1782}17831784edgepoint.Or (cornerpoint);17851786(*testout) << "2d sing edges: " << endl << edges << endl;1787(*testout) << "2d cornerpoints: " << endl << cornerpoint << endl1788<< "2d edgepoints: " << endl << edgepoint << endl;17891790facepoint = 0;1791}17921793if (!sing)1794{1795cout << "PrepareElements no more to do for actual refinement " << act_ref << endl;1796return(sing);1797}1798return(sing);1799}1800180118021803bool ClassifyHPElements (Mesh & mesh, ARRAY<HPRefElement> & elements, int & act_ref, int & levels)1804{18051806INDEX_2_HASHTABLE<int> edges(mesh.GetNSeg()+1);1807BitArray edgepoint(mesh.GetNP());1808INDEX_2_HASHTABLE<int> edgepoint_dom(mesh.GetNSeg()+1);18091810edgepoint.Clear();1811BitArray cornerpoint(mesh.GetNP());1812cornerpoint.Clear();18131814// value = nr > 0 ... refine elements in domain nr1815// value = -1 ..... refine elements in any domain1816INDEX_3_HASHTABLE<int> faces(mesh.GetNSE()+1);1817INDEX_2_HASHTABLE<int> face_edges(mesh.GetNSE()+1);1818INDEX_2_HASHTABLE<int> surf_edges(mesh.GetNSE()+1);1819ARRAY<int, PointIndex::BASE> facepoint(mesh.GetNP());18201821bool sing = CheckSingularities(mesh, edges, edgepoint_dom,1822cornerpoint, edgepoint, faces, face_edges,1823surf_edges, facepoint, levels, act_ref);18241825if(sing==0) return(sing);18261827int cnt_undef = 0, cnt_nonimplement = 0;1828ARRAY<int> misses(10000);1829misses = 0;18301831(*testout) << "edgepoint_dom = " << endl << edgepoint_dom << endl;18321833for( int i = 0; i<elements.Size(); i++)1834{1835// *testout << "classify element " << i << endl;18361837HPRefElement & hpel = elements[i];1838HPRef_Struct * hprs = Get_HPRef_Struct (hpel.type);1839HPRefElement old_el = elements[i];1840int dd=3;184118421843if(act_ref !=1 && (hpel.type == HP_HEX || hpel.type == HP_PRISM || hpel.type == HP_TET1844|| hpel.type == HP_PYRAMID || hpel.type == HP_QUAD || hpel.type == HP_TRIG || hpel.type == HP_SEGM))1845continue;18461847sing = 1;1848switch (hprs->geom)1849{1850case HP_TET:1851{1852hpel.type = ClassifyTet(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces,face_edges, surf_edges, facepoint);1853break;1854}1855case HP_PRISM:1856{1857hpel.type = ClassifyPrism(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces,1858face_edges, surf_edges, facepoint);185918601861break;1862}1863case HP_HEX:1864{1865hpel.type = hpel.type = ClassifyHex(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces,1866face_edges, surf_edges, facepoint);1867break;1868}1869case HP_TRIG:1870{1871int dim = mesh.GetDimension();1872const FaceDescriptor & fd = mesh.GetFaceDescriptor (hpel.GetIndex());18731874hpel.type = ClassifyTrig(hpel, edges, edgepoint_dom, cornerpoint, edgepoint,1875faces, face_edges, surf_edges, facepoint, dim, fd);18761877dd = 2;1878break;1879}1880case HP_QUAD:1881{1882int dim = mesh.GetDimension();1883const FaceDescriptor & fd = mesh.GetFaceDescriptor (hpel.GetIndex());1884hpel.type = ClassifyQuad(hpel, edges, edgepoint_dom, cornerpoint, edgepoint,1885faces, face_edges, surf_edges, facepoint, dim, fd);18861887dd = 2;1888break;1889}1890case HP_SEGM:1891{1892hpel.type = ClassifySegm(hpel, edges, edgepoint_dom, cornerpoint, edgepoint,1893faces, face_edges, surf_edges, facepoint);1894dd = 1;1895break;1896}1897case HP_PYRAMID:1898{1899hpel.type = ClassifyPyramid(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces,1900face_edges, surf_edges, facepoint);19011902cout << " ** Pyramid classified " << hpel.type << endl;1903break;1904}1905default:1906{1907cout << "illegal element type for hp-prepare elements " << hpel.type << endl;1908throw NgException ("hprefinement.cpp: don't know how to set parameters");1909}1910}19111912if(hpel.type == HP_NONE)1913cnt_undef++;19141915//else1916//cout << "elem " << i << " classified type " << hpel.type << endl;1917191819191920if (!Get_HPRef_Struct (hpel.type))1921{1922(*testout) << "hp-element-type " << hpel.type << " not implemented " << endl;1923(*testout) << " elType " << hprs->geom << endl;1924(cout) << " elType " << hprs->geom << endl;1925cnt_nonimplement++;1926misses[hpel.type]++;1927}192819291930for(int j=0; j<hpel.np; j++)1931{1932for( int k=0; k<hpel.np; k++)1933if(hpel[j] == old_el.pnums[k])1934{1935for(int l=0;l<dd;l++)1936hpel.param[j][l] = old_el.param[k][l];1937break;1938}1939}19401941}194219431944cout << "undefined elements update classification: " << cnt_undef << endl;1945cout << "non-implemented in update classification: " << cnt_nonimplement << endl;19461947for (int i = 0; i < misses.Size(); i++)1948if (misses[i])1949cout << " in update classification missing case " << i << " occured " << misses[i] << " times" << endl;19501951return(sing);1952}1953}1954195519561957