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
00045 #include "Sundance.hpp"
00046 using Sundance::List;
00047
00048
00049 #if defined(HAVE_SUNDANCE_EXODUS) && defined(Trilinos_DATA_DIR)
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 int main(int argc, char** argv)
00060 {
00061 try
00062 {
00063 std::string meshFile="pipe2D-2";
00064 std::string outFile="TwoZoneTransport1";
00065 double K_f = 0.145;
00066 double c_f = 2.0;
00067 double rho_f = 0.865;
00068 double K_s = 0.61;
00069 double U0 = 20.0;
00070 double Q = 1.0;
00071 std::string heatSolverFile="aztec-ifpack.xml";
00072 std::string flowSolverFile="aztec-ml.xml";
00073
00074 Sundance::setOption("meshFile", meshFile, "mesh file (omit .exo suffix)");
00075 Sundance::setOption("outFile", outFile, "output file (omit .vtu suffix)");
00076 Sundance::setOption("K-fluid", K_f, "Thermal diffusivity of fluid");
00077 Sundance::setOption("rho-fluid", rho_f, "Density of fluid");
00078 Sundance::setOption("c-fluid", rho_f, "Specific heat of fluid");
00079 Sundance::setOption("K-solid", K_s, "Thermal diffusivity of solid");
00080 Sundance::setOption("U0", U0, "Average velocity of fluid");
00081 Sundance::setOption("Q", Q, "Heat generation rate in solid");
00082 Sundance::setOption("flow-solver", flowSolverFile, "flow solver XML file");
00083 Sundance::setOption("heat-solver", heatSolverFile, "heat solver XML file");
00084
00085 Sundance::init(&argc, &argv);
00086
00087 Out::root() << "K_f = " << K_f << endl;
00088 Out::root() << "rho_f = " << rho_f << endl;
00089 Out::root() << "c_f = " << c_f << endl;
00090 Out::root() << "K_s = " << K_s << endl;
00091 Out::root() << "Q = " << Q << endl;
00092 Out::root() << "Peclet number = " << rho_f*c_f*U0 / K_f << endl;
00093
00094
00095 VectorType<double> vecType = new EpetraVectorType();
00096
00097
00098 LinearSolver<double> flowSolver
00099 = LinearSolverBuilder::createSolver(flowSolverFile);
00100
00101 LinearSolver<double> heatSolver
00102 = LinearSolverBuilder::createSolver(heatSolverFile);
00103
00104
00105
00106 Out::root() << "reading mesh" << endl;
00107 MeshType meshType = new BasicSimplicialMeshType();
00108 MeshSource meshSrc
00109 = new ExodusMeshReader(meshFile, meshType);
00110 Mesh mesh = meshSrc.getMesh();
00111
00112
00113 CellFilter interior = new MaximalCellFilter();
00114 CellFilter fluid = interior.labeledSubset(1);
00115 CellFilter solid = interior.labeledSubset(2);
00116
00117 CellFilter sides = new DimensionalCellFilter(1);
00118
00119 CellFilter east = sides.labeledSubset(1);
00120 CellFilter west = sides.labeledSubset(2);
00121 CellFilter north = sides.labeledSubset(3);
00122 CellFilter south = sides.labeledSubset(4);
00123
00124
00125
00126 BasisFamily basis = new Lagrange(1);
00127 Expr phi = new UnknownFunction(basis, "phi");
00128 Expr v = new TestFunction(basis, "v");
00129
00130
00131 Expr grad = gradient(2);
00132
00133
00134 QuadratureFamily quad2 = new GaussianQuadrature(2);
00135 QuadratureFamily quad4 = new GaussianQuadrature(4);
00136
00137
00138 Expr flowEqn = Integral(fluid, (grad*phi)*(grad*v), quad2);
00139
00140 Expr h = new CellDiameterExpr();
00141 Expr x = new CoordExpr(0);
00142 Expr flowBC = EssentialBC(west, v*(phi-x*U0)/h, quad2) +
00143 EssentialBC(east, v*(phi-x*U0)/h, quad2);
00144
00145
00146 LinearProblem flowProb(mesh, flowEqn, flowBC, v, phi, vecType);
00147
00148 Out::root() << "solving flow" << endl;
00149 Expr phi0 = flowProb.solve(flowSolver);
00150
00151
00152 Expr T = new UnknownFunction(basis);
00153
00154 Expr n = CellNormalExpr(2, "n");
00155
00156 Expr heatEqn = Integral(solid, K_s*(grad*v)*(grad*T) - v*Q, quad2)
00157 + Integral(fluid,
00158 (grad*v)*(K_f*(grad*T) - c_f*rho_f*(grad*phi0)*T), quad2)
00159 + Integral(east, c_f*rho_f*v*T*n*(grad*phi0), quad2);
00160
00161 Expr heatBC = EssentialBC(west, v*T/h, quad2);
00162
00163
00164 LinearProblem heatProb(mesh, heatEqn, heatBC, v, T, vecType);
00165
00166 Out::root() << "solving heat" << endl;
00167 Expr T0 = heatProb.solve(heatSolver);
00168
00169 Out::root() << "writing output" << endl;
00170 FieldWriter w = new VTKWriter(outFile);
00171 w.addMesh(mesh);
00172 w.addField("phi", new ExprFieldWrapper(phi0[0]));
00173 w.addField("T", new ExprFieldWrapper(T0[0]));
00174 w.write();
00175
00176
00177
00178 Out::root() << "checking flux balance" << endl;
00179 Expr J = c_f*rho_f*T0*(grad*phi0) - K_f*(grad*T0);
00180 Expr fluxCheckNet = Integral(east+west+north+south, n*J, quad2);
00181 Expr sourceCheck = Integral(solid, Q, quad2);
00182
00183 double netFlux = evaluateIntegral(mesh, fluxCheckNet);
00184 double netSource = evaluateIntegral(mesh, sourceCheck);
00185
00186
00187 Out::root() << endl;
00188 Out::root() << "net heat flux out: " << netFlux << endl;
00189 Out::root() << "net heat production by source: " << netSource << endl;
00190 Out::root() << endl;
00191
00192
00193
00194
00195 Sundance::passFailTest(fabs(netFlux - netSource), 1.0e-2);
00196 }
00197 catch(std::exception& e)
00198 {
00199 Sundance::handleException(e);
00200 }
00201 Sundance::finalize(); return Sundance::testStatus();
00202
00203 return Sundance::testStatus();
00204 }
00205
00206 #else
00207
00208
00209 int main(int argc, char** argv)
00210 {
00211 Sundance::init(&argc, &argv);
00212 std::cout << "dummy PoissonDemo3D PASSED. Enable exodus to run the actual test" << std::endl;
00213 Sundance::finalize();
00214 return 0;
00215 }
00216
00217
00218 #endif
00219
00220