Go to the documentation of this file.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 "SundanceTabs.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 "Teuchos_MPIContainerComm.hpp"
00041 #include "Teuchos_TimeMonitor.hpp"
00042
00043
00044
00045 namespace Sundance
00046 {
00047 using namespace Teuchos;
00048 using namespace TSFExtended;
00049
00050 Mesh unfoldPeriodicMesh(const Mesh& mesh)
00051 {
00052 const MeshBase* mb = mesh.ptr().get();
00053 const PeriodicMesh1D* pm = dynamic_cast<const PeriodicMesh1D*>(mb);
00054
00055 TEST_FOR_EXCEPT(pm==0);
00056
00057 int numElems = mesh.numCells(1);
00058 double a = mesh.nodePosition(0)[0];
00059 double b = mesh.nodePosition(numElems)[0];
00060
00061 MeshType meshType = new BasicSimplicialMeshType();
00062 MeshSource mesher = new PartitionedLineMesher(a, b, numElems, meshType,
00063 MPIComm::self());
00064
00065 Mesh rtn = mesher.getMesh();
00066
00067 return rtn;
00068 }
00069
00070
00071 DiscreteSpace unfoldPeriodicDiscreteSpace(const DiscreteSpace& space)
00072 {
00073 VectorType<double> vecType = space.vecType();
00074 Mesh mesh = unfoldPeriodicMesh(space.mesh());
00075 BasisArray basis = space.basis();
00076
00077 return DiscreteSpace(mesh, basis, vecType);
00078 }
00079
00080 Expr unfoldPeriodicDiscreteFunction(const Expr& f)
00081 {
00082 const DiscreteFunction* df = DiscreteFunction::discFunc(f);
00083 TEST_FOR_EXCEPT(df==0);
00084
00085
00086 DiscreteSpace perSpace = df->discreteSpace();
00087 DiscreteSpace space = unfoldPeriodicDiscreteSpace(perSpace);
00088
00089 Mesh oldMesh = perSpace.mesh();
00090 Mesh newMesh = space.mesh();
00091
00092 Vector<double> oldVec = df->getVector();
00093 Vector<double> newVec = space.createVector();
00094
00095 const RCP<DOFMapBase>& oldMap = perSpace.map();
00096 const RCP<DOFMapBase>& newMap = space.map();
00097
00098
00099
00100 Array<int> oldCellLID(oldMesh.numCells(1));
00101 for (int i=0; i<oldMesh.numCells(1); i++)
00102 {
00103 oldCellLID[i] = i;
00104 }
00105 RCP<const Set<int> > funcs = oldMap->allowedFuncsOnCellBatch(1, oldCellLID);
00106
00107 Array<Array<int> > oldElemDofs;
00108 Array<Array<int> > newElemDofs;
00109 Array<int> oldNNodes;
00110 RCP<const MapStructure> oldMapStruct ;
00111 RCP<const MapStructure> newMapStruct ;
00112
00113 if (funcs->size())
00114 {
00115 oldMapStruct
00116 = oldMap->getDOFsForCellBatch(1, oldCellLID, *funcs, oldElemDofs,
00117 oldNNodes, 0);
00118
00119 newMapStruct
00120 = newMap->getDOFsForCellBatch(1, oldCellLID, *funcs, newElemDofs,
00121 oldNNodes, 0);
00122
00123 for (int chunk=0; chunk<oldMapStruct->numBasisChunks(); chunk++)
00124 {
00125 int nf = oldMapStruct->numFuncs(chunk);
00126 int nDofsPerCell = oldNNodes[chunk] * nf;
00127 for (int c=0; c<oldCellLID.size(); c++)
00128 {
00129 for (int d=0; d<nDofsPerCell; d++)
00130 {
00131 int oldDof = oldElemDofs[chunk][nDofsPerCell*c + d];
00132 int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00133 newVec.setElement(newDof, oldVec.getElement(oldDof));
00134 }
00135 }
00136 }
00137 }
00138
00139
00140 Array<int> oldVertLID(oldMesh.numCells(0));
00141 Array<int> newVertLID(newMesh.numCells(0));
00142 for (int i=0; i<oldMesh.numCells(0); i++)
00143 {
00144 oldVertLID[i] = i;
00145 }
00146 for (int i=0; i<newMesh.numCells(0); i++)
00147 {
00148 newVertLID[i] = i;
00149 }
00150 if (funcs->size())
00151 {
00152 funcs = oldMap->allowedFuncsOnCellBatch(0, oldCellLID);
00153
00154 oldMapStruct = oldMap->getDOFsForCellBatch(0, oldVertLID, *funcs,
00155 oldElemDofs,
00156 oldNNodes, 0);
00157 newMapStruct
00158 = newMap->getDOFsForCellBatch(0, newVertLID, *funcs, newElemDofs,
00159 oldNNodes, 0);
00160
00161 for (int chunk=0; chunk<oldMapStruct->numBasisChunks(); chunk++)
00162 {
00163 int nf = oldMapStruct->numFuncs(chunk);
00164 int nDofsPerCell = oldNNodes[chunk] * nf;
00165 for (int c=0; c<newVertLID.size(); c++)
00166 {
00167 if (c < oldVertLID.size())
00168 {
00169 for (int d=0; d<nDofsPerCell; d++)
00170 {
00171 int oldDof = oldElemDofs[chunk][nDofsPerCell*c + d];
00172 int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00173 newVec.setElement(newDof, oldVec.getElement(oldDof));
00174 }
00175 }
00176 else
00177 {
00178 for (int d=0; d<nDofsPerCell; d++)
00179 {
00180 int oldDof = oldElemDofs[chunk][d];
00181 int newDof = newElemDofs[chunk][nDofsPerCell*c + d];
00182 newVec.setElement(newDof, oldVec.getElement(oldDof));
00183 }
00184 }
00185 }
00186 }
00187 }
00188
00189 return new DiscreteFunction(space, newVec);
00190 }
00191
00192
00193 }
00194
00195