cartesian2DMeshGenerator.C 10 KB
Newer Older
1
2
/*---------------------------------------------------------------------------*\
  =========                 |
Tomislav Lugaric's avatar
Tomislav Lugaric committed
3
  \\      /  F ield         | cfMesh: A library for mesh generation
4
   \\    /   O peration     |
Tomislav Lugaric's avatar
Tomislav Lugaric committed
5
6
    \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
     \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7
8
-------------------------------------------------------------------------------
License
Tomislav Lugaric's avatar
Tomislav Lugaric committed
9
    This file is part of cfMesh.
10

Tomislav Lugaric's avatar
Tomislav Lugaric committed
11
    cfMesh is free software; you can redistribute it and/or modify it
12
    under the terms of the GNU General Public License as published by the
Tomislav Lugaric's avatar
Tomislav Lugaric committed
13
    Free Software Foundation; either version 3 of the License, or (at your
14
15
    option) any later version.

Tomislav Lugaric's avatar
Tomislav Lugaric committed
16
    cfMesh is distributed in the hope that it will be useful, but WITHOUT
17
18
19
20
21
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
Tomislav Lugaric's avatar
Tomislav Lugaric committed
22
    along with cfMesh.  If not, see <http://www.gnu.org/licenses/>.
23
24
25
26
27
28

Description

\*---------------------------------------------------------------------------*/

#include "cartesian2DMeshGenerator.H"
Franjo's avatar
Franjo committed
29
#include "triSurface2DCheck.H"
30
31
32
#include "polyMeshGen2DEngine.H"
#include "triSurf.H"
#include "triSurfacePatchManipulator.H"
Franjo's avatar
Franjo committed
33
#include "triSurfaceCleanupDuplicateTriangles.H"
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "demandDrivenData.H"
#include "Time.H"
#include "meshOctreeCreator.H"
#include "cartesianMeshExtractor.H"
#include "meshSurfaceEngine.H"
#include "meshSurfaceMapper2D.H"
#include "meshSurfaceEdgeExtractor2D.H"
#include "meshSurfaceOptimizer.H"
#include "topologicalCleaner.H"
#include "boundaryLayers.H"
#include "refineBoundaryLayers.H"
#include "renameBoundaryPatches.H"
#include "checkMeshDict.H"
#include "checkCellConnectionsOverFaces.H"
#include "checkIrregularSurfaceConnections.H"
#include "checkNonMappableCellConnections.H"
#include "checkBoundaryFacesSharingTwoEdges.H"
Franjo's avatar
Franjo committed
51
#include "triSurfaceMetaData.H"
52
53
#include "polyMeshGenGeometryModification.H"
#include "surfaceMeshGeometryModification.H"
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

//#define DEBUG

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{

// * * * * * * * * * * * * Private member functions  * * * * * * * * * * * * //

void cartesian2DMeshGenerator::createCartesianMesh()
{
    //- create polyMesh from octree boxes
    cartesianMeshExtractor cme(*octreePtr_, meshDict_, mesh_);

    if( meshDict_.found("decomposePolyhedraIntoTetsAndPyrs") )
    {
        if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
            cme.decomposeSplitHexes();
    }

    cme.createMesh();
}

void cartesian2DMeshGenerator::surfacePreparation()
{
    //- removes unnecessary cells and morph the boundary
    //- such that there is only one boundary face per cell
    //- It also checks topology of cells after morphing is performed
    bool changed;

    do
    {
        changed = false;

        checkIrregularSurfaceConnections checkConnections(mesh_);
        if( checkConnections.checkAndFixIrregularConnections() )
            changed = true;

        if( checkNonMappableCellConnections(mesh_).removeCells() )
            changed = true;

        if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
            changed = true;
    } while( changed );

    checkBoundaryFacesSharingTwoEdges(mesh_).improveTopology();
}

void cartesian2DMeshGenerator::mapMeshToSurface()
{
    //- calculate mesh surface
    meshSurfaceEngine* msePtr = new meshSurfaceEngine(mesh_);

    //- pre-map mesh surface
    meshSurfaceMapper2D mapper(*msePtr, *octreePtr_);

    mapper.adjustZCoordinates();

    mapper.preMapVertices();

    //- map mesh surface on the geometry surface
    mapper.mapVerticesOntoSurface();

    deleteDemandDrivenData(msePtr);
}

121
void cartesian2DMeshGenerator::extractPatches()
122
{
123
124
    meshSurfaceEdgeExtractor2D(mesh_, *octreePtr_).distributeBoundaryFaces();
}
125

126
127
128
void cartesian2DMeshGenerator::mapEdgesAndCorners()
{
    meshSurfaceEdgeExtractor2D(mesh_, *octreePtr_).remapBoundaryPoints();
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
}

void cartesian2DMeshGenerator::optimiseMeshSurface()
{
    meshSurfaceEngine mse(mesh_);
    meshSurfaceOptimizer optimizer(mse, *octreePtr_);
    optimizer.optimizeSurface2D();
    optimizer.untangleSurface2D();
}

void cartesian2DMeshGenerator::generateBoundaryLayers()
{
    boundaryLayers bl(mesh_);

    bl.activate2DMode();

    bl.addLayerForAllPatches();

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    if( modSurfacePtr_ )
    {
        polyMeshGenGeometryModification meshMod(mesh_, meshDict_);

        //- revert the mesh into the original space
        meshMod.revertGeometryModification();

        //- delete modified surface mesh
        deleteDemandDrivenData(modSurfacePtr_);

        //- delete the octree
        deleteDemandDrivenData(octreePtr_);

        //- contruct a new octree from the input surface
        octreePtr_ = new meshOctree(*surfacePtr_, true);
        meshOctreeCreator(*octreePtr_).createOctreeWithRefinedBoundary(20);
163
164
165
166

        mapEdgesAndCorners();

        optimiseMeshSurface();
167
    }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
}

void cartesian2DMeshGenerator::refBoundaryLayers()
{
    if( meshDict_.isDict("boundaryLayers") )
    {
        refineBoundaryLayers refLayers(mesh_);

        refineBoundaryLayers::readSettings(meshDict_, refLayers);

        refLayers.activate2DMode();

        refLayers.refineLayers();

        meshSurfaceEngine mse(mesh_);
        meshSurfaceOptimizer optimizer(mse, *octreePtr_);

        optimizer.untangleSurface2D();
    }
}

void cartesian2DMeshGenerator::replaceBoundaries()
{
191
    renameBoundaryPatches rbp(mesh_, meshDict_, true);
192
193
194
195
196
197
198
199
200
}

void cartesian2DMeshGenerator::renumberMesh()
{
    polyMeshGenModifier(mesh_).renumberMesh();
}

void cartesian2DMeshGenerator::generateMesh()
{
201
202
    try
    {
203
204
205
206
        if( controller_.runCurrentStep("templateGeneration") )
        {
            createCartesianMesh();
        }
207

208
209
210
211
        if( controller_.runCurrentStep("surfaceTopology") )
        {
            surfacePreparation();
        }
212

213
214
215
216
217
218
219
220
221
        if( controller_.runCurrentStep("surfaceProjection") )
        {
            mapMeshToSurface();
        }

        if( controller_.runCurrentStep("patchAssignment") )
        {
            extractPatches();
        }
222

223
        if( controller_.runCurrentStep("edgeExtraction") )
224
225
        {
            mapEdgesAndCorners();
226

227
            optimiseMeshSurface();
228
        }
229

230
231
        if( controller_.runCurrentStep("boundaryLayerGeneration") )
        {
232
233
            generateBoundaryLayers();
        }
234

235
236
237
238
        if( controller_.runCurrentStep("meshOptimisation") )
        {
            optimiseMeshSurface();
        }
239

240
241
242
243
        if( controller_.runCurrentStep("boundaryLayerRefinement") )
        {
            refBoundaryLayers();
        }
244

245
        renumberMesh();
246

247
        replaceBoundaries();
248
249

        controller_.workflowCompleted();
250
    }
Franjo's avatar
Franjo committed
251
252
253
254
    catch(const std::string& message)
    {
        Info << message << endl;
    }
255
256
257
258
259
260
261
    catch(...)
    {
        WarningIn
        (
            "void cartesian2DMeshGenerator::generateMesh()"
        ) << "Meshing process terminated!" << endl;
    }
262
263
264
265
266
267
268
269
}

// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

cartesian2DMeshGenerator::cartesian2DMeshGenerator(const Time& time)
:
    db_(time),
    surfacePtr_(NULL),
270
    modSurfacePtr_(NULL),
271
272
273
274
275
276
277
278
279
280
281
282
    meshDict_
    (
        IOobject
        (
            "meshDict",
            db_.system(),
            db_,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    ),
    octreePtr_(NULL),
283
284
    mesh_(time),
    controller_(mesh_)
285
286
287
288
289
290
291
292
293
294
295
296
{
    if( true )
    {
        checkMeshDict cmd(meshDict_);
    }

    fileName surfaceFile = meshDict_.lookup("surfaceFile");
    if( Pstream::parRun() )
        surfaceFile = ".."/surfaceFile;

    surfacePtr_ = new triSurf(db_.path()/surfaceFile);

Franjo's avatar
Franjo committed
297
298
299
300
301
302
    if( true )
    {
        //- save meta data with the mesh (surface mesh + its topology info)
        triSurfaceMetaData sMetaData(*surfacePtr_);
        const dictionary& surfMetaDict = sMetaData.metaData();

303
304
        mesh_.metaData().add("surfaceFile", surfaceFile, true);
        mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
Franjo's avatar
Franjo committed
305
306
307
308
309
310
311
312
313
314

        triSurface2DCheck surfCheck(*surfacePtr_);
        if( !surfCheck.is2DSurface() )
        {
            surfCheck.createSubsets();

            Info << "Writting surface with subsets to file "
                 << "badSurfaceWithSubsets.fms" << endl;
            surfacePtr_->writeSurface("badSurfaceWithSubsets.fms");
        }
Franjo's avatar
Franjo committed
315
316
    }

317
318
    if( surfacePtr_->featureEdges().size() != 0 )
    {
Franjo's avatar
Franjo committed
319
320
321
        //- get rid of duplicate triangles as they cause strange problems
        triSurfaceCleanupDuplicateTriangles(const_cast<triSurf&>(*surfacePtr_));

322
323
324
325
326
327
328
329
330
331
332
333
        //- create surface patches based on the feature edges
        //- and update the meshDict based on the given data
        triSurfacePatchManipulator manipulator(*surfacePtr_);

        const triSurf* surfaceWithPatches =
            manipulator.surfaceWithPatches(&meshDict_);

        //- delete the old surface and assign the new one
        deleteDemandDrivenData(surfacePtr_);
        surfacePtr_ = surfaceWithPatches;
    }

334
335
336
337
338
339
340
341
342
343
344
345
    if( meshDict_.found("anisotropicSources") )
    {
        surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);

        modSurfacePtr_ = surfMod.modifyGeometry();

        octreePtr_ = new meshOctree(*modSurfacePtr_, true);
    }
    else
    {
        octreePtr_ = new meshOctree(*surfacePtr_, true);
    }
346
347
348
349
350
351
352
353
354
355
356

    meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();

    generateMesh();
}

// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

cartesian2DMeshGenerator::~cartesian2DMeshGenerator()
{
    deleteDemandDrivenData(surfacePtr_);
357
    deleteDemandDrivenData(modSurfacePtr_);
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    deleteDemandDrivenData(octreePtr_);
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

void cartesian2DMeshGenerator::writeMesh() const
{
    mesh_.write();
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

// ************************************************************************* //