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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "SundanceMeshIOUtils.hpp"
00044 #include "PlayaOut.hpp"
00045 #include "PlayaTabs.hpp"
00046
00047
00048 namespace Sundance
00049 {
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054 using std::ifstream;
00055 using std::ofstream;
00056
00057
00058 Expr readNodalFields(const MeshSource& mesher, const Mesh& mesh,
00059 const VectorType<double>& vecType, int verb)
00060 {
00061 Tabs tab0(0);
00062 PLAYA_ROOT_MSG1(verb, tab0 << "begin readNodalFields()");
00063 Tabs tab1;
00064
00065
00066 RCP<Array<Array<double> > > elemAttr;
00067 RCP<Array<Array<double> > > vertAttr;
00068
00069 PLAYA_ROOT_MSG2(verb, tab1 << "reading attributes");
00070 mesher.getAttributes(vertAttr, elemAttr);
00071 int nAttrs = vertAttr->size();
00072 PLAYA_ROOT_MSG2(verb, tab1 << "found " << nAttrs << " attributes");
00073 const Array<Array<double> >& funcVals = *vertAttr;
00074
00075
00076 Array<BasisFamily> bas(nAttrs);
00077 for (int i=0; i<bas.size(); i++) bas[i] = new Lagrange(1);
00078 PLAYA_ROOT_MSG2(verb, tab1 << "forming discrete space");
00079 DiscreteSpace discSpace(mesh, bas, vecType);
00080 PLAYA_ROOT_MSG2(verb, tab1 << "forming discrete function");
00081 Expr u0 = new DiscreteFunction(discSpace, 0.0, "u0");
00082
00083
00084
00085 Vector<double> vec = DiscreteFunction::discFunc(u0)->getVector();
00086 const RCP<DOFMapBase>& dofMap
00087 = DiscreteFunction::discFunc(u0)->map();
00088
00089
00090
00091 PLAYA_ROOT_MSG2(verb, tab1 << "filling discrete function");
00092 Array<int> dofs(1);
00093 for (int i=0; i<mesh.numCells(0); i++)
00094 {
00095 Tabs tab2;
00096 PLAYA_ROOT_MSG3(verb, tab2 << "node i=" << i);
00097 for (int f=0; f<nAttrs; f++)
00098 {
00099 Tabs tab3;
00100
00101 dofMap->getDOFsForCell(0, i, f, dofs);
00102 int dof = dofs[0];
00103 PLAYA_ROOT_MSG3(verb, tab3 << "f=" << f << " dof=" << dof << " val="
00104 << funcVals[f][i]);
00105 loadable(vec)->setElement(dof, funcVals[f][i]);
00106 }
00107 }
00108
00109
00110 DiscreteFunction::discFunc(u0)->setVector(vec);
00111
00112 PLAYA_ROOT_MSG1(verb, tab0 << "done readNodalFields()");
00113 return u0;
00114 }
00115
00116
00117
00118
00119
00120 Expr readSerialGridField(const std::string& gridFile,
00121 double ax, double bx,
00122 double ay, double by,
00123 const VectorType<double>& vecType,
00124 const MeshType& meshType,
00125 Mesh& mesh)
00126 {
00127 ifstream is(gridFile.c_str());
00128 int nNodes ;
00129 int nx;
00130 int ny;
00131 int nAttrs;
00132 is >> nx >> ny >> nAttrs;
00133 nNodes = nx*ny;
00134
00135 Array<Array<double> > funcVals(nAttrs);
00136 for (int i=0; i<nAttrs; i++) funcVals[i].resize(nNodes);
00137 for (int i=0; i<nNodes; i++)
00138 {
00139 for (int f=0; f<nAttrs; f++)
00140 {
00141 is >> funcVals[f][i];
00142 }
00143 }
00144
00145
00146 MeshSource mesher = new PartitionedRectangleMesher(ax, bx, nx-1, 1,
00147 ay, by, ny-1, 1,
00148 meshType);
00149
00150 mesh = mesher.getMesh();
00151
00152
00153
00154
00155 Array<BasisFamily> bas(nAttrs);
00156 for (int i=0; i<bas.size(); i++) bas[i] = new Lagrange(1);
00157 DiscreteSpace discSpace(mesh, bas, vecType);
00158 Expr u0 = new DiscreteFunction(discSpace, 0.0, "u0");
00159
00160
00161
00162
00163 Vector<double> vec = DiscreteFunction::discFunc(u0)->getVector();
00164 const RCP<DOFMapBase>& dofMap
00165 = DiscreteFunction::discFunc(u0)->map();
00166
00167
00168
00169 Array<int> dofs(1);
00170 for (int i=0; i<mesh.numCells(0); i++)
00171 {
00172 for (int f=0; f<nAttrs; f++)
00173 {
00174
00175 dofMap->getDOFsForCell(0, i, f, dofs);
00176 int dof = dofs[0];
00177 loadable(vec)->setElement(dof, funcVals[f][i]);
00178 }
00179 }
00180
00181
00182 DiscreteFunction::discFunc(u0)->setVector(vec);
00183
00184 return u0;
00185 }
00186
00187 double readbackTester(const std::string& infile, const MPIComm& comm, int verb)
00188 {
00189
00190 VectorType<double> vecType = new EpetraVectorType();
00191
00192
00193 Out::root() << "starting to read mesh " << std::endl;
00194 MeshType meshType = new BasicSimplicialMeshType();
00195 MeshSource mesher = new ExodusMeshReader(infile, meshType, verb, comm);
00196 Mesh mesh = mesher.getMesh();
00197
00198 Out::root() << "done reading mesh " << std::endl;
00199 int dim = mesh.spatialDim();
00200
00201 Expr x = new CoordExpr(0);
00202 Expr y = new CoordExpr(1);
00203 Expr z = new CoordExpr(2);
00204
00205
00206
00207 DiscreteSpace discSpace(mesh, new Lagrange(1), vecType);
00208 Out::root() << "done making discfunc " << std::endl;
00209 Expr u;
00210 if (dim==3)
00211 {
00212 L2Projector proj(discSpace, x*sin(x)*y*y+exp(z)*cos(y));
00213 u = proj.project();
00214 }
00215 else if (dim==2)
00216 {
00217 L2Projector proj(discSpace, x*sin(x)+x*x*cos(y));
00218 u = proj.project();
00219 }
00220 else
00221 {
00222 TEUCHOS_TEST_FOR_EXCEPT(dim != 2 && dim != 3);
00223 }
00224 Out::root() << "done projecting function " << std::endl;
00225
00226 CellFilter interior = new MaximalCellFilter();
00227 QuadratureFamily quad = new GaussianQuadrature(2);
00228 Expr F = Integral(interior, u*u, quad);
00229 double fVal = evaluateIntegral(mesh, F);
00230 Out::root() << "done evaluating functional on original mesh" << std::endl;
00231
00232
00233 FieldWriter w = new ExodusWriter("./readbackTest-out");
00234 w.addMesh(mesh);
00235 w.addField("u", new ExprFieldWrapper(u));
00236 w.write();
00237
00238
00239 MeshSource mesher2 = new ExodusMeshReader("./readbackTest-out", meshType, verb, comm);
00240 Mesh mesh2 = mesher2.getMesh();
00241 Expr u2 = readNodalFields(mesher2, mesh2, vecType, verb);
00242 Out::root() << "done readback " << std::endl;
00243
00244
00245 Expr F2 = Integral(interior, u2*u2, quad);
00246 double fVal2 = evaluateIntegral(mesh2, F2);
00247
00248 Out::root() << "functional on original mesh = " << fVal << std::endl;
00249 Out::root() << "functional on readback mesh = " << fVal2 << std::endl;
00250
00251 double diff = std::fabs(fVal - fVal2);
00252 Out::root() << "diff = " << diff << std::endl;
00253
00254 return diff;
00255 }
00256
00257
00258
00259 void invertMap(const Map<int,int>& in, Map<int,int>& out)
00260 {
00261 typedef Map<int,int>::const_iterator iter;
00262
00263 for (iter i=in.begin(); i!=in.end(); i++)
00264 {
00265 out.put(i->second, i->first);
00266 }
00267 }
00268
00269 void serialPartition(
00270 const RCP<SerialPartitionerBase>& part,
00271 int numProc,
00272 const MeshSource& mesher,
00273 const std::string& outfile)
00274 {
00275
00276
00277
00278 TEUCHOS_TEST_FOR_EXCEPTION(mesher.comm().getNProc() > 1, std::runtime_error,
00279 "serialPartition() should only be called from a "
00280 "single-process communicator");
00281
00282
00283 Mesh mesh = mesher.getMesh();
00284 int dim = mesh.spatialDim();
00285
00286
00287 FieldWriter origWriter = new ExodusWriter("orig-writback");
00288 origWriter.addMesh(mesh);
00289 origWriter.write();
00290
00291
00292
00293
00294 Array<Sundance::Map<int, int> > oldElemLIDToNewLIDMaps;
00295 Array<Sundance::Map<int, int> > oldVertLIDToNewLIDMaps;
00296
00297
00298 Array<Mesh> submesh = part->makeMeshParts(mesh, numProc,
00299 oldElemLIDToNewLIDMaps,
00300 oldVertLIDToNewLIDMaps
00301 );
00302
00303
00304 RCP<Array<Array<double> > > oldElemData;
00305 RCP<Array<Array<double> > > oldNodeData;
00306 mesher.getAttributes(oldNodeData, oldElemData);
00307
00308
00309 Array<Set<int> > vertViewers(mesh.numCells(0));
00310 for (int p=0; p<numProc; p++)
00311 {
00312 for (int v=0; v<submesh[p].numCells(0); v++)
00313 {
00314 int gid = submesh[p].mapLIDToGID(0,v);
00315 vertViewers[gid].put(p);
00316 }
00317 }
00318
00319
00320 for (int p=0; p<numProc; p++)
00321 {
00322 Out::os() << "writing part=" << p << " of " << numProc << std::endl;
00323 FieldWriter writer = new ExodusWriter(outfile);
00324
00325 writer.impersonateParallelProc(numProc, p);
00326 writer.addMesh(submesh[p]);
00327
00328
00329 Map<int, int> newElemLIDToOldLIDMap;
00330 Map<int, int> newVertLIDToOldLIDMap;
00331 Out::os() << "preparing maps to submeshes" << std::endl;
00332 invertMap(oldElemLIDToNewLIDMaps[p], newElemLIDToOldLIDMap);
00333 invertMap(oldVertLIDToNewLIDMaps[p], newVertLIDToOldLIDMap);
00334
00335
00336 Out::os() << "mapping element data to submeshes" << std::endl;
00337 RCP<Array<double> > elemData;
00338 int nElemFuncs = oldElemData->size();
00339 int nElems = submesh[p].numCells(dim);
00340 for (int f=0; f<nElemFuncs; f++)
00341 {
00342 elemData = rcp(new Array<double>(nElems));
00343 for (int lid=0; lid<nElems; lid++)
00344 {
00345 int oldLID = newElemLIDToOldLIDMap.get(lid);
00346 (*elemData)[lid] = (*oldElemData)[f][oldLID];
00347 }
00348
00349 writer.addField("uElem["+ Teuchos::toString(f)+"]",
00350 new CellLIDMappedFieldWrapper(dim, 1, elemData));
00351 }
00352
00353
00354 Out::os() << "mapping node data to submeshes" << std::endl;
00355 RCP<Array<double> > nodeData;
00356 int nNodeFuncs = oldNodeData->size();
00357 int nNodes = submesh[p].numCells(0);
00358 for (int f=0; f<nNodeFuncs; f++)
00359 {
00360 nodeData = rcp(new Array<double>(nNodes));
00361 for (int lid=0; lid<nNodes; lid++)
00362 {
00363 int oldLID = newVertLIDToOldLIDMap.get(lid);
00364 (*nodeData)[lid] = (*oldNodeData)[f][oldLID];
00365 }
00366
00367 writer.addField("uNode["+ Teuchos::toString(f)+"]",
00368 new CellLIDMappedFieldWrapper(0, 1, nodeData));
00369 }
00370
00371
00372 Out::os() << "doing write()" << std::endl;
00373 writer.write();
00374 Out::os() << "done part=" << p << " of " << numProc << std::endl;
00375 }
00376
00377
00378 for (int p=0; p<numProc; p++)
00379 {
00380 Out::os() << "writing part=" << p << " of " << numProc << std::endl;
00381
00382 string vvFile = outfile + "-" + Teuchos::toString(numProc)
00383 + "-" + Teuchos::toString(p) + ".pvv";
00384 ofstream of(vvFile.c_str());
00385 of << submesh[p].numCells(0) << endl;
00386 for (int v=0; v<submesh[p].numCells(0); v++)
00387 {
00388 int gid = submesh[p].mapLIDToGID(0, v);
00389 const Set<int>& viewers = vertViewers[gid];
00390 of << v << " " << gid << " " << viewers.size();
00391 for (Set<int>::const_iterator
00392 i=viewers.begin(); i!=viewers.end(); i++)
00393 {
00394 of << " " << *i;
00395 }
00396 of << endl;
00397 }
00398 }
00399 }
00400
00401
00402
00403
00404
00405 }