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 loadable(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 loadable(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 Out::root() << "starting to read mesh " << std::endl;
00132 MeshType meshType = new BasicSimplicialMeshType();
00133 MeshSource mesher = new ExodusMeshReader(infile, meshType, comm);
00134 Mesh mesh = mesher.getMesh();
00135
00136 Out::root() << "done reading mesh " << std::endl;
00137 int dim = mesh.spatialDim();
00138
00139 Expr x = new CoordExpr(0);
00140 Expr y = new CoordExpr(1);
00141 Expr z = new CoordExpr(2);
00142
00143
00144
00145 DiscreteSpace discSpace(mesh, new Lagrange(1), vecType);
00146 Out::root() << "done making discfunc " << std::endl;
00147 Expr u;
00148 if (dim==3)
00149 {
00150 L2Projector proj(discSpace, x*sin(x)*y*y+exp(z)*cos(y));
00151 u = proj.project();
00152 }
00153 else if (dim==2)
00154 {
00155 L2Projector proj(discSpace, x*sin(x)+x*x*cos(y));
00156 u = proj.project();
00157 }
00158 else
00159 {
00160 TEUCHOS_TEST_FOR_EXCEPT(dim != 2 && dim != 3);
00161 }
00162 Out::root() << "done projecting function " << std::endl;
00163
00164 CellFilter interior = new MaximalCellFilter();
00165 QuadratureFamily quad = new GaussianQuadrature(2);
00166 Expr F = Integral(interior, u*u, quad);
00167 double fVal = evaluateIntegral(mesh, F);
00168 Out::root() << "done evaluating functional on original mesh" << std::endl;
00169
00170
00171 FieldWriter w = new ExodusWriter("./readbackTest-out");
00172 w.addMesh(mesh);
00173 w.addField("u", new ExprFieldWrapper(u));
00174 w.write();
00175
00176
00177 MeshSource mesher2 = new ExodusMeshReader("./readbackTest-out", meshType, comm);
00178 Mesh mesh2 = mesher2.getMesh();
00179 Expr u2 = readNodalFields(mesher2, mesh2, vecType);
00180 Out::root() << "done readback " << std::endl;
00181
00182
00183 Expr F2 = Integral(interior, u2*u2, quad);
00184 double fVal2 = evaluateIntegral(mesh2, F2);
00185
00186 Out::root() << "functional on original mesh = " << fVal << std::endl;
00187 Out::root() << "functional on readback mesh = " << fVal2 << std::endl;
00188
00189 double diff = std::fabs(fVal - fVal2);
00190 Out::root() << "diff = " << diff << std::endl;
00191
00192 return diff;
00193 }
00194
00195
00196
00197 void invertMap(const Map<int,int>& in, Map<int,int>& out)
00198 {
00199 typedef Map<int,int>::const_iterator iter;
00200
00201 for (iter i=in.begin(); i!=in.end(); i++)
00202 {
00203 out.put(i->second, i->first);
00204 }
00205 }
00206
00207 void serialPartition(
00208 const RCP<SerialPartitionerBase>& part,
00209 int numProc,
00210 const MeshSource& mesher,
00211 const std::string& outfile)
00212 {
00213
00214
00215
00216 TEUCHOS_TEST_FOR_EXCEPTION(mesher.comm().getNProc() > 1, std::runtime_error,
00217 "serialPartition() should only be called from a "
00218 "single-process communicator");
00219
00220
00221 Mesh mesh = mesher.getMesh();
00222 int dim = mesh.spatialDim();
00223
00224
00225 FieldWriter origWriter = new ExodusWriter("orig-writback");
00226 origWriter.addMesh(mesh);
00227 origWriter.write();
00228
00229
00230
00231
00232 Array<Sundance::Map<int, int> > oldElemLIDToNewLIDMaps;
00233 Array<Sundance::Map<int, int> > oldVertLIDToNewLIDMaps;
00234
00235
00236 Array<Mesh> submesh = part->makeMeshParts(mesh, numProc,
00237 oldElemLIDToNewLIDMaps,
00238 oldVertLIDToNewLIDMaps
00239 );
00240
00241
00242 RCP<Array<Array<double> > > oldElemData;
00243 RCP<Array<Array<double> > > oldNodeData;
00244 mesher.getAttributes(oldNodeData, oldElemData);
00245
00246
00247 Array<Set<int> > vertViewers(mesh.numCells(0));
00248 for (int p=0; p<numProc; p++)
00249 {
00250 for (int v=0; v<submesh[p].numCells(0); v++)
00251 {
00252 int gid = submesh[p].mapLIDToGID(0,v);
00253 vertViewers[gid].put(p);
00254 }
00255 }
00256
00257
00258 for (int p=0; p<numProc; p++)
00259 {
00260 Out::os() << "writing part=" << p << " of " << numProc << std::endl;
00261 FieldWriter writer = new ExodusWriter(outfile);
00262
00263 writer.impersonateParallelProc(numProc, p);
00264 writer.addMesh(submesh[p]);
00265
00266
00267 Map<int, int> newElemLIDToOldLIDMap;
00268 Map<int, int> newVertLIDToOldLIDMap;
00269 Out::os() << "preparing maps to submeshes" << std::endl;
00270 invertMap(oldElemLIDToNewLIDMaps[p], newElemLIDToOldLIDMap);
00271 invertMap(oldVertLIDToNewLIDMaps[p], newVertLIDToOldLIDMap);
00272
00273
00274 Out::os() << "mapping element data to submeshes" << std::endl;
00275 RCP<Array<double> > elemData;
00276 int nElemFuncs = oldElemData->size();
00277 int nElems = submesh[p].numCells(dim);
00278 for (int f=0; f<nElemFuncs; f++)
00279 {
00280 elemData = rcp(new Array<double>(nElems));
00281 for (int lid=0; lid<nElems; lid++)
00282 {
00283 int oldLID = newElemLIDToOldLIDMap.get(lid);
00284 (*elemData)[lid] = (*oldElemData)[f][oldLID];
00285 }
00286
00287 writer.addField("uElem["+ Teuchos::toString(f)+"]",
00288 new CellLIDMappedFieldWrapper(dim, 1, elemData));
00289 }
00290
00291
00292 Out::os() << "mapping node data to submeshes" << std::endl;
00293 RCP<Array<double> > nodeData;
00294 int nNodeFuncs = oldNodeData->size();
00295 int nNodes = submesh[p].numCells(0);
00296 for (int f=0; f<nNodeFuncs; f++)
00297 {
00298 nodeData = rcp(new Array<double>(nNodes));
00299 for (int lid=0; lid<nNodes; lid++)
00300 {
00301 int oldLID = newVertLIDToOldLIDMap.get(lid);
00302 (*nodeData)[lid] = (*oldNodeData)[f][oldLID];
00303 }
00304
00305 writer.addField("uNode["+ Teuchos::toString(f)+"]",
00306 new CellLIDMappedFieldWrapper(0, 1, nodeData));
00307 }
00308
00309
00310 Out::os() << "doing write()" << std::endl;
00311 writer.write();
00312 Out::os() << "done part=" << p << " of " << numProc << std::endl;
00313 }
00314
00315
00316 for (int p=0; p<numProc; p++)
00317 {
00318 Out::os() << "writing part=" << p << " of " << numProc << std::endl;
00319
00320 string vvFile = outfile + "-" + Teuchos::toString(numProc)
00321 + "-" + Teuchos::toString(p) + ".pvv";
00322 ofstream of(vvFile.c_str());
00323 of << submesh[p].numCells(0) << endl;
00324 for (int v=0; v<submesh[p].numCells(0); v++)
00325 {
00326 int gid = submesh[p].mapLIDToGID(0, v);
00327 const Set<int>& viewers = vertViewers[gid];
00328 of << v << " " << gid << " " << viewers.size();
00329 for (Set<int>::const_iterator
00330 i=viewers.begin(); i!=viewers.end(); i++)
00331 {
00332 of << " " << *i;
00333 }
00334 of << endl;
00335 }
00336 }
00337 }
00338
00339
00340
00341
00342
00343 }