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
00044 #include "Sundance.hpp"
00045
00046
00047 #if defined(HAVE_SUNDANCE_EXODUS)
00048
00049 using namespace Sundance;
00050
00051
00052
00053
00054
00055
00056 int main(int argc, char** argv)
00057 {
00058 try
00059 {
00060
00061 std::string meshFile="plateWithHole3D-1";
00062 std::string solverFile = "aztec-ml.xml";
00063 Sundance::setOption("meshFile", meshFile, "mesh file");
00064 Sundance::setOption("solver", solverFile,
00065 "name of XML file for solver");
00066
00067
00068 Sundance::init(&argc, &argv);
00069
00070
00071 VectorType<double> vecType = new EpetraVectorType();
00072
00073
00074 MeshType meshType = new BasicSimplicialMeshType();
00075 MeshSource meshSrc
00076 = new ExodusMeshReader(meshFile, meshType);
00077 Mesh mesh = meshSrc.getMesh();
00078
00079
00080
00081
00082 CellFilter interior = new MaximalCellFilter();
00083
00084
00085 CellFilter edges = new DimensionalCellFilter(2);
00086
00087 CellFilter south = edges.labeledSubset(1);
00088 CellFilter east = edges.labeledSubset(2);
00089 CellFilter north = edges.labeledSubset(3);
00090 CellFilter west = edges.labeledSubset(4);
00091 CellFilter hole = edges.labeledSubset(5);
00092 CellFilter down = edges.labeledSubset(6);
00093 CellFilter up = edges.labeledSubset(7);
00094
00095
00096
00097
00098 BasisFamily basis = new Lagrange(1);
00099 Expr u = new UnknownFunction(basis, "u");
00100 Expr v = new TestFunction(basis, "v");
00101
00102
00103 Expr dx = new Derivative(0);
00104 Expr dy = new Derivative(1);
00105 Expr dz = new Derivative(2);
00106 Expr grad = List(dx, dy, dz);
00107
00108
00109 QuadratureFamily quad1 = new GaussianQuadrature(1);
00110 QuadratureFamily quad2 = new GaussianQuadrature(2);
00111
00112
00113
00114 Expr eqn
00115 = Integral(interior, (grad*u)*(grad*v), quad1)
00116 + Integral(east, v, quad1);
00117
00118
00119 Expr h = new CellDiameterExpr();
00120 Expr bc = EssentialBC(west, v*u/h, quad2);
00121
00122
00123 LinearProblem prob(mesh, eqn, bc, v, u, vecType);
00124
00125
00126
00127
00128
00129
00130 LinearSolver<double> solver
00131 = LinearSolverBuilder::createSolver(solverFile);
00132
00133
00134
00135 Expr soln = prob.solve(solver);
00136
00137
00138
00139
00140 DiscreteSpace discSpace(mesh, List(basis, basis, basis), vecType);
00141 L2Projector proj(discSpace, grad*soln);
00142 Expr gradU = proj.project();
00143
00144
00145 FieldWriter w = new VTKWriter("LaplaceDemo3D");
00146 w.addMesh(mesh);
00147 w.addField("soln", new ExprFieldWrapper(soln[0]));
00148 w.addField("du_dx", new ExprFieldWrapper(gradU[0]));
00149 w.addField("du_dy", new ExprFieldWrapper(gradU[1]));
00150 w.addField("du_dz", new ExprFieldWrapper(gradU[2]));
00151 w.write();
00152
00153
00154 Expr n = CellNormalExpr(3, "n");
00155 CellFilter wholeBdry = east+west+north+south+up+down+hole;
00156 Expr fluxExpr
00157 = Integral(wholeBdry, (n*grad)*soln, quad1);
00158 double flux = evaluateIntegral(mesh, fluxExpr);
00159 Out::root() << "numerical flux = " << flux << std::endl;
00160
00161
00162
00163
00164
00165 Expr x = new CoordExpr(0);
00166 Expr y = new CoordExpr(1);
00167 Expr z = new CoordExpr(2);
00168
00169 Expr xCMExpr = Integral(interior, x, quad1);
00170 Expr yCMExpr = Integral(interior, y, quad1);
00171 Expr zCMExpr = Integral(interior, z, quad1);
00172 Expr volExpr = Integral(interior, 1.0, quad1);
00173
00174 double vol = evaluateIntegral(mesh, volExpr);
00175 double xCM = evaluateIntegral(mesh, xCMExpr)/vol;
00176 double yCM = evaluateIntegral(mesh, yCMExpr)/vol;
00177 double zCM = evaluateIntegral(mesh, zCMExpr)/vol;
00178 Out::root() << "centroid = (" << xCM << ", " << yCM
00179 << ", " << zCM << ")" << std::endl;
00180
00181
00182
00183 Expr r = sqrt(x*x + y*y);
00184 Expr sinPhi = y/r;
00185
00186
00187 QuadratureFamily quad4 = new GaussianQuadrature(4);
00188
00189 Expr fourierSin1Expr = Integral(hole, sinPhi*soln, quad4);
00190 Expr fourierDenomExpr = Integral(hole, sinPhi*sinPhi, quad2);
00191 double fourierSin1 = evaluateIntegral(mesh, fourierSin1Expr);
00192 double fourierDenom = evaluateIntegral(mesh, fourierDenomExpr);
00193 Out::root() << "fourier sin m=1 = " << fourierSin1/fourierDenom << std::endl;
00194
00195
00196 Expr L2NormExpr = Integral(interior, soln*soln, quad2);
00197 double l2Norm_method1 = sqrt(evaluateIntegral(mesh, L2NormExpr));
00198 Out::os() << "method #1: ||soln|| = " << l2Norm_method1 << endl;
00199
00200
00201 double l2Norm_method2 = L2Norm(mesh, interior, soln, quad2);
00202 Out::os() << "method #2: ||soln|| = " << l2Norm_method2 << endl;
00203
00204
00205
00206
00207
00208
00209
00210 Sundance::passFailTest(fabs(flux), 1.0e-2);
00211 }
00212 catch(std::exception& e)
00213 {
00214 Sundance::handleException(e);
00215 }
00216 Sundance::finalize();
00217
00218 return Sundance::testStatus();
00219 }
00220
00221
00222
00223
00224
00225 #else
00226
00227
00228 int main(int argc, char** argv)
00229 {
00230 Sundance::init(&argc, &argv);
00231 std::cout << "dummy Laplace3D PASSED. Enable exodus to run the actual test" << std::endl;
00232 Sundance::finalize();
00233 return 0;
00234 }
00235
00236
00237 #endif
00238