/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Description Shrinking mesh (part of adding cell layers) \*----------------------------------------------------------------------------*/ #include "autoLayerDriver.H" #include "fvMesh.H" #include "Time.H" #include "pointFields.H" #include "motionSmoother.H" #include "pointData.H" #include "PointEdgeWave.H" #include "OBJstream.H" #include "meshTools.H" #include "PatchTools.H" #include "unitConversion.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // Calculate inverse sum of edge weights (currently always 1.0) void Foam::autoLayerDriver::sumWeights ( const PackedBoolList& isMasterEdge, const labelList& meshEdges, const labelList& meshPoints, const edgeList& edges, scalarField& invSumWeight ) const { const pointField& pts = meshRefiner_.mesh().points(); invSumWeight = 0; forAll(edges, edgeI) { if (isMasterEdge.get(meshEdges[edgeI]) == 1) { const edge& e = edges[edgeI]; //scalar eWeight = edgeWeights[edgeI]; //scalar eWeight = 1.0; scalar eMag = max ( VSMALL, mag ( pts[meshPoints[e[1]]] - pts[meshPoints[e[0]]] ) ); scalar eWeight = 1.0/eMag; invSumWeight[e[0]] += eWeight; invSumWeight[e[1]] += eWeight; } } syncTools::syncPointList ( meshRefiner_.mesh(), meshPoints, invSumWeight, plusEqOp(), scalar(0.0) // null value ); forAll(invSumWeight, pointI) { scalar w = invSumWeight[pointI]; if (w > 0.0) { invSumWeight[pointI] = 1.0/w; } } } // Smooth field on moving patch void Foam::autoLayerDriver::smoothField ( const motionSmoother& meshMover, const PackedBoolList& isMasterEdge, const labelList& meshEdges, const scalarField& fieldMin, const label nSmoothDisp, scalarField& field ) const { const indirectPrimitivePatch& pp = meshMover.patch(); const edgeList& edges = pp.edges(); const labelList& meshPoints = pp.meshPoints(); scalarField invSumWeight(pp.nPoints()); sumWeights ( isMasterEdge, meshEdges, meshPoints, edges, invSumWeight ); // Get smoothly varying patch field. Info<< "shrinkMeshDistance : Smoothing field ..." << endl; for (label iter = 0; iter < nSmoothDisp; iter++) { scalarField average(pp.nPoints()); averageNeighbours ( meshMover.mesh(), isMasterEdge, meshEdges, meshPoints, pp.edges(), invSumWeight, field, average ); // Transfer to field forAll(field, pointI) { //full smoothing neighbours + point value average[pointI] = 0.5*(field[pointI]+average[pointI]); // perform monotonic smoothing if ( average[pointI] < field[pointI] && average[pointI] >= fieldMin[pointI] ) { field[pointI] = average[pointI]; } } // Do residual calculation every so often. if ((iter % 10) == 0) { Info<< " Iteration " << iter << " residual " << gSum(mag(field-average)) /returnReduce(average.size(), sumOp