diff --git a/applications/test/laplacianFoam-communicators/Make/files b/applications/test/laplacianFoam-communicators/Make/files new file mode 100644 index 0000000000..67b30cabf3 --- /dev/null +++ b/applications/test/laplacianFoam-communicators/Make/files @@ -0,0 +1,3 @@ +laplacianFoam.C + +EXE = $(FOAM_USER_APPBIN)/laplacianFoam-communicators diff --git a/applications/test/laplacianFoam-communicators/Make/options b/applications/test/laplacianFoam-communicators/Make/options new file mode 100644 index 0000000000..d9745f69a0 --- /dev/null +++ b/applications/test/laplacianFoam-communicators/Make/options @@ -0,0 +1,3 @@ +EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude + +EXE_LIBS = -lfiniteVolume diff --git a/applications/test/laplacianFoam-communicators/createFields.H b/applications/test/laplacianFoam-communicators/createFields.H new file mode 100644 index 0000000000..616afe1a88 --- /dev/null +++ b/applications/test/laplacianFoam-communicators/createFields.H @@ -0,0 +1,37 @@ + Info<< "Reading field T\n" << endl; + + volScalarField T + ( + IOobject + ( + "T", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ); + + + Info<< "Reading transportProperties\n" << endl; + + IOdictionary transportProperties + ( + IOobject + ( + "transportProperties", + runTime.constant(), + mesh, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ) + ); + + + Info<< "Reading diffusivity DT\n" << endl; + + dimensionedScalar DT + ( + transportProperties.lookup("DT") + ); diff --git a/applications/test/laplacianFoam-communicators/laplacianFoam.C b/applications/test/laplacianFoam-communicators/laplacianFoam.C new file mode 100644 index 0000000000..8d10b56cf9 --- /dev/null +++ b/applications/test/laplacianFoam-communicators/laplacianFoam.C @@ -0,0 +1,250 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 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 . + +Application + laplacianFoam + +Description + Solves a simple Laplace equation, e.g. for thermal diffusion in a solid. + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "simpleControl.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Determine parent rank +label processorToRank +( + const label comm, + const label procI +) +{ + const List& parentRanks = UPstream::procID(comm); + label parentComm = UPstream::parent(comm); + + if (parentComm == -1) + { + return findIndex(parentRanks, procI); + } + else + { + label parentRank = processorToRank(parentComm, procI); + return findIndex(parentRanks, parentRank); + } +} + + +// Determine rank in new communicator +label rank +( + const label currentComm, + const label currentRank, + const label newComm +) +{ + // Determine actual processor (walk up the tree to the top) + label procID = currentRank; + label comm = currentComm; + + while (UPstream::parent(comm) != -1) + { + const List& parentRanks = UPstream::procID(comm); + procID = parentRanks[procID]; + comm = UPstream::parent(comm); + } + + //Pout<< "Walked to top : comm:" << comm << " procID:" << procID + // << endl; + + // Find out what procID in the newComm is. + return processorToRank(newComm, procID); +} + + +void setCommunicator(fvMesh& mesh, const label newComm) +{ + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + // The current state is consistent with the mesh so check where the new + // communicator is and adjust accordingly. + + forAll(pbm, patchI) + { + if (isA(pbm[patchI])) + { + processorPolyPatch& ppp = const_cast + ( + refCast + < + const processorPolyPatch + >(pbm[patchI]) + ); + + label thisRank = rank(ppp.comm(), ppp.myProcNo(), newComm); + label nbrRank = rank(ppp.comm(), ppp.neighbProcNo(), newComm); + + ppp.comm() = newComm; + ppp.myProcNo() = thisRank; + ppp.neighbProcNo() = nbrRank; + } + } + mesh.polyMesh::comm() = newComm; +} + + +void printIt(Ostream& os) +{ + os<< "**BLA**" << endl; +} + + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + + #include "createTime.H" + #include "createMesh.H" + #include "createFields.H" + + simpleControl simple(mesh); + + //const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + Info<< "\nCalculating temperature distribution\n" << endl; + + + // Get a subset of processors + labelList subProcs(2); + subProcs[0] = 1; + subProcs[1] = 2; + + + const UPstream::communicator newComm + ( + UPstream::worldComm, + subProcs, + true + ); + + + Pout<< "procIDs world :" << UPstream::procID(UPstream::worldComm) << endl; + Pout<< "procIDs newComm:" << UPstream::procID(newComm) << endl; + + + { + label oldComm = mesh.comm(); + setCommunicator(mesh, newComm); + Pout<< "** oldcomm:" << oldComm + << " newComm:" << mesh.comm() << endl; + + printIt(Info(mesh.comm())); + + setCommunicator(mesh, oldComm); + Pout<< "** reset mesh to:" << mesh.comm() << endl; + } + + + //{ + // Pout<< "World:" << UPstream::worldComm + // << " procID:" << 2 + // << " subComm:" << newComm + // << " rank:" << rank(UPstream::worldComm, 2, newComm) + // << endl; + //} + // + // + //{ + // setCommunicator(mesh, newComm); + // Pout<< "Mesh comm:" << mesh.comm() << endl; + // forAll(pbm, patchI) + // { + // if (isA(pbm[patchI])) + // { + // const processorPolyPatch& ppp = + // refCast + // < + // const processorPolyPatch + // >(pbm[patchI]); + // + // + // Pout<< " " << ppp.name() + // << " myRank:" << ppp.myProcNo() + // << " nbrRank:" << ppp.neighbProcNo() + // << endl; + // } + // } + // setCommunicator(mesh, UPstream::worldComm); + //} + + + while (simple.loop()) + { + Info<< "Time = " << runTime.timeName() << nl << endl; + + while (simple.correctNonOrthogonal()) + { + fvScalarMatrix Teqn + ( + fvm::ddt(T) - fvm::laplacian(DT, T) + ); + + + { + label oldWarn = UPstream::warnComm; + UPstream::warnComm = newComm; + + label oldComm = mesh.comm(); + setCommunicator(mesh, newComm); + Pout<< "** oldcomm:" << oldComm + << " newComm:" << mesh.comm() << endl; + + if (Pstream::myProcNo(mesh.comm()) != -1) + { + solve(Teqn); + } + + setCommunicator(mesh, oldComm); + Pout<< "** reset mesh to:" << mesh.comm() << endl; + + UPstream::warnComm = oldWarn; + } + } + + #include "write.H" + + Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" + << " ClockTime = " << runTime.elapsedClockTime() << " s" + << nl << endl; + } + + Pout<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/laplacianFoam-communicators/write.H b/applications/test/laplacianFoam-communicators/write.H new file mode 100644 index 0000000000..47aa182c0a --- /dev/null +++ b/applications/test/laplacianFoam-communicators/write.H @@ -0,0 +1,46 @@ + if (runTime.outputTime()) + { + volVectorField gradT(fvc::grad(T)); + + volScalarField gradTx + ( + IOobject + ( + "gradTx", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + gradT.component(vector::X) + ); + + volScalarField gradTy + ( + IOobject + ( + "gradTy", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + gradT.component(vector::Y) + ); + + volScalarField gradTz + ( + IOobject + ( + "gradTz", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + gradT.component(vector::Z) + ); + + + runTime.write(); + }