SundanceUnfoldPeriodicDF.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #include "SundanceMap.hpp"
00043 #include "PlayaTabs.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "SundanceUnfoldPeriodicDF.hpp"
00046 #include "SundancePeriodicMesh1D.hpp"
00047 #include "SundancePartitionedLineMesher.hpp"
00048 #include "SundanceMeshSource.hpp"
00049 #include "SundanceBasicSimplicialMeshType.hpp"
00050 #include "SundanceDOFMapBase.hpp"
00051 #include "PlayaMPIContainerComm.hpp"
00052 #include "Teuchos_TimeMonitor.hpp"
00053 #include "PlayaLoadableVector.hpp"
00054 
00055 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00056 #include "PlayaVectorSpaceImpl.hpp"
00057 #include "PlayaVectorImpl.hpp"
00058 #endif
00059 
00060 
00061 namespace Sundance
00062 {
00063 using namespace Teuchos;
00064 using namespace Playa;
00065 
00066 Mesh unfoldPeriodicMesh(const Mesh& mesh)
00067 {
00068   const MeshBase* mb = mesh.ptr().get();
00069   const PeriodicMesh1D* pm = dynamic_cast<const PeriodicMesh1D*>(mb);
00070 
00071   TEUCHOS_TEST_FOR_EXCEPT(pm==0);
00072 
00073   int numElems = mesh.numCells(1);
00074   double a = mesh.nodePosition(0)[0];
00075   double b = mesh.nodePosition(numElems)[0];
00076 
00077   MeshType meshType = new BasicSimplicialMeshType();
00078   int verb=0;
00079   MeshSource mesher = new PartitionedLineMesher(a, b, numElems, meshType, verb,
00080     MPIComm::self());
00081 
00082   Mesh rtn = mesher.getMesh();
00083 
00084   return rtn;
00085 }
00086 
00087 
00088 DiscreteSpace unfoldPeriodicDiscreteSpace(const DiscreteSpace& space)
00089 {
00090   VectorType<double> vecType = space.vecType();
00091   Mesh mesh = unfoldPeriodicMesh(space.mesh());
00092   BasisArray basis = space.basis();
00093 
00094   return DiscreteSpace(mesh, basis, vecType);
00095 }
00096 
00097 Expr unfoldPeriodicDiscreteFunction(const Expr& f, const string& name)
00098 {
00099   const DiscreteFunction* df = DiscreteFunction::discFunc(f);
00100   TEUCHOS_TEST_FOR_EXCEPT(df==0);
00101 
00102 
00103   DiscreteSpace perSpace = df->discreteSpace();
00104   DiscreteSpace space = unfoldPeriodicDiscreteSpace(perSpace);
00105   
00106   Mesh oldMesh = perSpace.mesh();
00107   Mesh newMesh = space.mesh();
00108 
00109   df->updateGhosts();
00110   RCP<GhostView<double> > ghostView = df->ghostView();
00111 
00112   Vector<double> newVec = space.createVector();
00113 
00114 
00115   const RCP<DOFMapBase>& oldMap = perSpace.map();
00116   const RCP<DOFMapBase>& newMap = space.map();
00117 
00118   /* Copy the element DOFs to the new vector. There are no duplicated
00119    * elements so this map is one-to-one */
00120   Array<int> oldCellLID(oldMesh.numCells(1));
00121   for (int i=0; i<oldMesh.numCells(1); i++)
00122   {
00123     oldCellLID[i] = i;
00124   }
00125   RCP<const Set<int> > funcs = oldMap->allowedFuncsOnCellBatch(1, oldCellLID);
00126 
00127   Array<Array<int> > oldElemDofs;
00128   Array<Array<int> > newElemDofs;
00129   Array<int> oldNNodes;
00130   RCP<const MapStructure> oldMapStruct ;
00131   RCP<const MapStructure> newMapStruct ;
00132 
00133   if (funcs->size())
00134   {
00135     oldMapStruct 
00136       = oldMap->getDOFsForCellBatch(1, oldCellLID, *funcs, oldElemDofs, 
00137         oldNNodes, 0);
00138     
00139     newMapStruct 
00140       = newMap->getDOFsForCellBatch(1, oldCellLID, *funcs, newElemDofs, 
00141         oldNNodes, 0);
00142     
00143     for (int chunk=0; chunk<oldMapStruct->numBasisChunks(); chunk++)
00144     {
00145       int nf = oldMapStruct->numFuncs(chunk);
00146       int nDofsPerCell = oldNNodes[chunk] * nf;
00147       for (int c=0; c<oldCellLID.size(); c++)
00148       {
00149         for (int d=0; d<nDofsPerCell; d++)
00150         {
00151           int oldDof = oldElemDofs[chunk][nDofsPerCell*c + d];
00152           int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00153           loadable(newVec)->setElement(newDof, ghostView->getElement(oldDof));
00154         }
00155       }
00156     }
00157   }
00158 
00159   /* Copy the vertex dofs to the new vector. The data at v=0 are duplicated */
00160   Array<int> oldVertLID(oldMesh.numCells(0));
00161   Array<int> newVertLID(newMesh.numCells(0));
00162   for (int i=0; i<oldMesh.numCells(0); i++)
00163   {
00164     oldVertLID[i] = i;
00165   }
00166   for (int i=0; i<newMesh.numCells(0); i++)
00167   {
00168     newVertLID[i] = i;
00169   }
00170   if (funcs->size())
00171   {
00172     funcs = oldMap->allowedFuncsOnCellBatch(0, oldCellLID);
00173     
00174     oldMapStruct = oldMap->getDOFsForCellBatch(0, oldVertLID, *funcs, 
00175       oldElemDofs, 
00176       oldNNodes, 0);
00177     newMapStruct 
00178       = newMap->getDOFsForCellBatch(0, newVertLID, *funcs, newElemDofs, 
00179         oldNNodes, 0);
00180     
00181     for (int chunk=0; chunk<oldMapStruct->numBasisChunks(); chunk++)
00182     {
00183       int nf = oldMapStruct->numFuncs(chunk);
00184       int nDofsPerCell = oldNNodes[chunk] * nf;
00185       for (int c=0; c<newVertLID.size(); c++)
00186       {
00187         if (c < oldVertLID.size())
00188         {
00189           for (int d=0; d<nDofsPerCell; d++)
00190           {
00191             int oldDof = oldElemDofs[chunk][nDofsPerCell*c + d];
00192             int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00193             loadable(newVec)->setElement(newDof, ghostView->getElement(oldDof));
00194           }
00195         }
00196         else
00197         {
00198           for (int d=0; d<nDofsPerCell; d++)
00199           {
00200             int oldDof = oldElemDofs[chunk][d];
00201             int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00202             loadable(newVec)->setElement(newDof, ghostView->getElement(oldDof));
00203           }
00204         }
00205       }
00206     }
00207   }
00208 
00209   return new DiscreteFunction(space, newVec, name);
00210 }
00211 
00212 
00213 }
00214 
00215 

Site Contact