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 "Sundance.hpp"
00044
00045 #if defined(HAVE_SUNDANCE_EXODUS) && defined(Trilinos_DATA_DIR)
00046
00047
00048 Array<double> runit(const string& meshName)
00049 {
00050 VectorType<double> vecType = new EpetraVectorType();
00051 MeshType meshType = new BasicSimplicialMeshType();
00052 MeshSource mesher = new ExodusMeshReader(meshName, meshType);
00053 Mesh mesh = mesher.getMesh();
00054
00055 BasisFamily P2 = new Lagrange(2);
00056 BasisFamily P1 = new Lagrange(1);
00057 QuadratureFamily quad = new GaussianQuadrature(4);
00058
00059 Expr ux = new UnknownFunction(P2);
00060 Expr uy = new UnknownFunction(P2);
00061 Expr vx = new TestFunction(P2);
00062 Expr vy = new TestFunction(P2);
00063 Expr u = List(ux, uy);
00064 Expr v = List(vx, vy);
00065
00066 Expr p = new UnknownFunction(P1);
00067 Expr q = new TestFunction(P1);
00068
00069 CellFilter interior = new MaximalCellFilter();
00070 CellFilter sides = new DimensionalCellFilter(1);
00071 CellFilter pts = new DimensionalCellFilter(0);
00072 CellFilter peg = pts.labeledSubset(1);
00073 CellFilter inner = sides.labeledSubset(2);
00074 CellFilter outer = sides.labeledSubset(1);
00075
00076 Expr grad = gradient(2);
00077 Expr x = new CoordExpr(0);
00078 Expr y = new CoordExpr(1);
00079 Expr r = sqrt(x*x+y*y);
00080 double uIn = 0.25;
00081 double uOut = 1.0;
00082 Expr uInnerX = -uIn*y/r;
00083 Expr uInnerY = uIn*x/r;
00084 Expr uOuterX = -uOut*y/r;
00085 Expr uOuterY = uOut*x/r;
00086 Expr uInner = List(uInnerX, uInnerY);
00087 Expr uOuter = List(uOuterX, uOuterY);
00088
00089 Expr nu = 1.0;
00090 double C1 = 20.0;
00091 double C2 = 20.0;
00092
00093
00094 Expr eqn = Integral(interior,
00095 nu * colonProduct( outerProduct(grad, u), outerProduct(grad, v) )
00096 - p*div(v) - q*div(u), quad)
00097 + NitscheStokesNoSlipBC(inner, quad, nu, v, q, u, p, uInner, C1, C2)
00098 + NitscheStokesNoSlipBC(outer, quad, nu, v, q, u, p, uOuter, C1, C2);
00099
00100 Expr dummyBC;
00101
00102
00103 Expr MpEqn = Integral(interior, p*q, quad);
00104 Expr ApEqn = Integral(interior, (grad*p)*(grad*q), quad)
00105 + Integral(peg, p*q, quad);
00106 Expr FpEqn = Integral(interior, (grad*p)*(grad*q), quad)
00107 + Integral(peg, p*q, quad);
00108
00109
00110 Array<Block> unkBlocks = tuple(Block(u, vecType), Block(p, vecType));
00111 Array<Block> varBlocks = tuple(Block(v, vecType), Block(q, vecType));
00112
00113
00114 LinearProblem prob( mesh , eqn , dummyBC , varBlocks, unkBlocks );
00115
00116
00117 LinearProblem MpProb(mesh, MpEqn, dummyBC, q, p, vecType);
00118 LinearProblem ApProb(mesh, ApEqn, dummyBC, q, p, vecType);
00119 LinearProblem FpProb(mesh, FpEqn, dummyBC, q, p, vecType);
00120
00121
00122
00123 ParameterXMLFileReader outerSolverReader("pcd-outer-belos.xml");
00124 ParameterList outerSolverParams = outerSolverReader.getParameters();
00125 ParameterList precParams = outerSolverParams.sublist("PCD Preconditioner");
00126 LinearSolver<double> outerSolver = LinearSolverBuilder::createSolver(outerSolverParams);
00127
00128
00129 PreconditionerFactory<double> outerPrec
00130 = new PCDPreconditionerFactory(precParams, MpProb, ApProb, FpProb);
00131 outerSolver.setUserPrec(outerPrec);
00132
00133
00134 Expr soln = prob.solve(outerSolver);
00135
00136
00137
00138 double c1 = -2.0/3.0*(uIn-2.0*uOut);
00139 double c2 = 1.0/3.0*(2.0*uIn - uOut);
00140 Expr uMagExact = c1*r + c2/r;
00141 Expr uxExact = -uMagExact*y/r;
00142 Expr uyExact = uMagExact*x/r;
00143 Expr uExact = List(uxExact, uyExact);
00144
00145 double area = L2Norm(mesh, interior, 1.0, quad);
00146 double uErrorNorm = L2Norm(mesh, interior, soln[0]-uExact, quad)/area;
00147 double pErrorNorm = L2Norm(mesh, interior, soln[1], quad)/area;
00148
00149
00150 Expr h = new CellDiameterExpr();
00151 double hAvg = L2Norm(mesh, interior, h, quad)/area;
00152
00153
00154 Out::root() << "average h = " << hAvg << std::endl;
00155 Out::root() << "velocity error norm = " << uErrorNorm << std::endl;
00156 Out::root() << "pressure error norm = " << pErrorNorm << std::endl;
00157
00158
00159
00160
00161
00162 DiscreteSpace P1Space( mesh , P1 , vecType );
00163 L2Projector proj_ux( P1Space , soln[0][0] );
00164 L2Projector proj_uy( P1Space , soln[0][1] );
00165 L2Projector proj_uxEx( P1Space , uxExact );
00166 L2Projector proj_uyEx( P1Space , uyExact );
00167
00168 Expr ux_P1 = proj_ux.project( );
00169 Expr uy_P1 = proj_uy.project( );
00170
00171 Expr uxEx_P1 = proj_uxEx.project( );
00172 Expr uyEx_P1 = proj_uyEx.project( );
00173
00174 FieldWriter w = new VTKWriter("PCDStokes-" + meshName);
00175 w.addMesh(mesh);
00176 w.addField( "ux" , new ExprFieldWrapper( ux_P1 ) );
00177 w.addField( "uy" , new ExprFieldWrapper( uy_P1 ) );
00178 w.addField( "p" , new ExprFieldWrapper( soln[1] ) );
00179 w.addField( "uxEx" , new ExprFieldWrapper( uxEx_P1 ) );
00180 w.addField( "uyEx" , new ExprFieldWrapper( uyEx_P1 ) );
00181 w.write();
00182
00183 return tuple<double>(hAvg, uErrorNorm, pErrorNorm);
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 int main( int argc , char **argv )
00194 {
00195 try
00196 {
00197 Sundance::init( &argc , &argv );
00198
00199 Array<Array<double> > results;
00200 for (int n=0; n<=1; n++)
00201 {
00202 string meshName = "diskWithHole2D-" + Teuchos::toString(n);
00203 Array<double> x = runit(meshName);
00204 results.append(x);
00205 }
00206
00207 for (int n=0; n<results.size(); n++)
00208 {
00209 Out::root() << setw(12) << results[n][0] << setw(20) << results[n][1]
00210 << setw(20) << results[n][2] << endl;
00211 }
00212
00213 Sundance::passFailTest(results[0][1], 0.001);
00214 }
00215 catch (std::exception &e) {
00216 Out::os() << e.what() << std::endl;
00217 }
00218
00219 Sundance::finalize();
00220 return Sundance::testStatus();
00221 }
00222
00223
00224
00225
00226 #else
00227
00228
00229 int main(int argc, char** argv)
00230 {
00231 Sundance::init(&argc, &argv);
00232 std::cout << "dummy PCDStokes PASSED. Enable exodus to run the actual test" << std::endl;
00233 Sundance::finalize();
00234 return 0;
00235 }
00236
00237
00238 #endif