/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | foam-extend: Open Source CFD \\ / O peration | \\ / A nd | For copyright notice see file Copyright \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of foam-extend. foam-extend 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. foam-extend 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 foam-extend. If not, see . \*---------------------------------------------------------------------------*/ #include "faFieldReconstructor.H" #include "Time.H" #include "PtrList.H" #include "faPatchFields.H" #include "emptyFaPatch.H" #include "emptyFaPatchField.H" #include "emptyFaePatchField.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template Foam::tmp > Foam::faFieldReconstructor::reconstructFaAreaField ( const IOobject& fieldIoObject ) { // Read the field for all the processors PtrList > procFields ( procMeshes_.size() ); forAll (procMeshes_, procI) { procFields.set ( procI, new GeometricField ( IOobject ( fieldIoObject.name(), procMeshes_[procI].time().timeName(), procMeshes_[procI](), IOobject::MUST_READ, IOobject::NO_WRITE ), procMeshes_[procI] ) ); } // Create the internalField Field internalField(mesh_.nFaces()); // Create the patch fields PtrList > patchFields(mesh_.boundary().size()); // Create global mesh patchs starts labelList gStarts(mesh_.boundary().size(), -1); if (mesh_.boundary().size() > 0) { gStarts[0] = mesh_.nInternalEdges(); } for(label i=1; i& procField = procFields[procI]; // Set the face values in the reconstructed field internalField.rmap ( procField.internalField(), faceProcAddressing_[procI] ); // Set the boundary patch values in the reconstructed field labelList starts(procMeshes_[procI].boundary().size(), -1); if(procMeshes_[procI].boundary().size() > 0) { starts[0] = procMeshes_[procI].nInternalEdges(); } for(label i=1; i= 0) { // Regular patch. Fast looping if (!patchFields(curBPatch)) { patchFields.set ( curBPatch, faPatchField::New ( procField.boundaryField()[patchI], mesh_.boundary()[curBPatch], DimensionedField::null(), faPatchFieldReconstructor ( mesh_.boundary()[curBPatch].size(), procField.boundaryField()[patchI].size() ) ) ); } const label curPatchStart = gStarts[curBPatch]; // mesh_.boundary()[curBPatch].start(); labelList reverseAddressing(cp.size()); forAll(cp, edgeI) { // Subtract one to take into account offsets for // face direction. // reverseAddressing[edgeI] = cp[edgeI] - 1 - curPatchStart; reverseAddressing[edgeI] = cp[edgeI] - curPatchStart; } patchFields[curBPatch].rmap ( procField.boundaryField()[patchI], reverseAddressing ); } else { const Field& curProcPatch = procField.boundaryField()[patchI]; // In processor patches, there's a mix of internal faces (some // of them turned) and possible cyclics. Slow loop forAll(cp, edgeI) { // Subtract one to take into account offsets for // face direction. // label curE = cp[edgeI] - 1; label curE = cp[edgeI]; // Is the face on the boundary? if (curE >= mesh_.nInternalEdges()) { // label curBPatch = mesh_.boundary().whichPatch(curE); label curBPatch = -1; forAll (mesh_.boundary(), pI) { if ( curE >= gStarts[pI] && curE < ( gStarts[pI] + mesh_.boundary()[pI].labelList::size() ) ) { curBPatch = pI; } } if (!patchFields(curBPatch)) { patchFields.set ( curBPatch, faPatchField::New ( mesh_.boundary()[curBPatch].type(), mesh_.boundary()[curBPatch], DimensionedField::null() ) ); } // add the edge // label curPatchEdge = // mesh_.boundary() // [curBPatch].whichEdge(curE); label curPatchEdge = curE - gStarts[curBPatch]; patchFields[curBPatch][curPatchEdge] = curProcPatch[edgeI]; } } } } } forAll(mesh_.boundary(), patchI) { // add empty patches if ( typeid(mesh_.boundary()[patchI]) == typeid(emptyFaPatch) && !patchFields(patchI) ) { patchFields.set ( patchI, faPatchField::New ( emptyFaPatchField::typeName, mesh_.boundary()[patchI], DimensionedField::null() ) ); } } // Now construct and write the field // setting the internalField and patchFields return tmp > ( new GeometricField ( IOobject ( fieldIoObject.name(), mesh_.time().timeName(), mesh_(), IOobject::NO_READ, IOobject::NO_WRITE ), mesh_, procFields[0].dimensions(), internalField, patchFields ) ); } template Foam::tmp > Foam::faFieldReconstructor::reconstructFaEdgeField ( const IOobject& fieldIoObject ) { // Read the field for all the processors PtrList > procFields ( procMeshes_.size() ); forAll (procMeshes_, procI) { procFields.set ( procI, new GeometricField ( IOobject ( fieldIoObject.name(), procMeshes_[procI].time().timeName(), procMeshes_[procI](), IOobject::MUST_READ, IOobject::NO_WRITE ), procMeshes_[procI] ) ); } // Create the internalField Field internalField(mesh_.nInternalEdges()); // Create the patch fields PtrList > patchFields(mesh_.boundary().size()); labelList gStarts(mesh_.boundary().size(), -1); if(mesh_.boundary().size() > 0) { gStarts[0] = mesh_.nInternalEdges(); } for(label i=1; i& procField = procFields[procI]; // Set the face values in the reconstructed field // It is necessary to create a copy of the addressing array to // take care of the face direction offset trick. // { labelList curAddr(edgeProcAddressing_[procI]); // forAll (curAddr, addrI) // { // curAddr[addrI] -= 1; // } internalField.rmap ( procField.internalField(), curAddr ); } // Set the boundary patch values in the reconstructed field labelList starts(procMeshes_[procI].boundary().size(), -1); if(procMeshes_[procI].boundary().size() > 0) { starts[0] = procMeshes_[procI].nInternalEdges(); } for(label i=1; i= 0) { // Regular patch. Fast looping if (!patchFields(curBPatch)) { patchFields.set ( curBPatch, faePatchField::New ( procField.boundaryField()[patchI], mesh_.boundary()[curBPatch], DimensionedField::null(), faPatchFieldReconstructor ( mesh_.boundary()[curBPatch].size(), procField.boundaryField()[patchI].size() ) ) ); } const label curPatchStart = gStarts[curBPatch]; // mesh_.boundary()[curBPatch].start(); labelList reverseAddressing(cp.size()); forAll(cp, edgeI) { // Subtract one to take into account offsets for // face direction. // reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart; reverseAddressing[edgeI] = cp[edgeI] - curPatchStart; } patchFields[curBPatch].rmap ( procField.boundaryField()[patchI], reverseAddressing ); } else { const Field& curProcPatch = procField.boundaryField()[patchI]; // In processor patches, there's a mix of internal faces (some // of them turned) and possible cyclics. Slow loop forAll(cp, edgeI) { // label curF = cp[edgeI] - 1; label curE = cp[edgeI]; // Is the face turned the right side round if (curE >= 0) { // Is the face on the boundary? if (curE >= mesh_.nInternalEdges()) { // label curBPatch = // mesh_.boundary().whichPatch(curF); label curBPatch = -1; forAll (mesh_.boundary(), pI) { if ( curE >= gStarts[pI] && curE < ( gStarts[pI] + mesh_.boundary()[pI].labelList::size() ) ) { curBPatch = pI; } } if (!patchFields(curBPatch)) { patchFields.set ( curBPatch, faePatchField::New ( mesh_.boundary()[curBPatch].type(), mesh_.boundary()[curBPatch], DimensionedField ::null() ) ); } // add the face // label curPatchFace = // mesh_.boundary() // [curBPatch].whichEdge(curF); label curPatchEdge = curE - gStarts[curBPatch]; patchFields[curBPatch][curPatchEdge] = curProcPatch[edgeI]; } else { // Internal face internalField[curE] = curProcPatch[edgeI]; } } } } } } forAll(mesh_.boundary(), patchI) { // add empty patches if ( typeid(mesh_.boundary()[patchI]) == typeid(emptyFaPatch) && !patchFields(patchI) ) { patchFields.set ( patchI, faePatchField::New ( emptyFaePatchField::typeName, mesh_.boundary()[patchI], DimensionedField::null() ) ); } } // Now construct and write the field // setting the internalField and patchFields return tmp > ( new GeometricField ( IOobject ( fieldIoObject.name(), mesh_.time().timeName(), mesh_(), IOobject::NO_READ, IOobject::NO_WRITE ), mesh_, procFields[0].dimensions(), internalField, patchFields ) ); } // Reconstruct and write all area fields template void Foam::faFieldReconstructor::reconstructFaAreaFields ( const IOobjectList& objects ) { const word& fieldClassName = GeometricField::typeName; IOobjectList fields = objects.lookupClass(fieldClassName); if (fields.size()) { Info<< " Reconstructing " << fieldClassName << "s\n" << endl; for ( IOobjectList::const_iterator fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) { Info << " " << fieldIter()->name() << endl; reconstructFaAreaField(*fieldIter())().write(); } Info<< endl; } } // Reconstruct and write all edge fields template void Foam::faFieldReconstructor::reconstructFaEdgeFields ( const IOobjectList& objects ) { const word& fieldClassName = GeometricField::typeName; IOobjectList fields = objects.lookupClass(fieldClassName); if (fields.size()) { Info<< " Reconstructing " << fieldClassName << "s\n" << endl; for ( IOobjectList::const_iterator fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter ) { Info<< " " << fieldIter()->name() << endl; reconstructFaEdgeField(*fieldIter())().write(); } Info<< endl; } } // ************************************************************************* //