1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "drnumwriter.h"
23 #include "guimainwindow.h"
25 DrNumWriter::DrNumWriter()
30 QString
DrNumWriter::boundaryCode(vtkIdType id_cell
, int i
)
32 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
34 vtkIdType id_neigh
= m_Part
.c2cGG(id_cell
, i
);
36 if (m_CellToCartPatch
[id_neigh
] == -1) {
37 if (isSurface(id_neigh
, m_Grid
)) {
38 BoundaryCondition bc
= GuiMainWindow::pointer()->getBC(cell_code
->GetValue(id_neigh
));
39 if (bc
.getName() != "unknown") {
48 void DrNumWriter::computeMeshDensity()
50 QString buffer
= GuiMainWindow::pointer()->getXmlSection("engrid/surface/settings").replace("\n", " ");
51 if (!buffer
.isEmpty()) {
52 QTextStream
in(&buffer
, QIODevice::ReadOnly
);
53 in
>> m_MaxEdgeLength
;
54 in
>> m_MinEdgeLength
;
57 m_MaxEdgeLength
= 1000.0;
58 m_MinEdgeLength
= 0.0;
62 m_H
.fill(m_MaxEdgeLength
, m_Grid
->GetNumberOfCells());
64 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
65 vec3_t x
= cellCentre(m_Grid
, id_cell
);
66 double cl_src
= m_ELSManager
.minEdgeLength(x
);
68 if (cl_src
< m_H
[id_cell
]) {
69 m_H
[id_cell
] = cl_src
;
75 vtkIdType id_min
= -1;
76 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
77 if (m_H
[id_cell
] < H_min
&& isVolume(id_cell
, m_Grid
)) {
86 QVector
<bool> marked(m_Grid
->GetNumberOfCells(), false);
87 marked
[id_min
] = true;
91 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
92 if (marked
[id_cell
] && m_H
[id_cell
] <= H_min
&& isVolume(id_cell
, m_Grid
)) {
93 vtkIdType num_pts
, *pts
;
94 m_Grid
->GetCellPoints(id_cell
, num_pts
, pts
);
95 for (int i
= 0; i
< num_pts
; ++i
) {
96 for (int j
= 0; j
< m_Part
.n2cGSize(pts
[i
]); ++j
) {
97 vtkIdType id_neigh
= m_Part
.n2cGG(pts
[i
], j
);
98 if (!marked
[id_neigh
] && isVolume(id_neigh
, m_Grid
)) {
99 double h
= m_GrowthFactor
*m_H
[id_cell
];
103 m_H
[id_neigh
] = min(m_H
[id_neigh
], h
);
104 marked
[id_neigh
] = true;
111 H_min
*= m_GrowthFactor
;
114 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
115 vec3_t x
= cellCentre(m_Grid
, id_cell
);
116 double cl_src
= m_ELSManager
.minEdgeLength(x
);
118 if (cl_src
< m_H
[id_cell
]) {
119 m_H
[id_cell
] = cl_src
;
126 void DrNumWriter::createAllCartPatches()
128 m_CellToCartPatch
.fill(-1, m_Grid
->GetNumberOfCells());
129 int num_cart_patches
= 0;
130 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
131 vtkIdType type_cell
= m_Grid
->GetCellType(id_cell
);
132 if (type_cell
== VTK_HEXAHEDRON
) {
133 m_CellToCartPatch
[id_cell
] = num_cart_patches
;
137 m_CartPatches
.resize(num_cart_patches
);
138 EG_VTKDCN(vtkDoubleArray
, cl
, m_Grid
, "node_meshdensity_desired");
139 for (vtkIdType id_cell
= 0; id_cell
< m_Grid
->GetNumberOfCells(); ++id_cell
) {
140 if (m_CellToCartPatch
[id_cell
] != -1) {
141 cart_patch_t patch
= m_CartPatches
[m_CellToCartPatch
[id_cell
]];
142 patch
.id_cell
= id_cell
;
143 vtkIdType num_pts
, *pts
;
145 m_Grid
->GetCellPoints(id_cell
, num_pts
, pts
);
149 vec3_t xc
= cellCentre(m_Grid
, id_cell
);
150 for (int i
= 0; i
< 8; ++i
) {
151 m_Grid
->GetPoint(pts
[i
], x
[i
].data());
153 double h
= m_H
[id_cell
];
154 vec3_t gi
= 0.25*(x
[1] + x
[2] + x
[6] + x
[5] - x
[0] - x
[3] - x
[7] - x
[4]);
155 vec3_t gj
= 0.25*(x
[4] + x
[5] + x
[6] + x
[7] - x
[0] - x
[1] - x
[2] - x
[3]);
158 vec3_t gk
= gi
.cross(gj
);
162 for (int i
= 0; i
< 8; ++i
) {
163 vec3_t Dx
= x
[i
] - xc
;
164 Li
= max(2*fabs(Dx
*gi
), Li
);
165 Lj
= max(2*fabs(Dx
*gj
), Lj
);
166 Lk
= max(2*fabs(Dx
*gk
), Lk
);
168 int Ni
= max(5, int(Li
/h
));
169 int Nj
= max(5, int(Lj
/h
));
170 int Nk
= max(5, int(Lk
/h
));
174 vec3_t x0
= xc
- 0.5*(Li
*gi
+ Lj
*gj
+ Lk
*gk
);
177 QString bc
= boundaryCode(id_cell
, 4);
180 patch
.sl_i1
= m_OverlapLayers
;
181 Ni
+= m_OverlapLayers
;
182 Li
+= m_OverlapLayers
*hi
;
183 x0
-= m_OverlapLayers
*hi
*gi
;
189 QString bc
= boundaryCode(id_cell
, 5);
192 patch
.sl_i2
= m_OverlapLayers
;
193 Ni
+= m_OverlapLayers
;
194 Li
+= m_OverlapLayers
*hi
;
200 QString bc
= boundaryCode(id_cell
, 0);
203 patch
.sl_j1
= m_OverlapLayers
;
204 Nj
+= m_OverlapLayers
;
205 Lj
+= m_OverlapLayers
*hj
;
206 x0
-= m_OverlapLayers
*hj
*gj
;
212 QString bc
= boundaryCode(id_cell
, 1);
215 patch
.sl_j2
= m_OverlapLayers
;
216 Nj
+= m_OverlapLayers
;
217 Lj
+= m_OverlapLayers
*hj
;
223 QString bc
= boundaryCode(id_cell
, 3);
226 patch
.sl_k1
= m_OverlapLayers
;
227 Nk
+= m_OverlapLayers
;
228 Lk
+= m_OverlapLayers
*hk
;
229 x0
-= m_OverlapLayers
*hk
*gk
;
235 QString bc
= boundaryCode(id_cell
,2);
238 patch
.sl_k2
= m_OverlapLayers
;
239 Nk
+= m_OverlapLayers
;
240 Lk
+= m_OverlapLayers
*hk
;
261 m_CartPatches
[m_CellToCartPatch
[id_cell
]] = patch
;
266 void DrNumWriter::writeCartPatches(QTextStream
&s
)
268 foreach (cart_patch_t patch
, m_CartPatches
) {
271 s
<< " " << patch
.x0
[0] << " " << patch
.x0
[1] << " " << patch
.x0
[2] << "\n";
272 s
<< " " << patch
.gi
[0] << " " << patch
.gi
[1] << " " << patch
.gi
[2] << "\n";
273 s
<< " " << patch
.gj
[0] << " " << patch
.gj
[1] << " " << patch
.gj
[2] << "\n";
275 s
<< " " << patch
.Ni
<< " " << patch
.Nj
<< " " << patch
.Nk
<< "\n";
276 s
<< " " << patch
.sl_i1
<< " " << patch
.sl_i2
<< " " << patch
.sl_j1
<< " " << patch
.sl_j2
<< " " << patch
.sl_k1
<< " " << patch
.sl_k2
<< "\n";
277 s
<< " " << patch
.Li
<< " " << patch
.Lj
<< " " << patch
.Lk
<< "\n";
278 s
<< " " << patch
.fx
<< " " << patch
.fy
<< " " << patch
.fz
<< "\n";
279 s
<< " " << patch
.bx
<< " " << patch
.bX
<< " " << patch
.by
<< " " << patch
.bY
<< " " << patch
.bz
<< " " << patch
.bZ
<< "\n";
280 s
<< " " << patch
.s
<< "\n";
286 void DrNumWriter::operate()
289 readOutputDirectory();
291 QString p1
= getFileName();
292 QString p2
= p1
+ "/patches";
304 p2
= p1
+ "/complex";
309 m_PatchFile
= getFileName() + "/patches/from_enGrid";
310 m_ComplexPath
= getFileName() + "/patches/complex";
311 if (!QDir(m_ComplexPath
).exists()) {
314 QFile
file(m_PatchFile
);
315 file
.open(QIODevice::WriteOnly
);
316 QTextStream
s(&file
);
317 computeMeshDensity();
318 createAllCartPatches();
322 } catch (Error err
) {