00001 #include "SundanceMeshIOUtils.hpp"
00002
00003
00004 namespace Sundance
00005 {
00006 using namespace Sundance;
00007 using namespace Sundance;
00008 using namespace Sundance;
00009 using namespace Teuchos;
00010
00011
00012 Expr readNodalFields(const MeshSource& mesher, const Mesh& mesh,
00013 const VectorType<double>& vecType)
00014 {
00015
00016 RCP<Array<Array<double> > > elemAttr;
00017 RCP<Array<Array<double> > > vertAttr;
00018 mesher.getAttributes(vertAttr, elemAttr);
00019 int nAttrs = vertAttr->size();
00020 const Array<Array<double> >& funcVals = *vertAttr;
00021
00022
00023 Array<BasisFamily> bas(nAttrs);
00024 for (int i=0; i<bas.size(); i++) bas[i] = new Lagrange(1);
00025 DiscreteSpace discSpace(mesh, bas, vecType);
00026 Expr u0 = new DiscreteFunction(discSpace, 0.0, "u0");
00027
00028
00029
00030 Vector<double> vec = DiscreteFunction::discFunc(u0)->getVector();
00031 const RCP<DOFMapBase>& dofMap
00032 = DiscreteFunction::discFunc(u0)->map();
00033
00034
00035
00036 Array<int> dofs(1);
00037 for (int i=0; i<mesh.numCells(0); i++)
00038 {
00039 for (int f=0; f<nAttrs; f++)
00040 {
00041
00042 dofMap->getDOFsForCell(0, i, f, dofs);
00043 int dof = dofs[0];
00044 vec.setElement(dof, funcVals[f][i]);
00045 }
00046 }
00047
00048
00049 DiscreteFunction::discFunc(u0)->setVector(vec);
00050
00051 return u0;
00052 }
00053
00054
00055
00056
00057
00058 Expr readSerialGridField(const std::string& gridFile,
00059 double ax, double bx,
00060 double ay, double by,
00061 const VectorType<double>& vecType,
00062 const MeshType& meshType,
00063 Mesh& mesh)
00064 {
00065 ifstream is(gridFile.c_str());
00066 int nNodes ;
00067 int nx;
00068 int ny;
00069 int nAttrs;
00070 is >> nx >> ny >> nAttrs;
00071 nNodes = nx*ny;
00072
00073 Array<Array<double> > funcVals(nAttrs);
00074 for (int i=0; i<nAttrs; i++) funcVals[i].resize(nNodes);
00075 for (int i=0; i<nNodes; i++)
00076 {
00077 for (int f=0; f<nAttrs; f++)
00078 {
00079 is >> funcVals[f][i];
00080 }
00081 }
00082
00083
00084 MeshSource mesher = new PartitionedRectangleMesher(ax, bx, nx-1, 1,
00085 ay, by, ny-1, 1,
00086 meshType);
00087
00088 mesh = mesher.getMesh();
00089
00090
00091
00092
00093 Array<BasisFamily> bas(nAttrs);
00094 for (int i=0; i<bas.size(); i++) bas[i] = new Lagrange(1);
00095 DiscreteSpace discSpace(mesh, bas, vecType);
00096 Expr u0 = new DiscreteFunction(discSpace, 0.0, "u0");
00097
00098
00099
00100
00101 Vector<double> vec = DiscreteFunction::discFunc(u0)->getVector();
00102 const RCP<DOFMapBase>& dofMap
00103 = DiscreteFunction::discFunc(u0)->map();
00104
00105
00106
00107 Array<int> dofs(1);
00108 for (int i=0; i<mesh.numCells(0); i++)
00109 {
00110 for (int f=0; f<nAttrs; f++)
00111 {
00112
00113 dofMap->getDOFsForCell(0, i, f, dofs);
00114 int dof = dofs[0];
00115 vec.setElement(dof, funcVals[f][i]);
00116 }
00117 }
00118
00119
00120 DiscreteFunction::discFunc(u0)->setVector(vec);
00121
00122 return u0;
00123 }
00124
00125 double readbackTester(const std::string& infile, const MPIComm& comm)
00126 {
00127
00128 VectorType<double> vecType = new EpetraVectorType();
00129
00130
00131 MeshType meshType = new BasicSimplicialMeshType();
00132 MeshSource mesher = new ExodusMeshReader(infile, meshType, comm);
00133 Mesh mesh = mesher.getMesh();
00134
00135 Out::root() << "done reading mesh " << std::endl;
00136 int dim = mesh.spatialDim();
00137
00138 Expr x = new CoordExpr(0);
00139 Expr y = new CoordExpr(1);
00140 Expr z = new CoordExpr(2);
00141
00142
00143
00144 DiscreteSpace discSpace(mesh, new Lagrange(1), vecType);
00145 Out::root() << "done making discfunc " << std::endl;
00146 Expr u;
00147 if (dim==3)
00148 {
00149 L2Projector proj(discSpace, x*sin(x)*y*y+exp(z)*cos(y));
00150 u = proj.project();
00151 }
00152 else if (dim==2)
00153 {
00154 L2Projector proj(discSpace, x*sin(x)+x*x*cos(y));
00155 u = proj.project();
00156 }
00157 else
00158 {
00159 TEST_FOR_EXCEPT(dim != 2 && dim != 3);
00160 }
00161 Out::root() << "done projecting function " << std::endl;
00162
00163 CellFilter interior = new MaximalCellFilter();
00164 QuadratureFamily quad = new GaussianQuadrature(2);
00165 Expr F = Integral(interior, u*u, quad);
00166 double fVal = evaluateIntegral(mesh, F);
00167 Out::root() << "done evaluating functional on original mesh" << std::endl;
00168
00169
00170 FieldWriter w = new ExodusWriter("./readbackTest-out");
00171 w.addMesh(mesh);
00172 w.addField("u", new ExprFieldWrapper(u));
00173 w.write();
00174
00175
00176 MeshSource mesher2 = new ExodusMeshReader("./readbackTest-out", meshType, comm);
00177 Mesh mesh2 = mesher2.getMesh();
00178 Expr u2 = readNodalFields(mesher2, mesh2, vecType);
00179 Out::root() << "done readback " << std::endl;
00180
00181
00182 Expr F2 = Integral(interior, u2*u2, quad);
00183 double fVal2 = evaluateIntegral(mesh2, F2);
00184
00185 Out::root() << "functional on original mesh = " << fVal << std::endl;
00186 Out::root() << "functional on readback mesh = " << fVal2 << std::endl;
00187
00188 double diff = std::fabs(fVal - fVal2);
00189 Out::root() << "diff = " << diff << std::endl;
00190
00191 return diff;
00192 }
00193
00194
00195
00196 void invertMap(const Map<int,int>& in, Map<int,int>& out)
00197 {
00198 typedef Map<int,int>::const_iterator iter;
00199
00200 for (iter i=in.begin(); i!=in.end(); i++)
00201 {
00202 out.put(i->second, i->first);
00203 }
00204 }
00205
00206 void serialPartition(
00207 const RCP<SerialPartitionerBase>& part,
00208 int numProc,
00209 const MeshSource& mesher,
00210 const std::string& outfile)
00211 {
00212
00213
00214
00215 TEST_FOR_EXCEPTION(mesher.comm().getNProc() > 1, RuntimeError,
00216 "serialPartition() should only be called from a "
00217 "single-process communicator");
00218
00219
00220 Mesh mesh = mesher.getMesh();
00221 int dim = mesh.spatialDim();
00222
00223
00224
00225
00226 Array<Sundance::Map<int, int> > oldElemLIDToNewLIDMaps;
00227 Array<Sundance::Map<int, int> > oldVertLIDToNewLIDMaps;
00228
00229
00230 Array<Mesh> submesh = part->makeMeshParts(mesh, numProc,
00231 oldElemLIDToNewLIDMaps,
00232 oldVertLIDToNewLIDMaps
00233 );
00234
00235
00236 RCP<Array<Array<double> > > oldElemData;
00237 RCP<Array<Array<double> > > oldNodeData;
00238 mesher.getAttributes(oldNodeData, oldElemData);
00239
00240
00241 for (int p=0; p<numProc; p++)
00242 {
00243 Out::os() << "writing part=" << p << " of " << numProc << std::endl;
00244 FieldWriter writer = new ExodusWriter(outfile);
00245
00246 writer.impersonateParallelProc(numProc, p);
00247 writer.addMesh(submesh[p]);
00248
00249
00250 Map<int, int> newElemLIDToOldLIDMap;
00251 Map<int, int> newVertLIDToOldLIDMap;
00252 invertMap(oldElemLIDToNewLIDMaps[p], newElemLIDToOldLIDMap);
00253 invertMap(oldVertLIDToNewLIDMaps[p], newVertLIDToOldLIDMap);
00254
00255
00256 RCP<Array<double> > elemData;
00257 int nElemFuncs = oldElemData->size();
00258 int nElems = submesh[p].numCells(dim);
00259 for (int f=0; f<nElemFuncs; f++)
00260 {
00261 elemData = rcp(new Array<double>(nElems));
00262 for (int lid=0; lid<nElems; lid++)
00263 {
00264 int oldLID = newElemLIDToOldLIDMap.get(lid);
00265 (*elemData)[lid] = (*oldElemData)[f][oldLID];
00266 }
00267
00268 writer.addField("uElem["+ Teuchos::toString(f)+"]",
00269 new CellLIDMappedFieldWrapper(dim, 1, elemData));
00270 }
00271
00272
00273 RCP<Array<double> > nodeData;
00274 int nNodeFuncs = oldNodeData->size();
00275 int nNodes = submesh[p].numCells(0);
00276 for (int f=0; f<nNodeFuncs; f++)
00277 {
00278 nodeData = rcp(new Array<double>(nNodes));
00279 for (int lid=0; lid<nNodes; lid++)
00280 {
00281 int oldLID = newVertLIDToOldLIDMap.get(lid);
00282 (*nodeData)[lid] = (*oldNodeData)[f][oldLID];
00283 }
00284
00285 writer.addField("uNode["+ Teuchos::toString(f)+"]",
00286 new CellLIDMappedFieldWrapper(0, 1, nodeData));
00287 }
00288
00289
00290 writer.write();
00291 }
00292 }
00293
00294
00295
00296
00297
00298 }