AFEPack
HGeometry.templates.nd.h
浏览该文件的文档。
00001 
00011 template <>
00012 HGeometry<0,DOW>::HGeometry()
00013   : index(0), bmark(0) {}
00014 
00015 
00016 template <>
00017 HGeometry<1,DOW>::HGeometry() 
00018 : index(0),
00019   vertex(n_vertex, NULL),
00020   parent(NULL),
00021   child(n_child, NULL),
00022   bmark(0) {}
00023 
00024 
00025 
00026 template <>
00027 HGeometry<2,DOW>::HGeometry()
00028 : index(0),
00029   vertex(n_vertex, NULL),
00030   boundary(n_boundary, NULL),
00031   parent(NULL),
00032   child(n_child, NULL),
00033   bmark(0) {}
00034 
00035 
00036 
00037 template <>
00038 HGeometry<3,DOW>::HGeometry()
00039 : index(0),
00040   vertex(n_vertex, NULL),
00041   boundary(n_boundary, NULL),
00042   parent(NULL),
00043   child(n_child, NULL),
00044   bmark(0) {}
00045 
00046 
00047 template <>
00048 bool HGeometry<1,DOW>::isRefined() const
00049 {
00050   return (child.size() > 0 && child[0] != NULL);
00051 }
00052 
00053 
00054 
00055 template <>
00056 bool HGeometry<2,DOW>::isRefined() const
00057 {
00058   return (child.size() > 0 && child[0] != NULL);
00059 }
00060 
00061 
00062 
00063 template <>
00064 bool HGeometry<3,DOW>::isRefined() const
00065 {
00066   return (child.size() > 0 && child[0] != NULL);
00067 }
00068 
00069 
00070 
00071 template <>
00072 void HGeometry<1,DOW>::refine()
00073 {
00074   if (isRefined()) return;
00075         
00076   // add the midpoint of the edge at first
00077   HGeometry<0,DOW> * new_point = new HGeometry<0,DOW>();
00078   Assert(new_point != NULL, ExcOutOfMemory());
00079   if (mid_point == NULL) {
00080     *dynamic_cast<Point<DOW> *>(new_point) = midpoint(*vertex[0], *vertex[1]);
00081   }
00082   else {
00083     (*mid_point)(*vertex[0], *vertex[1], bmark, *new_point);
00084   }
00085   new_point->bmark = bmark;
00086 
00087   // construct the 0th child for the edge
00088   child[0] = new HGeometry<1,DOW>();
00089   Assert(child[0] != NULL, ExcOutOfMemory());
00090   child[0]->parent = this;
00091   child[0]->vertex[0] = vertex[0];
00092   child[0]->vertex[1] = new_point;
00093   child[0]->bmark = bmark;
00094 
00095   // construct the 1st child for the edge
00096   child[1] = new HGeometry<1,DOW>();
00097   Assert(child[1] != NULL, ExcOutOfMemory());
00098   child[1]->parent = this;
00099   child[1]->vertex[0] = new_point;
00100   child[1]->vertex[1] = vertex[1];
00101   child[1]->bmark = bmark;
00102 }
00103 
00104 
00105 
00106 template <>
00107 void HGeometry<2,DOW>::refine()
00108 {
00109   int i, ii[]={0, 1, 2, 0, 1, 2};
00110   if (isRefined()) return;
00111 
00112   // refine its edge at first
00113   for (i = 0;i < 3;i ++) 
00114     boundary[i]->refine();
00115         
00116   // add the three new edge in the triangle
00117   HGeometry<0,DOW> * edge_midpoint[3];
00118   for (i = 0;i < 3;i ++) {
00119     edge_midpoint[i] = boundary[i]->child[0]->vertex[1];
00120   }
00121   HGeometry<1,DOW> * new_edge[3];
00122   for (i = 0;i < 3;i ++) {
00123     new_edge[i] = new HGeometry<1,DOW>();
00124     Assert(new_edge[i] != NULL, ExcOutOfMemory());
00125     new_edge[i]->vertex[0] = edge_midpoint[ii[i+1]];
00126     new_edge[i]->vertex[1] = edge_midpoint[ii[i+2]];
00127     new_edge[i]->bmark = bmark;
00128   }
00129         
00130   // construct the 0th to 2nd child for the triangle
00131   for (i = 0;i < 3;i ++) {
00132     if (typeid(*this) == typeid(HGeometry<2, DOW>))
00133       child[i] = (HGeometry<2,DOW> *) new HGeometry<2, DOW>();
00134     else
00135       child[i] = new HGeometry<2,DOW>();
00136     Assert(child[i] != NULL, ExcOutOfMemory());
00137     child[i]->parent = this;
00138     child[i]->vertex[0] = vertex[i];
00139     child[i]->vertex[1] = edge_midpoint[ii[i+2]];
00140     child[i]->vertex[2] = edge_midpoint[ii[i+1]];
00141     child[i]->boundary[0] = new_edge[i];
00142     if (boundary[ii[i+1]]->vertex[0] == vertex[i]) 
00143       child[i]->boundary[1] = boundary[ii[i+1]]->child[0];
00144     else 
00145       child[i]->boundary[1] = boundary[ii[i+1]]->child[1];
00146     if (boundary[ii[i+2]]->vertex[0] == vertex[i]) 
00147       child[i]->boundary[2] = boundary[ii[i+2]]->child[0];
00148     else 
00149       child[i]->boundary[2] = boundary[ii[i+2]]->child[1];
00150     child[i]->bmark = bmark;
00151   }
00152         
00153   // construct the 3rd child, the center child, for the triangle
00154   child[3] = new HGeometry<2,DOW>();
00155   Assert(child[3] != NULL, ExcOutOfMemory());
00156   child[3]->parent = this;
00157   child[3]->vertex[0] = edge_midpoint[0];
00158   child[3]->vertex[1] = edge_midpoint[1];
00159   child[3]->vertex[2] = edge_midpoint[2];
00160   child[3]->boundary[0] = new_edge[0];
00161   child[3]->boundary[1] = new_edge[1];
00162   child[3]->boundary[2] = new_edge[2];
00163   child[3]->bmark = bmark;
00164 }
00165 
00166 
00167 
00168 template <>
00169 void HGeometry<3,DOW>::refine()
00170 {
00171   int i, ii[]={0, 1, 2, 0, 1, 2, 0, 1, 2};
00172   if (isRefined()) return;
00173 
00174   // refine its surfaces at first. After the surfaces of the tetrahedron are refined,
00175   // all those edges of the tetrahedron are refined, too.
00176   for (i = 0;i < HGeometry<3,DOW>::n_boundary;i ++) 
00177     boundary[i]->refine();
00178 
00179   // retrieve the information of those midpoints of the edges of the tetrahedron. 
00180   // Because the data of the surfaces of the tetrahedron are not unique for the
00181   // tetrahedron, it's not so simple to get the information of those midpoints.
00182   // A lot of codes are written to get the relationship detail between the surfaces
00183   // and the tetrahedron. Be patiently and let's do it step by step,
00184   HGeometry<0,DOW> * edge_midpoint[6];
00185   HGeometry<2,DOW> * surface_child[4][4];
00186         
00187   {
00188     // for the first surface of the tetrahedron, which is on the bottom of the tetrahedron,
00189     // we should judge the pose of the triangle at first.
00190     // boundary[0]: the first surface
00191     // boundary[0]->vertex[i]: the i-th vertex of the triangle
00192     int start, step;
00193     for (start = 0;start < 3; start ++)
00194       if (boundary[0]->vertex[start] == vertex[1])
00195         break;
00196     Assert (start < 3,ExcInternalError());
00197     if (boundary[0]->vertex[ii[start+1]] == vertex[2])
00198       step = 1;
00199     else {
00200       Assert(boundary[0]->vertex[ii[start+1]] == vertex[3], ExcInternalError());
00201       Assert(boundary[0]->vertex[ii[start+2]] == vertex[2], ExcInternalError());
00202       step = 2;
00203     }
00204     edge_midpoint[3] = boundary[0]->boundary[start]->child[0]->vertex[1];
00205     edge_midpoint[4] = boundary[0]->boundary[ii[start+step]]->child[0]->vertex[1];
00206     edge_midpoint[5] = boundary[0]->boundary[ii[start+2*step]]->child[0]->vertex[1];
00207                 
00208     surface_child[0][0] = boundary[0]->child[start];
00209     surface_child[0][1] = boundary[0]->child[ii[start+step]];
00210     surface_child[0][2] = boundary[0]->child[ii[start+2*step]];
00211     surface_child[0][3] = boundary[0]->child[3];
00212 
00213     // for the second surface of the tetrahedron, we should judge its pose at first, too.
00214     // boundary[1]: the second surface
00215     // boundary[1]->vertex[i]: the i-th vertex of the triangle
00216     for (start = 0;start < 3; start ++)
00217       if (boundary[1]->vertex[start] == vertex[0])
00218         break;
00219     Assert (start < 3,ExcInternalError());
00220     if (boundary[1]->vertex[ii[start+1]] == vertex[2])
00221       step = 1;
00222     else {
00223       Assert(boundary[1]->vertex[ii[start+1]] == vertex[3], ExcInternalError());
00224       Assert(boundary[1]->vertex[ii[start+2]] == vertex[2], ExcInternalError());
00225       step = 2;
00226     }
00227     Assert(edge_midpoint[3] == boundary[1]->boundary[start]->child[0]->vertex[1], ExcInternalError());
00228     edge_midpoint[2] = boundary[1]->boundary[ii[start+step]]->child[0]->vertex[1];
00229     edge_midpoint[1] = boundary[1]->boundary[ii[start+2*step]]->child[0]->vertex[1];
00230 
00231     surface_child[1][0] = boundary[1]->child[start];
00232     surface_child[1][1] = boundary[1]->child[ii[start+step]];
00233     surface_child[1][2] = boundary[1]->child[ii[start+2*step]];
00234     surface_child[1][3] = boundary[1]->child[3];
00235                 
00236     // for the third surface of the tetrahedron, we should judge its pose at first, too.
00237     // boundary[2]: the third surface
00238     // boundary[2]->vertex[i]: the i-th vertex of the triangle
00239     for (start = 0;start < 3; start ++)
00240       if (boundary[2]->vertex[start] == vertex[0])
00241         break;
00242     Assert (start < 3,ExcInternalError());
00243     if (boundary[2]->vertex[ii[start+1]] == vertex[1])
00244       step = 1;
00245     else {
00246       Assert(boundary[2]->vertex[ii[start+1]] == vertex[3], ExcInternalError());
00247       Assert(boundary[2]->vertex[ii[start+2]] == vertex[1], ExcInternalError());
00248       step = 2;
00249     }
00250     Assert(edge_midpoint[4] == boundary[2]->boundary[start]->child[0]->vertex[1], ExcInternalError());
00251     Assert(edge_midpoint[2] == boundary[2]->boundary[ii[start+step]]->child[0]->vertex[1], ExcInternalError());
00252     edge_midpoint[0] = boundary[2]->boundary[ii[start+2*step]]->child[0]->vertex[1];
00253 
00254     surface_child[2][0] = boundary[2]->child[start];
00255     surface_child[2][1] = boundary[2]->child[ii[start+step]];
00256     surface_child[2][2] = boundary[2]->child[ii[start+2*step]];
00257     surface_child[2][3] = boundary[2]->child[3];
00258 
00259     // for the fourth surface of the tetrahedron, we should judge its pose at first, too.
00260     // boundary[3]: the fourth surface
00261     // boundary[3]->vertex[i]: the i-th vertex of the triangle
00262     for (start = 0;start < 3; start ++)
00263       if (boundary[3]->vertex[start] == vertex[0])
00264         break;
00265     Assert (start < 3,ExcInternalError());
00266     if (boundary[3]->vertex[ii[start+1]] == vertex[1])
00267       step = 1;
00268     else {
00269       Assert(boundary[3]->vertex[ii[start+1]] == vertex[2], ExcInternalError());
00270       Assert(boundary[3]->vertex[ii[start+2]] == vertex[1], ExcInternalError());
00271       step = 2;
00272     }
00273     Assert(edge_midpoint[5] == boundary[3]->boundary[start]->child[0]->vertex[1], ExcInternalError());
00274     Assert(edge_midpoint[1] == boundary[3]->boundary[ii[start+step]]->child[0]->vertex[1], ExcInternalError());
00275     Assert(edge_midpoint[0] == boundary[3]->boundary[ii[start+2*step]]->child[0]->vertex[1], ExcInternalError());
00276 
00277     surface_child[3][0] = boundary[3]->child[start];
00278     surface_child[3][1] = boundary[3]->child[ii[start+step]];
00279     surface_child[3][2] = boundary[3]->child[ii[start+2*step]];
00280     surface_child[3][3] = boundary[3]->child[3];
00281   }
00282 
00283   // we add those geometries should be added for all refine model at first, which
00284   // include four triangles and four tetrahedrons at the four vertices.
00285   HGeometry<2,DOW> * triangle[8];
00286   for (i = 0;i < 8;i ++) {
00287     triangle[i] = new HGeometry<2,DOW>();
00288     Assert(triangle[i] != NULL, ExcOutOfMemory());
00289   }
00290   triangle[0]->vertex[0] = edge_midpoint[0];
00291   triangle[0]->vertex[1] = edge_midpoint[1];
00292   triangle[0]->vertex[2] = edge_midpoint[2];
00293   triangle[0]->boundary[0] = surface_child[1][0]->boundary[0];
00294   triangle[0]->boundary[1] = surface_child[2][0]->boundary[0];
00295   triangle[0]->boundary[2] = surface_child[3][0]->boundary[0];
00296   triangle[0]->bmark = bmark;
00297         
00298   triangle[1]->vertex[0] = edge_midpoint[4];
00299   triangle[1]->vertex[1] = edge_midpoint[5];
00300   triangle[1]->vertex[2] = edge_midpoint[0];
00301   triangle[1]->boundary[0] = surface_child[3][1]->boundary[0];
00302   triangle[1]->boundary[1] = surface_child[2][1]->boundary[0];
00303   triangle[1]->boundary[2] = surface_child[0][0]->boundary[0];  
00304   triangle[1]->bmark = bmark;
00305         
00306   triangle[2]->vertex[0] = edge_midpoint[5];
00307   triangle[2]->vertex[1] = edge_midpoint[3];
00308   triangle[2]->vertex[2] = edge_midpoint[1];
00309   triangle[2]->boundary[0] = surface_child[1][1]->boundary[0];
00310   triangle[2]->boundary[1] = surface_child[3][2]->boundary[0];
00311   triangle[2]->boundary[2] = surface_child[0][1]->boundary[0];  
00312   triangle[2]->bmark = bmark;
00313 
00314   triangle[3]->vertex[0] = edge_midpoint[2];
00315   triangle[3]->vertex[1] = edge_midpoint[3];
00316   triangle[3]->vertex[2] = edge_midpoint[4];
00317   triangle[3]->boundary[0] = surface_child[0][2]->boundary[0];
00318   triangle[3]->boundary[1] = surface_child[2][2]->boundary[0];
00319   triangle[3]->boundary[2] = surface_child[1][2]->boundary[0];  
00320   triangle[3]->bmark = bmark;
00321 
00322   // the four child tetrahedrons on the four verteics
00323   for (i = 0;i < 8;i ++) {
00324     child[i] = new HGeometry<3,DOW>();
00325     Assert (child[i] != NULL, ExcOutOfMemory());
00326   }
00327         
00328   child[0]->parent = this;
00329   child[0]->vertex[0] = vertex[0];
00330   child[0]->vertex[1] = edge_midpoint[0];
00331   child[0]->vertex[2] = edge_midpoint[1];
00332   child[0]->vertex[3] = edge_midpoint[2];
00333   child[0]->boundary[0] = triangle[0];
00334   child[0]->boundary[1] = surface_child[1][0];
00335   child[0]->boundary[2] = surface_child[2][0];
00336   child[0]->boundary[3] = surface_child[3][0];
00337   child[0]->bmark = bmark;
00338         
00339   child[1]->parent = this;
00340   child[1]->vertex[0] = vertex[1];
00341   child[1]->vertex[1] = edge_midpoint[5];
00342   child[1]->vertex[2] = edge_midpoint[0];
00343   child[1]->vertex[3] = edge_midpoint[4];
00344   child[1]->boundary[0] = triangle[1];
00345   child[1]->boundary[1] = surface_child[2][1];
00346   child[1]->boundary[2] = surface_child[0][0];
00347   child[1]->boundary[3] = surface_child[3][1];
00348   child[1]->bmark = bmark;
00349         
00350   child[2]->parent = this;
00351   child[2]->vertex[0] = vertex[2];
00352   child[2]->vertex[1] = edge_midpoint[1];
00353   child[2]->vertex[2] = edge_midpoint[5];
00354   child[2]->vertex[3] = edge_midpoint[3];
00355   child[2]->boundary[0] = triangle[2];
00356   child[2]->boundary[1] = surface_child[0][1];
00357   child[2]->boundary[2] = surface_child[1][1];
00358   child[2]->boundary[3] = surface_child[3][2];
00359   child[2]->bmark = bmark;
00360         
00361   child[3]->parent = this;
00362   child[3]->vertex[0] = vertex[3];
00363   child[3]->vertex[1] = edge_midpoint[2];
00364   child[3]->vertex[2] = edge_midpoint[3];
00365   child[3]->vertex[3] = edge_midpoint[4];
00366   child[3]->boundary[0] = triangle[3];
00367   child[3]->boundary[1] = surface_child[0][2];
00368   child[3]->boundary[2] = surface_child[2][2];
00369   child[3]->boundary[3] = surface_child[1][2];
00370   child[3]->bmark = bmark;      
00371 
00372   // choose the best refinement model. There are total 3 models to refine the
00373   // central part of the tetrahedron, between which the key difference is which
00374   // line is chosed as the main axis of geometry. To make the obtained tetrahedrons
00375   // more regular, we will choose the shortest diagonal line as the main axis.
00376   double l03, l14, l25;
00377   l03 = (*edge_midpoint[0] - *edge_midpoint[3]).length();
00378   l14 = (*edge_midpoint[1] - *edge_midpoint[4]).length();
00379   l25 = (*edge_midpoint[2] - *edge_midpoint[5]).length();
00380   if (l03 <= l14)
00381     if (l03 <= l25)
00382       refine_model = REFINE_MODEL_03;
00383     else
00384       refine_model = REFINE_MODEL_25;
00385   else
00386     if (l14 <= l25)
00387       refine_model = REFINE_MODEL_14;
00388     else
00389       refine_model = REFINE_MODEL_25;
00390 
00391   HGeometry<1,DOW> * axis;
00392   switch (refine_model) {
00393         
00394   case REFINE_MODEL_03:
00395     // add the main axis at first
00396     axis = new HGeometry<1,DOW>();
00397     Assert (axis != NULL, ExcOutOfMemory());
00398     axis->vertex[0] = edge_midpoint[0];
00399     axis->vertex[1] = edge_midpoint[3];
00400     axis->bmark = bmark;
00401                 
00402     // add the four triangles
00403     triangle[4]->vertex[0] = edge_midpoint[4];
00404     triangle[4]->vertex[1] = edge_midpoint[3];
00405     triangle[4]->vertex[2] = edge_midpoint[0];
00406     triangle[4]->boundary[0] = axis;
00407     triangle[4]->boundary[1] = surface_child[2][1]->boundary[0];
00408     triangle[4]->boundary[2] = surface_child[0][2]->boundary[0];
00409     triangle[4]->bmark = bmark;
00410                 
00411     triangle[5]->vertex[0] = edge_midpoint[2];
00412     triangle[5]->vertex[1] = edge_midpoint[3];
00413     triangle[5]->vertex[2] = edge_midpoint[0];
00414     triangle[5]->boundary[0] = axis;
00415     triangle[5]->boundary[1] = surface_child[2][0]->boundary[0];
00416     triangle[5]->boundary[2] = surface_child[1][2]->boundary[0];
00417     triangle[5]->bmark = bmark;
00418                 
00419     triangle[6]->vertex[0] = edge_midpoint[1];
00420     triangle[6]->vertex[1] = edge_midpoint[3];
00421     triangle[6]->vertex[2] = edge_midpoint[0];
00422     triangle[6]->boundary[0] = axis;
00423     triangle[6]->boundary[1] = surface_child[3][0]->boundary[0];
00424     triangle[6]->boundary[2] = surface_child[1][1]->boundary[0];
00425     triangle[6]->bmark = bmark;
00426 
00427     triangle[7]->vertex[0] = edge_midpoint[5];
00428     triangle[7]->vertex[1] = edge_midpoint[3];
00429     triangle[7]->vertex[2] = edge_midpoint[0];
00430     triangle[7]->boundary[0] = axis;
00431     triangle[7]->boundary[1] = surface_child[3][1]->boundary[0];
00432     triangle[7]->boundary[2] = surface_child[0][1]->boundary[0];
00433     triangle[7]->bmark = bmark;
00434                 
00435     // add the four tetrahedrons
00436     child[4]->parent = this;
00437     child[4]->vertex[0] = edge_midpoint[0];
00438     child[4]->vertex[1] = edge_midpoint[3];
00439     child[4]->vertex[2] = edge_midpoint[4];
00440     child[4]->vertex[3] = edge_midpoint[5];
00441     child[4]->boundary[0] = surface_child[0][3];
00442     child[4]->boundary[1] = triangle[1];
00443     child[4]->boundary[2] = triangle[7];
00444     child[4]->boundary[3] = triangle[4];
00445     child[4]->bmark = bmark;
00446 
00447     child[5]->parent = this;
00448     child[5]->vertex[0] = edge_midpoint[0];
00449     child[5]->vertex[1] = edge_midpoint[3];
00450     child[5]->vertex[2] = edge_midpoint[1];
00451     child[5]->vertex[3] = edge_midpoint[2];
00452     child[5]->boundary[0] = surface_child[1][3];
00453     child[5]->boundary[1] = triangle[0];
00454     child[5]->boundary[2] = triangle[5];
00455     child[5]->boundary[3] = triangle[6];
00456     child[5]->bmark = bmark;
00457 
00458     child[6]->parent = this;
00459     child[6]->vertex[0] = edge_midpoint[3];
00460     child[6]->vertex[1] = edge_midpoint[0];
00461     child[6]->vertex[2] = edge_midpoint[4];
00462     child[6]->vertex[3] = edge_midpoint[2];
00463     child[6]->boundary[0] = surface_child[2][3];
00464     child[6]->boundary[1] = triangle[3];
00465     child[6]->boundary[2] = triangle[5];
00466     child[6]->boundary[3] = triangle[4];
00467     child[6]->bmark = bmark;
00468 
00469     child[7]->parent = this;
00470     child[7]->vertex[0] = edge_midpoint[3];
00471     child[7]->vertex[1] = edge_midpoint[0];
00472     child[7]->vertex[2] = edge_midpoint[1];
00473     child[7]->vertex[3] = edge_midpoint[5];
00474     child[7]->boundary[0] = surface_child[3][3];
00475     child[7]->boundary[1] = triangle[2];
00476     child[7]->boundary[2] = triangle[7];
00477     child[7]->boundary[3] = triangle[6];
00478     child[7]->bmark = bmark;
00479 
00480     break;
00481 
00482   case REFINE_MODEL_14:
00483     // add the main axis at first
00484     axis = new HGeometry<1,DOW>();
00485     Assert (axis != NULL, ExcOutOfMemory());
00486     axis->vertex[0] = edge_midpoint[1];
00487     axis->vertex[1] = edge_midpoint[4];
00488     axis->bmark = bmark;
00489                 
00490     // add the four triangles
00491     triangle[4]->vertex[0] = edge_midpoint[5];
00492     triangle[4]->vertex[1] = edge_midpoint[4];
00493     triangle[4]->vertex[2] = edge_midpoint[1];
00494     triangle[4]->boundary[0] = axis;
00495     triangle[4]->boundary[1] = surface_child[3][2]->boundary[0];
00496     triangle[4]->boundary[2] = surface_child[0][0]->boundary[0];
00497     triangle[4]->bmark = bmark;
00498                 
00499     triangle[5]->vertex[0] = edge_midpoint[0];
00500     triangle[5]->vertex[1] = edge_midpoint[4];
00501     triangle[5]->vertex[2] = edge_midpoint[1];
00502     triangle[5]->boundary[0] = axis;
00503     triangle[5]->boundary[1] = surface_child[3][0]->boundary[0];
00504     triangle[5]->boundary[2] = surface_child[2][1]->boundary[0];
00505     triangle[5]->bmark = bmark;
00506                 
00507     triangle[6]->vertex[0] = edge_midpoint[2];
00508     triangle[6]->vertex[1] = edge_midpoint[4];
00509     triangle[6]->vertex[2] = edge_midpoint[1];
00510     triangle[6]->boundary[0] = axis;
00511     triangle[6]->boundary[1] = surface_child[1][0]->boundary[0];
00512     triangle[6]->boundary[2] = surface_child[2][2]->boundary[0];
00513     triangle[6]->bmark = bmark;
00514 
00515     triangle[7]->vertex[0] = edge_midpoint[3];
00516     triangle[7]->vertex[1] = edge_midpoint[4];
00517     triangle[7]->vertex[2] = edge_midpoint[1];
00518     triangle[7]->boundary[0] = axis;
00519     triangle[7]->boundary[1] = surface_child[1][1]->boundary[0];
00520     triangle[7]->boundary[2] = surface_child[0][2]->boundary[0];
00521     triangle[7]->bmark = bmark;
00522                 
00523     // add the four tetrahedrons
00524     child[4]->parent = this;
00525     child[4]->vertex[0] = edge_midpoint[1];
00526     child[4]->vertex[1] = edge_midpoint[4];
00527     child[4]->vertex[2] = edge_midpoint[5];
00528     child[4]->vertex[3] = edge_midpoint[3];
00529     child[4]->boundary[0] = surface_child[0][3];
00530     child[4]->boundary[1] = triangle[2];
00531     child[4]->boundary[2] = triangle[7];
00532     child[4]->boundary[3] = triangle[4];
00533     child[4]->bmark = bmark;
00534 
00535     child[5]->parent = this;
00536     child[5]->vertex[0] = edge_midpoint[4];
00537     child[5]->vertex[1] = edge_midpoint[1];
00538     child[5]->vertex[2] = edge_midpoint[2];
00539     child[5]->vertex[3] = edge_midpoint[3];
00540     child[5]->boundary[0] = surface_child[1][3];
00541     child[5]->boundary[1] = triangle[3];
00542     child[5]->boundary[2] = triangle[7];
00543     child[5]->boundary[3] = triangle[6];
00544     child[5]->bmark = bmark;
00545 
00546     child[6]->parent = this;
00547     child[6]->vertex[0] = edge_midpoint[1];
00548     child[6]->vertex[1] = edge_midpoint[4];
00549     child[6]->vertex[2] = edge_midpoint[2];
00550     child[6]->vertex[3] = edge_midpoint[0];
00551     child[6]->boundary[0] = surface_child[2][3];
00552     child[6]->boundary[1] = triangle[0];
00553     child[6]->boundary[2] = triangle[5];
00554     child[6]->boundary[3] = triangle[6];
00555     child[6]->bmark = bmark;
00556 
00557     child[7]->parent = this;
00558     child[7]->vertex[0] = edge_midpoint[4];
00559     child[7]->vertex[1] = edge_midpoint[1];
00560     child[7]->vertex[2] = edge_midpoint[5];
00561     child[7]->vertex[3] = edge_midpoint[0];
00562     child[7]->boundary[0] = surface_child[3][3];
00563     child[7]->boundary[1] = triangle[1];
00564     child[7]->boundary[2] = triangle[5];
00565     child[7]->boundary[3] = triangle[4];
00566     child[7]->bmark = bmark;
00567 
00568     break;
00569 
00570   case REFINE_MODEL_25:
00571     // add the main axis at first
00572     axis = new HGeometry<1,DOW>();
00573     Assert (axis != NULL, ExcOutOfMemory());
00574     axis->vertex[0] = edge_midpoint[2];
00575     axis->vertex[1] = edge_midpoint[5];
00576     axis->bmark = bmark;
00577                 
00578     // add the four triangles
00579     triangle[4]->vertex[0] = edge_midpoint[4];
00580     triangle[4]->vertex[1] = edge_midpoint[5];
00581     triangle[4]->vertex[2] = edge_midpoint[2];
00582     triangle[4]->boundary[0] = axis;
00583     triangle[4]->boundary[1] = surface_child[2][2]->boundary[0];
00584     triangle[4]->boundary[2] = surface_child[0][0]->boundary[0];
00585     triangle[4]->bmark = bmark;
00586                 
00587     triangle[5]->vertex[0] = edge_midpoint[0];
00588     triangle[5]->vertex[1] = edge_midpoint[5];
00589     triangle[5]->vertex[2] = edge_midpoint[2];
00590     triangle[5]->boundary[0] = axis;
00591     triangle[5]->boundary[1] = surface_child[2][0]->boundary[0];
00592     triangle[5]->boundary[2] = surface_child[3][1]->boundary[0];
00593     triangle[5]->bmark = bmark;
00594                 
00595     triangle[6]->vertex[0] = edge_midpoint[1];
00596     triangle[6]->vertex[1] = edge_midpoint[5];
00597     triangle[6]->vertex[2] = edge_midpoint[2];
00598     triangle[6]->boundary[0] = axis;
00599     triangle[6]->boundary[1] = surface_child[1][0]->boundary[0];
00600     triangle[6]->boundary[2] = surface_child[3][2]->boundary[0];
00601     triangle[6]->bmark = bmark;
00602 
00603     triangle[7]->vertex[0] = edge_midpoint[3];
00604     triangle[7]->vertex[1] = edge_midpoint[5];
00605     triangle[7]->vertex[2] = edge_midpoint[2];
00606     triangle[7]->boundary[0] = axis;
00607     triangle[7]->boundary[1] = surface_child[1][2]->boundary[0];
00608     triangle[7]->boundary[2] = surface_child[0][1]->boundary[0];
00609     triangle[7]->bmark = bmark;
00610                 
00611     // add the four tetrahedrons
00612     child[4]->parent = this;
00613     child[4]->vertex[0] = edge_midpoint[2];
00614     child[4]->vertex[1] = edge_midpoint[5];
00615     child[4]->vertex[2] = edge_midpoint[3];
00616     child[4]->vertex[3] = edge_midpoint[4];
00617     child[4]->boundary[0] = surface_child[0][3];
00618     child[4]->boundary[1] = triangle[3];
00619     child[4]->boundary[2] = triangle[4];
00620     child[4]->boundary[3] = triangle[7];
00621     child[4]->bmark = bmark;
00622 
00623     child[5]->parent = this;
00624     child[5]->vertex[0] = edge_midpoint[5];
00625     child[5]->vertex[1] = edge_midpoint[2];
00626     child[5]->vertex[2] = edge_midpoint[3];
00627     child[5]->vertex[3] = edge_midpoint[1];
00628     child[5]->boundary[0] = surface_child[1][3];
00629     child[5]->boundary[1] = triangle[2];
00630     child[5]->boundary[2] = triangle[6];
00631     child[5]->boundary[3] = triangle[7];
00632     child[5]->bmark = bmark;
00633 
00634     child[6]->parent = this;
00635     child[6]->vertex[0] = edge_midpoint[5];
00636     child[6]->vertex[1] = edge_midpoint[2];
00637     child[6]->vertex[2] = edge_midpoint[0];
00638     child[6]->vertex[3] = edge_midpoint[4];
00639     child[6]->boundary[0] = surface_child[2][3];
00640     child[6]->boundary[1] = triangle[1];
00641     child[6]->boundary[2] = triangle[4];
00642     child[6]->boundary[3] = triangle[5];
00643     child[6]->bmark = bmark;
00644 
00645     child[7]->parent = this;
00646     child[7]->vertex[0] = edge_midpoint[2];
00647     child[7]->vertex[1] = edge_midpoint[5];
00648     child[7]->vertex[2] = edge_midpoint[0];
00649     child[7]->vertex[3] = edge_midpoint[1];
00650     child[7]->boundary[0] = surface_child[3][3];
00651     child[7]->boundary[1] = triangle[0];
00652     child[7]->boundary[2] = triangle[6];
00653     child[7]->boundary[3] = triangle[5];
00654     child[7]->bmark = bmark;
00655 
00656     break;
00657 
00658   default:
00659     Assert(false, ExcInternalError());
00660   }     
00661 }
00662 
00663 
00664 template <>
00665 void HGeometry<1,DOW>::checkIntegrity() const
00666 {
00667   if (!isRefined()) return;
00668   for (int i = 0;i < n_child;i ++) {
00669     child[i]->checkIntegrity();
00670   }
00671 }
00672 
00673 
00674 
00675 template <>
00676 void HGeometry<2,DOW>::checkIntegrity() const
00677 {
00678   int i, j, k;
00679   for (i = 0;i < n_boundary;i ++) {
00680     HGeometry<1,DOW> * b = boundary[i];
00681     for (j = 0;j < b->n_vertex;j ++) {
00682       for (k = 0;k < n_vertex;k ++) {
00683         if (k == i) continue;
00684         if (b->vertex[j] == vertex[k])
00685           break;
00686       }
00687       Assert(k < n_vertex, ExcInternalError());
00688     }
00689   }
00690   if (!isRefined()) return;
00691   for (int i = 0;i < n_child;i ++) {
00692     child[i]->checkIntegrity(); 
00693   }
00694 }
00695 
00696 
00697 
00698 template <>
00699 void HGeometry<3,DOW>::checkIntegrity() const
00700 {
00701   int i, j, k;
00702   for (i = 0;i < n_boundary;i ++) {
00703     HGeometry<2,DOW> * b = boundary[i];
00704     for (j = 0;j < b->n_vertex;j ++) {
00705       for (k = 0;k < n_vertex;k ++) {
00706         if (k == i) continue;
00707         if (b->vertex[j] == vertex[k])
00708           break;
00709       }
00710       Assert(k < n_vertex, ExcInternalError());
00711     }
00712   }
00713   if (!isRefined()) return;
00714   for (int i = 0;i < n_child;i ++) {
00715     child[i]->checkIntegrity(); 
00716   }
00717 }
00718 
00719 
00720 
00721 template <>
00722 bool HGeometry<1,DOW>::isIncludePoint(const Point<DOW>& p) const
00723 {
00724   std::cerr << "warning: HGeometry<1,DOW>::isIncludePoint not implemented, return true" << std::endl;
00725   return true;
00726 }
00727 
00728 
00729 template <>
00730 bool HGeometry<2,DOW>::isIncludePoint(const Point<DOW>& p) const
00731 {
00732   double lambda[3];
00733   double volume = (((*vertex[1])[0] - (*vertex[0])[0])*((*vertex[2])[1] - (*vertex[0])[1]) - 
00734                    ((*vertex[1])[1] - (*vertex[0])[1])*((*vertex[2])[0] - (*vertex[0])[0]));
00735   double mzero = -1.0e-08;
00736   lambda[0] = (((*vertex[1])[0] - p[0])*((*vertex[2])[1] - p[1]) - 
00737                ((*vertex[1])[1] - p[1])*((*vertex[2])[0] - p[0]))/volume;
00738   lambda[1] = (((*vertex[2])[0] - p[0])*((*vertex[0])[1] - p[1]) - 
00739                ((*vertex[2])[1] - p[1])*((*vertex[0])[0] - p[0]))/volume;
00740   lambda[2] = (((*vertex[0])[0] - p[0])*((*vertex[1])[1] - p[1]) -
00741                ((*vertex[0])[1] - p[1])*((*vertex[1])[0] - p[0]))/volume;
00742   return (lambda[0] >= mzero && lambda[1] >= mzero && lambda[2] >= mzero);
00743 }
00744 
00745 
00746 
00747 template <>
00748 bool HGeometry<3,DOW>::isIncludePoint(const Point<DOW>& p) const
00749 {
00750   std::cerr << "warning: HGeometry<3,DOW>::isIncludePoint not implemented, return true" << std::endl;
00751   return true;
00752 }
00753 
00754 
00755 
00756 template <>
00757 void HElement<2, DOW>::refine()
00758 {
00759   if (isRefined()) return;
00760 
00761   h_element->refine();
00762 
00763   // construct its own child
00764   for (int i = 0;i < n_child;i ++) {
00765     child[i] = new HElement<2, DOW>();
00766     Assert (child[i] != NULL, ExcOutOfMemory());
00767     child[i]->h_element = h_element->child[i];
00768     child[i]->parent = this;
00769   }
00770 }
00771 
00772 
00773 
00774 template <>
00775 void HElement<3, DOW>::refine()
00776 {
00777   if (isRefined()) return;
00778         
00779   // refine the h geometry tree at first
00780   h_element->refine();
00781 
00782   // construct its own child
00783   for (int i = 0;i < n_child;i ++) {
00784     child[i] = new HElement<3, DOW>();
00785     Assert (child[i] != NULL, ExcOutOfMemory());
00786     child[i]->h_element = h_element->child[i];
00787     child[i]->parent = this;
00788   }
00789 }
00790 
00791 
00792 
00793 template <>
00794 std::ostream& operator<<(std::ostream& os, const HGeometry<1,DOW>& geometry)
00795 {
00796   os << (*geometry.vertex[0])[0] << "\t"
00797      << (*geometry.vertex[1])[0] << "\t"
00798      << (*geometry.vertex[0])[1] << "\t"
00799      << (*geometry.vertex[1])[1] << "\n";
00800   return os;
00801 }
00802 
00803 
00804 
00805 template <>
00806 std::ostream& operator<<(std::ostream& os, const HGeometry<0,DOW>& geometry)
00807 {
00808   //    for (int i = 0;i < DOW;i ++)
00809   //            os << geometry[i] << "\t";
00810   return os;
00811 }
00812 
00813 
00814 
00815 template <>
00816 void IrregularMesh<2, DOW>::regularize(bool renumerate)
00817 {
00818   if (regular_mesh != NULL)
00819     delete regular_mesh;
00820   std::cerr << "Generating regular mesh from the semiregular mesh ..." << std::flush; 
00821   int i, j, k, n_node, n_side, n_element;
00822   int ii[] = {0, 1, 2, 0, 1, 2, 0, 1, 2};
00823 
00824   std::cerr << "\n\tpreparing data ..." << std::flush;
00825   Tools tools;
00826   ActiveElementIterator<2, DOW> 
00827     the_ele = beginActiveElement(),
00828     end_ele = endActiveElement();
00829   // ΪԼ׼
00830   n_element = 0;
00831   for (;the_ele != end_ele;++ the_ele) {
00832     HGeometry<2, DOW> *& h_element = the_ele->h_element;
00837     for (i = 0;i < h_element->n_vertex;i ++) {
00838       tools.setGeometryActive(*(h_element->vertex[i]));
00839     }
00845     int n_refined_edge = 0;
00846     for (i = 0;i < the_ele->n_boundary;i ++) { 
00847       HGeometry<1, DOW>& side = *(h_element->boundary[i]);
00852       if (tools.isRefined(side)) { 
00853         tools.setGeometryActive(*side.child[0]->vertex[1]); 
00854         tools.setGeometryActive(*side.child[0]);
00855         tools.setGeometryActive(*side.child[1]);
00856         tools.setGeometryInactive(side);
00857         n_refined_edge += 1;
00858       } else { 
00859         tools.setGeometryActive(side);
00860       }
00861     }
00862     assert (n_refined_edge <= 1);
00863     assert (tools.isGeometryUsed(*h_element));
00864     tools.setParentInactive(*h_element);
00865     n_element += 1;
00866   }
00867 
00868   // м
00869   n_node = 0;
00870   n_side = 0;
00871   n_element = 0;
00872   the_ele = beginActiveElement();
00873   for (;the_ele != end_ele;++ the_ele) {
00874     HGeometry<2, DOW> *& h_element = the_ele->h_element;
00879     for (i = 0;i < the_ele->n_vertex;i ++) { 
00880       HGeometry<0, DOW>& node = *(h_element->vertex[i]);
00881       if (tools.isGeometryActive(node)) {
00882         node.index = n_node ++;
00883       }
00884     }
00889     int n_refined_edge = 0;
00890     for (i = 0;i < the_ele->n_boundary;i ++) { 
00891       HGeometry<1, DOW>& side = *(h_element->boundary[i]);
00892       if (tools.isGeometryActive(side)) { 
00893         side.index = n_side ++;
00894       } else if (tools.isGeometryInactive(side)) { 
00895         HGeometry<0, DOW>& mp = *(side.child[0]->vertex[1]);
00896         if (tools.isGeometryActive(mp)) { 
00897           mp.index = n_node ++;
00898         }
00899         for (j = 0;j < side.n_child;++ j) { 
00900           HGeometry<1, DOW> *& chd = side.child[j];
00901           if (tools.isGeometryActive(*chd)) {
00902             chd->index = n_side ++;
00903           }
00904         }
00905         n_refined_edge += 1;
00906       }
00907     }
00908     assert (n_refined_edge <= 1);
00909     assert (tools.isGeometryActive(*h_element));
00910     h_element->index = n_element ++; 
00911     the_ele->index = h_element->index;
00912   }
00913         
00914   std::cerr << "\n\tbuilding the regular mesh ..." << std::flush;
00915   // 򻯵
00916   regular_mesh = new RegularMesh<2, DOW>(this);
00917   Assert (regular_mesh != NULL, ExcOutOfMemory());
00918   regular_mesh->point().resize(n_node);
00919   regular_mesh->geometry(0).resize(n_node);
00920   regular_mesh->geometry(1).resize(n_side);
00921   regular_mesh->geometry(2).resize(n_element);
00922 
00923 #ifdef __SERIALIZATION__
00924   std::vector<std::vector<HBuffer*> >& h_geometry = regular_mesh->h_geometry();
00925   h_geometry.clear();
00926   h_geometry.resize(3);
00927   h_geometry[0].resize(n_node);
00928   h_geometry[1].resize(n_side);
00929   h_geometry[2].resize(n_element);
00930 #endif
00931 
00932   int n_triangle = 0, n_twin_triangle = 0;
00933   the_ele = beginActiveElement();
00934   for (;the_ele != end_ele;++ the_ele) {
00935     HGeometry<2, DOW> * h_element = the_ele->h_element;
00936     // ȼεĶ
00937     for (i = 0;i < the_ele->n_vertex;i ++) {
00938       HGeometry<0, DOW>& vtx = *(h_element->vertex[i]);
00939       j = vtx.index;
00940       GeometryBM& pnt = regular_mesh->geometry(0,j);
00941       tools.regularize_add_node(vtx, 
00942                                 pnt,
00943                                 regular_mesh->point(j));
00944 #ifdef __SERIALIZATION__
00945       h_geometry[0][j] = &vtx;
00946 #endif
00947     }
00948 
00949     // Ȼε
00950     int m_refined_edge = -1;
00951     for (i = 0;i < the_ele->n_boundary;i ++) {
00952       HGeometry<1, DOW>& bnd = *(h_element->boundary[i]);
00953       if (tools.isGeometryInactive(bnd)) { // ϸֵı
00954         assert (m_refined_edge == -1);
00955         m_refined_edge = i;
00956 
00958         HGeometry<0, DOW>& mp = *(bnd.child[0]->vertex[1]);
00959         j = mp.index;
00960         tools.regularize_add_node(mp, 
00961                                   regular_mesh->geometry(0,j),
00962                                   regular_mesh->point(j));
00963 #ifdef __SERIALIZATION__
00964         h_geometry[0][j] = &mp;
00965 #endif
00966 
00967         HGeometry<1, DOW>& bnd0 = *(bnd.child[0]);
00968         j = bnd0.index;
00969         tools.regularize_add_side(bnd0,
00970                                   regular_mesh->geometry(1,j));
00971 #ifdef __SERIALIZATION__
00972         h_geometry[1][j] = &bnd0;
00973 #endif
00974 
00975         HGeometry<1, DOW>& bnd1 = *(bnd.child[1]);
00976         j = bnd1.index;
00977         tools.regularize_add_side(bnd1,
00978                                   regular_mesh->geometry(1,j));
00979 #ifdef __SERIALIZATION__
00980         h_geometry[1][j] = &bnd1;
00981 #endif
00982       } else { 
00983 
00984         j = bnd.index;
00985         tools.regularize_add_side(bnd,
00986                                   regular_mesh->geometry(1,j));
00987 #ifdef __SERIALIZATION__
00988         h_geometry[1][j] = &bnd;
00989 #endif
00990       }
00991     }
00992 
00993     // Ϊκ˫
00994     j = h_element->index;
00995     assert (j == the_ele->index);
00996     GeometryBM& element = regular_mesh->geometry(2,j);
00997     Assert(element.index() == -1, ExcInternalError());
00998 #ifdef __SERIALIZATION__
00999     h_geometry[2][j] = h_element;
01000 #endif
01001     element.boundaryMark() = h_element->bmark;
01002     if (m_refined_edge == -1) { 
01003       n_triangle ++;
01004       tools.regularize_add_triangle(*h_element, element);
01005     } else { // ˫ε
01006       n_twin_triangle ++;
01007       tools.regularize_add_twin_triangle(*h_element, element, m_refined_edge);
01008     }
01009   }
01010         
01011   geometry_tree->unlock(); 
01012   std::cerr << "\n\tnodes: " << n_node 
01013             << "; sides: " << n_side
01014             << "; elements: " << n_element
01015             << " (" << n_triangle
01016             << ", " << n_twin_triangle
01017             << ")" << std::endl;
01018         
01019   if (renumerate) renumerateElement();
01020 }
01021 
01022 
01023 
01024 template <>
01025 void IrregularMesh<3, DOW>::regularize(bool renumerate)
01026 {
01027   if (regular_mesh != NULL)
01028     delete regular_mesh;
01029   std::cerr << "Generating regular mesh from the semiregular mesh ..." << std::flush; 
01030   int i, j, k, l, m, n_node, n_edge, n_surface, n_element;
01031   int ii[] = {0, 1, 2, 0, 1, 2, 0, 1, 2};
01032 
01033   std::cerr << "\n\tpreparing data ..." << std::flush;
01034   Tools tools;
01035   ActiveElementIterator<3, DOW> 
01036     the_ele = beginActiveElement(),
01037     end_ele = endActiveElement();
01038   // Ϊм׼
01039   for (;the_ele != end_ele;++ the_ele) {
01040     HGeometry<3, DOW> * h_element = the_ele->h_element;
01041     for (i = 0;i < the_ele->n_vertex;i ++) {
01042       tools.setGeometryActive(*(h_element->vertex[i]));
01043     }
01044     for (i = 0;i < h_element->n_boundary;i ++) { 
01045       HGeometry<2, DOW>& surface = *(h_element->boundary[i]);
01052       if (tools.isRefined(surface)) { 
01053         tools.setGeometryActive(*surface.child[3]->boundary[0]);
01054         tools.setGeometryActive(*surface.child[3]->boundary[1]);
01055         tools.setGeometryActive(*surface.child[3]->boundary[2]);
01056         tools.setGeometryActive(*surface.child[0]);
01057         tools.setGeometryActive(*surface.child[1]);
01058         tools.setGeometryActive(*surface.child[2]);
01059         tools.setGeometryActive(*surface.child[3]);
01060         tools.setGeometryInactive(surface);
01061       } else { 
01062         tools.setGeometryActive(surface);
01063       }
01064       for (j = 0;j < surface.n_boundary;++ j) { 
01065         HGeometry<1, DOW>& edge = *(surface.boundary[j]);
01066         if (tools.isRefined(edge)) {
01067           tools.setGeometryActive(*edge.child[0]->vertex[1]);
01068           tools.setGeometryActive(*edge.child[0]);
01069           tools.setGeometryActive(*edge.child[1]);
01070           tools.setGeometryInactive(edge);
01071         }
01072       }
01073     }
01074     Assert(tools.isGeometryActive(*h_element), ExcInternalError());
01075     tools.setParentInactive(*h_element);
01076   }
01077 
01078   // м
01079   n_node = 0;
01080   n_edge = 0;
01081   n_surface = 0;
01082   n_element = 0;
01083   the_ele = beginActiveElement();
01084   for (;the_ele != end_ele;++ the_ele) {
01085     HGeometry<3, DOW> * h_element = the_ele->h_element;
01086     // Ŷ
01087     for (i = 0;i < the_ele->n_vertex;i ++) {
01088       HGeometry<0, DOW>& node = *(h_element->vertex[i]);
01089       if (tools.isGeometryActive(node)) {
01090         node.index = n_node ++;
01091       }
01092     }
01093 
01094     // 
01095     for (i = 0;i < the_ele->n_boundary;i ++) {
01096       HGeometry<2, DOW>& surface = *(h_element->boundary[i]);
01097       if (tools.isGeometryActive(surface)) {
01098         surface.index = n_surface ++;
01099         for (j = 0;j < surface.n_boundary;j ++) {
01100           HGeometry<1, DOW>& edge = *(surface.boundary[j]);
01101           if (tools.isGeometryActive(edge)) {
01102             edge.index = n_edge ++;
01103           }
01104         }
01105       } else if (tools.isGeometryInactive(surface)) {
01106         for (u_int j = 0;j < surface.n_child;++ j) {
01107           HGeometry<2,DOW> * chd = surface.child[j];
01108           if (tools.isGeometryActive(*chd)) {
01109             chd->index = n_surface ++;
01110           }
01111           for (u_int k = 0;k < chd->n_vertex;++ k) {
01112             HGeometry<0,DOW>& vtx = *(chd->vertex[k]);
01113             if (tools.isGeometryActive(vtx)) {
01114               vtx.index = n_node ++;
01115             }
01116           }
01117           for (u_int k = 0;k < chd->n_boundary;++ k) {
01118             HGeometry<1,DOW>& bnd = *(chd->boundary[k]);
01119             if (tools.isGeometryActive(bnd)) {
01120               bnd.index = n_edge ++;
01121             }
01122           }
01123         }
01124       }
01125     }
01126     Assert(tools.isGeometryActive(*h_element),  ExcInternalError());
01127     h_element->index = n_element ++;
01128     the_ele->index = h_element->index;
01129   }
01130         
01131   std::cerr << "\n\tbuilding the regular mesh ..." << std::flush;
01132   // 
01133   regular_mesh = new RegularMesh<3, DOW>(this);
01134   Assert(regular_mesh != NULL, ExcOutOfMemory());
01135   regular_mesh->point().resize(n_node);
01136   regular_mesh->geometry(0).resize(n_node);
01137   regular_mesh->geometry(1).resize(n_edge);
01138   regular_mesh->geometry(2).resize(n_surface);
01139   regular_mesh->geometry(3).resize(n_element);
01140         
01141 #ifdef __SERIALIZATION__
01142   std::vector<std::vector<HBuffer*> >& h_geometry = regular_mesh->h_geometry();
01143   h_geometry.clear();
01144   h_geometry.resize(4);
01145   h_geometry[0].resize(n_node);
01146   h_geometry[1].resize(n_edge);
01147   h_geometry[2].resize(n_surface);
01148   h_geometry[3].resize(n_element);
01149 #endif
01150 
01151   int n_tetrahedron = 0;
01152   int n_twin_tetrahedron = 0;
01153   int n_four_tetrahedron = 0;
01154   int n_twin_triangle_surface, twin_triangle_surface[3];
01155   int n_nonactive_neighbour, nonactive_neighbour;
01156   HGeometry<1, DOW> * m_refined_edge;
01157   HGeometry<1, DOW> * edge;
01158   HGeometry<2, DOW> * surface;
01159   the_ele = beginActiveElement();
01160   for (;the_ele != end_ele;++ the_ele) {
01161     HGeometry<3, DOW> * h_element = the_ele->h_element;
01162     // ȼ붥
01163     for (i = 0;i < h_element->n_vertex;i ++) {
01164       HGeometry<0,DOW>& vtx = *(h_element->vertex[i]);
01165       j = vtx.index;
01166       tools.regularize_add_node(vtx, 
01167                                 regular_mesh->geometry(0, j),
01168                                 regular_mesh->point(j));
01169 #ifdef __SERIALIZATION__
01170       h_geometry[0][j] = &vtx;
01171 #endif 
01172     }
01173 
01174     // ȻԪı
01175     n_twin_triangle_surface = 0;
01176     n_nonactive_neighbour = 0;
01177     for (i = 0;i < the_ele->n_boundary;i ++) {
01178       HGeometry<2, DOW>& bnd = *(h_element->boundary[i]);
01179       if (tools.isGeometryActive(bnd) ||  // һûдactive
01180           tools.isGeometryIndexed(bnd)) { // һactive
01185         for (k = 0;k < HGeometry<2, DOW>::n_boundary;k ++) {
01186           if (tools.isGeometryInactive(*(bnd.boundary[k]))) {
01187             m_refined_edge = bnd.boundary[k];
01188             break;
01189           }
01190         }
01191 
01192         j = bnd.index;
01193         GeometryBM& surface = regular_mesh->geometry(2,j);
01194         // 洦ˣǼһ
01195         if (surface.index() != -1) {
01196           if (k < HGeometry<2, DOW>::n_boundary) {
01197             Assert(n_twin_triangle_surface <= 2, ExcInternalError());
01198             twin_triangle_surface[n_twin_triangle_surface ++] = i;
01199           }
01200           continue;
01201         } else if (k == HGeometry<2, DOW>::n_boundary) { // 
01202           for (l = 0;l < HGeometry<2, DOW>::n_boundary;l ++) { // ȼ
01203             edge = bnd.boundary[l];
01204             m = edge->index;
01205             tools.regularize_add_side(*edge, regular_mesh->geometry(1,m));
01206 #ifdef __SERIALIZATION__
01207             h_geometry[1][m] = edge;
01208 #endif
01209           }
01210           // ټ
01211           tools.regularize_add_triangle(bnd, surface);
01212 #ifdef __SERIALIZATION__
01213           h_geometry[2][j] = &bnd;
01214 #endif
01215         } else { // this is a twin-triangle and the refined boundary is the k-th one
01216           Assert(n_twin_triangle_surface <= 2, ExcInternalError());
01217           twin_triangle_surface[n_twin_triangle_surface ++] = i;
01218                                         
01223           for (m = 1;m < 3;++ m) {
01224             edge = bnd.boundary[ii[k+m]];
01225             int n = edge->index;
01226             tools.regularize_add_side(*edge, regular_mesh->geometry(1,n));
01227 #ifdef __SERIALIZATION__
01228             h_geometry[1][n] = edge;
01229 #endif
01230           }
01231 
01232           // Ȼ˫
01233           tools.regularize_add_twin_triangle(bnd, surface, k);
01234 #ifdef __SERIALIZATION__
01235           h_geometry[2][j] = &bnd;
01236 #endif
01237         }
01238       } else { 
01242         n_nonactive_neighbour ++;
01243         Assert(n_nonactive_neighbour == 1, ExcInternalError());
01244         nonactive_neighbour = i; // Ϳ
01245 
01246         for (u_int j = 0;j < bnd.n_child;++ j) {
01247           HGeometry<2,DOW>& chd = *bnd.child[j];
01248           int& idx = chd.index;
01249           tools.regularize_add_triangle(chd, regular_mesh->geometry(2,idx));
01250 #ifdef __SERIALIZATION__
01251           h_geometry[2][idx] = &chd;
01252 #endif
01253 
01254           for (u_int k = 0;k < chd.n_vertex;++ k) {
01255             HGeometry<0,DOW>& vtx = *chd.vertex[k];
01256             int& vtx_idx = vtx.index;
01257             tools.regularize_add_node(vtx,
01258                                       regular_mesh->geometry(0,vtx_idx),
01259                                       regular_mesh->point(vtx_idx));
01260 #ifdef __SERIALIZATION__
01261             h_geometry[0][vtx_idx] = &vtx;
01262 #endif
01263           }
01264           for (u_int k = 0;k < chd.n_boundary;++ k) {
01265             HGeometry<1,DOW>& bnd = *chd.boundary[k];
01266             int& bnd_idx = bnd.index;
01267             tools.regularize_add_side(bnd,
01268                                       regular_mesh->geometry(1,bnd_idx));
01269 #ifdef __SERIALIZATION__
01270             h_geometry[1][bnd_idx] = &bnd;
01271 #endif
01272           }
01273         }
01274         
01275       }
01276     }
01277 
01278     // 
01279     j = h_element->index;
01280     GeometryBM& tetra = regular_mesh->geometry(3,j);
01281     tetra.index() = j;
01282 #ifdef __SERIALIZATION__
01283     h_geometry[3][j] = h_element;
01284 #endif
01285     if (n_nonactive_neighbour == 1) { // İ̥
01286       Assert(n_twin_triangle_surface == 3, ExcInternalError());
01287       tetra.vertex().resize(7);
01288       tetra.boundary().resize(7);
01289       int start, step;
01290       switch (nonactive_neighbour) {
01291       case 0:
01292         tetra.vertex(0) = h_element->vertex[0]->index;
01293         tetra.vertex(1) = h_element->vertex[1]->index;
01294         tetra.vertex(2) = h_element->vertex[2]->index;
01295         tetra.vertex(3) = h_element->vertex[3]->index;
01296         for (start = 0;start < 3;start ++) {
01297           if (h_element->vertex[1] == 
01298               h_element->boundary[0]->vertex[start])
01299             break;
01300         }
01301         Assert (start < 3, ExcInternalError());
01302         if (h_element->vertex[2] == h_element->boundary[0]->vertex[ii[start+1]]) {
01303           step = 1;
01304         } else {
01305           Assert (h_element->vertex[3] == h_element->boundary[0]->vertex[ii[start+1]], ExcInternalError());
01306           Assert (h_element->vertex[2] == h_element->boundary[0]->vertex[ii[start+2]], ExcInternalError());
01307           step = 2;
01308         }
01309         tetra.vertex(4) = h_element->boundary[0]->boundary[start]->child[0]->vertex[1]->index;
01310         tetra.vertex(5) = h_element->boundary[0]->boundary[ii[start+step]]->child[0]->vertex[1]->index;
01311         tetra.vertex(6) = h_element->boundary[0]->boundary[ii[start+2*step]]->child[0]->vertex[1]->index;
01312 
01313         tetra.boundary(0) = h_element->boundary[0]->child[3]->index;
01314         tetra.boundary(1) = h_element->boundary[0]->child[start]->index;
01315         tetra.boundary(2) = h_element->boundary[0]->child[ii[start+step]]->index;
01316         tetra.boundary(3) = h_element->boundary[0]->child[ii[start+2*step]]->index;
01317         tetra.boundary(4) = h_element->boundary[1]->index;
01318         tetra.boundary(5) = h_element->boundary[2]->index;
01319         tetra.boundary(6) = h_element->boundary[3]->index;
01320 
01321         tetra.boundaryMark() = h_element->bmark;
01322         break;
01323 
01324       case 1:
01325         tetra.vertex(0) = h_element->vertex[1]->index;
01326         tetra.vertex(1) = h_element->vertex[2]->index;
01327         tetra.vertex(2) = h_element->vertex[0]->index;
01328         tetra.vertex(3) = h_element->vertex[3]->index;
01329         for (start = 0;start < 3;start ++) {
01330           if (h_element->vertex[2] == 
01331               h_element->boundary[1]->vertex[start])
01332             break;
01333         }
01334         Assert (start < 3, ExcInternalError());
01335         if (h_element->vertex[0] == h_element->boundary[1]->vertex[ii[start+1]]) {
01336           step = 1;
01337         } else {
01338           Assert (h_element->vertex[3] == h_element->boundary[1]->vertex[ii[start+1]], ExcInternalError());
01339           Assert (h_element->vertex[0] == h_element->boundary[1]->vertex[ii[start+2]], ExcInternalError());
01340           step = 2;
01341         }
01342         tetra.vertex(4) = h_element->boundary[1]->boundary[start]->child[0]->vertex[1]->index;
01343         tetra.vertex(5) = h_element->boundary[1]->boundary[ii[start+step]]->child[0]->vertex[1]->index;
01344         tetra.vertex(6) = h_element->boundary[1]->boundary[ii[start+2*step]]->child[0]->vertex[1]->index;
01345 
01346         tetra.boundary(0) = h_element->boundary[1]->child[3]->index;
01347         tetra.boundary(1) = h_element->boundary[1]->child[start]->index;
01348         tetra.boundary(2) = h_element->boundary[1]->child[ii[start+step]]->index;
01349         tetra.boundary(3) = h_element->boundary[1]->child[ii[start+2*step]]->index;
01350         tetra.boundary(4) = h_element->boundary[2]->index;
01351         tetra.boundary(5) = h_element->boundary[0]->index;
01352         tetra.boundary(6) = h_element->boundary[3]->index;
01353 
01354         tetra.boundaryMark() = h_element->bmark;
01355         break;
01356 
01357       case 2:
01358         tetra.vertex(0) = h_element->vertex[2]->index;
01359         tetra.vertex(1) = h_element->vertex[3]->index;
01360         tetra.vertex(2) = h_element->vertex[0]->index;
01361         tetra.vertex(3) = h_element->vertex[1]->index;
01362         for (start = 0;start < 3;start ++) {
01363           if (h_element->vertex[3] == 
01364               h_element->boundary[2]->vertex[start])
01365             break;
01366         }
01367         Assert (start < 3, ExcInternalError());
01368         if (h_element->vertex[0] == h_element->boundary[2]->vertex[ii[start+1]]) {
01369           step = 1;
01370         } else {
01371           Assert (h_element->vertex[1] == h_element->boundary[2]->vertex[ii[start+1]], ExcInternalError());
01372           Assert (h_element->vertex[0] == h_element->boundary[2]->vertex[ii[start+2]], ExcInternalError());
01373           step = 2;
01374         }
01375         tetra.vertex(4) = h_element->boundary[2]->boundary[start]->child[0]->vertex[1]->index;
01376         tetra.vertex(5) = h_element->boundary[2]->boundary[ii[start+step]]->child[0]->vertex[1]->index;
01377         tetra.vertex(6) = h_element->boundary[2]->boundary[ii[start+2*step]]->child[0]->vertex[1]->index;
01378 
01379         tetra.boundary(0) = h_element->boundary[2]->child[3]->index;
01380         tetra.boundary(1) = h_element->boundary[2]->child[start]->index;
01381         tetra.boundary(2) = h_element->boundary[2]->child[ii[start+step]]->index;
01382         tetra.boundary(3) = h_element->boundary[2]->child[ii[start+2*step]]->index;
01383         tetra.boundary(4) = h_element->boundary[3]->index;
01384         tetra.boundary(5) = h_element->boundary[0]->index;
01385         tetra.boundary(6) = h_element->boundary[1]->index;
01386 
01387         tetra.boundaryMark() = h_element->bmark;
01388         break;
01389 
01390       case 3:
01391         tetra.vertex(0) = h_element->vertex[3]->index;
01392         tetra.vertex(1) = h_element->vertex[0]->index;
01393         tetra.vertex(2) = h_element->vertex[2]->index;
01394         tetra.vertex(3) = h_element->vertex[1]->index;
01395         for (start = 0;start < 3;start ++) {
01396           if (h_element->vertex[0] == 
01397               h_element->boundary[3]->vertex[start])
01398             break;
01399         }
01400         Assert (start < 3, ExcInternalError());
01401         if (h_element->vertex[2] == h_element->boundary[3]->vertex[ii[start+1]]) {
01402           step = 1;
01403         } else {
01404           Assert (h_element->vertex[1] == h_element->boundary[3]->vertex[ii[start+1]], ExcInternalError());
01405           Assert (h_element->vertex[2] == h_element->boundary[3]->vertex[ii[start+2]], ExcInternalError());
01406           step = 2;
01407         }
01408         tetra.vertex(4) = h_element->boundary[3]->boundary[start]->child[0]->vertex[1]->index;
01409         tetra.vertex(5) = h_element->boundary[3]->boundary[ii[start+step]]->child[0]->vertex[1]->index;
01410         tetra.vertex(6) = h_element->boundary[3]->boundary[ii[start+2*step]]->child[0]->vertex[1]->index;
01411 
01412         tetra.boundary(0) = h_element->boundary[3]->child[3]->index;
01413         tetra.boundary(1) = h_element->boundary[3]->child[start]->index;
01414         tetra.boundary(2) = h_element->boundary[3]->child[ii[start+step]]->index;
01415         tetra.boundary(3) = h_element->boundary[3]->child[ii[start+2*step]]->index;
01416         tetra.boundary(4) = h_element->boundary[0]->index;
01417         tetra.boundary(5) = h_element->boundary[2]->index;
01418         tetra.boundary(6) = h_element->boundary[1]->index;
01419 
01420         tetra.boundaryMark() = h_element->bmark;
01421         break;
01422 
01423       default:
01424         Assert(false, ExcInternalError());
01425       }
01426                         
01427       n_four_tetrahedron ++;
01428     }
01429     else if (n_twin_triangle_surface == 2) { // ˫̥
01430       // жϸ
01431       int refined_edge;
01432       if ((twin_triangle_surface[0] == 0 || twin_triangle_surface[0] == 1)
01433           && (twin_triangle_surface[1] == 0 || twin_triangle_surface[1] == 1))
01434         refined_edge = 3;
01435       else if ((twin_triangle_surface[0] == 0 || twin_triangle_surface[0] == 2)
01436                && (twin_triangle_surface[1] == 0 || twin_triangle_surface[1] == 2))
01437         refined_edge = 4;
01438       else if ((twin_triangle_surface[0] == 0 || twin_triangle_surface[0] == 3)
01439                && (twin_triangle_surface[1] == 0 || twin_triangle_surface[1] == 3))
01440         refined_edge = 5;
01441       else if ((twin_triangle_surface[0] == 2 || twin_triangle_surface[0] == 3)
01442                && (twin_triangle_surface[1] == 2 || twin_triangle_surface[1] == 3))
01443         refined_edge = 0;
01444       else if ((twin_triangle_surface[0] == 3 || twin_triangle_surface[0] == 1)
01445                && (twin_triangle_surface[1] == 3 || twin_triangle_surface[1] == 1))
01446         refined_edge = 1;
01447       else if ((twin_triangle_surface[0] == 1 || twin_triangle_surface[0] == 2)
01448                && (twin_triangle_surface[1] == 1 || twin_triangle_surface[1] == 2))
01449         refined_edge = 2;
01450       else
01451         Assert(false, ExcInternalError());
01452 
01453       tetra.vertex().resize(5);
01454       tetra.boundary().resize(4);
01455       switch (refined_edge) {
01456       case 0:                           
01457         tetra.boundary(0) = h_element->boundary[3]->index;
01458         tetra.boundary(1) = h_element->boundary[1]->index;
01459         tetra.boundary(2) = h_element->boundary[0]->index;
01460         tetra.boundary(3) = h_element->boundary[2]->index;
01461 
01462         tetra.vertex(0) = h_element->vertex[3]->index;
01463         tetra.vertex(1) = h_element->vertex[1]->index;
01464         tetra.vertex(2) = m_refined_edge->child[0]->vertex[1]->index;
01465         tetra.vertex(3) = h_element->vertex[0]->index;
01466         tetra.vertex(4) = h_element->vertex[2]->index;
01467 
01468         tetra.boundaryMark() = h_element->bmark;
01469         break;
01470       case 1:
01471         tetra.boundary(0) = h_element->boundary[1]->index;
01472         tetra.boundary(1) = h_element->boundary[2]->index;
01473         tetra.boundary(2) = h_element->boundary[0]->index;
01474         tetra.boundary(3) = h_element->boundary[3]->index;
01475 
01476         tetra.vertex(0) = h_element->vertex[1]->index;
01477         tetra.vertex(1) = h_element->vertex[2]->index;
01478         tetra.vertex(2) = m_refined_edge->child[0]->vertex[1]->index;
01479         tetra.vertex(3) = h_element->vertex[0]->index;
01480         tetra.vertex(4) = h_element->vertex[3]->index;
01481 
01482         tetra.boundaryMark() = h_element->bmark;
01483         break;
01484 
01485       case 2:
01486         tetra.boundary(0) = h_element->boundary[1]->index;
01487         tetra.boundary(1) = h_element->boundary[0]->index;
01488         tetra.boundary(2) = h_element->boundary[3]->index;
01489         tetra.boundary(3) = h_element->boundary[2]->index;
01490 
01491         tetra.vertex(0) = h_element->vertex[1]->index;
01492         tetra.vertex(1) = h_element->vertex[0]->index;
01493         tetra.vertex(2) = m_refined_edge->child[0]->vertex[1]->index;
01494         tetra.vertex(3) = h_element->vertex[3]->index;
01495         tetra.vertex(4) = h_element->vertex[2]->index;
01496 
01497         tetra.boundaryMark() = h_element->bmark;
01498         break;
01499 
01500       case 3:
01501         tetra.boundary(0) = h_element->boundary[0]->index;
01502         tetra.boundary(1) = h_element->boundary[2]->index;
01503         tetra.boundary(2) = h_element->boundary[3]->index;
01504         tetra.boundary(3) = h_element->boundary[1]->index;
01505 
01506         tetra.vertex(0) = h_element->vertex[0]->index;
01507         tetra.vertex(1) = h_element->vertex[2]->index;
01508         tetra.vertex(2) = m_refined_edge->child[0]->vertex[1]->index;
01509         tetra.vertex(3) = h_element->vertex[3]->index;
01510         tetra.vertex(4) = h_element->vertex[1]->index;
01511 
01512         tetra.boundaryMark() = h_element->bmark;
01513         break;
01514 
01515       case 4:
01516         tetra.boundary(0) = h_element->boundary[0]->index;
01517         tetra.boundary(1) = h_element->boundary[3]->index;
01518         tetra.boundary(2) = h_element->boundary[1]->index;
01519         tetra.boundary(3) = h_element->boundary[2]->index;
01520 
01521         tetra.vertex(0) = h_element->vertex[0]->index;
01522         tetra.vertex(1) = h_element->vertex[3]->index;
01523         tetra.vertex(2) = m_refined_edge->child[0]->vertex[1]->index;
01524         tetra.vertex(3) = h_element->vertex[1]->index;
01525         tetra.vertex(4) = h_element->vertex[2]->index;
01526 
01527         tetra.boundaryMark() = h_element->bmark;
01528         break;
01529 
01530       case 5:
01531         tetra.boundary(0) = h_element->boundary[0]->index;
01532         tetra.boundary(1) = h_element->boundary[1]->index;
01533         tetra.boundary(2) = h_element->boundary[2]->index;
01534         tetra.boundary(3) = h_element->boundary[3]->index;
01535 
01536         tetra.vertex(0) = h_element->vertex[0]->index;
01537         tetra.vertex(1) = h_element->vertex[1]->index;
01538         tetra.vertex(2) = m_refined_edge->child[0]->vertex[1]->index;
01539         tetra.vertex(3) = h_element->vertex[2]->index;
01540         tetra.vertex(4) = h_element->vertex[3]->index;
01541 
01542         tetra.boundaryMark() = h_element->bmark;
01543         break;
01544 
01545       default:
01546         Assert(false, ExcInternalError());
01547       }
01548                         
01549       n_twin_tetrahedron ++;    
01550     } else { // 
01551       Assert(n_nonactive_neighbour == 0 && n_twin_triangle_surface == 0, ExcInternalError());
01552                 
01553       tetra.vertex().resize(4);
01554       tetra.boundary().resize(4);
01555 
01556       tetra.vertex(0) = h_element->vertex[0]->index;
01557       tetra.vertex(1) = h_element->vertex[1]->index;
01558       tetra.vertex(2) = h_element->vertex[2]->index;
01559       tetra.vertex(3) = h_element->vertex[3]->index;
01560                         
01561       tetra.boundary(0) = h_element->boundary[0]->index;
01562       tetra.boundary(1) = h_element->boundary[1]->index;
01563       tetra.boundary(2) = h_element->boundary[2]->index;
01564       tetra.boundary(3) = h_element->boundary[3]->index;
01565                         
01566       tetra.boundaryMark() = h_element->bmark;
01567 
01568       n_tetrahedron ++;
01569     }
01570   }
01571         
01572   geometry_tree->unlock(); 
01573   std::cerr << "\n\tnodes: " << n_node 
01574             << "; edges: " << n_edge
01575             << "; surface: " << n_surface
01576             << "; elements: " << n_element
01577             << " (" << n_tetrahedron
01578             << ", " << n_twin_tetrahedron
01579             << ", " << n_four_tetrahedron
01580             << ")" << std::endl;
01581         
01582   if (renumerate) renumerateElement();
01583 }
01584 
01585 
01586 template <>
01587 void RegularMesh<2, DOW>::writeEasyMesh(const std::string& filename) const
01588 {
01589   unsigned int i, j, k, ii[] = {0, 1, 2, 0, 1, 2, 0, 1, 2};
01590   unsigned int n_node = n_geometry(0);
01591   unsigned int n_side = n_geometry(1);
01592   unsigned int n_element = n_geometry(2);
01593   unsigned int n_triangle = 0;
01594   unsigned int n_twin_triangle = 0;
01595   std::cerr << "Writing easymesh data file ..." << std::endl;   
01596   std::cerr << "  preparing data ..." << std::flush;
01597   std::vector<int> index(n_element, -1);
01598   for (i = 0;i < n_element;i ++) {
01599     j = geometry(2, i).n_vertex();
01600     if (j == 3)
01601       n_triangle ++;
01602     else if (j == 4)
01603       index[i] = n_twin_triangle ++;
01604     else
01605       Assert(false, ExcInternalError());
01606   }
01607         
01609   std::vector<std::vector<int> > side_neighbour
01610     (2, std::vector<int>(n_side, -1));
01611   for (i = 0;i < n_element;i ++) {
01612     const GeometryBM& the_ele = geometry(2, i);
01613     if (index[i] == -1) { // this is a triangle
01614       for (j = 0;j < 3;j ++) {
01615         k = the_ele.boundary(j);
01616         const GeometryBM& the_side = geometry(1, k);
01617         if (the_side.vertex(0) == the_ele.vertex(ii[j+1])) {
01618           Assert(the_side.vertex(1) == the_ele.vertex(ii[j+2]), ExcInternalError());
01619           side_neighbour[1][k] = i;
01620         }
01621         else if (the_side.vertex(0) == the_ele.vertex(ii[j+2])) {
01622           Assert(the_side.vertex(1) == the_ele.vertex(ii[j+1]), ExcInternalError());
01623           side_neighbour[0][k] = i;
01624         }
01625         else {
01626           Assert(false, ExcInternalError()); // something must be wrong!
01627         }
01628       }
01629     }
01630     else { // this is a twin triangle
01631       // the 0-th side
01632       k = the_ele.boundary(0);
01633       const GeometryBM& the_side_0 = geometry(1, k);
01634       if (the_side_0.vertex(0) == the_ele.vertex(0)) {
01635         Assert(the_side_0.vertex(1) == the_ele.vertex(1), ExcInternalError());
01636         side_neighbour[1][k] = i;
01637       }
01638       else if (the_side_0.vertex(0) == the_ele.vertex(1)) {
01639         Assert(the_side_0.vertex(1) == the_ele.vertex(0), ExcInternalError());
01640         side_neighbour[0][k] = i;
01641       }
01642       else {
01643         Assert(false, ExcInternalError());
01644       }
01645       // the 1-st side
01646       k = the_ele.boundary(1);
01647       const GeometryBM& the_side_1 = geometry(1, k);
01648       if (the_side_1.vertex(0) == the_ele.vertex(1)) {
01649         Assert(the_side_1.vertex(1) == the_ele.vertex(2), ExcInternalError());
01650         side_neighbour[1][k] = i;
01651       }
01652       else if (the_side_1.vertex(0) == the_ele.vertex(2)) {
01653         Assert(the_side_1.vertex(1) == the_ele.vertex(1), ExcInternalError());
01654         side_neighbour[0][k] = i;
01655       }
01656       else {
01657         Assert(false, ExcInternalError());
01658       }
01659       // the 2-nd side
01660       k = the_ele.boundary(2);
01661       const GeometryBM& the_side_2 = geometry(1, k);
01662       if (the_side_2.vertex(0) == the_ele.vertex(2)) {
01663         Assert(the_side_2.vertex(1) == the_ele.vertex(3), ExcInternalError());
01664         side_neighbour[1][k] = n_element + index[i];
01665       }
01666       else if (the_side_2.vertex(0) == the_ele.vertex(3)) {
01667         Assert(the_side_2.vertex(1) == the_ele.vertex(2), ExcInternalError());
01668         side_neighbour[0][k] = n_element + index[i];
01669       }
01670       else {
01671         Assert(false, ExcInternalError());
01672       }
01673       // the 3th side
01674       k = the_ele.boundary(3);
01675       const GeometryBM& the_side_3 = geometry(1, k);
01676       if (the_side_3.vertex(0) == the_ele.vertex(3)) {
01677         Assert(the_side_3.vertex(1) == the_ele.vertex(0), ExcInternalError());
01678         side_neighbour[1][k] = n_element + index[i];
01679       }
01680       else if (the_side_3.vertex(0) == the_ele.vertex(0)) {
01681         Assert(the_side_3.vertex(1) == the_ele.vertex(3), ExcInternalError());
01682         side_neighbour[0][k] = n_element + index[i];
01683       }
01684       else {
01685         Assert(false, ExcInternalError());
01686       }
01687     }
01688   }
01689 
01691   std::vector<std::vector<int> > element_neighbour
01692     (3, std::vector<int>(n_element + n_twin_triangle, -1));
01693   for (i = 0;i < n_element;i ++) {
01694     const GeometryBM& the_ele = geometry(2, i);
01695     if (index[i] == -1) {
01696       for (j = 0;j < 3;j ++) {
01697         k = the_ele.boundary(j);
01698         const GeometryBM& the_side = geometry(1, k);
01699         if (the_side.vertex(0) == the_ele.vertex(ii[j+1])) {
01700           element_neighbour[j][i] = side_neighbour[0][k];
01701         }
01702         else { // if (the_side->vertex[0] == the_ele->vertex[ii[j+2]])
01703           element_neighbour[j][i] = side_neighbour[1][k];
01704         }
01705       }
01706     }
01707     else {
01708       element_neighbour[1][i] = n_element + index[i];
01709       element_neighbour[2][n_element + index[i]] = i;
01710       k = the_ele.boundary(0);
01711       const GeometryBM& the_side_0 = geometry(1, k);
01712       if (the_side_0.vertex(0) == the_ele.vertex(0))
01713         element_neighbour[2][i] = side_neighbour[0][k];
01714       else
01715         element_neighbour[2][i] = side_neighbour[1][k];
01716       k = the_ele.boundary(1);
01717       const GeometryBM& the_side_1 = geometry(1, k);
01718       if (the_side_1.vertex(0) == the_ele.vertex(1))
01719         element_neighbour[0][i] = side_neighbour[0][k];
01720       else
01721         element_neighbour[0][i] = side_neighbour[1][k];
01722       k = the_ele.boundary(2);
01723       const GeometryBM& the_side_2 = geometry(1, k);
01724       if (the_side_2.vertex(0) == the_ele.vertex(2))
01725         element_neighbour[0][n_element + index[i]] = side_neighbour[0][k];
01726       else
01727         element_neighbour[0][n_element + index[i]] = side_neighbour[1][k];
01728       k = the_ele.boundary(3);
01729       const GeometryBM& the_side_3 = geometry(1, k);
01730       if (the_side_3.vertex(0) == the_ele.vertex(3))
01731         element_neighbour[1][n_element + index[i]] = side_neighbour[0][k];
01732       else
01733         element_neighbour[1][n_element + index[i]] = side_neighbour[1][k];
01734     }
01735   }
01736   std::cerr << " OK!" << std::endl;
01737 
01738   std::cerr << "  writing node data ..." << std::flush;
01739   std::ofstream os((filename + ".n").c_str());
01740   os << n_node << "\t"
01741      << n_element + n_twin_triangle << "\t"
01742      << n_side + n_twin_triangle << " **(Nnd, Nee, Nsd)**\n";
01743   os.precision(8);
01744   os.setf(std::ios::scientific, std::ios::floatfield);
01745   for (i = 0;i < n_node;i ++) {
01746     j = geometry(0, i).vertex(0);
01747     os << i << "\t"
01748        << point(j)[0] << "\t"
01749        << point(j)[1] << "\t"
01750        << boundaryMark(0, i) << "\n";
01751   }
01752   os << "---------------------------------------------------------------\n"
01753      << "   n:  x                          y                            \n";
01754   os.close();
01755   std::cerr << " OK!" << std::endl;
01756 
01757   std::cerr << "  writing side data ..." << std::flush;
01758   os.open((filename + ".s").c_str());
01759   os << n_side + n_twin_triangle << "\n";
01760   for (i = 0;i < n_side;i ++) {
01761     const GeometryBM& the_side = geometry(1, i);
01762     os << i << "\t"
01763        << the_side.vertex(0) << "\t"
01764        << the_side.vertex(1) << "\t"
01765        << side_neighbour[0][i] << "\t"
01766        << side_neighbour[1][i] << "\t"
01767        << boundaryMark(1, i) << "\n";
01768   }
01769   for (i = 0;i < n_element;i ++) {
01770     if (index[i] == -1) continue;
01771     os << n_side + index[i] << "\t"
01772        << geometry(2,i).vertex(0) << "\t"
01773        << geometry(2,i).vertex(2) << "\t"
01774        << i << "\t"
01775        << n_element + index[i] << "\t"
01776        << boundaryMark(2, i) << "\n";
01777   }
01778   os << "---------------------------------------------------------------\n"
01779      << "   s:    c      d       ea       eb                            \n";
01780   os.close();
01781   std::cerr << " OK!" << std::endl;
01782 
01783   std::cerr << "  writing element data ..." << std::flush;
01784   os.open((filename+".e").c_str());
01785   os << n_element + n_twin_triangle << "\t"
01786      << n_node << "\t"
01787      << n_side + n_twin_triangle << " **(Nee, Nnd, Nsd)**\n";
01788   for (i = 0;i < n_element;i ++) {
01789     const GeometryBM& the_ele = geometry(2, i);
01790     if (index[i] == -1) {
01791       os << i << "\t"
01792          << the_ele.vertex(0) << "\t"
01793          << the_ele.vertex(1) << "\t"
01794          << the_ele.vertex(2) << "\t"
01795          << element_neighbour[0][i] << "\t"
01796          << element_neighbour[1][i] << "\t"
01797          << element_neighbour[2][i] << "\t"
01798          << the_ele.boundary(0) << "\t"
01799          << the_ele.boundary(1) << "\t"
01800          << the_ele.boundary(2) << "\n";
01801     }
01802     else {
01803       os << i << "\t"
01804          << the_ele.vertex(0) << "\t"
01805          << the_ele.vertex(1) << "\t"
01806          << the_ele.vertex(2) << "\t"
01807          << element_neighbour[0][i] << "\t"
01808          << element_neighbour[1][i] << "\t"
01809          << element_neighbour[2][i] << "\t"
01810          << the_ele.boundary(1) << "\t"
01811          << n_side + index[i] << "\t"
01812          << the_ele.boundary(0) << "\n";
01813     }
01814   }
01815   for (i = 0;i < n_element;i ++) {
01816     if (index[i] == -1) continue;
01817     const GeometryBM& the_ele = geometry(2, i);
01818     j = n_element + index[i];
01819     os << j << "\t"
01820        << geometry(2,i).vertex(0) << "\t"
01821        << geometry(2,i).vertex(2) << "\t"
01822        << geometry(2,i).vertex(3) << "\t"
01823        << element_neighbour[0][j] << "\t"
01824        << element_neighbour[1][j] << "\t"
01825        << element_neighbour[2][j] << "\t"
01826        << the_ele.boundary(2) << "\t"
01827        << the_ele.boundary(3) << "\t"
01828        << n_side + index[i] << "\n";
01829   }
01830   os << "---------------------------------------------------------------\n"
01831      << "   e:  i,   j,   k,   ei,   ej,   ek,   si,   sj,   sk         \n";
01832   os.close();
01833   std::cerr << " OK!" << std::endl;
01834 }
01835 
01836 
01837 
01838 template <>
01839 void RegularMesh<2, DOW>::writeTecplotData(const std::string& filename) const
01840 {
01841   int i;
01842   std::cerr << "Write mesh data into Tecplot data file " 
01843             << filename << " ... " << std::flush;
01844   std::ofstream os(filename.c_str());
01845   os << "TITLE = \x22" << "2D mesh data generated by AFEPack" << "\x22\n"
01846      << "VARIABLES = \x22" << "X\x22, \x22" << "Y\x22\n";
01847   os.precision(8);
01848   os.setf(std::ios::scientific, std::ios::floatfield);
01849 
01850   int n_node = n_point();
01851   int n_element = n_geometry(2);
01852   os << "ZONE N=" << n_node
01853      << ",E=" << n_element
01854      << ",F=FEPOINT ET=TRIANGLE\n";
01855   for (i = 0;i < n_node;i ++)
01856     os << point(i) << "\n";
01857   os << "\n";
01858   for (i = 0;i < n_element;i ++) {
01859     int n_vertex = geometry(2,i).n_vertex();
01860     switch (n_vertex) {
01861     case 3:
01862       os << geometry(0,geometry(2,i).vertex(0)).vertex(0)+1 << "\t"
01863          << geometry(0,geometry(2,i).vertex(1)).vertex(0)+1 << "\t"
01864          << geometry(0,geometry(2,i).vertex(2)).vertex(0)+1 << "\n";
01865       break;
01866     case 4:
01867       os << geometry(0,geometry(2,i).vertex(0)).vertex(0)+1 << "\t"
01868          << geometry(0,geometry(2,i).vertex(1)).vertex(0)+1 << "\t"
01869          << geometry(0,geometry(2,i).vertex(2)).vertex(0)+1 << "\n";
01870       break;
01871     default:
01872       Assert(false, ExcInternalError());
01873     }
01874   }
01875   os.close();
01876   std::cerr << "OK!" << std::endl;
01877 }
01878 
01879 
01880 
01881 template <>
01882 void RegularMesh<3, DOW>::writeTecplotData(const std::string& filename) const
01883 {
01884   int i;
01885   std::cerr << "Write mesh data into Tecplot data file " 
01886             << filename << " ... " << std::flush;
01887   std::ofstream os(filename.c_str());
01888   os << "TITLE = \x22" << "3D mesh data generated by AFEPack" << "\x22\n"
01889      << "VARIABLES = \x22" << "X\x22, \x22" << "Y\x22, \x22" << "Z\x22\n";
01890   os.precision(8);
01891   os.setf(std::ios::scientific, std::ios::floatfield);
01892 
01893   int n_node = n_point();
01894   int n_element = n_geometry(3);
01895   os << "ZONE N=" << n_node
01896      << ",E=" << n_element
01897      << ",F=FEPOINT ET=TETRAHEDRON\n";
01898   for (i = 0;i < n_node;i ++)
01899     os << point(i) << "\n";
01900   os << "\n";
01901   for (i = 0;i < n_element;i ++) {
01902     int n_vertex = geometry(3,i).n_vertex();
01903     switch (n_vertex) {
01904     case 4:
01905       os << geometry(0,geometry(3,i).vertex(0)).vertex(0) + 1 << "\t"
01906          << geometry(0,geometry(3,i).vertex(1)).vertex(0) + 1 << "\t"
01907          << geometry(0,geometry(3,i).vertex(2)).vertex(0) + 1 << "\t"
01908          << geometry(0,geometry(3,i).vertex(3)).vertex(0) + 1 << "\n";
01909       break;
01910     case 5:
01911       os << geometry(0,geometry(3,i).vertex(0)).vertex(0) + 1 << "\t"
01912          << geometry(0,geometry(3,i).vertex(1)).vertex(0) + 1 << "\t"
01913          << geometry(0,geometry(3,i).vertex(3)).vertex(0) + 1 << "\t"
01914          << geometry(0,geometry(3,i).vertex(4)).vertex(0) + 1 << "\n";
01915       break;
01916     case 7:
01917       os << geometry(0,geometry(3,i).vertex(0)).vertex(0) + 1 << "\t"
01918          << geometry(0,geometry(3,i).vertex(1)).vertex(0) + 1 << "\t"
01919          << geometry(0,geometry(3,i).vertex(2)).vertex(0) + 1 << "\t"
01920          << geometry(0,geometry(3,i).vertex(3)).vertex(0) + 1 << "\n";
01921       break;
01922     default:
01923       Assert(false, ExcInternalError());
01924     }
01925   }
01926   os.close();
01927   std::cerr << "OK!" << std::endl;
01928 }
01929 
01930 template <>
01931 void RegularMesh<1, DOW>::writeOpenDXData(const std::string& filename) const
01932 {
01933   std::cout << "Not implemented." << std::endl;
01934 }
01935 
01936 template <>
01937 void RegularMesh<2, DOW>::writeOpenDXData(const std::string& filename) const
01938 {
01939   std::ofstream os(filename.c_str());
01940         
01941   os.precision(8);
01942   os.setf(std::ios::scientific, std::ios::floatfield);
01943   int n_node = n_point();
01944   int i, j;
01945         
01946   os << "object 1 class array type float rank 1 shape " << DOW << " item " 
01947      << n_node << " data follows\n";
01948   for (i = 0;i < n_node;i ++) {
01949     os << point(geometry(0,i).vertex(0)) << "\n";
01950   }
01951         
01952   int n_element = n_geometry(2);
01953   for (i = 0, j = 0;i < n_element;i ++) {
01954     switch (geometry(2,i).n_vertex()) {
01955     case 3:
01956       j += 1;
01957       break;
01958     case 4:
01959       j += 2;
01960       break;
01961     default:
01962       Assert(false, ExcInternalError());
01963     }
01964   }
01965   os << "\nobject 2 class array type int rank 1 shape 3 item "
01966      << j << " data follows\n";
01967   for (i = 0;i < n_element;i ++) {
01968     switch (geometry(2,i).n_vertex()) {
01969     case 3:
01970       os << geometry(2,i).vertex(0) << "\t"
01971          << geometry(2,i).vertex(1) << "\t"
01972          << geometry(2,i).vertex(2) << "\t\n";
01973       break;
01974     case 4:
01975       os << geometry(2,i).vertex(0) << "\t"
01976          << geometry(2,i).vertex(1) << "\t"
01977          << geometry(2,i).vertex(2) << "\t\n";
01978       os << geometry(2,i).vertex(0) << "\t"
01979          << geometry(2,i).vertex(2) << "\t"
01980          << geometry(2,i).vertex(3) << "\t\n";
01981       break;
01982     default:
01983       Assert(false, ExcInternalError());
01984     }
01985   }
01986   os << "attribute \"element type\" string \"triangles\"\n"
01987      << "attribute \"ref\" string \"positions\"\n\n";
01988         
01989   os << "object \"FEMFunction-2d\" class field\n"
01990      << "component \"positions\" value 1\n"
01991      << "component \"connections\" value 2\n"
01992      << "end\n";
01993   os.close();
01994 }
01995 
01996 
01997 
01998 template <>
01999 void RegularMesh<3, DOW>::writeOpenDXData(const std::string& filename) const
02000 {
02001   std::ofstream os(filename.c_str());
02002         
02003   os.precision(8);
02004   os.setf(std::ios::scientific, std::ios::floatfield);
02005   int n_node = n_point();
02006   int i, j;
02007         
02008   os << "object 1 class array type float rank 1 shape " << DOW << " item " 
02009      << n_node << " data follows\n";
02010   for (i = 0;i < n_node;i ++) {
02011     os << point(geometry(0,i).vertex(0)) << "\n";
02012   }
02013         
02014   int n_element = n_geometry(3);
02015   for (i = 0, j = 0;i < n_element;i ++) {
02016     switch (geometry(3,i).n_vertex()) {
02017     case 4:
02018       j += 1;
02019       break;
02020     case 5:
02021       j += 2;
02022       break;
02023     case 7:
02024       j += 4;
02025       break;
02026     default:
02027       Assert(false, ExcInternalError());
02028     }
02029   }
02030   os << "\nobject 2 class array type int rank 1 shape 4 item "
02031      << j << " data follows\n";
02032   for (i = 0;i < n_element;i ++) {
02033     switch (geometry(3,i).n_vertex()) {
02034     case 4:
02035       os << geometry(3,i).vertex(0) << "\t"
02036          << geometry(3,i).vertex(1) << "\t"
02037          << geometry(3,i).vertex(2) << "\t"
02038          << geometry(3,i).vertex(3) << "\t\n";
02039       break;
02040     case 5:
02041       os << geometry(3,i).vertex(0) << "\t"
02042          << geometry(3,i).vertex(1) << "\t"
02043          << geometry(3,i).vertex(2) << "\t"
02044          << geometry(3,i).vertex(4) << "\t\n";
02045       os << geometry(3,i).vertex(0) << "\t"
02046          << geometry(3,i).vertex(2) << "\t"
02047          << geometry(3,i).vertex(3) << "\t"
02048          << geometry(3,i).vertex(4) << "\t\n";
02049       break;
02050     case 7:
02051       os << geometry(3,i).vertex(0) << "\t"
02052          << geometry(3,i).vertex(1) << "\t"
02053          << geometry(3,i).vertex(6) << "\t"
02054          << geometry(3,i).vertex(5) << "\t\n";
02055       os << geometry(3,i).vertex(0) << "\t"
02056          << geometry(3,i).vertex(2) << "\t"
02057          << geometry(3,i).vertex(4) << "\t"
02058          << geometry(3,i).vertex(6) << "\t\n";
02059       os << geometry(3,i).vertex(0) << "\t"
02060          << geometry(3,i).vertex(3) << "\t"
02061          << geometry(3,i).vertex(5) << "\t"
02062          << geometry(3,i).vertex(4) << "\t\n";
02063       os << geometry(3,i).vertex(0) << "\t"
02064          << geometry(3,i).vertex(4) << "\t"
02065          << geometry(3,i).vertex(5) << "\t"
02066          << geometry(3,i).vertex(6) << "\t\n";
02067       break;
02068     default:
02069       Assert(false, ExcInternalError());
02070     }
02071   }
02072   os << "attribute \"element type\" string \"tetrahedra\"\n"
02073      << "attribute \"ref\" string \"positions\"\n\n";
02074         
02075   os << "object \"FEMFunction-3d\" class field\n"
02076      << "component \"positions\" value 1\n"
02077      << "component \"connections\" value 2\n"
02078      << "end\n";
02079   os.close();
02080 }
02081 
02082 
02083 
02084 template <>
02085 void HGeometryTree<2, DOW>::readEasyMesh(const std::string& filename)
02086 {
02087   std::cerr << "Reading easymesh data file ..." << std::endl;
02088         
02089   std::ifstream is((filename + ".n").c_str());
02090   int i, j, k, l;
02091   int n_node, n_side, n_element;
02092   char dummy[64];
02093   is >> n_node >> n_element >> n_side;
02094   is.getline(dummy, 64);
02095   std::vector<HGeometry<0, DOW> *> node(n_node);
02096   std::vector<HGeometry<1, DOW> *> side(n_side);
02097   std::vector<HGeometry<2, DOW> *> element(n_element);
02098   std::cerr << "\treading the nodes data ..." << std::flush;
02099   for (i = 0;i < n_node;i ++) {
02100     node[i] = new HGeometry<0, DOW>();
02101     Assert(node[i] != NULL, ExcOutOfMemory());
02102     is >> j
02103        >> *(dynamic_cast<Point<DOW> *>(node[i]))
02104        >> node[i]->bmark;
02105   }
02106   is.close();
02107   std::cerr << " OK!" << std::endl;
02108         
02109   is.open((filename + ".s").c_str());
02110   is >> i;
02111   Assert(i == n_side, ExcInternalError());
02112   std::cerr << "\treading the sides data ..." << std::flush;    
02113   for (i = 0;i < n_side;i ++) {
02114     side[i] = new HGeometry<1, DOW>();
02115     Assert(side[i] != NULL, ExcOutOfMemory());
02116     is >> l >> j >> k;
02117     side[i]->vertex[0] = node[j];
02118     side[i]->vertex[1] = node[k];
02119     is >> j >> k >> side[i]->bmark;
02120   }
02121   is.close();
02122   std::cerr << " OK!" << std::endl;
02123 
02124   is.open((filename + ".e").c_str());
02125   is >> i >> j >> k;
02126   Assert(i == n_element, ExcInternalError());
02127   Assert(j == n_node, ExcInternalError());
02128   Assert(k == n_side, ExcInternalError());
02129   is.getline(dummy, 64);
02130   std::cerr << "\treading the elements data ..." << std::flush; 
02131   for (i = 0;i < n_element;i ++) {
02132     element[i] = new HGeometry<2, DOW>();
02133     Assert(element[i] != NULL, ExcOutOfMemory());
02134     is >> l >> j >> k >> l;
02135     element[i]->vertex[0] = node[j];
02136     element[i]->vertex[1] = node[k];
02137     element[i]->vertex[2] = node[l];
02138     element[i]->bmark = 0;
02139     is >> j >> k >> l;
02140     is >> j >> k >> l;
02141     element[i]->boundary[0] = side[j];
02142     element[i]->boundary[1] = side[k];
02143     element[i]->boundary[2] = side[l];
02144     root_element.push_back(element[i]);
02145   }
02146   is.close();
02147   std::cerr << " OK!" << std::endl;
02148 }
02149 
02150 
02151 template <>
02152 void RegularMesh<1, DOW>::writeSimplestSimplexMesh(const std::string& filename) const
02153 {
02154   std::cout << "Not implemented." << std::endl;
02155 }
02156 
02157 template <>
02158 void RegularMesh<2, DOW>::writeSimplestSimplexMesh(const std::string& filename) const
02159 {
02160   std::ofstream os(filename.c_str());
02161         
02162   os.precision(8);
02163   os.setf(std::ios::scientific, std::ios::floatfield);
02164   int n_node = n_point();
02165   int i, j;
02166         
02167   os << n_node << "\n";
02168   for (i = 0;i < n_node;i ++) {
02169     os << point(geometry(0,i).vertex(0)) << "\n";
02170   }
02171         
02172   int n_element = n_geometry(2);
02173   for (i = 0, j = 0;i < n_element;i ++) {
02174     switch (geometry(2,i).n_vertex()) {
02175     case 3:
02176       j += 1;
02177       break;
02178     case 4:
02179       j += 2;
02180       break;
02181     default:
02182       Assert(false, ExcInternalError());
02183     }
02184   }
02185   os << j << "\n";
02186   for (i = 0;i < n_element;i ++) {
02187     switch (geometry(2,i).n_vertex()) {
02188     case 3:
02189       os << geometry(2,i).vertex(0) << "\t"
02190          << geometry(2,i).vertex(1) << "\t"
02191          << geometry(2,i).vertex(2) << "\t\n";
02192       break;
02193     case 4:
02194       os << geometry(2,i).vertex(0) << "\t"
02195          << geometry(2,i).vertex(1) << "\t"
02196          << geometry(2,i).vertex(2) << "\t\n";
02197       os << geometry(2,i).vertex(0) << "\t"
02198          << geometry(2,i).vertex(2) << "\t"
02199          << geometry(2,i).vertex(3) << "\t\n";
02200       break;
02201     default:
02202       Assert(false, ExcInternalError());
02203     }
02204   }
02205   os.close();
02206 }
02207 
02208 
02209 
02210 template <>
02211 void RegularMesh<3, DOW>::writeSimplestSimplexMesh(const std::string& filename) const
02212 {
02213   std::ofstream os(filename.c_str());
02214         
02215   os.precision(8);
02216   os.setf(std::ios::scientific, std::ios::floatfield);
02217   int n_node = n_point();
02218   int i, j;
02219         
02220   os << n_node << "\n";
02221   for (i = 0;i < n_node;i ++) {
02222     os << point(geometry(0,i).vertex(0)) << "\n";
02223   }
02224         
02225   int n_element = n_geometry(3);
02226   for (i = 0, j = 0;i < n_element;i ++) {
02227     switch (geometry(3,i).n_vertex()) {
02228     case 4:
02229       j += 1;
02230       break;
02231     case 5:
02232       j += 2;
02233       break;
02234     case 7:
02235       j += 4;
02236       break;
02237     default:
02238       Assert(false, ExcInternalError());
02239     }
02240   }
02241   os << j << "\n";
02242   for (i = 0;i < n_element;i ++) {
02243     switch (geometry(3,i).n_vertex()) {
02244     case 4:
02245       os << geometry(3,i).vertex(0) << "\t"
02246          << geometry(3,i).vertex(1) << "\t"
02247          << geometry(3,i).vertex(2) << "\t"
02248          << geometry(3,i).vertex(3) << "\t\n";
02249       break;
02250     case 5:
02251       os << geometry(3,i).vertex(0) << "\t"
02252          << geometry(3,i).vertex(1) << "\t"
02253          << geometry(3,i).vertex(2) << "\t"
02254          << geometry(3,i).vertex(4) << "\t\n";
02255       os << geometry(3,i).vertex(0) << "\t"
02256          << geometry(3,i).vertex(2) << "\t"
02257          << geometry(3,i).vertex(3) << "\t"
02258          << geometry(3,i).vertex(4) << "\t\n";
02259       break;
02260     case 7:
02261       os << geometry(3,i).vertex(0) << "\t"
02262          << geometry(3,i).vertex(1) << "\t"
02263          << geometry(3,i).vertex(6) << "\t"
02264          << geometry(3,i).vertex(5) << "\t\n";
02265       os << geometry(3,i).vertex(0) << "\t"
02266          << geometry(3,i).vertex(2) << "\t"
02267          << geometry(3,i).vertex(4) << "\t"
02268          << geometry(3,i).vertex(6) << "\t\n";
02269       os << geometry(3,i).vertex(0) << "\t"
02270          << geometry(3,i).vertex(3) << "\t"
02271          << geometry(3,i).vertex(5) << "\t"
02272          << geometry(3,i).vertex(4) << "\t\n";
02273       os << geometry(3,i).vertex(0) << "\t"
02274          << geometry(3,i).vertex(4) << "\t"
02275          << geometry(3,i).vertex(5) << "\t"
02276          << geometry(3,i).vertex(6) << "\t\n";
02277       break;
02278     default:
02279       Assert(false, ExcInternalError());
02280     }
02281   }
02282   os.close();
02283 }
02284 
02285 template <>
02286 void RegularMesh<1, DOW>::writeSimplexMesh(const std::string& filename) const
02287 {
02288   std::cout << "Not implemented." << std::endl;
02289 }
02290 
02291 template <>
02292 void RegularMesh<2, DOW>::writeSimplexMesh(const std::string& filename) const
02293 {
02294   std::ofstream os(filename.c_str());
02295         
02296   os.precision(8);
02297   os.setf(std::ios::scientific, std::ios::floatfield);
02298   int n_node = n_point();
02299   int i, j;
02300         
02301   os << n_node << "\n";
02302   for (i = 0;i < n_node;i ++) {
02303     os << point(geometry(0,i).vertex(0)) << "\n";
02304   }
02305 
02306   os << "\n" << n_node << "\n";
02307   for (i = 0;i < n_node;i ++) {
02308     os << i << "\n"
02309        << "1\t" << i << "\n"
02310        << "1\t" << i << "\n"
02311        << geometry(0,i).boundaryMark() << "\n";
02312   }
02313 
02314   int n_twin_triangle = 0;
02315   int n_element = n_geometry(2);
02316   for (i = 0;i < n_element;i ++) {
02317     if (geometry(2,i).n_vertex() == 4) {
02318       n_twin_triangle += 1;
02319     }
02320   }
02321 
02322   int n_side = n_geometry(1);
02323   os << "\n" << n_side + n_twin_triangle << "\n";
02324   for (i = 0;i < n_side;i ++) {
02325     os << i << "\n"
02326        << "2\t" << geometry(1,i).vertex(0) << " " << geometry(1,i).vertex(1) << "\n"
02327        << "2\t" << geometry(1,i).vertex(0) << " " << geometry(1,i).vertex(1) << "\n"
02328        << geometry(1,i).boundaryMark() << "\n";  
02329   }
02330   for (i = 0, j = 0;i < n_element;i ++) {
02331     if (geometry(2,i).n_vertex() == 4) {
02332       os << n_side + j << "\n"
02333          << "2\t" << geometry(2,i).vertex(0) << " " << geometry(2,i).vertex(2) << "\n"
02334          << "2\t" << geometry(2,i).vertex(0) << " " << geometry(2,i).vertex(2) << "\n"
02335          << geometry(2,i).boundaryMark() << "\n";
02336       j += 1;
02337     }
02338   }
02339 
02340   os << "n" << n_element + n_twin_triangle << "\n";
02341   for (i = 0, j = 0;i < n_element;i ++) {
02342     const GeometryBM& geo = geometry(2,i);
02343     switch (geo.n_vertex()) {
02344     case 3:
02345       os << i + j << "\n"
02346          << "3\t" << geo.vertex(0) << " " << geo.vertex(1) << " " << geo.vertex(2) << "\n"
02347          << "3\t" << geo.boundary(0) << " " << geo.boundary(1) << " " << geo.boundary(2) << "\n"
02348          << geo.boundaryMark() << "\n";
02349       break;
02350     case 4:
02351       os << i + j << "\n"
02352          << "3\t" << geo.vertex(0) << " " << geo.vertex(1) << " " << geo.vertex(2) << "\n"
02353          << "3\t" << geo.boundary(1) << " " << n_side + j << " " << geo.boundary(0) << "\n"
02354          << geo.boundaryMark() << "\n";
02355       j += 1;
02356       os << i + j << "\n"
02357          << "3\t" << geo.vertex(0) << " " << geo.vertex(2) << " " << geo.vertex(3) << "\n"
02358          << "3\t" << geo.boundary(2) << " " << geo.boundary(3) << " " << n_side + j << "\n"
02359          << geo.boundaryMark() << "\n";
02360       break;
02361     default:
02362       Assert(false, ExcInternalError());
02363     }
02364   }
02365   os.close();
02366 }
02367 
02368 
02369 
02370 template <>
02371 void RegularMesh<3, DOW>::writeSimplexMesh(const std::string& filename) const
02372 {
02373   std::ofstream os(filename.c_str());
02374         
02375   os.precision(8);
02376   os.setf(std::ios::scientific, std::ios::floatfield);
02377   int n_node = n_point();
02378   int i, j;
02379         
02380   os << n_node << "\n";
02381   for (i = 0;i < n_node;i ++) {
02382     os << point(geometry(0,i).vertex(0)) << "\n";
02383   }
02384 
02385   os << "\n" << n_node << "\n";
02386   for (i = 0;i < n_node;i ++) {
02387     os << i << "\n"
02388        << "1\t" << i << "\n"
02389        << "1\t" << i << "\n"
02390        << geometry(0,i).boundaryMark() << "\n";
02391   }
02392 
02393   int n_twin_triangle = 0;
02394   int n_side = n_geometry(1);
02395   int n_face = n_geometry(2);
02396   for (i = 0;i < n_face;++ i) {
02397     if (geometry(2,i).n_vertex() == 4) {
02398       n_twin_triangle += 1;
02399     }
02400   }
02401 
02402   int n_twin_tetrahedron = 0;
02403   int n_four_tetrahedron = 0;
02404   int n_element = n_geometry(3);
02405   for (i = 0, j = 0;i < n_element;i ++) {
02406     switch (geometry(3,i).n_vertex()) {
02407     case 5:
02408       n_twin_tetrahedron += 1;
02409       break;
02410     case 7:
02411       n_four_tetrahedron += 1;
02412       break;
02413     }
02414   }
02415 
02416   os << "\n" << n_side + n_twin_triangle << "\n";
02417   for (i = 0;i < n_side;i ++) {
02418     os << i << "\n"
02419        << "2\t" << geometry(1,i).vertex(0) << " " << geometry(1,i).vertex(1) << "\n"
02420        << "2\t" << geometry(1,i).vertex(0) << " " << geometry(1,i).vertex(1) << "\n"
02421        << geometry(1,i).boundaryMark() << "\n";  
02422   }
02423   for (i = 0, j = 0;i < n_face;i ++) {
02424     if (geometry(2,i).n_vertex() == 4) {
02425       os << n_side + j << "\n"
02426          << "2\t" << geometry(2,i).vertex(0) << " " << geometry(2,i).vertex(2) << "\n"
02427          << "2\t" << geometry(2,i).vertex(0) << " " << geometry(2,i).vertex(2) << "\n"
02428          << geometry(2,i).boundaryMark() << "\n";
02429       j += 1;
02430     }
02431   }
02432     
02433   os << "n" << (n_face + 
02434                 n_twin_triangle + 
02435                 n_twin_tetrahedron +
02436                 3*n_four_tetrahedron) << "\n";
02437   for (i = 0;i < n_face;i ++) {
02438     const GeometryBM& geo = geometry(2,i);
02439     switch (geo.n_vertex()) {
02440     case 3:
02441       os << i + j << "\n"
02442          << "3\t" << geo.vertex(0) << " " << geo.vertex(1) << " " << geo.vertex(2) << "\n"
02443          << "3\t" << geo.boundary(0) << " " << geo.boundary(1) << " " << geo.boundary(2) << "\n"
02444          << geo.boundaryMark() << "\n";
02445       break;
02446     case 4:
02447       os << i + j << "\n"
02448          << "3\t" << geo.vertex(0) << " " << geo.vertex(1) << " " << geo.vertex(2) << "\n"
02449          << "3\t" << geo.boundary(1) << " " << n_side + j << " " << geo.boundary(0) << "\n"
02450          << geo.boundaryMark() << "\n";
02451       break;
02452     default:
02453       Assert(false, ExcInternalError());
02454     }
02455   }
02456   for (i = 0, j = 0;i < n_face;i ++) {
02457     const GeometryBM& geo = geometry(2,i);
02458     if (geo.n_vertex() == 3) continue;
02459     os << n_face + j << "\n"
02460        << "3\t" << geo.vertex(0) << " " << geo.vertex(2) << " " << geo.vertex(3) << "\n"
02461        << "3\t" << geo.boundary(2) << " " << geo.boundary(3) << " " << n_side + j << "\n"
02462        << geo.boundaryMark() << "\n";
02463     j += 1;
02464   }
02465   for (i = 0, j = 0;i < n_element;i ++) {
02466     const GeometryBM& geo = geometry(3,i);
02467     if (geo.n_vertex() != 5) continue;
02468     os << n_face + n_twin_triangle + j << "\n"
02469        << "3\t" << geo.vertex(0) << " " << geo.vertex(2) << " " << geo.vertex(4) << "\n"
02470        << "3\t" << n_side + geo.boundary(0) << " "
02471               //<< geo.???
02472                 << n_side + geo.boundary(3) << "\n"
02473        << geo.boundaryMark() << "\n";
02474     j += 1;
02475   }
02476 
02478 
02479   os.close();
02480 }
02481