00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "SundanceMap.hpp"
00032 #include "PlayaTabs.hpp"
00033 #include "SundanceOut.hpp"
00034 #include "SundanceUnfoldPeriodicDF.hpp"
00035 #include "SundancePeriodicMesh1D.hpp"
00036 #include "SundancePartitionedLineMesher.hpp"
00037 #include "SundanceMeshSource.hpp"
00038 #include "SundanceBasicSimplicialMeshType.hpp"
00039 #include "SundanceDOFMapBase.hpp"
00040 #include "PlayaMPIContainerComm.hpp"
00041 #include "Teuchos_TimeMonitor.hpp"
00042 #include "PlayaLoadableVector.hpp"
00043
00044 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00045 #include "PlayaVectorSpaceImpl.hpp"
00046 #include "PlayaVectorImpl.hpp"
00047 #endif
00048
00049
00050 namespace Sundance
00051 {
00052 using namespace Teuchos;
00053 using namespace Playa;
00054
00055 Mesh unfoldPeriodicMesh(const Mesh& mesh)
00056 {
00057 const MeshBase* mb = mesh.ptr().get();
00058 const PeriodicMesh1D* pm = dynamic_cast<const PeriodicMesh1D*>(mb);
00059
00060 TEUCHOS_TEST_FOR_EXCEPT(pm==0);
00061
00062 int numElems = mesh.numCells(1);
00063 double a = mesh.nodePosition(0)[0];
00064 double b = mesh.nodePosition(numElems)[0];
00065
00066 MeshType meshType = new BasicSimplicialMeshType();
00067 MeshSource mesher = new PartitionedLineMesher(a, b, numElems, meshType,
00068 MPIComm::self());
00069
00070 Mesh rtn = mesher.getMesh();
00071
00072 return rtn;
00073 }
00074
00075
00076 DiscreteSpace unfoldPeriodicDiscreteSpace(const DiscreteSpace& space)
00077 {
00078 VectorType<double> vecType = space.vecType();
00079 Mesh mesh = unfoldPeriodicMesh(space.mesh());
00080 BasisArray basis = space.basis();
00081
00082 return DiscreteSpace(mesh, basis, vecType);
00083 }
00084
00085 Expr unfoldPeriodicDiscreteFunction(const Expr& f, const string& name)
00086 {
00087 const DiscreteFunction* df = DiscreteFunction::discFunc(f);
00088 TEUCHOS_TEST_FOR_EXCEPT(df==0);
00089
00090
00091 DiscreteSpace perSpace = df->discreteSpace();
00092 DiscreteSpace space = unfoldPeriodicDiscreteSpace(perSpace);
00093
00094 Mesh oldMesh = perSpace.mesh();
00095 Mesh newMesh = space.mesh();
00096
00097 df->updateGhosts();
00098 RCP<GhostView<double> > ghostView = df->ghostView();
00099
00100 Vector<double> newVec = space.createVector();
00101
00102
00103 const RCP<DOFMapBase>& oldMap = perSpace.map();
00104 const RCP<DOFMapBase>& newMap = space.map();
00105
00106
00107
00108 Array<int> oldCellLID(oldMesh.numCells(1));
00109 for (int i=0; i<oldMesh.numCells(1); i++)
00110 {
00111 oldCellLID[i] = i;
00112 }
00113 RCP<const Set<int> > funcs = oldMap->allowedFuncsOnCellBatch(1, oldCellLID);
00114
00115 Array<Array<int> > oldElemDofs;
00116 Array<Array<int> > newElemDofs;
00117 Array<int> oldNNodes;
00118 RCP<const MapStructure> oldMapStruct ;
00119 RCP<const MapStructure> newMapStruct ;
00120
00121 if (funcs->size())
00122 {
00123 oldMapStruct
00124 = oldMap->getDOFsForCellBatch(1, oldCellLID, *funcs, oldElemDofs,
00125 oldNNodes, 0);
00126
00127 newMapStruct
00128 = newMap->getDOFsForCellBatch(1, oldCellLID, *funcs, newElemDofs,
00129 oldNNodes, 0);
00130
00131 for (int chunk=0; chunk<oldMapStruct->numBasisChunks(); chunk++)
00132 {
00133 int nf = oldMapStruct->numFuncs(chunk);
00134 int nDofsPerCell = oldNNodes[chunk] * nf;
00135 for (int c=0; c<oldCellLID.size(); c++)
00136 {
00137 for (int d=0; d<nDofsPerCell; d++)
00138 {
00139 int oldDof = oldElemDofs[chunk][nDofsPerCell*c + d];
00140 int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00141 loadable(newVec)->setElement(newDof, ghostView->getElement(oldDof));
00142 }
00143 }
00144 }
00145 }
00146
00147
00148 Array<int> oldVertLID(oldMesh.numCells(0));
00149 Array<int> newVertLID(newMesh.numCells(0));
00150 for (int i=0; i<oldMesh.numCells(0); i++)
00151 {
00152 oldVertLID[i] = i;
00153 }
00154 for (int i=0; i<newMesh.numCells(0); i++)
00155 {
00156 newVertLID[i] = i;
00157 }
00158 if (funcs->size())
00159 {
00160 funcs = oldMap->allowedFuncsOnCellBatch(0, oldCellLID);
00161
00162 oldMapStruct = oldMap->getDOFsForCellBatch(0, oldVertLID, *funcs,
00163 oldElemDofs,
00164 oldNNodes, 0);
00165 newMapStruct
00166 = newMap->getDOFsForCellBatch(0, newVertLID, *funcs, newElemDofs,
00167 oldNNodes, 0);
00168
00169 for (int chunk=0; chunk<oldMapStruct->numBasisChunks(); chunk++)
00170 {
00171 int nf = oldMapStruct->numFuncs(chunk);
00172 int nDofsPerCell = oldNNodes[chunk] * nf;
00173 for (int c=0; c<newVertLID.size(); c++)
00174 {
00175 if (c < oldVertLID.size())
00176 {
00177 for (int d=0; d<nDofsPerCell; d++)
00178 {
00179 int oldDof = oldElemDofs[chunk][nDofsPerCell*c + d];
00180 int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00181 loadable(newVec)->setElement(newDof, ghostView->getElement(oldDof));
00182 }
00183 }
00184 else
00185 {
00186 for (int d=0; d<nDofsPerCell; d++)
00187 {
00188 int oldDof = oldElemDofs[chunk][d];
00189 int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00190 loadable(newVec)->setElement(newDof, ghostView->getElement(oldDof));
00191 }
00192 }
00193 }
00194 }
00195 }
00196
00197 return new DiscreteFunction(space, newVec, name);
00198 }
00199
00200
00201 }
00202
00203