From 12c3d37b2d6ffdda7fc9714947ac07f0b8a9db80 Mon Sep 17 00:00:00 2001 From: Christian Van Wambeke Date: Thu, 5 Jun 2014 16:04:10 +0200 Subject: [PATCH] tetra_hpc in place of tepal --- .gitignore | 22 + doc/file.mesh.pdf | Bin 0 -> 118865 bytes .../images/ghs3dprl_parameters_basic.png | Bin 25365 -> 25445 bytes .../GHS3DPRLPLUGIN/input/ghs3dprl_hypo.doc | 379 +++----- idl/GHS3DPRLPlugin_Algorithm.idl | 16 +- src/GHS3DPRLPlugin/GHS3DPRLPluginBuilder.py | 29 +- .../GHS3DPRLPlugin_GHS3DPRL.cxx | 179 +++- .../GHS3DPRLPlugin_GHS3DPRL.hxx | 17 +- .../GHS3DPRLPlugin_Hypothesis.cxx | 76 +- .../GHS3DPRLPlugin_Hypothesis.hxx | 28 +- .../GHS3DPRLPlugin_Hypothesis_i.cxx | 80 +- .../GHS3DPRLPlugin_Hypothesis_i.hxx | 17 +- .../GHS3DPRLPluginGUI_HypothesisCreator.cxx | 54 +- src/gui/GHS3DPRLPluginGUI_HypothesisCreator.h | 12 +- src/gui/GHS3DPRLPlugin_msg_en.ts | 20 +- src/tepal2med/CMakeLists.txt | 11 +- src/tepal2med/ghs3dprl_mesh_wrap.cxx | 358 +++++++- src/tepal2med/ghs3dprl_mesh_wrap.h | 8 +- src/tepal2med/tepal2med.cxx | 17 +- src/tepal2med/tetrahpc2med.cxx | 830 ++++++++++++++++++ 20 files changed, 1804 insertions(+), 349 deletions(-) create mode 100644 .gitignore create mode 100644 doc/file.mesh.pdf create mode 100755 src/tepal2med/tetrahpc2med.cxx diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..36597d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Compiled source +################# +*.pyc +*.pyo + +# Edition bak +################# +*~ +*.old +*_old + +# CASTEM +################# +UTILNOTI +UTILPROC +fort.98 + +# AUTOTOOLS +################# +Makefile.in +Makefile + diff --git a/doc/file.mesh.pdf b/doc/file.mesh.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c0f071ee6d2a31e965803b661f882c4e7dc2381c GIT binary patch literal 118865 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 OtX1r-w`LFN7yExE+Rxbl literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GHS3DPRLPLUGIN/images/ghs3dprl_parameters_basic.png b/doc/salome/gui/GHS3DPRLPLUGIN/images/ghs3dprl_parameters_basic.png index 0628058ee764c5f3bc1ee602b34555ba48742017..cdf1c3d7b363b9d22349bfe2b52b1d4e6f8d4c37 100644 GIT binary patch literal 25445 zcma&N1yoj1+ctP;q*X#d>5`BZkOl$i?(P}`V z=<54nfqIM$vX5uIo9~PFM zt|L_lREu(qhK$lk8Do%KkJ+(`J0MXSIV>LFJ`YfCI>e$ zhgf_5AVQylqBvDEOLj=Vxsm-<>id6`ZAcggH1ONBp3 zuJ&wFF?N+&M37=J~ z-_X`~RFp=*kbR}kDlWjyFzB{4cdR3!BhqPx4UsS&98Q+%RK3_}E6>kWZjDqNePoP% zil6(-W})4cT-W`9HkS}V?xVb|xrj2p$i-6>rt0m5*NO$vT z3|pMH|IRE$1?N5T)UuU%pjjqRaSWs9G2(8qh7PsYzfIdu_)dB3|8RQ4 zwB&h<fhPUqYad8~UVKm7w%kO+gS#mR}^iv$JbeCT3WP zvU{t5VzIw#v5Zs8rZirN&4x?;E<2+@Kd@VmTZ3Tcf@4~leOg)HmiWx7(DSLa1X(B> zhaGLDNKHybTSQ*cojq*Mr(>0JBL-&@T^WMcd?F)Ie4+b5u2s&lb_R5ehy>{x&5fb0B(TWIax8*lwXBWzdD9UQdvobP7b{Q4z zgvBVyAwU~E;c)bEjgfx7p=2R_MdkG7W#w7&jq+wSf%P?cm6PpB(pGtwdtv34$e4V) zXXiiJYg&gbG7rm>BPu+(*cPejEnAt@5-%>bLN&rcyZzr<&(-Y%zF)3 zmN#>5KM-<75YaKnSnTES3^DNIr%Pn|*b$nV(MrHTRO-7jRTBu1l$!gCC32zwjIZpe zW|`x{xes=9C^jy9{r?ri-Vx9|2>>#&4?fs-*t0zahuW} zQBqO<*Q|o9f=+CQ-WTies!Hj;5V7ex*FK3K!_=*EvEvo^t7FnTe$l3t32;vC?^oYV z6V=zbrBd`;`j2{r^%3ptZNURmum2suj{8UtzRYZYzc+Zf3*ji{>r_^#$ zHJx}rV2@xfFTu#WEj`#B{cM|K=(XC}fA}JNl;J(TG>1OLJl}|x%aOP2AB{8`voWZm5H&og591XR* z(v~hRgt_R_!qt2|Jr9|36Ng)Cq1@Vo>>~jt0%qr>)Brg&U!t2hNoqd05x#Ul7Mf&p zz*ecv$Y`b5mVPZxwH8cEU`*Ld`0e$?N19ZIuv{0}pMQQ{ByuXKcx%Z|(~43#&*1wp zrvAxLTvlTL=_C&WS*OO_pWfb|y0-7muiuMjgVi(``4RKVe38e^L{oXExMuLo>OMd8 z1?4IWYVjAfnqi8wAL=T`F0#*J8XeBMiw7jPnhRZYl>BnNz1_Y?R_O2l!IO)8Eif~@WZ$oV1+bBhT9*3Hpgx%PTPtSedmc{9duu|>) zjfTS{1T`MlcBia{3*?LLy3bPqg4l5|5Y3PyyHe{clhdE_aeC#A--Ppx8r-h*=t>Dv zh!IIJkQYL08EH$*XChjIh$}RzkPajD4=(Lr18|0MAHaIhr}C`4s@uI4kGyk^I3k0E zz|*43`jw9t0EdA8#WEqtPiq5*U z<709mRd^kKCI&R)!nY|XlUvz15y^gdYf&|Y*x$s+J6GA>p`SBV?cL8CPqZFLfjcq1 zv~_vtcV`nAjjZbQM_BkrVcs_p_u`gBDoD>KV+LBCoZR{OO~S&NM;c-(^0hfph^Po^^tj;^ zWW{;&lcOKh?C2eg#!!k@(a$9I;)sJOS4U3n@Y?&FtHO40#k2b02?+@xP1q?N( zv)nnF@C7t<&@TjKOImjh#3pjSV35~B(9?peBNrFuFTDw)-Z}D~lLCBbMDpOK(I2~p zBV>REohr@a>^0Q>_t{~HlkUpvExe;vCRcB_r_nc)p3O%CwYAx9Kio6BM5O+nA2u%R zW<{}?7>A_f6!!PNHA4%BfqYO3ln|lNju*zlrpLkhRcc1&u`@N^xkQHfp`&fl>IUWo zDA1?=Z*V~ttm?5})Evdp)kS0ba<-cbnMV~yRO0d+>vj_Vc32Xd#P<`-w9q<_&CQaN z3Qed+OEVUk9>G$Ry)86RQys~lh{3Z_qwu?8m`vquA^Z3`F_2X*+D}#celeMqL)&;K zt-1jYcRw$#XT5)*8l3+}Edhiz} zl?aI_)h|@`Fl(Q#bIp(*eNZ{rMd`op>?3YBR;GyQ<0yQljr(8hOq$t>qw8e)w3j`q z3mPA<&L5v55+kV+!Z|0>QxZSXyG16)2F3ldClrRoILm7+tV$$f6njjdBQU5;pvQd~ z=3jq=aAB)j0#nR6KQkrXwPH&HF(*hlGoWTbkQDCTT#IUoCdavel>Da1T{cfQ{!U@P z*;{exx-mk2g#o*H;~^&GFhrIQTAdXi?U2W*9bbRf(wV<1)O=N7M2+{n_XQ0yXqT=U z1WcT-`3E!4$4J=-{DeAsY_U<~PNKA&1`VFOTtY;Cur$~xe!ETg-a;^t8a#axFT$Id z04!gjOuj_)i(-5)54&7OGvt-GT@f$WF$I;muDFogj`hpR4Yp=%Iz1+<9EKIIp+L!u zPgPOF$;7=y35JyvOC1Z>YW#vq5~A}Zxm7>x*a(*M)DLaTjE%c2{mtHR308ein+ket>mpfan3T!EZuxh;jc zWa(}~fcFQ}5kL?Y$_0JfT350wHhkqPHZi-weii@v8l!=xB4PPq2z6zogj*j5{ncx-Nki2$Wpd1l-HQ{+PX~*cijw_&Hn2WryXx{0u zEc83N4Npv47t?A;$H=Udh`QDh=fy@@lV>Fe**z;0&+A0xClikSUAFeeq~$qr}Y+VV2P(c#W|0ltnwhTi7Uyl zzpriA&%uQW(61Cwm?C^GqB!)M4V%Jd|MWWv_JR)w(N++hS=>|{ue&z$l$!NCZ2s8Q z;O=P@WsQen&vAV<>YFd zv7~OdcYK^xu8lRE=8MfImfLfziS%d$7G?(@Qje=@;+fR!~a3oHVhhT zc7tTl7-=K5PnT?CED@6#oyPEk%)O}HF8hWm-(Y}8WIZD+7lC@r_r|RUmJ1h+k<5WSSJ-;XXa+)(+aoi zJAX?iqbja@Fep0m?GD0i#J%lrVG~uC9vBq6F;d@r_u*`34~175-<=&F(MMTr^vnB4 zt{)=;7tJ>_@W_i@?O)M5SNIxwL&$#=Mtwki3{KiMGO*0bB%%DJR~1Z0Xv6#Vhuj#M zct7S;O42V=AIfE!)wIm|dTg*M`JKdZTF9A)bANy8PC7kR$l@N#-B;&)mZlU)XSUy% z!k6D@9+g{`Rbz%3`~48-)e1>HthzDYx!9yd-v;eB19>qWwnWURvE%Vb{YMR#gaK{8)K4$GH3Drjx&1@@n0Nv?N9Ko*%E}4-OJ3yIx{u18o|{)$ zd*hN5D~6?c#qdV^B4X&+O^42`;Egpo8#_Ik(h^7AlfzA9ebsZ{ZZx!Y_a&cWyKzZV zwL#?mdY6xrL#i5D8`US$)~SQTz?sn?O&{y;7(f{)5{462+TeoIC<6bUnL5sbkxT0oH&q-R3_&JBL z`0%$1WsNP2Wv1u8tEge!Br8ns)99{4^H~$w2n;it0|t1IV7|+KXmV?#Nh_{nc06Tp zGAzT8mq145hrlndAc5UT%E1d|2%0GVquV((|CJ`)gtO*HVLcFzJ5AS*Czs;6+oN4_ahkixC#Jdr>U=iUG zy~aj^%nA{brt}gWzF49nW1?zaT7I!aH|xX2jh6N$P92W8YD0MH*1#4cR`1Qub)v z`@j59562f*H*0EY3KjE;iVOF4cBRw#c)7U=q2tp{Nos0pX>@66^g(ej7Ymo^D2h zejhq_!IC)k&_Q02wQ-TPS&_B4x%o)vSekEn8JDTQshn>QrOsD)bb?dRHEH|PH#l2k zKAy_$aqO_o-_gmUqO3GS;8wO*f=U>YJIW+ z5M(l(m>QF!B&T*f%>R_a@07NPWo>;B+#kFawH6Zp&VYI5tzuqGY}|=D^)C*e4*lq-`fj;jEpQRD@#U3hKh;`f)Ef8goTB{1G%`kD2*xc6C)zd1hITO^m1}? z@}!d;Pbd0N@!lz^T&g=|$kCu7l9Q9KukUpd&8-TVo9{H(ZR6tMosE-1Uh>(ZeFFm_ zfq@0Z#V^G_nwy(n(xM^y^sHZ;pI;sC--^! z@Vphh*&b6j9}@!w0|RBqQymUk!RFn5+Ltz&qfa)k4lO>{)X?}SB2qcSheX+A>v*h` zz!37|2bLkZ;dQNDk4*g!DXQh*7C-8h>2h5gBeM;TE zKYvw!Ri~n}rGvceHynBu!yt+C+X{9 zTQqpv+0jwK>dQ^kU?9SEyZyAL zg1qqLbFm>;3qheB`AdH|OIB7^@)tqi-4*j?HXFIcpNWff@%4}~+g5&uk&uw6HXYvj zplwpAhV~gZWp;M<;^M+8=p`~d7gvJ^^OsDp=ERUG0)QXLXp{1oQ(`qoVumB?S(rrO-csjs1Ha6B1PUORgx4XA@G}B->L8H^wL_tfH zboJqAVn;CyJq&DumsCwskk(!fcior;@5a`d}+R>1wtG->@T^q zn;YJ3`VOmw=9g{tN+=tU33OwD@H1YksgrY%h4Z~-jX24 zk&e5onI-g~MPwEo+`Ygh@c;C*ZDM9mj7#v|^e~0A(1Mf6^zik^TYe7VjJt{vrYGI| z)y>OGM=>NZYSVo8yUT~Gq=1w#!uLr@i9@N}SJjb^ZP(;uPeJ%eCussC?Wkab5D*Yx z67%GY?~su_c$!DbZ`WMpYt_2iiWF{u2 zPckwlc;S@Yd1Z^Y{($0 zX|-5|<4tnu-xL1k?DEvn{tMX66j;d2%*>$RJ)a(aW@j7zeH=+kOQV#G3uPfTW}Y*M z+opewA@-`hXtLNNDcS*E#^2=JPwb>>tSTiX1@x^eIoGVuA8&4NtKfoBLe@U_WRCvz z_V!+Eaum~vV0-_b&-qwSSs8~QtXq!>m;*w>UwEm>pat z@lEKPgF|hnGZH2yCNXjPdCmD~wiqL_8U%5ES@A+v-*9-eL_-9a37ne-zLQtY?_c3x zc=ELhTm_>9H^Y_bwtcp?W?*1A*xhY(n?CICm$>vPg=s@<=QDlw?3to=-mfKDI+YU6 zuh+;&ALMB!cG-(7)%HX2Syjq4TFg$!z@jTED!RKrczeSF478js>+0_Q)rv-^TB_Cd z*}b+9>6&lV|O6as$O+^nUlI{oKQs2E1YIq2~&`N7AF zg@vW7tfvFrZbTPVY9)jmpXpIG5Ft5vd1hADkkHWkgP*PQ(>Xb}9-hsGl|c_zK3xV} z?nCutq@*yKhwT9fb%d})5l06H);2arhliJEXFdTIRMA15>njjTBAOtUn^?=lBfsnJ z(UGpI=JwwD{QUeL_c8~k^T_izL`OGAioQqQ-&+OsccQ!Vb zrd0_QbTA=Z-l((O-pf@`NQWL)&_~$sST4K@A|igQdCUG41IYJr9s8OfBuRd6GgsrH zXlr}2z-0#(#@fmX@%_O_hj1^&_O_wfkmXzK{@UW{Ztl>wH=f*EDpG$+6AF^$0eS*D z1H7j$19`VX@LedA^8;shPfwfkNmhRT_DY9O3%E__p!j7K7vKF|B}efCwekWVzt4#2 zEjEhPy5J22c}W};2lN?@xtiO5SnTXH95~WkYV(xMl%u7iBj$Bw`yz}RGAX&2D@Owu z8sIHoRza6oYIT>)lhbhGV) zD1S?lWx*5fy=J>NL};0;V^Iz^PO41498GI$D}Z#+b+v2EB5!EysG`L)^h2u=$drE9VCL8qVhEOM*u>Cw$rzH*p{ z82nN;uBDyVkPyLgM1AWS{^S$*XzIsE{QQ*&LRZIDz3!DeLzt)?fPwI!$9?*zrsJbn z&*zIz0^b}xhIhzW*v{OpgOSp&wv9|o0F}>{D;Uq0v9z!V4h(EJys03&HDM#WO-~@b zyTp#;gY^0*-ZqoJeEH(1^66D9WWmvKYeT1yLOkW0jWN)A#?mX3Qm$|upBS;#FC04jF2!t@< zM;|I+M<3*1J34s@ytT{pW=a@wp^LcNowEsUh4Gj%eUei|hJKTVt)#G|@ zr^8TUej=T%+pk~0dULR`uxPZnIxv>Ti&c2(fF6sg^@4L_l26=?W!x?=JUl!k1a%sM zahHRI@y=N92}dnB)kj6ixICJV5X~ILBJj>|IoncJQQ6wq=b_(<9Zv~+2(ch7gm!M&hI0LBNTEsysqp076_;h6{{kPrSN z_lVidYG`rkpTwW_wRe37XF^zl1b-s_OyUYOyx|nC@wvHv^-sA94_kNm_yjv={9Pe59JRh6GYQxIH4?BF21|$Zw@*2$wEaBf_7`Z*9^4d*}{ZddBo3@No1vu|D z_81{R^S3*UkiC}u*q10w^kvXTO3GY6RJ>M?2ZD$m;eWEI*Qlzh>Z^c&fWAH{QAE%B zNd+OR#}_#oY>WW%=)SzXJR%~Zo0}WZ^>A@UYpfXP(xY z8vDD;195S2a?#KP7Gsp@S3E>VM@MZQ53Z`Js*;ie;H`RlKLL)3gM$N_251+y)=8j% zBO)UF{Sn~>wcy}S#h+y<0393|+0ya=ni&_WI(^)g)zN;+e)F`;i>Md#b)OB(8{@w+ zp2(~nT+fSP5YJZFb^^&_+R{r)LlfA7g9-(Ph4Fsf=$*7w4G9kE)`-w1s?icKe^Qkb z5EZ4OrVen&M+)f@!otSG%g@gC>0Dj;>b!b+Fb}Q`=WC3B&W?57&;KqMB1rPT@bdCr z0hvBNuBfCWB_*}LzYkag+Oub1AE9d4wmLaExwN!Y zTTAQM`5TbRaSWP3=OIwD8g`?BivZrmbU5wd;cB_Cu+YTB#PjiHd!kTr8NAd+-^(&) za0uQR8yg$R95!(=F+i&_>bBlbm1=^50n6s-=*UCRn+^7t;Im^szm?jK?cr3L&!0`= zv5?`xRldf<1#6bZ=iaY_Q%@lWj#yT9cw%CrqeDo`aHc^uYS~5gQBEbFt1kIXXHzFOLdppPO@C`yCWP%d7^i-4Dz1`+`4kSQDhBschLRbq_{FVu!VahzFOi}QXR36cUn5IcJreE~-_aVM} zmcr{+*Us{Wg@BL{;M1xxStJc3TwD8kxWIL7t!f$%YNEcL6Ixm83b~(VwK;4S4!{7L0tNz- zzRfJ*zWYxSJHU#>^xnQ`Y9LfoIBj7)2FzFP)sH?>MFU(dEH94`%9N0lY;Z*8XV${! zcBD^~T57PPw#rOPPk-8-1m;*wjFN~5f=|cF^G8>vbVWQMjRISb@LOMD+LPBIDBoLorBAaL3okAxTCsJ1I(Fv42=I9d zV6^{s1n;S2Wo32UKztVRtvwPG?mukc_+X~SJbEbq{$@LUneydEE1R!P&k_KV!^OLn zY6!wVdhYwusF_#-(DjEFMS&Gm(DMCj!!CaCBL4_Ncg_Fqsfntsppa?;UBVwGMK zkc@Dw7><~s%}q`!g9TPp90yI>(7y)&c_kNEy+>E%l$ zDyV3@uP_1Z91vA-?=zaSCs>p?UX(EZ5j8YiKcP2VUvu*Ewl)Xi=~PS5Fj1GA%~|)| zoeuXK4(98QmRgz`8*hPn22fzP{iiE~xgtKJuI@67kmL3>EDS9vsUVPwI;d@BVmcfw zEWypVeeb?&6Mj*9t>u%Gv+?MDcc-Fn+boS7a3hJ89+P2zw6o*Fd-|dI+r#ZeVj3&g z^qQ^nDH5mkd!|=tL=m88%>$#=&#!Cw>CR1WaCdiiy*rHCabKXo9Ad&ldp~BYp1R2iVXJtk2 z`t4D9_A(FBdx$*p6EMb>mX@9#?~ZoH^DQkc6Q#Be7n?AN`Sy2rX{o48jEw9L=4t`b z0qbZ+@=JfrTSlGczkmO>ub+U{O3Z2!nv+9;8{+4FMuRQ!?c06OOKQ-Lii?X^h3W}c zjgh@ghSRiFR1ohTZOd+--|R;COjA<^{+srqqGBT`Ehq@=(EHuh?c(hG%^V$o96mn2 zmTD=wy4&TS*|<2|At7Y%x}zB#C9QLyg8;?{1|rutgEgqly)eEU7)<6US8o9?Ma4yV zBRUZ_GBT2sL;$siA8>VxV5 z&aUV6ab{%X^ZXz@h=hUyl+Y`W%0-9Uf1d7CzdMT|@b@`8D$^PLT3a9gj%Lf##58+1 zN0ejE`(pVCmFiRz1auB2FlRS3xQwoefRzCyb$fdY8UPyN`dqE0W}VgZmoLH60wEt7 z5kc(Tjp-d4DkUi?si+uTU+>%|tE8e*S6LbP;P`ld6aP-z!rEF|QZo6yHG%0yR|sB9 zGZ;(;s0fJV>p$ogqgf)8las(vfHmvEjDX6w|D31n@GZ7fRgI00S1%UPk7I~PNZT}=N`zV)XXM=cvLgs7`R62l|+}wO)zF{-@ktks5r%o9RO+j$_EGkC^WD~S3<8Y zF3>SC!PiZCU!-f>_3pmjUNcL}@tt#!c%aqw06z>6sqXG>3>Qrgdw4f~6Eiiljf+oY zku&8fqWSXt?K`Mq`QwF37UJT4-ROj@EG#PYx*gf4D=RCYNu{L`U0a))<`*T=0`V?K zv#+>2?A@W)+}vDeH495fKRr2_n~%A9U@S!yEt3x}*>bbX_`rZ=Ulb*<`aY7`f+ZS= zW03sx$!mUZXUE*kjMHw5+VlxHMgS8)39r*PJD;q9om|EL1vuh+)8&|3bf8%4J}-h7 z=yxb(B3D}kY#<>q5uIMQ!5}x!pXxq|)eS@I`tm@NU6~yK6p;GZD3r|1@`{qts+&m! zWuMFTBY2FodmE~^7qk{(ap4ofHmb%ufSH^Rf*7DZftI2lR<~Jh-SnIvuKKbn1f&k2 ze-C$8z+2e?so0mBU>rKYXz*UVAfu(V09T;AJpIQHC>^CbGAat_%(eSpbU@}bHh!R? z`LqcKyorCQg=9BeBEP3cTQnWK*EKu_X`pO|m%umJ=UD!T|3j=V1n~T?CW!``Bob`m zHVHEM|5LF4m#)_u#%IAw7Z7CH!1&JeUp@5)T`W#)Sy`EGWu}jhkJmeNav;I6(%U=! znih2UeSxnC@#3L{$h(WEw>myn1&!3*_->?=jDT&=- zk<<{#8jn=TC@I<9hOEdUukYfPyMF%$jz*g?pZBRG>j;P5)AMv*JIAF3mldDnFp^7T zh=!34h*Og`?G}p*z}Q@3P`x7_xn8j$`ZU<@jQvSuMMp=!I+*V2Tc#VzCX7C%C zm9-jB4-X{CBpX!7Ybe96^7PTRGQY9}8RmfL3P)wtBTW=8)KlF%$7y?e&v zcs{e%-u2?eiwBiAkISp$`Le99LVq}ro^1~w{hR_UWM$e5IH*90f=H6r?FtyQK<_w^ z?g5cJVs;K(PshW#pbkA0R8&*9;WQ4Le@qKRP{47ntF2X6*MNZxK6h!gc`Q2nRz_Av zwzct3f5i={Jt}tx=_NLb@%{Blrhewy+S->?k4KLyg~Q3|X-3`3h2>>p2n!#-0Xz^C zKLv|9Xw#sfYH2=3ZWBzII;)p^*T)b4P@@uC*dc~CN<Hrl%tDgkNS)HA08f7R#w6} z9Bm&32xX3#)ugvAM|O(gGU}9+mt&S2xMg-U_N;yZ3!odXBV{k8r1nNhMs=5WULd}Y? z7SB6l+*F46gT2|he;Bz~_(H8){P*u2(+A+wAY^0)#>NPmPo>&Tjz9(gD)jI=+kwm*O**;bdQq9N+Kq7oY$>+0$Xc@_23&fFnf z3URyc)8K~iIvp;w#JFiWzMpaUCD?ClWHe(ce^k6|Sg8iO`V6lHN!@>L0IAv7?8m#M zPPew@$)uvpn_*znf)jy;OsFFinz z5dlRxzPtn`R+HP+yO6FA&c`IUA)ERE*W&`)B;3^V%foF=`Aq>}*O%<4Sl#9$za#$c zX;ZuPlU-h(SWFBU?$2z4MzcjhJ4Pqu_~M|L%wi0b6Nh9bR7wSEP z!PJUXj=C{IyrKuVULad5?a_dP6b^I0)h$d<|12u%pY3b-`Ez<`=p8*zs2E*15mzG^ z#h{7?vbfD=nU8P&v4`06{>bymCm!?7hZ@hP$6Cv2u$h+XZ4Ed3V>dT9fwu-U7XQNr z5n95ssj+bw5wGiPmGL6)zdxYvfg!Pc`dV-1CKsO&zh@zMbaeFjdANUy?EToWdz+xQ z*!>t37#yr1uZ*w8*KP5~{%Yr^!Drq9=Wd72$zqi=Pu)4Zn_SYXwt!_3a(F9i zE8U|mKV~Qrl!0-fYh1Lv{eTD}54TYt{ert`V3|0fAPW!cU6Fb+`llW~_mF5E$QXkA zXF9LNcgKR`|2*G#;AVRA475G8-;7~Mou#I}S8D{`Og{ggZudu$Wli@fQe^>?bY$dj zEa#1~vXWQl=l51KV8lSU)e;__@A(AJcGm#jEY~bo16M=&SKZB)ez(+k-5Xv(%DHu3-IQ*WEJVy>hh(6{Znb#rY@r@W z+Bv$nkB^(18w>>WY&4b3*yJetdzPhU^E0^%%wJa`D~-f7u0)LyK|%i}h;joZLB)Yu zFDmjvfB|io&PA~bc#~ZrxIok}CrY*5cmQEgex}>A7|wk%{OoeM6C^&5Tqm+Z2Hv${ z4xc_Dn+^gCb9*RVQC_~U_Yct6oKBAm?JY+$t?P?TPUbu2j5@6a#iiW#$5@cwRT(hC zmOx}*WmmO*^M~-)JE7}vWR)u|kzwI0ut$M!%*4$6eOYulln8h%z*UBU94{Tor9^o= z?yrHW2J;q{!c(AI0B?y{H{JIdo^xq@{N;OARAl5&G7^tj#Mq#;0WF=cGDh9Es{K0I ze|-%;0uuT0o9YRmR2U&$z%28uBl0DN6&yTr2}}#9ZjUR~e5c)9V{j8pE*1fre$reL zFt}&Na3C;LF+RHVT`2RzhY#K1_^5beW^71ENY3h_Du_B*cz6LM1q}^}2ZNXDdct)4 z{QTF$QGG_g-gkjXrllsQa==BKo4vLS5+qb@d~V5Uv==^|wZ z|6cR>yAKlZdjVp(9*+nPCH(m#<>GSlov-{qDD0eBRu|r90XMdtlaCYX5l`yVU1A&^=d<)>{@o{luW;O12S76}kgntGOVtN%CA3qIj zY`x<4#>U3;b9+cYNJvOilMr4I>`4fE92~>)XN8^MjgU-i{s|yGteME=>G9zVYz!{9 zEugxObCa{h!dVif*a+Nj`Zra}brO>j2>ue@*KPeA8j^ADRM)9iDb+HzGP*CjUu=E2 zZ%nG3{offq0z^Sg9Z~%zKfm~=L053w)72H;0|P0VrvDNn`eSQdeNIA8u9Pw5Ch1eF zFd+~ue9xdhH@U}Agx=A_a_NO-u3u{$EbVkyi~Njc%wwCtSD@!NBKOS{PmkRT$1m^ zv|0gpdp2KuMNXG%aJ{fFFj$+dHobZF{yj^00}ilT&m8Uu_%Ns7k&yQO{-xJ$Ja?l$ zy+A{4W8)#x1=f_#zX#U8X8yYI34F>$_RF{#8$B+!@6A~s(D|S-w?25>Y`b0jVKS}1 z&W+>;@f;Si5evRg$9?OKlgw2Wpr5>MmkUi!!~J9Z?v30~`%LfkNT%>RMQxLzglEu9 zwP^$Z4=_L(9j$0$LKSgtVQIl@>S|G7Sug8kV`T*oVdLT^B_;u zK`@;cmMr=zVq|>M&d$z9dSb@N*jT&KKB&b-O>KrP-aHOBZhJU=yKxyL3Sb&%cW=i= ztqtb!+0p+nqbfa@Ioa7APILM`%zfA*9|T#$t@vqe?fOAaI-dgpG%_>8X*%@Uo%g}~ z-MG+I!0q6bA@$jGx~Fs+n+ph_ATQ0IpVcF3r$(o2Q@4_yJ`k6QDT~xLG~ny#067Eb z0|c24r(9f}VWOZUvDrqImNGOE0$=gXo7d>)=m7kWLqdc6sXGT4!=k?*8iQg1Sxg#} zzL2Pi=$}$Pq*?EK@0t1;z+xe<#KhUo08GiHnCm}h>dnr~5zGD&!NGHPJxllA-=2vF zkq1Py`vI{8<}EnDph(ZhfPjGQtu0un&Uz8B^vmPX&aAbpH{6cLpIS3B1;yoe9PbbQ zCj12hBtL6v&_aO;7n6{1O~0=0=y(b2H5kBkt(PlX3hMuYzz}c{K)u0Ob8xUOoQHO; zt8!m*6llUg2v=Da6ci+YsAViy(o_4I4$=cK0FJ_?{7fc=2Y3lR%YoKrW+1$2vAY^d z<8=!T3GviC)4cwE9K}HiRQBWJBgkCDhWS12ox6f@oT3lQbbmfx4Yt8SW^8l6bn$L) zZg6mMhEh2=9vyii20fAe<8=v=I~E2IUmROP1dCUk&A`J;NO%P=2u4cI?XP0u<1tm9 z_PMG7jEhr5#mD2#qv3~i-Co~95Qu-Yw6#GrxMS~XWVBItFb|x1FmVDf%J~oeCyFuf zG#CgZ#9)}9t4qr&JsyGKB@RyPj~{A{_B*8snh*pMMGzQf%h9+XxPa!6FPjbvW!Z>= z0gtBodN3Lam?Ri7aXtgW&3W*24$RZ0G=R^|vk@EsJz3$90_JSAkU<)Fe}6Xw56UDZ zH5J5o@-#|%dL*fW+wM#?m6gm)Ob|2^@pE{1*tAj&*q9JR|8Lyp3kavRUwfMUuS@XD z9K+#ctqXv2ZCy>)=wHx$z^!8!fU7?qF!p05{NjO{_)_260z7Uo66|De4+0F}26-d_ zqB<+xX;9fRvGko8EUi1LL~w=O0Vo?VTM(C;iVpofJglpzfS`%VY1_q}!Gh!@jih(u zw>5j-D^CzDs^k`roqv>Ng@6$H3XHv&qcE2}_xO+9#w{3`T* z`sU~7#jkdDoq9}QvWwek-wLFqVC{5UH+Wee>BS<54)*u0EG@Y`?(666IXJDA*_G*W z!AuKq;R8B>f8lw&(g8+y>2Zr&T2if%1G+P0Q#ePLmRe0N2*6}fmjShO5;g&WMD{4i zEuUIW8K+Yl>+30~DNRjGzz7o%hFNknbaelwyCa`lQEIDbfT1=+B6DC4Hx?J8VtCwL zG90ZCd$0bDN9>$zu>v-M5epbQZ#VZ=Y`X?3oQs>Ao0Ajl*?!lw+?<^ATrNq_+4QR!l+3@k{@#R+QyZEVDOjFZ;%ciNWflo-ts8x>zVO71`SeUi@ zT=p3T750y4QindU;qqlt=ZG71#WYR98@sr;>=RU|fw2u!P-s)-n!^T_myeY{8yn|l zdYxCxQ5Sg^NZI0B*_oJ-(b2Ulzxe^T4eY;d#*~0z1;_mb+vD~Qz*s@1onE(Y<&qQD zWgwf%R|_&Q0A5G4Ej=BhtNfRpPTSijl6MiHlMG#^rA8;8wY#dysrch%9~acABy7CB zz5U9`wU-wJPW&i!G@@g89S9A}$m#1)HYTR)=hR%;qG4;diV$+M;9=W;f574Y5t!x=pcBzAH(vE)L)H9T>rar4H!9?mj?oDHR|MYT@v`7c2%1j8}KpPc(x#a08`E3 z#Qa0#q5?VwfEa;M##4_n*zcb3k6K*Q+og!}64KfXA3hN13=Ix$>U**Nc)H%$V-izP z_&PAfu*@Bj9)oB*Fg8LUB+~h}W?4?Tw0t7@vl_lSq#b7fj2g-NhX4qeIefvE)XuY3M39@BW39nXpizL;TcX)k zwjtdIx)m;?#=_K8cf&YHo&nv?%gqP92z+cqSu`$w+4$?%s-`A4LH&;4SUQh~3sn?9 z7H~?K@m0V>11{B4c$@piaU@Xfub;M^r$S1A&o`r4sfUGB>j8#BdVc@rk#SD}V;oT_ zu+U74<6XV=$(zDfGq@$bQ@0=CTm?RuoQH_*D__H=XL_SSXgl@tik zd#0&L`CxR|P4-{Sh}tlnRs2mJ1+HE)r!5)OKD6}Nw=dA+{i}~;l}$}eAiomLE-WbM z?e9PRH2mj}6)+JX$i~KonYj`SMszg)cCL>>c=rtZ<;#B`LIBk0%NIG2!^FjbVGxhh zCjzv!jHw7++4!A?xU z^Rob;_g})MEqBxm0|VojWuDO*9PEE7AUa99Yin6qS+P56B5|MtEj={P?zWccXlbdW zlWI(lh`{l6jIEzj`0x&YqIjXo$V~Lkcz@iUhiJHAVR8`x(N=CR0BDwGug*0+!#W@b z|F6oaB!y(2$vk8T+qlg#WyqLq zO2|BHv5ouOzHgng&N}O??|i3!>_u67c;Dx_?(6zpPb(l9d+IdNXc<$(fOqfOAHkCv zuRXS>vfumZ(NPIKV_dNVV zgxupvdqg~8mdvetV*Wz&+-DNk1n`;j(T`yRxp3ja;>%K%VRJ9`z7HIdflZIQpfMvj z&2d9ND?6J*(lMyj6!-%3xsPeS3ch=lnN(*RdISYT`9;AA4OKFY3}O`vl;`sG_t(z4 z$N28Pfk8(pt%*pKOO(HV3%r)FWp0>|S>Hz_Bz%`K_T}a0?`Um>_ZpG{klQk9r#n>m zFG^mVvp$JT06zsQ6vR9}E^klFXl?3YBr@G2fDtGyy-MLdK}vz6d{akY#K(ErxsQ!l zK7G2uC!5+6`NaT&z~Zd8yvR*mU8j*vE7EH?5SB?voY3}wWXp+WtG-?ic@3d5tk;f9 zxDxw0Eh&y0mVKF|$7o(y_Ye1!TaQ)%_D|uxxU>|>ZwOa&pH3%7om7i`~?DxLGNvTrMp|PTkQYf#x z9+&>-gOFW76#n0=BiWkDEvTnqMahg!9}v4v$4g(;<)g1VIwCaEv?C> zCNUvD!KTHw&Z+Bpb27^EMd_sNeQ6`*(!0&aN$Cvr6nFxY_dQ(?{* zHIyzFc8!K46eH{?T_tkZMcleu8p|EWv=8@+;ve= zQ6An)qaU!qm@Ns78AHPkIH!fdyx{lmAP=>+v6&U+m1Vx<2a+__)^Q461%jjsD2@b| zd2TMUAe;w|Zs6R1`os{bgrcNm#hiL85BCl5Pq&jbz>%ujYQk>o{g=J(b#th|_SW8# z^N``Of02I|{5U?Sv!UX=83zYx0N@Nr*souYVG8<({|{C(D0bin2y>U;2+F;#AWC3G zuij0RiN9_#!-Lnl?BfUI7Pl6oU_m?)VN7z1$EL_{#x+Wrm|GOr3#)5;9vDuZ0 zw6hCz7bYeVUTINh*ME8Z1W(sl4x0N1#I?H(sMM${m&5M`8$4EumQOi9r5`xdnZ}y3 zqxEK}B$OfiQ=fHNN#4Cn`fPcZpOuw%?r_i5>%5UG{a6`=d)zEOyLTYIZ+6j%H8QRX z|3xHm+hA-(L@;r?!}j|EDFS%F0f?1V!rY?dV_JDZYkYjm%p zsVOZtx8tML@W4RnqdIRJ?81|y{dSDi>$f&&p!UKO2*m;g1z9G}H9X61nzS21Xky`Y zB@6qO?Q7bwp2f)KSv;T#Ho!%}-Uo!8fL@WQkfK-6D;W{2D1$;neSKRy%za?$9vLS? z_1+BW=`^2-R7}&-*3$Bmr2J-1Q$^&ElTTVcD^E86?>;bMeG_mKD@sAflI!q&3fwol zBD;hcsZRHp*vQz(#I42c;@P8JRFqVKXaqG4sC)}@UQut|8pujcg9kYFGke^ z{XOgtoSD8Gt-jd$V}O46Fgq_zU`&>dOb=@)zwV1DRkf4r!{Ny~7GQQBiq{F>mF<4>zA zo2YFD#Xuu~q2IyPhC5?nY%H6sk)EX{2|`&@v*+)^;1L9>rP%#VHnhmuvvm&d`H;H68j_$jHW zi3y7q6_?PTIJCMaD;w5KXq56IxWrMxAUJFI7CUX&a=k#$3fM^Ef+dXxS97^ zov2|(Z>Hw>4_n#p`+tCS?|l@ zBvQfl3y@?{Rsj({5fMImr}{g0?{2OAE#F)y38P0;WWpO7ZwzJ>u9Tj zA8`~Z!4Yk2Y_5_^SHoHx^N13tif6O=kT1J#tw?*UV=A(DAkK7d06yP&*O~Zt&*jN$wu{MQ6OMk+ z)&?93el4)70KxCS^zqrK)gT0HGzqGq(KT6FcQ|PSl(G5wAL<@$xNCs=oGeU9`885z zbK?S>I3+%8OE>~t9DbX93_3lKDcd?YH2w8Y;ZX?m#`YTyft;gr<$B?I8fSP6(J<7O z2Ec(jBP~07{#)odaIOd{P-cel;@Y*c`D{xj^GJ}6kz$vR99doabwv1&%mjS;v0~2{ z!>iq=Dn) z{#0TjTI+K>1f5^MLh~?EA@8W`%-%L0+<2cj5RJM<|nk>=BN3b zoSZu6Vt^ZhV8J13&gsVy1d2|;kk!X_&uz@i%s^0aToQ=c23^+UO!P6Vu>i3n2sm39 z;&4vnmp2FI_Aaj=Awe!PzNLmT{@kBG7?T!ioO%I-6NBOXyE9wxd_`GLAhc)B1Tz(x z75}l{@yaBHx0u8W*-D?zojDDhWqer%sHYk|JT2X;vveU(_Nx@BE7JNYPk zjVla&?>d;^Tmgw8$vu464e4vM;&vE=%Ol=PeJoyM2LSEhyNYyKg4R-d5ev0u+s756%t&_{GB0^F)X|P=f?bu=A zgP@6&BSms=e-9?rrm>|=^X^2xm35b#<%a-C3YHm;4GlR%o&=@Vy{f(H-A%C1$*k+x zUpA6>b4p7s6I`Ix+%4FCoZ>rNbGx)B-k#^>ZG9w^o0n&Dw;4P?YR{mZn|)r;Z$xTA z#-nDLE!74gMuZ8$IS2E@7M>e?!c;SYwOB^bp%37!#2AU#&hKq)^*JsWSD4g>z7&9p zgC5|-%W_zl=VE^3MLgKo#x>a$f&w($OKgHVa)m?%#(#LS!Qa=+3=|3c%KA2&u_`_5 zVuNQD5n-ue-PrR0`Fchis8&ZGqdCnm@EkhZ7~|9ddx2_}S5SH(I6cJ8iEj}rc6YaP zankz>e< zrTG$AhKpyvGZMAkCTFRj1c1EOD?WS`)jS@P9kycy#y;KG4qGxXB({C~rg8uNVdF#U zmJCtPqvI{}WMT-9YyFn^_3QBWL*v6bp)G#es#oyN;b7I?6)WK|4*?>Az{oRltF$Hl zZTt6D#;;UwI4(lhfx_E#)^uFC{ICAH&5ivHdUV3akB^ISGcI*@KEvcWI{6J`J9olyR&oPvd{%DX6fw65d>JK!zxYn?iM8_6;NIb;S9SkXWrJr z6|r#Ak0iAw8BNfFZi`&96m+i2%k@A7z;PeQD!wTZ7}01|IM8nWcPl^@2m&=uxF%1& z{d$01(1&pb>+ybT;?EzY3|Op4ye5L#JVAu|s&e0rmv9g>cbM(T67GZ41l$%=VLjb4 zCK}V*7h5bWe|$4tkEj*kEz^Rj=&)=HXFWVFgfL^!$Wwrq_ieE2{?>x5zE9@8`8UVu zrK+XApvwcd9>E_A3#dQBy*>4^d`xBx?BJfBwf=Tp%%ri?o#U__^b8D;BT)jPt}qPw z8Q;590v}XC0jMFszyfzH>Ee=C>E_-UJ&b&@fU##aBz%tE2kixWZtLgI8{;p)oAP^Z9YeLLoDtsQDgI$MFgzjxaz7yK!Bzqv7pVnB zTGh z@}yw3$KMKQ$&L7o7Y#pWVTp#7?a(kvPbWu0K7D$#Vl2xYmKX7mJwO6T`|O--6OW+6 z-THidcl?}+Ry;2c&$rgrIw4hcb?e2U!tQGZ-!usIj_3ua!8XXuT3XC;7~3Bu={B1q zP~yTR*VFXefKMrf2RdW$rW{2GFPkDu97?{Qo&{Y3Q5*nDwwsGU+(*DB9(IqrGwwRQ z(VCOlN=-FTA1aK3$vscg@oFmQNc+q~7Xfo2q-&P%5-*3e<2^;iW*ly>V$z}bsF`w` z@;hSjgRkq9yQcuXg#Zf7r=A<~q;O2;43KuZZsl@7GdcO?zv!d~Y;rnQK;*BP7SE^t zxPI_t=i0XyO|;mbT3dqh;OFB5*#?F{0y@FnLV-*%7{-~2!*S*_Q_|sN6XZwizs0$K z^xqzb{@2;*v**_Mvu74GTBm8hY4p;J>gwFz+&j%gwqA}5UZ>?EaiBTNrLpxdAN2kp zK64%Q+qBDQxLP4JuBk{fa(?S&qBj_a7#|j1Ks7HIs?Tds;Mv9OqrZfp?Z;j41wAJ^ zA~|o4dXoJgUr@ozM@i~H;zFAZ3fqUX5a8UP#N0f)LPA2I)&z7kDT1zXo12&@upX5# zG8(U=NEIP%--6f%TK=BI{cFK3U_awmSDC98d_e4j*aE8L@thieqF`iu{1p>LN5`u* zle|bR;F~|cTEH0|qheQ}#`5mnf&&ww&cyk!ucCK&jz|Z~i4*UkYC_oFzOSnbL=7pT z!O$dxk_`crAopR3C0ONPCovaUSRka+Gcyw6;?IA61>XSf%c~HE$;gaB#Zai86nVt# zmy(H54|uRsCrS4{TTu3wWVYwdA5s%$dm``<;3|WIew-eT5dsxjv%4%w?O*J;ba?2_ z-Y1C8IzY|C20B{daLdJ!TxbAl$6#2wySc4KLUJo6EG$R+8SGYZaZF|=2$$Z0fvf!d zs#;n_1qI#kPn(*iJ&C*HAo8zS{rvsw7YQ=4<_wkrmUtkU*frSOTj9LMT56? z#*?cdX&1cnq6hpiRT$5blaoVa4WA{P9>MH)iiyb%&ZN9?12V6(2`6_XPkVFHa7eAL zug@15D=7uk)Oe_=z0b*60MQA7wk88yPwe1j99EPrU5en>D+140BEAN?xIm(UX9D!< z6r3*Lf^TkUm;x>YR6Y1B(CkoFQ-hS?+>4r)GT9ZaEl9i!&Cccq8$W=(4e}O%B%yGCz+`BA-n-QAZFPk?bxYOr_H#?? zlN4m45_xvF#2m!H@ktI;4pirh=P;8oD0y|to9o`CzwM`txOjv;>Ye*rv%#$AXIy}~ z4EFrKTNgW7`1 zs?k&AHI$AjT`}i)dJP#7M2ZS^SW-1@ZsX*shf7l|W@N7>S~<<*)jequ6khthV!LO= zc(VEBNR`x{)#K1@Wo^Ory5Fg*tQ@GyJvcCsot5R_oReK-IbP!q z5DoHrU_b}@sbsPm4B-&|<{$a?(G<=1rKTpKWeTj&fDh>VdJe=fcf9WmK?NFHL)`(K z6n>AHB~A`r2byyoG~}QCCbLy@9Y>Mmjrzg?yB) zQ%nMOxhD!~>jat`L`cu>85woObk^U{MQ%QQ`locl>d;)3q=#JP;wE#239=0q^%qFqzeE7cRZma2fQ=;J59qc)S<9n4H2(veru&}UJuNH_|*pg@+ zQ<9Qu&5F-$D%w-nkmcL0sxwofCVS(!6lAY3$c8L$iH3zC2uaxC{}E6GP{1F52XzZQ zUNj8RKE{Vh4lTd6YdMjFg$(Y_4#t>m>&-(^*Vi@Q5xyd7Ks5>RyWPdi zoA#gJU;}XP*g2H#^g`wE7MS~m7axQF2Q9(kqN1AZ89>pX(Ex7<5N$Akfp@)n9c|AW z#7R*r!~el5*NR%69lF%dY;3w(TPN|`D!CCjSO~?$?sL+vZtwZioEhlvKTGuV@Vhep z-Cl{3=49eZWhcp=bd7Y^+S!iv)hd z4G)DS*o%G6ms1BFANu`DXotTn9fj21z92td>A7<7DNEarGr-umcx8rq%e=wOKOw1> zGqqe1c8A9+<#sh%=gGjCIN0fHec+r}f4kPrpLy-TU{10j$yJ;F$MRSkCi3j&xGPOCU>d*wNrZFkiT*fTqT_e4BA*)mzB@wJZ79)@pkhR;5|a3m+|hr9QI~n2 zB;QVkWJZNHY5B%~`|_%1|9e6Ft&`14N8o3#Dm-Ysg1F_sjNeMU2@_|9KP_FR>pvfa z2ItRCPCnat}^^I6}f=c|cPv9#vvhNeP!Hg4|J1 Km(Q1b2C# literal 25365 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 LhHAdDMbN(i*6NoX diff --git a/doc/salome/gui/GHS3DPRLPLUGIN/input/ghs3dprl_hypo.doc b/doc/salome/gui/GHS3DPRLPLUGIN/input/ghs3dprl_hypo.doc index 83fe233..f70161d 100644 --- a/doc/salome/gui/GHS3DPRLPLUGIN/input/ghs3dprl_hypo.doc +++ b/doc/salome/gui/GHS3DPRLPLUGIN/input/ghs3dprl_hypo.doc @@ -2,18 +2,17 @@ \page ghs3dprl_hypo_page GHS3DPRL Parameters hypothesis -\n GHS3DPRL Parameters hypothesis works only with Tetrahedron (Tepal with TetMesh-GHS3D) algorithm. -This algorithm is a commercial software, its use requires a licence (http://www.distene.com/fr/build/offer.html). -\n Tepal_V1.4 gives the possibility to generate a partitioned -mesh with 200 million tetrahedrons on a computer with average memory size -(2Go RAM) in about 50 hours on one CPU (Xeon, 2008). -\n New Tepal_V2.0 gives the possibility to generate a partitioned mesh with (for the moment) no more than 100 million -tetrahedrons on computers using MPI, (Total 16 Go RAM) -in about 900 seconds (!yes! : !seconds!) on 2 octo processors (Xeon, 2009). -The launch of this beta-version is described below. +\n GHS3DPRL Parameters hypothesis works only with Tetrahedron and code tetra_hpc (formerly tepal) +which is the parallel implementation of MeshGems-Tetra (formerly TetMesh-GHS3D) algorithm. +This algorithm is a DISTENE commercial software, its use requires a licence. +\n +See http://www.distene.com and http://www.meshgems.com/volume-meshing-meshgems-tetra.html. +\n tetra_hpc (Tepal V3 in fact) gives the possibility to generate a partitioned +mesh with more than 200 million tetrahedrons on computers using MPI. +The launch of this version is described below. \n This is a serious alternative to GHS3D, which requires a much less common configuration with 64Go RAM to only try to make a partition of a mesh with -200 million tetrahedrons, no result guaranteed. +200 million tetrahedrons, no result guaranteed (2010). \n \note The Plugin doesn't load in the Memory the supposedly large resulting meshes. The meshes are saved in MED files and can be imported in the user-defined location via menu File-Import-MED Files. @@ -44,269 +43,174 @@ in Nb_Part by the elementary algorithm implemented in Tepal.
background mode was not used).
  • -Tepal_in_Background - if this box is checked, Tepal execution +Tetra_hpc in Background - if this box is checked, Tetra_hpc execution and MED file generation are launched in background mode and the user can even exit Salome. Pay attention that in this case Tepal algorithm works independently of "killSalome.py", and sometimes on another host.
  • -To_Mesh_Holes - if this box is checked, the parameter component -of tetmesh-ghs3d will mesh holes. +merge subdomains - if this box is checked, merge the subdomains +into one mesh and write the output .mesh(b). +
  • +
  • +tag subdomains - if this box is checked, use the parallel subdomain +index as tag into the merged output mesh or not (used in combination with the +merge_subdomains option). +
  • +
  • +output interfaces - if this box is checked, write the parallel subdomains interface +triangles into the merged output mesh (used in combination with the merge_subdomains option). +
  • +
  • +discard subdomains - if this box is checked, discard the parallel subdomains +(mesh, global numbering and interfaces).
  • Modifying GHS3DPRL Advanced Parameters


    -GHS3DPRL Plugin launches a standalone binary executable tepal2med.
    -tepal2med launches tepal, waits for the end of computation, and +GHS3DPRL Plugin launches a standalone binary executable tetrahpc2med.
    +tetrahpc2med launches tetra_hpc, waits for the end of computation, and converts the resulting output tepal files into MED files.
    -Some advanced optional parameters are accessible as arguments.
    -If keep_files option is checked, it is possible to re-launch tepal2med -or tepal in the Terminal as a command with custom parameters.
    +If keep_files option is checked, it is possible to re-launch tetrahpc2med +or tetra_hpcl in the Terminal as a command with custom parameters.
  • -Advanced tepal2med Parameters - type "tepal2med --help" in the Terminal.

    +Advanced tetrahpc2med Parameters - type tetrahpc2med --help in the Terminal.

    \verbatim -myname@myhost > /export/home/myname/salome_5/GHS3DPRLPLUGIN_5/bin/salome/tepal2med --help -Available options: - --help : produces this help message - --casename : path and name of input tepal2med files which are - - output files of tepal .msg .noboite .faces .points .glo - - output file of GHS3DPRL_Plugin casename_skin.med (optional) - with initial skin and its initial groups - --number : number of partitions - --medname : path and name of output MED files - --limitswap : max size of working cpu memory (Mo) (before swapping on .temp files) - --verbose : trace of execution (0->6) - --test : more tests about joints, before generation of output files - --menu : a GUI menu for option number - --launchtepal : also launch tepal on files casename.faces and casename.points and option number - --meshholes : force parameter component of tetmesh-ghs3d to mesh holes - --background : force background mode from launch tepal and generation of final MED files (big meshes) - --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files - (try --deletegroups="(\bAll_Nodes|\bAll_Faces)" - (try --deletegroups="((\bAll_|\bNew_)(N|F|T))" +myname@myhost > /export/home/myname/salome_7/GHS3DPRLPLUGIN/bin/salome/tetrahpc2med --help +tetrahpc2med V3.0 (MED3+tetra-hpc) Available options: + --help : produces this help message + --casename : path and name of input tetrahpc2med files which are + - output files of GHS3DPRL_Plugin .mesh + - output file of GHS3DPRL_Plugin casename_skin.med (optional) + with initial skin and its initial groups + --number : number of partitions + --medname : path and name of output MED files + --limitswap : max size of working cpu memory (Mo) (before swapping on .temp files) + --verbose : trace of execution (0->6) + --test : more tests about joints, before generation of output files + --menu : a GUI menu for option number + --launchtetra : also launch tetra-hpc on files casename.mesh and option number + --merge_subdomains : merge the subdomains into one mesh and write the output .mesh(b) file + --tag_subdomains : use the parallel subdomain index as tag into the merged output mesh + to identify the parallel subdomains (used in combination with the merge_subdomains option) + --output_interfaces : write the parallel subdomains interface triangles into the merged output mesh + (used in combination with the merge_subdomains option) + --discard_subdomains : discard the parallel subdomains informations output (mesh, global numbering and interfaces) + --background : force background mode from launch tetra-hpc and generation of final MED files (big meshes) + --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files + (try --deletegroups="(\bJOINT)" + (try --deletegroups="(\bAll_Nodes|\bAll_Faces)" + (try --deletegroups="((\bAll_|\bNew_)(N|F|T))" example: - tepal2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN --limitswap=1000 - --verbose=0 --test=yes --menu=no --launchtepal=no + tetrahpcl2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN --limitswap=1000 --verbose=0 --test=yes --menu=no --launchtetra=no \endverbatim \n

  • -Advanced Tepal_V1.4 Parameters

    +Advanced tetra_hpc parameters (2014)

    \verbatim -USAGE : tepal options - -With options : - --filename name (-f name) : - Prefix of the input case (MANDATORY) - - --ndom n (-n n) : - Number of subdomains to make (MANDATORY) - - --ghs3d ghs3d options (-g ghs3d options) : - Runs temesh ghs3d on a previously generated subdomain. (ghs3d options must be "quoted") - - --memory m (-m m) : - Max amount of memory (megabytes) allowed for ghs in the cutting process. (default is 0 : unlimited) - - --mesh_only (-Z ) : - Only (re)meshes all subdomains and updates communications messages - - --mesh_call command (-c command) : - Calls the user specified command for meshing all the - subomains after their skin has been generated - - --stats_only (-S ) : - Only computes and shows some statistics on subdomains - - --rebuild (-r ) : - Merges final subdomains skins - - --rebuild_tetra (-R ) : - Merges final subdomains skins and tetraedra - - --rebuild_iface (-i ) : - Includes interfaces in final subdomains merge - - --rebuild_retag (-t ) : - Tags vertices, faces (and tetra if selected) with their - subdomain number in the final merge of subdomains (keeps the lowest tag for shared elements) - - --rebuild_ensight_parts (-e ) : - Builds ensight geom file with parts - - --tetmesh_args str (-G str) : - Arguments to pass to Tetmesh during cutting process +Usage: tetra_hpc.exe [options] + +Options: + + Short option (if it exists) + / Long option + | / Description + | | / + v v v + + --help + print this help + + --in + Sets the input file + (MANDATORY) + + --out + Sets the output file + (MANDATORY) + + --merge_subdomains + Describes whether to merge the subdomains into one mesh and write the + output .mesh(b) file or not. + if is + yes : the subdomains will be merged into one mesh and written to + the output .mesh(b), + no : the subdomains will not be merged. + default : no + + --tag_subdomains + Describes whether to use the parallel subdomain index as tag into the + merged output mesh or not (used in combination with the + merge_subdomains option). + if is + yes : the tags of the tetrahedra in the merged output will + identify the parallel subdomains, + no : the tag will keep its standard meaning of volume domain. + default : no + + --output_interfaces + Describes whether to write the parallel subdomains interface + triangles into the merged output mesh or not (used in combination + with the merge_subdomains option). + if is + yes : the parallel subdomains interface triangles will be written + into the merged output mesh, + no : they will not be added to the merged output mesh. + default : no + + --verbose + Set the verbosity level, increasing from 0 to 10. + values are increasing from 0 to 10 : + 0 : no details + 10 : very detailed + default : 3 + + --discard_subdomains + Describes whether to discard the parallel subdomains (mesh, global + numbering and interfaces) or not. + if is + yes : the subdomain informations (mesh, global numbering and + interfaces) will be discarded, + no : they will be written to disk as output. + default : no \endverbatim \n

  • -
  • -Advanced ghs3d Parameters (through Tepal_V1.4's --tetmesh_args) - type "ghs3d -h" in a Terminal.

    -\verbatim -myname@myhost > ghs3d -h - -USE - /export/home/myname/ghs3d-4.0/DISTENE/Tools/TetMesh-GHS3D4.0/bin/Linux/ghs3dV4.0 - [-u] [-m memory>] [-M MEMORY] [-f prefix] [-v verbose] - [-c component] [-p0] [-C] [-E count] [-t] [-o level] - [-I filetype] [-a/-b] [-O n m] - -DESCRIPTION - - -u (-h) : prints this message. - - -m memory : launches the software with memory in Megabytes. - The default value of this parameter is 64 Megabytes and its - minimum value is 10 Megabytes. - It is also possible to set this parameter with the - environment variable GHS3D_MEMORY by means of an operation - equivalent to: - setenv GHS3D_MEMORY memory, - the value specified in the command line has the priority on - the environment variable. - - -M MEMORY : provides the automatic memory adjustment feature. - If MEMORY (in Megabytes) is equal to zero, the size of the work space is - calculated from the input. If MEMORY is not equal to - zero, the software starts with MEMORY amount of work space. - The software reallocates memory as necessary. - The start value of MEMORY can range from 0 to 64 Megabytes, - the maximum depends on -m option and the actual memory available. - - -f prefix : defines the generic prefix of the files. - - -v verbose : sets the output level parameter (the verbose parameter - must be in the range 0 to 10). - - -c component : chooses the meshed component. If the parameter is - 0, all components will be meshed, if - 1, only the main (outermost) component will be meshed - - -p0 : disables creation of internal points. - - -C : uses an alternative boundary recovery mechanism. It should be used only - when the standard boundary recovery fails. - - -E count : sets the extended output for error messages. If -E is used, - the error messages will be printed, it is possible - to indicate the maximum number of printed messages between 1 and 100. - - -t : generates an error file prefix.Log - - -o level : sets the required optimisation level. - Valid optimisation levels are: - none, light, standard or strong, - with increase of "quality vs speed" ratio. - - -I filetype : defines the input mesh format as follows: - -IP input files are ascii files, named prefix.points - and prefix.faces - this is the default type of files - -IPb input files are binary files, named prefix.pointsb - and prefix.facesb - -IM input file is ascii file, named prefix.mesh - where prefix is defined with -f option - - -a/-b : selects the output file type: - -a for ascii (the default) and - -b for binary. - - -On : saves a NOPO file in addition. NOPO is the mesh data - structure of the Simail and Modulef software packages. - -Om : saves a mesh file in addition. - -Omn : saves both NOPO and mesh files. - - ============================================================================== - TETMESH-GHS3D SOFTWARE 4.0-3 (December, 2006) - END OF SESSION - COPYRIGHT (C)1989-2006 INRIA ALL RIGHTS RESERVED - ============================================================================== - ( Distene SAS - Phone: +33(0)1-69-26-62-10 Fax: +33(0)1-69-26-90-33 - EMail: support@distene.com ) - -\endverbatim -\n -

  • Saving user's preferred GHS3DPRL Advanced Parameters


    -GHS3DPRL Plugin launches standalone binary executable tepal2med.
    -You may rename file tepal2med as tepal2med.exe for example, and replace -tepal2med by a shell script at your convenience to overriding parameters. -
    ... or else $PATH modification... .
    Idem for file tepal.

    +GHS3DPRL Plugin launches standalone binary executable tetrahpc2med.
    +You may rename file tetrahpc2med as tetrahpc2med.exe for example, and replace +tetrahpc2med by a shell script at your convenience to overriding parameters. +
    ... or else $PATH modification... .
  • -Advanced tepal2med Parameters - overriding parameter deletegroups

    -You may rename tepal2med as tepal2med.exe for example. +Advanced tetrahpc2med Parameters - overriding parameter deletegroups

    +You may rename tetrahpc2med as tetrahpc2med.exe for example. \code #!/bin/bash -#script tepal2med overriding parameter deletegroups -#we have renamed binary executable tepal2med as tepal2med.exe -#echo tepal2med initial parameters are $1 $2 $3 $4 ... or $* +#script tetrahpc2med overriding parameter deletegroups +#we have renamed binary executable tetrahpc2med as tetrahpc2med.exe +#echo tetrahpc2med initial parameters are $1 $2 $3 $4 ... or $* #$0 is ignored -tepal2med.exe $* --deletegroups="(\bAll_Nodes|\bAll_Faces)" - -\endcode -\n -

  • -
  • -Advanced Tepal_V1.4 Parameters - overriding parameter component of ghs3d (to mesh holes).

    -You may rename tepal as tepal.exe for example. - -\code -#!/bin/bash -#script tepal overriding parameter component of tetmesh-ghs3d -#we have renamed binary executable tepal as tepal.exe - -#optionnaly we could set licence only for us -DISTENE_LICENSE_FILE="Use global envvar: DLIM8VAR" -DLIM8VAR="dlim8 1:1:29030@is142356/0016175ef08c::a1ba1...etc...e19" -SIMULOGD_LICENSE_FILE=29029@is142356 - -tepal.exe $* --tetmesh_args "-c 0" - -\endcode -\n -

  • -
  • -Advanced tepal Parameters - overriding launching tepal on other host.

    -You may rename tepal as tepal.exe for example. - -\code -#!/bin/bash -#script tepal overriding launching tepal on other host (tepal run 64 bits only) -#we have renamed binary executable tepal as tepal.exe -#common file system (same path) otherwise scp... on input or result files -#ssh -keygen -t rsa done and files id_rsa et id-rsa.pub move in ~/.ssh - -#example of typical command -#tepal -f /home/myname/tmp/GHS3DPRL -n 4 > /home/myname/tmp/tepal.log -#echo parameters $1 $2 $3 $4 ... or $* - -#tepal licence ought to be known on otherhost -ssh otherhost "tepal.exe $* > /home/myname/tmp/tepal.log" - -#or more and more -#ssh otherhost "tepal.exe $* --tetmesh_args \"-c 0\"" > /home/myname/tmp/tepal.log +tetrahpc2med.exe $* --deletegroups="(\bAll_Nodes|\bAll_Faces)" \endcode \n

  • -

    Tepal_V2.0 and MPI use.


    -This all new beta-version needs MPI, (openmpi-1.3.1 was used). To use it you have to proceed -as done in "overriding parameter component of ghs3d". -Advanced ghs3d Parameters (through Tepal_V1.4's --tetmesh_args) are not assumed yet. -It meshes holes. -\n You may rename tepal as tepal64_v2.exe for example, and replace tepal by a shell script like below. +

    tetra_hpc and MPI use.


    +This 2014 beta-version needs MPI, (openmpi was used). To use it you have to proceed as below.
  • -example tepal_v2_mpirun.

    +Obsolete example tepal_v2_mpirun.

    \code @@ -444,8 +348,8 @@ algo2d.SetPhySize(5) algo2d.SetGeometricMesh(0) -# 3D mesh with tepal -# ------------------ +# 3D mesh with tetra-hpc (formerly tepal v3 (2014)) +# ---------------------------------------------------- algo3d = m.Tetrahedron(smeshBuilder.GHS3DPRL) @@ -453,7 +357,10 @@ algo3d.SetMEDName(results) algo3d.SetNbPart(4) algo3d.SetBackground(False) algo3d.SetKeepFiles(False) -algo3d.SetToMeshHoles(True) +algo3d.SetToMergeSubdomains(False) +algo3d.SetToTagSubdomains(False) +algo3d.SetToOutputInterfaces(False) +algo3d.SetToDiscardSubdomains(False) # Launch meshers # -------------- @@ -464,9 +371,9 @@ status = m.Compute() # ---------- if os.access(results+".xml", os.F_OK): - print "Ok: tepal" + print "Ok: tetra_hpc" else: - print "KO: tepal" + print "KO: tetra_hpc" \endcode \n

  • diff --git a/idl/GHS3DPRLPlugin_Algorithm.idl b/idl/GHS3DPRLPlugin_Algorithm.idl index 3d3f201..e961862 100755 --- a/idl/GHS3DPRLPlugin_Algorithm.idl +++ b/idl/GHS3DPRLPlugin_Algorithm.idl @@ -56,8 +56,20 @@ module GHS3DPRLPlugin void SetBackground(in boolean value); boolean GetBackground(); - void SetToMeshHoles(in boolean value); - boolean GetToMeshHoles(); + //void SetToMeshHoles(in boolean value); + //boolean GetToMeshHoles(); + + void SetToMergeSubdomains(in boolean value); + boolean GetToMergeSubdomains(); + + void SetToTagSubdomains(in boolean value); + boolean GetToTagSubdomains(); + + void SetToOutputInterfaces(in boolean value); + boolean GetToOutputInterfaces(); + + void SetToDiscardSubdomains(in boolean value); + boolean GetToDiscardSubdomains(); }; }; diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPluginBuilder.py b/src/GHS3DPRLPlugin/GHS3DPRLPluginBuilder.py index 245d6f5..ee2f34e 100644 --- a/src/GHS3DPRLPlugin/GHS3DPRLPluginBuilder.py +++ b/src/GHS3DPRLPlugin/GHS3DPRLPluginBuilder.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Copyright (C) 2007-2013 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or @@ -109,8 +110,32 @@ class GHS3DPRL_Algorithm(Mesh_Algorithm): ## To mesh "holes" in a solid or not. Default is to mesh. # @param toMesh "mesh holes" flag value - def SetToMeshHoles(self, toMesh): - self.Parameters().SetToMeshHoles(toMesh) + #def SetToMeshHoles(self, toMesh): + # self.Parameters().SetToMeshHoles(toMesh) + # pass + + ## To Merge Subdomains. Default is to no. + # @param toMesh "MergeSubdomains" flag value + def SetToMergeSubdomains(self, toMesh): + self.Parameters().SetToMergeSubdomains(toMesh) + pass + + ## To Tag Subdomains. Default is to no. + # @param toMesh "TagSubdomains" flag value + def SetToTagSubdomains(self, toMesh): + self.Parameters().SetToTagSubdomains(toMesh) + pass + + ## To Output Interfaces. Default is to no. + # @param toMesh "OutputInterfaces" flag value + def SetToOutputInterfaces(self, toMesh): + self.Parameters().SetToOutputInterfaces(toMesh) + pass + + ## To Discard Subdomains. Default is to no. + # @param toMesh "DiscardSubdomains" flag value + def SetToDiscardSubdomains(self, toMesh): + self.Parameters().SetToDiscardSubdomains(toMesh) pass pass # end of GHS3DPRL_Algorithm class diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx index 153fac7..96d723b 100755 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx @@ -407,7 +407,10 @@ void GHS3DPRLPlugin_GHS3DPRL::SetParameters(const GHS3DPRLPlugin_Hypothesis* hyp _NbPart = hyp->GetNbPart(); _KeepFiles = hyp->GetKeepFiles(); _Background = hyp->GetBackground(); - _ToMeshHoles = hyp->GetToMeshHoles(); + _ToMergeSubdomains = hyp->GetToMergeSubdomains(); + _ToTagSubdomains = hyp->GetToTagSubdomains(); + _ToOutputInterfaces = hyp->GetToOutputInterfaces(); + _ToDiscardSubdomains = hyp->GetToDiscardSubdomains(); } } @@ -440,9 +443,171 @@ static TCollection_AsciiString getTmpDir() } //============================================================================= -// Here we are going to use the GHS3DPRL mesher +// Here we are going to use the GHS3DPRL mesher for tetra-hpc (formerly tepal in v3 (2014)) bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape) +{ + bool Ok=false; + TCollection_AsciiString pluginerror("ghs3dprl: "); + SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); + //cout<<"GetMeshDS done\n"; + if (_countSubMesh==0){ + MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute for tetra-hpc"); + _countTotal=0; + TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID); + for ( ; expf.More(); expf.Next() ) _countTotal++; + } + _countSubMesh++; + //cout<<"Compute _countSubMesh "<<_countSubMesh<0) { + path=casenamemed.SubString(1,n); + casenamemed=casenamemed.SubString(n+1,casenamemed.Length()); + } + else + path=tmpDir; + + if (casenamemed.Length()>20){ + casenamemed=casenamemed.SubString(1,20); + cerr<<"MEDName truncated (no more 20 characters) = "< avoid warning message + //med_idt fid=MEDouvrir((const char *)fileskinmed.ToCString(),MED_CREATION); + //med_err ret=MEDfermer(fid); + //fileskinmed=fileskinmed + "cp /home/wambeke/empty.med "+ path + "GHS3DPRL_skin.med"; + //system( fileskinmed.ToCString() ); + fileskinmed=path + "GHS3DPRL_skin.med"; + cout<<"Write file "< 0) { - //Processus père + //Processus p�re cout<<"le pere est la\n"; system("echo le pere > lepere.tmp"); system("sleep 10"); @@ -601,7 +768,7 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, } else if (pid == 0) { //Processus fils cout<<"le fils est la\n"; - //On rend le fils indépendant de tout terminal + //On rend le fils ind�pendant de tout terminal setsid(); system("sleep 20"); system("echo le fils > lefils.tmp"); diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.hxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.hxx index d82fbfe..e93a908 100755 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.hxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.hxx @@ -40,17 +40,16 @@ public: GHS3DPRLPlugin_GHS3DPRL(int hypId, int studyId, SMESH_Gen* gen); virtual ~GHS3DPRLPlugin_GHS3DPRL(); - virtual bool CheckHypothesis(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus); void SetParameters(const GHS3DPRLPlugin_Hypothesis* hyp); - virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool ComputeForTepal(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); //obsolescent - virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - MapShapeNbElems& aResMap); + virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap); ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); @@ -68,7 +67,11 @@ private: int _NbPart; //number of partitions bool _KeepFiles; //tepal file .noboite binary or not bool _Background; //true for big meshes - bool _ToMeshHoles; + //ToMergeSubdomains ToTagSubdomains ToOutputInterfaces ToDiscardSubdomains + bool _ToMergeSubdomains; + bool _ToTagSubdomains; + bool _ToOutputInterfaces; + bool _ToDiscardSubdomains; }; #endif diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.cxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.cxx index 76b0e60..0cd578a 100755 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.cxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.cxx @@ -30,14 +30,16 @@ * */ //============================================================================= -GHS3DPRLPlugin_Hypothesis::GHS3DPRLPlugin_Hypothesis (int hypId, int studyId, - SMESH_Gen * gen) +GHS3DPRLPlugin_Hypothesis::GHS3DPRLPlugin_Hypothesis (int hypId, int studyId, SMESH_Gen * gen) : SMESH_Hypothesis(hypId, studyId, gen), _MEDName( GetDefaultMEDName() ), _NbPart( GetDefaultNbPart() ), _KeepFiles( GetDefaultKeepFiles() ), _Background( GetDefaultBackground() ), - _ToMeshHoles( GetDefaultToMeshHoles() ) + _ToMergeSubdomains( GetDefaultToMergeSubdomains() ), + _ToTagSubdomains( GetDefaultToTagSubdomains() ), + _ToOutputInterfaces( GetDefaultToOutputInterfaces() ), + _ToDiscardSubdomains( GetDefaultToDiscardSubdomains() ) { MESSAGE("GHS3DPRLPlugin_Hypothesis::GHS3DPRLPlugin_Hypothesis"); _name = "GHS3DPRL_Parameters"; @@ -114,11 +116,39 @@ void GHS3DPRLPlugin_Hypothesis::SetBackground(bool theVal) { } } -void GHS3DPRLPlugin_Hypothesis::SetToMeshHoles(bool theVal) { +/*void GHS3DPRLPlugin_Hypothesis::SetToMeshHoles(bool theVal) { if (theVal != _ToMeshHoles) { _ToMeshHoles = theVal; NotifySubMeshesHypothesisModification(); } +}*/ + +void GHS3DPRLPlugin_Hypothesis::SetToMergeSubdomains(bool theVal) { + if (theVal != _ToMergeSubdomains) { + _ToMergeSubdomains = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +void GHS3DPRLPlugin_Hypothesis::SetToTagSubdomains(bool theVal) { + if (theVal != _ToTagSubdomains) { + _ToTagSubdomains = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +void GHS3DPRLPlugin_Hypothesis::SetToOutputInterfaces(bool theVal) { + if (theVal != _ToOutputInterfaces) { + _ToOutputInterfaces = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +void GHS3DPRLPlugin_Hypothesis::SetToDiscardSubdomains(bool theVal) { + if (theVal != _ToDiscardSubdomains) { + _ToDiscardSubdomains = theVal; + NotifySubMeshesHypothesisModification(); + } } @@ -137,7 +167,11 @@ std::ostream& GHS3DPRLPlugin_Hypothesis::SaveTo(std::ostream& save) //save without any whitespaces! save<<"MEDName="<<_MEDName<<";"; save<<"NbPart="<<_NbPart<<";"; - save<<"ToMeshHoles="<<(int) _ToMeshHoles<<";"; + //save<<"ToMeshHoles="<<(int) _ToMeshHoles<<";"; + save<<"ToMergeSubdomains="<<(int) _ToMergeSubdomains<<";"; + save<<"ToTagSubdomains="<<(int) _ToTagSubdomains<<";"; + save<<"ToOutputInterfaces="<<(int) _ToOutputInterfaces<<";"; + save<<"ToDiscardSubdomains="<<(int) _ToDiscardSubdomains<<";"; save<<"KeepFiles="<<(int) _KeepFiles<<";"; save<<"Background="<<(int) _Background<<";"; return save; @@ -174,7 +208,11 @@ std::istream& GHS3DPRLPlugin_Hypothesis::LoadFrom(std::istream& load) if (str3=="MEDName") _MEDName = str4.c_str(); if (str3=="NbPart") _NbPart = atoi(str4.c_str()); if (str3=="KeepFiles") _KeepFiles = (bool) atoi(str4.c_str()); - if (str3=="ToMeshHoles") _ToMeshHoles = (bool) atoi(str4.c_str()); + //if (str3=="ToMeshHoles") _ToMeshHoles = (bool) atoi(str4.c_str()); + if (str3=="ToMergeSubdomains") _ToMergeSubdomains = (bool) atoi(str4.c_str()); + if (str3=="ToTagSubdomains") _ToTagSubdomains = (bool) atoi(str4.c_str()); + if (str3=="ToOutputInterfaces") _ToOutputInterfaces = (bool) atoi(str4.c_str()); + if (str3=="ToDiscardSubdomains") _ToDiscardSubdomains = (bool) atoi(str4.c_str()); if (str3=="Background") _Background = (bool) atoi(str4.c_str()); } return load; @@ -252,7 +290,31 @@ bool GHS3DPRLPlugin_Hypothesis::GetDefaultBackground() } //============================================================================= -bool GHS3DPRLPlugin_Hypothesis::GetDefaultToMeshHoles() +//bool GHS3DPRLPlugin_Hypothesis::GetDefaultToMeshHoles() +//{ +// return false; +//} + +//============================================================================= +bool GHS3DPRLPlugin_Hypothesis::GetDefaultToMergeSubdomains() +{ + return false; +} + +//============================================================================= +bool GHS3DPRLPlugin_Hypothesis::GetDefaultToTagSubdomains() +{ + return false; +} + +//============================================================================= +bool GHS3DPRLPlugin_Hypothesis::GetDefaultToOutputInterfaces() +{ + return false; +} + +//============================================================================= +bool GHS3DPRLPlugin_Hypothesis::GetDefaultToDiscardSubdomains() { return false; } diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx index 76f785d..a09e0c5 100755 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx @@ -50,9 +50,19 @@ public: void SetBackground(bool theVal); bool GetBackground() const { return _Background; } - - void SetToMeshHoles(bool theVal); - bool GetToMeshHoles() const { return _ToMeshHoles; } + + //ToMergeSubdomains ToTagSubdomains ToOutputInterfaces ToDiscardSubdomains + void SetToMergeSubdomains(bool theVal); + bool GetToMergeSubdomains() const { return _ToMergeSubdomains; } + + void SetToTagSubdomains(bool theVal); + bool GetToTagSubdomains() const { return _ToTagSubdomains; } + + void SetToOutputInterfaces(bool theVal); + bool GetToOutputInterfaces() const { return _ToOutputInterfaces; } + + void SetToDiscardSubdomains(bool theVal); + bool GetToDiscardSubdomains() const { return _ToDiscardSubdomains; } // the parameters default values @@ -60,7 +70,10 @@ public: static int GetDefaultNbPart(); static bool GetDefaultKeepFiles(); static bool GetDefaultBackground(); - static bool GetDefaultToMeshHoles(); + static bool GetDefaultToMergeSubdomains(); + static bool GetDefaultToTagSubdomains(); + static bool GetDefaultToOutputInterfaces(); + static bool GetDefaultToDiscardSubdomains(); // Persistence virtual std::ostream& SaveTo(std::ostream& save); @@ -90,7 +103,10 @@ private: int _NbPart; // number of partitions bool _KeepFiles; // keep intermediates tepal files or not bool _Background; // tepal in background - bool _ToMeshHoles; -}; + bool _ToMergeSubdomains; + bool _ToTagSubdomains; + bool _ToOutputInterfaces; + bool _ToDiscardSubdomains; + }; #endif diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.cxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.cxx index cf66c1b..1a3bac8 100755 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.cxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.cxx @@ -37,16 +37,11 @@ */ //============================================================================= GHS3DPRLPlugin_Hypothesis_i:: -GHS3DPRLPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl) - : SALOME::GenericObj_i( thePOA ), - SMESH_Hypothesis_i( thePOA ) +GHS3DPRLPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, int theStudyId, ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "GHS3DPRLPlugin_Hypothesis_i::GHS3DPRLPlugin_Hypothesis_i" ); - myBaseImpl = new ::GHS3DPRLPlugin_Hypothesis (theGenImpl->GetANewId(), - theStudyId, - theGenImpl); + myBaseImpl = new ::GHS3DPRLPlugin_Hypothesis (theGenImpl->GetANewId(), theStudyId, theGenImpl); } //============================================================================= @@ -67,7 +62,10 @@ GHS3DPRLPlugin_Hypothesis_i::~GHS3DPRLPlugin_Hypothesis_i() * GHS3DPRLPlugin_Hypothesis_i::SetNbPart * GHS3DPRLPlugin_Hypothesis_i::SetKeepFiles * GHS3DPRLPlugin_Hypothesis_i::SetBackground - * GHS3DPRLPlugin_Hypothesis_i::SetToMeshHoles + * GHS3DPRLPlugin_Hypothesis_i::SetToMergeSubdomains + * GHS3DPRLPlugin_Hypothesis_i::SetToTagSubdomains + * GHS3DPRLPlugin_Hypothesis_i::SetToOutputInterfaces + * GHS3DPRLPlugin_Hypothesis_i::SetToDiscardSubdomains */ //============================================================================= @@ -103,12 +101,36 @@ void GHS3DPRLPlugin_Hypothesis_i::SetBackground (CORBA::Boolean theValue) SMESH::TPythonDump() << _this() << ".SetBackground( " << theValue << " )"; } -void GHS3DPRLPlugin_Hypothesis_i::SetToMeshHoles (CORBA::Boolean theValue) +void GHS3DPRLPlugin_Hypothesis_i::SetToMergeSubdomains (CORBA::Boolean theValue) { - MESSAGE("GHS3DPRLPlugin_Hypothesis_i::SetToMeshHoles"); + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::SetToMergeSubdomains"); ASSERT(myBaseImpl); - this->GetImpl()->SetToMeshHoles(theValue); - SMESH::TPythonDump() << _this() << ".SetToMeshHoles( " << theValue << " )"; + this->GetImpl()->SetToMergeSubdomains(theValue); + SMESH::TPythonDump() << _this() << ".SetToMergeSubdomains( " << theValue << " )"; +} + +void GHS3DPRLPlugin_Hypothesis_i::SetToTagSubdomains (CORBA::Boolean theValue) +{ + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::SetToTagSubdomains"); + ASSERT(myBaseImpl); + this->GetImpl()->SetToTagSubdomains(theValue); + SMESH::TPythonDump() << _this() << ".SetToTagSubdomains( " << theValue << " )"; +} + +void GHS3DPRLPlugin_Hypothesis_i::SetToOutputInterfaces (CORBA::Boolean theValue) +{ + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::SetToOutputInterfaces"); + ASSERT(myBaseImpl); + this->GetImpl()->SetToOutputInterfaces(theValue); + SMESH::TPythonDump() << _this() << ".SetToOutputInterfaces( " << theValue << " )"; +} + +void GHS3DPRLPlugin_Hypothesis_i::SetToDiscardSubdomains (CORBA::Boolean theValue) +{ + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::SetToDiscardSubdomains"); + ASSERT(myBaseImpl); + this->GetImpl()->SetToDiscardSubdomains(theValue); + SMESH::TPythonDump() << _this() << ".SetToDiscardSubdomains( " << theValue << " )"; } //============================================================================= @@ -117,7 +139,10 @@ void GHS3DPRLPlugin_Hypothesis_i::SetToMeshHoles (CORBA::Boolean theValue) * GHS3DPRLPlugin_Hypothesis_i::GetNbPart * GHS3DPRLPlugin_Hypothesis_i::GetKeepFiles * GHS3DPRLPlugin_Hypothesis_i::GetBackground - * GHS3DPRLPlugin_Hypothesis_i::GetToMeshHoles + * GHS3DPRLPlugin_Hypothesis_i::GetToMergeSubdomains + * GHS3DPRLPlugin_Hypothesis_i::GetToTagSubdomains + * GHS3DPRLPlugin_Hypothesis_i::GetToOutputInterfaces + * GHS3DPRLPlugin_Hypothesis_i::GetToDiscardSubdomains */ //============================================================================= @@ -151,11 +176,32 @@ CORBA::Boolean GHS3DPRLPlugin_Hypothesis_i::GetBackground() return this->GetImpl()->GetBackground(); } -CORBA::Boolean GHS3DPRLPlugin_Hypothesis_i::GetToMeshHoles() +CORBA::Boolean GHS3DPRLPlugin_Hypothesis_i::GetToMergeSubdomains() +{ + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::GetToMergeSubdomains"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetToMergeSubdomains(); +} + +CORBA::Boolean GHS3DPRLPlugin_Hypothesis_i::GetToTagSubdomains() +{ + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::GetToTagSubdomains"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetToTagSubdomains(); +} + +CORBA::Boolean GHS3DPRLPlugin_Hypothesis_i::GetToOutputInterfaces() +{ + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::GetToOutputInterfaces"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetToOutputInterfaces(); +} + +CORBA::Boolean GHS3DPRLPlugin_Hypothesis_i::GetToDiscardSubdomains() { - MESSAGE("GHS3DPRLPlugin_Hypothesis_i::GetToMeshHoles"); + MESSAGE("GHS3DPRLPlugin_Hypothesis_i::GetToDiscardSubdomains"); ASSERT(myBaseImpl); - return this->GetImpl()->GetToMeshHoles(); + return this->GetImpl()->GetToDiscardSubdomains(); } //============================================================================= diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.hxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.hxx index a62a189..70cc6f8 100755 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.hxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis_i.hxx @@ -43,9 +43,7 @@ class GHS3DPRLPLUGIN_EXPORT GHS3DPRLPlugin_Hypothesis_i: { public: // Constructor - GHS3DPRLPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl); + GHS3DPRLPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, int theStudyId, ::SMESH_Gen* theGenImpl); // Destructor virtual ~GHS3DPRLPlugin_Hypothesis_i(); @@ -62,8 +60,17 @@ class GHS3DPRLPLUGIN_EXPORT GHS3DPRLPlugin_Hypothesis_i: void SetBackground(CORBA::Boolean theVal); CORBA::Boolean GetBackground(); - void SetToMeshHoles(CORBA::Boolean theVal); - CORBA::Boolean GetToMeshHoles(); + void SetToMergeSubdomains(CORBA::Boolean theVal); + CORBA::Boolean GetToMergeSubdomains(); + + void SetToTagSubdomains(CORBA::Boolean theVal); + CORBA::Boolean GetToTagSubdomains(); + + void SetToOutputInterfaces(CORBA::Boolean theVal); + CORBA::Boolean GetToOutputInterfaces(); + + void SetToDiscardSubdomains(CORBA::Boolean theVal); + CORBA::Boolean GetToDiscardSubdomains(); // Get implementation ::GHS3DPRLPlugin_Hypothesis* GetImpl(); diff --git a/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.cxx b/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.cxx index 12b9d79..a4026d9 100755 --- a/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.cxx +++ b/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.cxx @@ -46,7 +46,7 @@ GHS3DPRLPluginGUI_HypothesisCreator::GHS3DPRLPluginGUI_HypothesisCreator( const : SMESHGUI_GenericHypothesisCreator( theHypType ), myIs3D( true ) { - printf("Hypo creator !!!!!!!!!!!!!!!!!!!!!!!!!! RNV"); + printf("Hypo creator GHS3DPRLPlugin"); } GHS3DPRLPluginGUI_HypothesisCreator::~GHS3DPRLPluginGUI_HypothesisCreator() @@ -113,9 +113,25 @@ QFrame* GHS3DPRLPluginGUI_HypothesisCreator::buildFrame() myBackground->setWhatsThis( tr( "GHS3DPRL_WhatsThis_Background" ) ); l->addWidget( myBackground, row++, 0, 1, 2 ); - myToMeshHoles = new QCheckBox( tr( "GHS3DPRL_ToMeshHoles" ), GroupC1 ); - myToMeshHoles->setWhatsThis( tr( "GHS3DPRL_WhatsThis_ToMeshHoles" ) ); - l->addWidget( myToMeshHoles, row++, 0, 1, 2 ); + //myToMeshHoles = new QCheckBox( tr( "GHS3DPRL_ToMeshHoles" ), GroupC1 ); + //myToMeshHoles->setWhatsThis( tr( "GHS3DPRL_WhatsThis_ToMeshHoles" ) ); + //l->addWidget( myToMeshHoles, row++, 0, 1, 2 ); + + myToMergeSubdomains = new QCheckBox( tr( "GHS3DPRL_ToMergeSubdomains" ), GroupC1 ); + myToMergeSubdomains->setWhatsThis( tr( "GHS3DPRL_WhatsThis_ToMergeSubdomains" ) ); + l->addWidget( myToMergeSubdomains, row++, 0, 1, 2 ); + + myToTagSubdomains = new QCheckBox( tr( "GHS3DPRL_ToTagSubdomains" ), GroupC1 ); + myToTagSubdomains->setWhatsThis( tr( "GHS3DPRL_WhatsThis_ToTagSubdomains" ) ); + l->addWidget( myToTagSubdomains, row++, 0, 1, 2 ); + + myToOutputInterfaces = new QCheckBox( tr( "GHS3DPRL_ToOutputInterfaces" ), GroupC1 ); + myToOutputInterfaces->setWhatsThis( tr( "GHS3DPRL_WhatsThis_ToOutputInterfaces" ) ); + l->addWidget( myToOutputInterfaces, row++, 0, 1, 2 ); + + myToDiscardSubdomains = new QCheckBox( tr( "GHS3DPRL_ToDiscardSubdomains" ), GroupC1 ); + myToDiscardSubdomains->setWhatsThis( tr( "GHS3DPRL_WhatsThis_ToDiscardSubdomains" ) ); + l->addWidget( myToDiscardSubdomains, row++, 0, 1, 2 ); myIs3D = true; @@ -132,7 +148,11 @@ void GHS3DPRLPluginGUI_HypothesisCreator::retrieveParams() const myNbPart->setValue( data.myNbPart ); myKeepFiles->setChecked( data.myKeepFiles ); myBackground->setChecked( data.myBackground ); - myToMeshHoles->setChecked( data.myToMeshHoles ); + //myToMeshHoles->setChecked( data.myToMeshHoles ); + myToMergeSubdomains->setChecked( data.myToMergeSubdomains ); + myToTagSubdomains->setChecked( data.myToTagSubdomains ); + myToOutputInterfaces->setChecked( data.myToOutputInterfaces ); + myToDiscardSubdomains->setChecked( data.myToDiscardSubdomains ); //myNbPart->setEnabled( true ); } @@ -145,7 +165,11 @@ QString GHS3DPRLPluginGUI_HypothesisCreator::storeParams() const QString valStr; valStr += tr( "GHS3DPRL_MEDName" ) + " = " + data.myMEDName + "; "; valStr += tr( "GHS3DPRL_NbPart" ) + " = " + QString::number( data.myNbPart ) + "; "; - valStr += tr( "GHS3DPRL_ToMeshHoles" ) + " = " + QString::number( data.myToMeshHoles ) + "; "; + //valStr += tr( "GHS3DPRL_ToMeshHoles" ) + " = " + QString::number( data.myToMeshHoles ) + "; "; + valStr += tr( "GHS3DPRL_ToMergeSubdomains" ) + " = " + QString::number( data.myToMergeSubdomains ) + "; "; + valStr += tr( "GHS3DPRL_ToTagSubdomains" ) + " = " + QString::number( data.myToTagSubdomains ) + "; "; + valStr += tr( "GHS3DPRL_ToOutputInterfaces" ) + " = " + QString::number( data.myToOutputInterfaces ) + "; "; + valStr += tr( "GHS3DPRL_ToDiscardSubdomains" ) + " = " + QString::number( data.myToDiscardSubdomains ) + "; "; valStr += tr( "GHS3DPRL_KeepFiles" ) + " = " + QString::number( data.myKeepFiles ) + "; "; valStr += tr( "GHS3DPRL_Background" ) + " = " + QString::number( data.myBackground ) + "; "; @@ -163,7 +187,11 @@ bool GHS3DPRLPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DPRLHypothesis h_data.myNbPart = h->GetNbPart(); h_data.myKeepFiles = h->GetKeepFiles(); h_data.myBackground = h->GetBackground(); - h_data.myToMeshHoles = h->GetToMeshHoles(); + //h_data.myToMeshHoles = h->GetToMeshHoles(); + h_data.myToMergeSubdomains = h->GetToMergeSubdomains(); + h_data.myToTagSubdomains = h->GetToTagSubdomains(); + h_data.myToOutputInterfaces = h->GetToOutputInterfaces(); + h_data.myToDiscardSubdomains = h->GetToDiscardSubdomains(); return true; } @@ -183,7 +211,11 @@ bool GHS3DPRLPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DPRLHypot h->SetNbPart( h_data.myNbPart ); h->SetKeepFiles( h_data.myKeepFiles ); h->SetBackground( h_data.myBackground ); - h->SetToMeshHoles( h_data.myToMeshHoles ); + //h->SetToMeshHoles( h_data.myToMeshHoles ); + h->SetToMergeSubdomains( h_data.myToMergeSubdomains ); + h->SetToTagSubdomains( h_data.myToTagSubdomains ); + h->SetToOutputInterfaces( h_data.myToOutputInterfaces ); + h->SetToDiscardSubdomains( h_data.myToDiscardSubdomains ); } catch ( const SALOME::SALOME_Exception& ex ) { @@ -200,7 +232,11 @@ bool GHS3DPRLPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DPRLHypothe h_data.myNbPart = myNbPart->value(); h_data.myKeepFiles = myKeepFiles->isChecked(); h_data.myBackground = myBackground->isChecked(); - h_data.myToMeshHoles = myToMeshHoles->isChecked(); + //h_data.myToMeshHoles = myToMeshHoles->isChecked(); + h_data.myToMergeSubdomains = myToMergeSubdomains->isChecked(); + h_data.myToTagSubdomains = myToTagSubdomains->isChecked(); + h_data.myToOutputInterfaces = myToOutputInterfaces->isChecked(); + h_data.myToDiscardSubdomains = myToDiscardSubdomains->isChecked(); return true; } diff --git a/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.h b/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.h index 558c32c..d5bbf1c 100755 --- a/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.h +++ b/src/gui/GHS3DPRLPluginGUI_HypothesisCreator.h @@ -49,7 +49,11 @@ typedef struct int myNbPart; bool myKeepFiles; bool myBackground; - bool myToMeshHoles; + //bool myToMeshHoles; + bool myToMergeSubdomains; + bool myToTagSubdomains; + bool myToOutputInterfaces; + bool myToDiscardSubdomains; } GHS3DPRLHypothesisData; /*! @@ -86,7 +90,11 @@ private: QtxIntSpinBox* myNbPart; QCheckBox* myKeepFiles; QCheckBox* myBackground; - QCheckBox* myToMeshHoles; + //QCheckBox* myToMeshHoles; + QCheckBox* myToMergeSubdomains; + QCheckBox* myToTagSubdomains; + QCheckBox* myToOutputInterfaces; + QCheckBox* myToDiscardSubdomains; bool myIs3D; }; diff --git a/src/gui/GHS3DPRLPlugin_msg_en.ts b/src/gui/GHS3DPRLPlugin_msg_en.ts index 1cc4e4f..7bdea86 100644 --- a/src/gui/GHS3DPRLPlugin_msg_en.ts +++ b/src/gui/GHS3DPRLPlugin_msg_en.ts @@ -17,11 +17,27 @@ GHS3DPRL_Background - Tepal in background + Tetra_hpc in background GHS3DPRL_ToMeshHoles - To mesh holes + Mesh holes + + + GHS3DPRL_ToMergeSubdomains + Merge subdomains + + + GHS3DPRL_ToTagSubdomains + Tag subdomains + + + GHS3DPRL_ToOutputInterfaces + Output interfaces + + + GHS3DPRL_ToDiscardSubdomains + Discard subdomains GHS3DPRL_MEDName diff --git a/src/tepal2med/CMakeLists.txt b/src/tepal2med/CMakeLists.txt index f4bdd03..ba53f7b 100644 --- a/src/tepal2med/CMakeLists.txt +++ b/src/tepal2med/CMakeLists.txt @@ -66,9 +66,11 @@ SET(_other_SOURCES ghs3dprl_mesh_wrap.cxx ghs3dprl_msg_parser.cxx dlg_ghs3dmain.cxx - tepal2med.cxx ) +# tepal2med.cxx +# tetrahpc2med.cxx + # resource files / to be processed by uic SET(_uic_files dlg_ghs3dmain.ui @@ -78,10 +80,13 @@ SET(_uic_files QT4_WRAP_UI(_uic_HEADERS ${_uic_files}) # sources / to compile -SET(tepal2med_SOURCES ${_other_SOURCES} ${_moc_SOURCES} ${_uic_HEADERS}) +SET(tepal2med_SOURCES tepal2med.cxx ${_other_SOURCES} ${_moc_SOURCES} ${_uic_HEADERS}) +SET(tetrahpc2med_SOURCES tetrahpc2med.cxx ${_other_SOURCES} ${_moc_SOURCES} ${_uic_HEADERS}) # --- rules --- ADD_EXECUTABLE(tepal2med ${tepal2med_SOURCES}) +ADD_EXECUTABLE(tetrahpc2med ${tetrahpc2med_SOURCES}) TARGET_LINK_LIBRARIES(tepal2med ${_link_LIBRARIES}) -INSTALL(TARGETS tepal2med EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) +TARGET_LINK_LIBRARIES(tetrahpc2med ${_link_LIBRARIES}) +INSTALL(TARGETS tepal2med tetrahpc2med EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) diff --git a/src/tepal2med/ghs3dprl_mesh_wrap.cxx b/src/tepal2med/ghs3dprl_mesh_wrap.cxx index d3a344f..79e03bd 100755 --- a/src/tepal2med/ghs3dprl_mesh_wrap.cxx +++ b/src/tepal2med/ghs3dprl_mesh_wrap.cxx @@ -448,6 +448,40 @@ bool CVW_FindString(const std::string &str,std::fstream &Ff, long &count) return true; } +//************************************ +bool CVW_FindStringInFirstLines(const std::string &str,std::fstream &Ff, long &maxline) +//find in file maximum maxline first lines with string str in first position of line +//converts count value expected after " " in line found +{ + std::string line; + long nbLine=0; + do + { + if (getline(Ff,line)) + { + nbLine++; + if (line[0]==str[0]) //faster + { + if (line.find(str)==0) + { + return true; + } + } + if (nbLine>=maxline) + { + std::cerr<<"Problem line '"< for speed (and so no test) +{ + QString tmp; + std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in); + std::string line; + long i,count,meshversion,maxline; + bool ok; + + if (!Ff.is_open()) + { + std::cerr<<"Problem File '"<2) std::cout<<"MeshVersionFormatted_"<nofile<<" ok"<nbfiles++; + return true; +} + ///************************************ bool ghs3dprl_mesh_wrap::ReadFileGLO(const QString FileName) //read file .glo with no parser xml because big file (volume) @@ -645,6 +707,171 @@ bool ghs3dprl_mesh_wrap::ReadFileFACES(const QString FileName) return true; } +//************************************ +bool ghs3dprl_mesh_wrap::ReadFileMESH(const QString FileName) +//read file .mesh from tetra_hpc (with volume) +{ + std::string line(" "); + QString tmp; + std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in); + long Mversion=0,Mdim=0,Mvert=0,Mtria=0,Mtetra=0; + med_int garbage; + //long ne,np,npfixe,subnumber,reste; + bool ok; + if (verbose>=6)std::cout<<"Read File '"<>tmflo[i]>>tmflo[i+1]>>tmflo[i+2]>>garbage; + if (verbose>4) std::cout<<"Vertices "<nofile); + ok=this->insert_key(tmp,montab); + + getline(Ff,line); + getline(Ff,line); + + if (!(getline(Ff,line) && (line.find("Triangles")==0))) + { + std::cerr<<"Problem on line 'Triangles' of file: not found"<>tmint[i]>>tmint[i+1]>>tmint[i+2]>>garbage; + tmint[i+3]=0; + tmint[i+4]=0; + tmint[i+5]=0; + tmint[i+6]=0; + } + if (verbose>4) std::cout<<"Triangles "<nofile); + ok=this->insert_key(tmp,montab); + + getline(Ff,line); + getline(Ff,line); + + if (!(getline(Ff,line) && (line.find("Tetrahedra")==0))) + { + std::cerr<<"Problem on line 'Tetrahedra' of file: not found"<=2) + { + std::cout<<"MeshVersionFormatted="<nofile); + ok=this->insert_key(tmp,montab); + + //swap on file if too big for memory in one cpu + //default 1GOctet/8(for double)/10(for arrays in memory at the same time) + if (Mvert*3>this->nbelem_limit_swap) + this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp)); + //beware record 6 lenght 1 + //ferme le fichier : + Ff.close(); + this->nbfiles++; + return true; +} + //************************************ bool ghs3dprl_mesh_wrap::ReadFileNOBOITE(const QString FileName) //read file .noboite (volume) @@ -1381,7 +1608,7 @@ bool ghs3dprl_mesh_wrap::Write_masterxmlMEDfile() //Description tag node = xmlNewChild(root_node,0, BAD_CAST "description",0); - xmlNewProp(node, BAD_CAST "what", BAD_CAST "tetrahedral mesh by tepal"); + xmlNewProp(node, BAD_CAST "what", BAD_CAST "tetrahedral mesh by MeshGems-Tetra-hpc (formerly tepal)"); #ifdef WIN32 SYSTEMTIME present; GetLocalTime ( &present ); @@ -1522,7 +1749,8 @@ bool ghs3dprl_mesh_wrap::Write_MEDfiles_v2(bool deletekeys) cmd.toLatin1().constData()<<"> does not exist\n"; } //define family 0 if not existing, no groups - families.add("0",""); + //La famille FAMILLE_ZERO n'a pas été trouvée, elle est obligatoire + families.add("0","FAMILLE_ZERO"); //define family Group_of_New_Nodes (which not exists before tetrahedra) famallnodes=0; if (QString("All_Nodes").contains(deletegroups)==0){ @@ -1647,6 +1875,7 @@ bool ghs3dprl_mesh_wrap::Write_MEDfiles_v2(bool deletekeys) MEDfileClose(fid); //but loop on others domains } + MEDfileClose(fidjoint); //no error if (verbose>0)std::cout<<"\nTotalNumberOftetrahedra="<restore_key(key); //tab1=this->mestab[key1]; if (!tab) { - tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".noboite"; - ok=this->ReadFileNOBOITE(tmp); + if (!for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".noboite"; + ok=this->ReadFileNOBOITE(tmp); + } + if (for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".mesh"; + ok=this->ReadFileMESH(tmp); + } tab=this->restore_key(key); //tab1=this->mestab[key1]; if (!tab) return false; } @@ -1690,8 +1925,14 @@ bool ghs3dprl_mesh_wrap::idom_nodes() key1=key1.sprintf("GL%d VE",idom); //global numerotation tab1=this->restore_key(key1); //tab1=this->mestab[key1]; if (!tab1) { - tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo"; - ok=this->ReadFileGLO(tmp); + if (!for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo"; + ok=this->ReadFileGLO(tmp); + } + if (for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".glo"; + ok=this->ReadFileGLO(tmp); + } if (!ok) {std::cerr<<"Problem file "<restore_key(key1); //tab1=this->mestab[key1]; if (!tab1) return false; @@ -1942,17 +2183,14 @@ bool ghs3dprl_mesh_wrap::idom_joints() //qt3 if (this->nb_key_mesh_wrap(QRegExp(tmp,true,true))<=0) { if (this->nb_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp))<=0) { this->nofile=idom; - /*old version with xml parser too slow - ghs3dprl_msg_parser handler; - handler.mailw=this; - QXmlSimpleReader reader; - reader.setContentHandler(&handler); - tmp=pathini+casename+tmp.sprintf(format,nbfilestot,idom)+".msg"; - QFile File(tmp); - QXmlInputSource source(&File); - reader.parse(source); - File.close();*/ - tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".msg"; + + if (!for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".msg"; + } + if (for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".msg"; + } + ok=this->ReadFileMSGnew(tmp); if (!ok) { std::cerr<<"Problem in file "<restore_key(key1); //if not yet loaded (first time) try to load necessary file msg of neighbourg if (!tab2) { - tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,ineig)+".msg"; + + if (!for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,ineig)+".msg"; + } + if (for_tetrahpc) { + tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),ineig)+".msg"; + } + this->nofile=ineig; //neighbourg file ok=this->ReadFileMSGnew(tmp); this->nofile=idom; //restaure initial domain @@ -2019,14 +2264,14 @@ bool ghs3dprl_mesh_wrap::idom_joints() //two indices for one correspondence arrayi=new med_int[nb*2]; arraynodes=new med_float[nbnodesneig*3]; //for file DOMAIN_join.med - inodes=new med_int[nbnodes]; //for file DOMAIN_join.med + inodes=new med_int[nbnodes]; //for file DOMAIN_join.med med_int * fammore=new med_int[nbnodes]; - for (i=0; i equals tab1->tmint[i]==tab2->tmint[i] - j=tab1->tmint[i]-1; //contents of tab1 1 to nb - inodes[j]=k; k++; //indices 0->n-1 of nodes of joint from nodes of domain + j=tab1->tmint[i]-1; //contents of tab1 1->nb, j 0->nb-1 + inodes[j]=k; k++; //contents of inodes 1->n ,nodes of joint from nodes of domain arraynodes[jj]=tab->tmflo[j*3]; jj++; arraynodes[jj]=tab->tmflo[j*3+1]; jj++; arraynodes[jj]=tab->tmflo[j*3+2]; jj++; @@ -2061,7 +2306,7 @@ bool ghs3dprl_mesh_wrap::idom_joints() key1=key1.sprintf("MS%d NE%d FA SE",ineig,idom); //SE or RE identicals tab2=this->restore_key(key1); if (!tab2) std::cerr<<"Problem existing triangles of joint in domain "<size; nbtria3neig=tab2->size; if (nb!=nbtria3neig) { std::cerr<<"Problem in file "<restore_key(key); //tab1=this->mestab[key1]; med_int nb=tab1->size; nbtria3neig=nb; - if (verbose>4) - std::cout<<"NumberOfTrianglesOfJoint_"<=0) std::cout<<"NumberOfTrianglesOfJoint_"<tmint[i]; ii++; + arrayi[ii]=tab2->tmint[i]; ii++; //correspondance indices triangles in 2 domains + fammore[tab1->tmint[i]-1]=famjoint; //famtria3[tab1->tmint[i]-1]=famjoint; - arrayi[ii]=tab2->tmint[i]; ii++; - //std::cout<tmint[i]-1)*7; //indice of node connectivity - arrayfaces[jj]=inodes[tab->tmint[k]-1]+1; jj++; - arrayfaces[jj]=inodes[tab->tmint[k+1]-1]+1; jj++; - arrayfaces[jj]=inodes[tab->tmint[k+2]-1]+1; jj++; + + k=tab1->tmint[i]-1; //indice of node connectivity + //std::cout<<"k="<tmint[k]-1]; jj++; + arrayfaces[jj]=inodes[tab->tmint[k+1]-1]; jj++; + arrayfaces[jj]=inodes[tab->tmint[k+2]-1]; jj++; + } + int happens=0; + for (i=0; isize ; i++) std::cout<<"triangle i "<tmint[i]<size ; i=i+7) std::cout<<"conn i "<tmint[i]<<" "<tmint[i+1]<<" "<tmint[i+2]<0) { //for (i=0; i5) - std::cout<<"CreateFamilyInMEDFile <"<\tNbGroups="<\tNbGroups="<5)std::cout<name; + char attdes[MED_COMMENT_SIZE+1]="_NO_DESCRIPTION"; + + char *gro; + med_int i,attide=1,attval=1,natt=1,num=0,ngro=0; + + gro=new char[MED_LNAME_SIZE*ngro+2]; + if (verbose>3)std::cout<<"\ncreate_family_ZERO "<verbose>3){ med_float *coo=new med_float[nnoe*sdim]; /* table des numeros de familles des noeuds profil : (nombre de noeuds) */ med_int *famnodesskin=new med_int[nnoe]; - med_int *pfltab=new med_int[1]; //inutilise car on lit tout + //med_int *pfltab=new med_int[1]; //inutilise car on lit tout //lecture des noeuds : coordonnees ret=MEDmeshNodeCoordinateRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_FULL_INTERLACE,coo); //mdim,coo,mode_coo,MED_ALL,pfltab,0,&rep,mymailw->nomcoo,mymailw->unicoo); @@ -378,10 +379,10 @@ if (mymailw->verbose>3){ } std::cout<nommaa,MED_NO_DT,MED_NO_IT, - MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,pfltab); + MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,conn3); //MEDconnLire(fid,mymailw->nommaa,mdim,conn3,mode_coo,pfltab,0,MED_MAILLE,MED_TRIA3,MED_NOD); if (ret < 0){ std::cerr<<"Problem reading MED_TRIA3\n"; @@ -529,7 +530,7 @@ int main(int argc, char *argv[]) QString path,pathini,casename,casenamemed,fileskinmed, tmp,cmd,format, test,menu,launchtepal,background,deletegroups, - version="V2.0 (MED3)"; + version="V3.0 (MED3+tepalv1)"; char *chelp=NULL, *ccasename=NULL, @@ -667,7 +668,7 @@ int main(int argc, char *argv[]) if (menu=="yes") { QApplication a(argc,argv); dlg_ghs3dmain *m = new dlg_ghs3dmain(); - m->setWindowTitle("tepal2med 2.1"); + m->setWindowTitle("tepal2med 3.0"); m->show(); a.exec(); if ( m->result() == QDialog::Accepted ) { @@ -776,6 +777,8 @@ int main(int argc, char *argv[]) int nbf=format.length(); format=format.sprintf(".%%.%dd.%%.%dd",nbf,nbf); mymailw->format=format; + mymailw->format_tetra=format; //here is tepal: not used + mymailw->for_tetrahpc=false; //to know what files to read: .noboite or .mesh //something like "/home/wambeke/tmp/GHS3DPRL_skin.med" fileskinmed=pathini+casename+"_skin.med"; diff --git a/src/tepal2med/tetrahpc2med.cxx b/src/tepal2med/tetrahpc2med.cxx new file mode 100755 index 0000000..7bcfc58 --- /dev/null +++ b/src/tepal2med/tetrahpc2med.cxx @@ -0,0 +1,830 @@ +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D +// +// This library 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. +// +// This library 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 this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// --- +// File : tetrahpc2med.cxx +// Author : Christian VAN WAMBEKE (CEA) +// --- +// +/* +** prog principal de ghs3dprl +*/ + +#include /* printf clrscr fopen fread fwrite fclose */ +#include +#include +#include +#include +#include +#include +#include +#ifndef WIN32 +#include +#endif + +#include + +#include +#include +#include + +#include "ghs3dprl_msg_parser.h" +#include "dlg_ghs3dmain.h" + +#ifdef WIN32 +#include +#include +#define F_OK 0 +#endif + +//#include "MEDMEM_Exception.hxx" +//#include "MEDMEM_define.hxx" + +extern "C" { +#include +//#include +//#include +//#include +} + +//************************************ +med_idt ouvre_fichier_MED(char *fichier,int verbose) +{ + med_idt fid = 0; + med_err ret = 0; + med_int majeur,mineur,release; + + /* on regarde si le fichier existe */ + ret = (int) access(fichier,F_OK); + if (ret < 0) return fid; + + /* on regarde s'il s'agit d'un fichier au format HDF5 */ + med_bool hdfok,medok; + ret = MEDfileCompatibility(fichier,&hdfok,&medok); + if (ret < 0){ + std::cerr<<"File "<0)fprintf(stdout,"\nReading %s with MED V%d.%d.%d", + fichier,majeur,mineur,release); + + /* Ouverture du fichier MED en lecture seule */ + fid = MEDfileOpen(fichier,MED_ACC_RDONLY); + if (ret < 0) return fid; + + MEDfileNumVersionRd(fid, &majeur, &mineur, &release); + if (majeur < 2 || majeur == 2 && mineur < 2) { + fprintf(stderr,"File %s from MED V%d.%d.%d not assumed\n", + fichier,majeur,mineur,release); + //" version est ant�ieure �la version 2.2"; + ret = MEDfileClose(fid); + fid=0; } + else { + if (verbose>0)fprintf(stdout,", file from MED V%d.%d.%d\n",majeur,mineur,release); } + + return fid; +} + +//************************************ +bool ReadFileMED(QString nomfilemed,ghs3dprl_mesh_wrap *mymailw) +{ + med_err ret; + med_idt fid=0; + med_int i,j,sdim,mdim,nmaa,edim,majeur_lu,mineur_lu,release_lu,nprofils,nstep; + med_mesh_type type_maillage; + char dtunit[MED_SNAME_SIZE+1]; + char axisname[MED_SNAME_SIZE+1]; + char axisunit[MED_SNAME_SIZE*3+1]; + med_sorting_type sortingtype; + med_axis_type axistype; + int numero=1; + QString key,tmp; + med_bool chan; + med_bool tran; + + //version qt3 + char* chaine = (char*)malloc((nomfilemed.length()+1)*sizeof(char)); + strncpy(chaine,nomfilemed.toLatin1().constData(),nomfilemed.length()+1); + //std::cout<<"*** ReadFileMED *** "<verbose); + free(chaine); + if (fid == 0) { + std::cerr<<"Problem opening file "< 1) std::cout<<"More than one mesh in "<nommaa,&sdim,&mdim,&type_maillage,mymailw->maillage_description, + dtunit,&sortingtype,&nstep,&axistype,axisname,axisunit); + if (ret < 0){ + std::cerr<<"Problem MEDmeshInfo in "<nommaa,MED_NO_DT,MED_NO_IT, + MED_NODE,MED_NO_GEOTYPE,MED_COORDINATE,MED_NO_CMODE,&chan,&tran); + //(med_geometrie_element)0,(med_connectivite)0); + if (nnoe<1){ + std::cerr<<"Problem number of Vertices < 1\n"; + ret = MEDfileClose(fid); + return false; + } + + //nombre d'objets MED : mailles, faces, aretes , ... + med_int nmailles[MED_N_CELL_GEO],nbtria3; + med_int nfaces[MED_N_FACE_GEO]; + med_int naretes[MED_N_EDGE_FIXED_GEO],nbseg2; + //med_int nmailles[MED_NBR_GEOMETRIE_MAILLE],nbtria3; + //med_int nfaces[MED_NBR_GEOMETRIE_FACE]; + //med_int naretes[MED_NBR_GEOMETRIE_ARETE],nbseg2; + //polygones et polyedres familles equivalences joints + med_int nmpolygones,npolyedres,nfpolygones,nfam,nequ,njnt; + + //Combien de mailles, faces ou aretes pour chaque type geometrique ? + /*for (i=0;inommaa,MED_CONN,MED_MAILLE,typmai[i],typ_con); + //lecture_nombre_mailles_standards(fid,nommaa,typmai[i],typ_con,i); + if (mymailw->verbose>6) std::cout<<"NumberOf"<nommaa,MED_NO_DT,MED_NO_IT, + MED_CELL,MED_TRIA3,MED_CONNECTIVITY,MED_NODAL,&chan,&tran); + nbseg2=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT, + MED_CELL,MED_SEG2,MED_CONNECTIVITY,MED_NODAL,&chan,&tran); + + //combien de familles ? + nfam=MEDnFamily(fid,mymailw->nommaa); + if (mymailw->verbose>2) { + std::cout<<"\nNumberOfFamilies="< famdelete = std::vector(nfam); +{ + med_int ngro; + char *gro; + char nomfam[MED_NAME_SIZE+1]; + med_int numfam; + char str1[MED_COMMENT_SIZE+1]; + char str2[MED_LNAME_SIZE+1]; + med_err ret = 0; + + for (i=0;inommaa,i+1); + if (ngro < 0){ + std::cerr<<"Problem reading number of groups of family\n"; + continue; + } + + //atributs obsolete MED3 + //allocation memoire par exces + gro = (char*) malloc(MED_LNAME_SIZE*(ngro+1)); + + ret = MEDfamilyInfo(fid,mymailw->nommaa,i+1,nomfam,&numfam,gro); + if (ret < 0){ + std::cerr<<"Problem reading informations of family\n"; + continue; + } + + if (mymailw->verbose>8) { + std::cout<<"Family "<deletegroups)>0) { + //std::cout<<"idelete++ "<0) { //only delete family whith all delete groups + //std::cout<<"famdelete++ "<deletegroups)==0){ + if (sgro.contains(qgroup)>0) { + sgro="Skin_"+sgro; //pas sur que ce soit pertinent + } + if (mymailw->verbose>8) std::cout<<"families.add("<families.add(sfam,sgro); + } + else { + //sgro="Skin_"+sgro; //pas sur que ce soit pertinent + //std::cout<<"--deletegroups matches \""<verbose>3) std::cout<<"--deletegroups matches \""<< + sgro.toLatin1().constData()<< + "\" in family "<deletegroups)==0){ + //sgro="Skin_"+sgro; //pas sur que ce soit pertinent + std::cout<<"families.add("<families.add(sfam,sgro); + } + else { + std::cout<<"--deletegroups matches \""<verbose>3){ + std::cout<<"\nFamiliesAndGroupsOf "<families.write(); +} + /* Allocations memoires */ + /* table des coordonnees profil : (space dimension * nombre de noeuds ) */ + med_float *coo=new med_float[nnoe*sdim]; + /* table des numeros de familles des noeuds profil : (nombre de noeuds) */ + med_int *famnodesskin=new med_int[nnoe]; + //med_int *pfltab=new med_int[1]; //inutilise car on lit tout + //lecture des noeuds : coordonnees + ret=MEDmeshNodeCoordinateRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_FULL_INTERLACE,coo); + //mdim,coo,mode_coo,MED_ALL,pfltab,0,&rep,mymailw->nomcoo,mymailw->unicoo); + if (ret < 0){ + std::cerr<<"Problem reading nodes\n"; + ret = MEDfileClose(fid); + //return false; + } + ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_NODE,MED_NONE,famnodesskin); + //famnodesskin,nnoe,MED_NOEUD,(med_geometrie_element) 0); + if (ret < 0){ + std::cerr<<"Problem reading families of nodes\n"; + ret = MEDfileClose(fid); + return false; + } + if (mymailw->verbose>9) { + std::cout<<"\nVertices: no x y z family\n"; + for (i=0;inommaa,MED_NO_DT,MED_NO_IT, + MED_CELL,MED_SEG2,MED_NODAL,MED_FULL_INTERLACE,conn2); + //mdim,conn2,mode_coo,pfltab,0,MED_MAILLE,MED_SEG2,MED_NOD); + if (ret < 0){ + std::cerr<<"Problem reading MED_SEG2\n"; + ret = MEDfileClose(fid); + //return false; + } + med_int *famseg2skin=new med_int[nbseg2]; + ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_SEG2,famseg2skin); + //MEDfamLire(fid,mymailw->nommaa,famseg2skin,nbseg2,MED_MAILLE,MED_SEG2); + if (ret < 0){ + std::cerr<<"Problem reading families of MED_SEG2\n"; + ret = MEDfileClose(fid); + return false; + } + if (mymailw->verbose>9) { + std::cout<<"\nConnectivity MED_SEG2: no node1 node2 family\n"; + for (i=0;inommaa,MED_NO_DT,MED_NO_IT, + MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,conn3); + //MEDconnLire(fid,mymailw->nommaa,mdim,conn3,mode_coo,pfltab,0,MED_MAILLE,MED_TRIA3,MED_NOD); + if (ret < 0){ + std::cerr<<"Problem reading MED_TRIA3\n"; + ret = MEDfileClose(fid); + //return false; + } + med_int *famtria3skin=new med_int[nbtria3]; + ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,famtria3skin); + //MEDfamLire(fid,mymailw->nommaa,famtria3skin,nbtria3,MED_MAILLE,MED_TRIA3); + if (ret < 0){ + std::cerr<<"Problem reading families of MED_TRIA3\n"; + ret = MEDfileClose(fid); + return false; + } + if (mymailw->verbose>9) { + std::cout<<"\nConnectivity MED_TRIA3: no node1 node2 node3 family\n"; + for (i=0;i0) { + //std::cout<<"!!!!!!!!nodes "<insert_key(tmp,montab); + + montab=new CVWtab(nnoe,famnodesskin); + tmp="SKIN_VERTICES_FAMILIES"; + ok=mymailw->insert_key(tmp,montab); + + montab=new CVWtab(nbseg2*2,conn2); + tmp="SKIN_SEG2_CONNECTIVITIES"; + ok=mymailw->insert_key(tmp,montab); + + montab=new CVWtab(nbtria3,famseg2skin); + tmp="SKIN_SEG2_FAMILIES"; + ok=mymailw->insert_key(tmp,montab); + + montab=new CVWtab(nbtria3*3,conn3); + tmp="SKIN_TRIA3_CONNECTIVITIES"; + ok=mymailw->insert_key(tmp,montab); + + montab=new CVWtab(nbtria3,famtria3skin); + tmp="SKIN_TRIA3_FAMILIES"; + ok=mymailw->insert_key(tmp,montab); + + //if (mymailw->verbose>6) ok=mymailw->list_keys_mesh_wrap(); + + ret = MEDfileClose(fid); + if (ret < 0){ + std::cerr<<"Problem closing "<6)\n"<< + " --test : more tests about joints, before generation of output files\n"<< + " --menu : a GUI menu for option number\n"<< + " --launchtetra : also launch tetra-hpc on files casename.mesh and option number\n"<< + " --merge_subdomains : merge the subdomains into one mesh and write the output .mesh(b) file\n"<< + " --tag_subdomains : use the parallel subdomain index as tag into the merged output mesh\n"<< + " to identify the parallel subdomains (used in combination with the merge_subdomains option)\n"<< + " --output_interfaces : write the parallel subdomains interface triangles into the merged output mesh\n"<< + " (used in combination with the merge_subdomains option)\n"<< + " --discard_subdomains : discard the parallel subdomains informations output (mesh, global numbering and interfaces)\n"<< + " --background : force background mode from launch tetra-hpc and generation of final MED files (big meshes)\n"<< + " --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files\n"<< + " (try --deletegroups=\"(\\bJOINT)\"\n"<< + " (try --deletegroups=\"(\\bAll_Nodes|\\bAll_Faces)\"\n"<< + " (try --deletegroups=\"((\\bAll_|\\bNew_)(N|F|T))\"\n"; + std::cout<<"example:\n tetrahpcl2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN "<< + "--limitswap=1000 --verbose=0 --test=yes --menu=no --launchtetra=no\n\n"; + return 1; //no output files + } + + if (!ccasename){ + std::cerr<<"--casename: a path/name is expected\n\n"; + return 1; + } + casename=ccasename; + if (!cnumber){ + std::cerr<<"--number: an integer is expected\n\n"; + return 1; + } + tmp=cnumber; + nbfiles=tmp.toLong(&ok,10); + if (!ok){ + std::cerr<<"--number: an integer is expected\n\n"; + return 1; + } + if (nbfiles<=0){ + std::cerr<<"--number: a positive integer is expected\n\n"; + return 1; + } + if (nbfiles>2048){ //delirium in 2014 + std::cerr<<"--number: a positive integer <= 2048 is expected\n\n"; + return 1; + } + if (!cmedname) cmedname=ccasename; + casenamemed=cmedname; + limit_swap_defaut=1000; //1000Mo + limit_swap=limit_swap_defaut; + if (climitswap){ + tmp=climitswap; + limit_swap=tmp.toLong(&ok,10); + if (!ok){ + std::cerr<<"--limitswap: an integer is expected. try 1000\n\n"; + return 1; + } + if (limit_swap<1 || limit_swap>32000){ + std::cerr<<"--limitswap: [1->32000] expected. try 1000\n\n"; + return 1; + } + } + //default 1GOctet/8(for float) + nbelem_limit_swap=limit_swap*1000000; //100% + CVWtab::memorymax=nbelem_limit_swap; + + verbose=1; //default + if (cverbose){ + tmp=cverbose; + verbose=tmp.toLong(&ok,10); + if (!ok){ + std::cerr<<"--verbose: an integer is expected\n\n"; + return 1; + } + if (verbose<0){ + std::cerr<<"--verbose: a positive integer is expected\n\n"; + return 1; + } + } + + test="no"; //default + if (ctest){ + tmp=ctest; + if (tmp=="yes") test="yes"; + } + + menu="no"; //default + if (cmenu){ + tmp=cmenu; + if (tmp=="yes") menu="yes"; + } + + launchtetra="no"; //default + if (claunchtetra){ + tmp=claunchtetra; + if (tmp=="yes") launchtetra="yes"; + } + + ToMergeSubdomains="no"; //default + if (cToMergeSubdomains){ + tmp=cToMergeSubdomains; + if (tmp=="yes") ToMergeSubdomains="yes"; + } + + ToTagSubdomains="no"; //default + if (cToTagSubdomains){ + tmp=cToTagSubdomains; + if (tmp=="yes") ToTagSubdomains="yes"; + } + + ToOutputInterfaces="no"; //default + if (cToOutputInterfaces){ + tmp=cToOutputInterfaces; + if (tmp=="yes") ToOutputInterfaces="yes"; + } + + ToDiscardSubdomains="no"; //default + if (cToDiscardSubdomains){ + tmp=cToDiscardSubdomains; + if (tmp=="yes") ToDiscardSubdomains="yes"; + } + + background="no"; //default + if (cbackground){ + tmp=cbackground; + if (tmp=="yes") background="yes"; + } + + + // We must always have an application + if (menu=="yes") { + QApplication a(argc,argv); + dlg_ghs3dmain *m = new dlg_ghs3dmain(); + m->setWindowTitle("tetrahpc2med 3.0"); + m->show(); + a.exec(); + if ( m->result() == QDialog::Accepted ) { + std::cout<<"parameters "<KeepFiles()<<" "<NbPart()<NbPart(); + } + else { + return 1; + } + delete m; + } + + int n=casenamemed.count('/'); + if (n>0) + path=casenamemed.section('/',-n-1,-2)+"/"; + else + path="./"; + casenamemed=casenamemed.section('/',-1); + if (casenamemed.length()>20){ + std::cerr<<"--medname truncated (no more 20 characters)"<0) + pathini=casename.section('/',-n-1,-2)+"/"; + else + pathini="./"; + casename=casename.section('/',-1); + if (casename.length()>20){ + std::cerr<<"--casename truncated (no more 20 characters)"<0) + std::cout<<"tetrahpc2med "< 0) { + //Process father + exit(0); //temporary ok for plugin + } + //process children + //On rend le fils independant de tout terminal + //from here everything in background: tetrahpc AND generation of final MED files + setsid(); + system("sleep 10"); //for debug + } +#else + printf("background mode is not supported on win32 platform !\n"); +#endif + + //"tetrahpc -f exemple1 -n 4" + if (launchtetra=="yes"){ + //tetra_hpc.exe --help + //mpirun -n 3 tetra_hpc.exe --in GHS3DPRL.mesh --out TOTO.mesh + cmd="mpirun -n "+cmd.sprintf("%d",nbfiles)+" tetra_hpc.exe --in "+ + pathini+casename+".mesh --out "+ + pathini+casename+".mesh"+ + " --merge_subdomains "+ToMergeSubdomains+ + " --tag_subdomains "+ToTagSubdomains+ + " --output_interfaces "+ToOutputInterfaces+ + " --discard_subdomains "+ToDiscardSubdomains+ + " > "+path+"tetrahpc.log"; + std::cout<<"\nlaunchtetra command: background="<nbfiles=0; + mymailw->nbfilestot=nbfiles; + //for huge cases big array swap in huge binary files + mymailw->nbelem_limit_swap=nbelem_limit_swap; + mymailw->verbose=verbose; + mymailw->casename=casename; + mymailw->medname=casenamemed; + mymailw->path=path; + mymailw->pathini=pathini; + mymailw->deletegroups=QRegExp(deletegroups,Qt::CaseSensitive,QRegExp::RegExp); + ghs3dprl_msg_parser handler; + //constructor later maybe + //handler.verbose=true; + handler.mailw=mymailw; + mymailw->families.no=1; + //std::cout<<"coucou1 "<families.no<families.add(casename,casenamemed); + format=format.sprintf("%d",nbfiles); + int nbf=format.length(); + format=format.sprintf(".%%0%dd.%%0%dd",nbf,nbf); + format_tetra=".%05d"; + if (verbose>10)std::cout<<"format "<10)std::cout<<"format_tetra "<format=format; + mymailw->format_tetra=format_tetra; + mymailw->for_tetrahpc=true; //to know what files to read: .noboite or .mesh + + //something like "/home/wambeke/tmp/GHS3DPRL_skin.med" + fileskinmed=pathini+casename+"_skin.med"; + //fileskinmed="/home/wambeke/tmp/GHS3DPRL_skin.med"; + /*for debug + { + char ctmp[fileskinmed.length()+1] ; strcpy(ctmp,fileskinmed); + int res=dumpMED(&ctmp[0],1); + }*/ + int ret = access(fileskinmed.toLatin1().constData(),F_OK); //on regarde si le fichier existe + if (ret >= 0) { + ok=ReadFileMED(fileskinmed,mymailw); } + else { + if (verbose>0)std::cout<<"Initial skin file <"< does not exist\n"; } + + +//if test quickly read all files before (or only small files) + if (test=="yes"){ + if (verbose>0) std::cout<<"\nReading output files of tetrahpc as input files of tetrahpc2med...\n"; + //only read beginning of files .xxxxx.mesh + //supposed big files big arrays so only see first lines + mymailw->nbfiles=0; + for (int i=1; i<=nbfiles; i++){ + mymailw->nofile=i; + tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),i)+".mesh"; + if (verbose>0) std::cout<<"FileName="<TestExistingFileMESHnew(tmp); + } + if (verbose>0) + std::cout<<"NumberOfFilesMESHTested="<nbfiles<<": ok\n\n"; + if (mymailw->nbfiles != nbfiles){ + std::cerr<<"NumberOfFiles != NumberOfFilesTested is unexpected\n\n"; + return 1; + } + } //end if test + + ok=mymailw->Write_MEDfiles_v2(true); //deletekeys=true + + nb=mymailw->remove_all_keys_mesh_wrap(); + if (verbose>3)std::cout<<"***remove_all_key_mesh_wrap*** "<0)std::cout<