00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <VariationalProblemExpression.hpp>
00021
00022 #include <VariationalProblem.hpp>
00023
00024 #include <ScalarFunctionBase.hpp>
00025
00026 #include <VariationalOperatorMuGradUGradV.hpp>
00027 #include <VariationalOperatorAlphaDxUDxV.hpp>
00028 #include <VariationalOperatorAlphaUV.hpp>
00029 #include <VariationalOperatorNuUdxV.hpp>
00030 #include <VariationalOperatorNuDxUV.hpp>
00031
00032 #include <VariationalBorderOperatorAlphaUV.hpp>
00033 #include <VariationalBorderOperatorFV.hpp>
00034
00035 #include <VariationalOperatorFV.hpp>
00036 #include <VariationalOperatorFdxGV.hpp>
00037 #include <VariationalOperatorFdxV.hpp>
00038 #include <VariationalOperatorFgradGgradV.hpp>
00039
00040 #include <Information.hpp>
00041
00042 #include <BoundaryConditionExpressionDirichlet.hpp>
00043
00044 #include <BoundaryList.hpp>
00045
00046 class VariationalProblemExpression::AlgebraicPlus
00047 {
00048 public:
00049 static
00050 ConstReferenceCounting<ScalarFunctionBase>
00051 convert(ConstReferenceCounting<FunctionExpression> f)
00052 {
00053 return f->function();
00054 }
00055 };
00056
00057 class VariationalProblemExpression::AlgebraicMinus
00058 {
00059 public:
00060 static
00061 ConstReferenceCounting<ScalarFunctionBase>
00062 convert(ReferenceCounting<FunctionExpression> f)
00063 {
00064 ScalarFunctionBuilder functionBuilder;
00065 functionBuilder.setFunction(f->function());
00066 functionBuilder.setUnaryMinus();
00067 return functionBuilder.getBuiltFunction();
00068 }
00069 };
00070
00071 void
00072 VariationalProblemExpression::
00073 __splitBilinearBoundaryList(const size_t& unknownNumber,
00074 const size_t& testNumber,
00075 const ScalarFunctionBase* alpha,
00076 const Boundary* b)
00077 {
00078 const BoundaryList& boundaryList = dynamic_cast<const BoundaryList&>(*b);
00079
00080 for (BoundaryList::List::const_iterator i = boundaryList.list().begin();
00081 i != boundaryList.list().end(); ++i) {
00082 if ((**i).type() == Boundary::list) {
00083 this->__splitBilinearBoundaryList(unknownNumber, testNumber, alpha, *i);
00084 } else {
00085 __variationalProblem->add(new VariationalBorderOperatorAlphaUV(unknownNumber,
00086 testNumber,
00087 alpha,
00088 *i));
00089 }
00090 }
00091 }
00092
00093 void
00094 VariationalProblemExpression::
00095 __splitLinearBoundaryList(const size_t& testNumber,
00096 const ScalarFunctionBase* f,
00097 const Boundary* b)
00098 {
00099 const BoundaryList& boundaryList = dynamic_cast<const BoundaryList&>(*b);
00100
00101 for (BoundaryList::List::const_iterator i = boundaryList.list().begin();
00102 i != boundaryList.list().end(); ++i) {
00103 if ((*i)->type() == Boundary::list) {
00104 this->__splitLinearBoundaryList(testNumber, f, *i);
00105 } else {
00106 __variationalProblem->add(new VariationalBorderOperatorFV(testNumber, f, *i));
00107 }
00108 }
00109 }
00110
00111 template <typename AlgebraicOperator>
00112 void VariationalProblemExpression::
00113 __internalSetBilinearBC(VariationalFormulaExpression::BilinearOperatorList& bilinearList)
00114 {
00115 for (VariationalFormulaExpression::BilinearOperatorList::iterator
00116 i = bilinearList.begin(); i != bilinearList.end(); ++i) {
00117 switch ((*i)->operatorType()) {
00118 case VariationalBilinearOperatorExpression::alphaUV: {
00119 VariationalAlphaUVExpression& I
00120 = dynamic_cast<VariationalAlphaUVExpression&>(**i);
00121
00122 ConstReferenceCounting<ScalarFunctionBase> alpha
00123 = AlgebraicOperator::convert(I.alpha());
00124
00125 const size_t unknownNumber = __unknownList->number(I.unknownName());
00126 const size_t testNumber = __testFunctionList->number(I.testFunctionName());
00127
00128 ReferenceCounting<BoundaryExpression> boundary = I.border();
00129
00130 if (boundary->boundary()->type() == Boundary::list) {
00131 this->__splitBilinearBoundaryList(unknownNumber, testNumber, alpha, boundary->boundary());
00132 } else {
00133 __variationalProblem->add(new VariationalBorderOperatorAlphaUV(unknownNumber,
00134 testNumber,
00135 alpha,
00136 boundary->boundary()));
00137 }
00138 break;
00139 }
00140 default: {
00141 throw ErrorHandler(__FILE__,__LINE__,
00142 "unexpected boundary operator type",
00143 ErrorHandler::unexpected);
00144
00145 }
00146 }
00147 }
00148 }
00149
00150
00151
00152 template <typename AlgebraicOperator>
00153 void VariationalProblemExpression::
00154 __internalSetBilinear(VariationalFormulaExpression::BilinearOperatorList& bilinearList)
00155 {
00156 for (VariationalFormulaExpression::BilinearOperatorList::iterator
00157 i = bilinearList.begin(); i != bilinearList.end(); ++i) {
00158 switch ((*i)->operatorType()) {
00159 case VariationalBilinearOperatorExpression::mugradUgradV: {
00160 VariationalMuGradUGradVExpression& I
00161 = dynamic_cast<VariationalMuGradUGradVExpression&>(**i);
00162
00163 ConstReferenceCounting<ScalarFunctionBase> mu = AlgebraicOperator::convert(I.mu());
00164 const size_t unknownNumber = __unknownList->number(I.unknownName());
00165 const size_t testNumber = __testFunctionList->number(I.testFunctionName());
00166
00167 __variationalProblem->add(new VariationalMuGradUGradVOperator(unknownNumber,
00168 I.unknownProperty(),
00169 testNumber,
00170 I.testFunctionProperty(),
00171 mu));
00172 break;
00173 }
00174 case VariationalBilinearOperatorExpression::alphaDxUDxV: {
00175 VariationalAlphaDxUDxVExpression& I
00176 = dynamic_cast<VariationalAlphaDxUDxVExpression&>(*(*i));
00177
00178 ConstReferenceCounting<ScalarFunctionBase> alpha
00179 = AlgebraicOperator::convert(I.alpha());
00180
00181 const size_t unknownNumber = __unknownList->number(I.unknownName());
00182 const size_t testNumber = __testFunctionList->number(I.testFunctionName());
00183
00184 __variationalProblem->add(new VariationalAlphaDxUDxVOperator(unknownNumber,
00185 I.unknownProperty(),
00186 testNumber,
00187 I.testFunctionProperty(),
00188 alpha,
00189 I.i(),
00190 I.j()));
00191 break;
00192 }
00193 case VariationalBilinearOperatorExpression::nuUdxV: {
00194 VariationalNuUdxVExpression& I
00195 = dynamic_cast<VariationalNuUdxVExpression&>(*(*i));
00196
00197 ConstReferenceCounting<ScalarFunctionBase> nu
00198 = AlgebraicOperator::convert(I.nu());
00199
00200 const size_t unknownNumber = __unknownList->number(I.unknownName());
00201 const size_t testNumber = __testFunctionList->number(I.testFunctionName());
00202
00203 __variationalProblem->add(new VariationalNuUdxVOperator(unknownNumber,
00204 I.unknownProperty(),
00205 testNumber,
00206 I.testFunctionProperty(),
00207 nu,
00208 I.number()));
00209 break;
00210 }
00211 case VariationalBilinearOperatorExpression::nuDxUV: {
00212 VariationalNuDxUVExpression& I
00213 = dynamic_cast<VariationalNuDxUVExpression&>(*(*i));
00214
00215 ConstReferenceCounting<ScalarFunctionBase> nu
00216 = AlgebraicOperator::convert(I.nu());
00217
00218 const size_t unknownNumber = __unknownList->number(I.unknownName());
00219 const size_t testNumber = __testFunctionList->number(I.testFunctionName());
00220
00221 __variationalProblem->add(new VariationalNuDxUVOperator(unknownNumber,
00222 I.unknownProperty(),
00223 testNumber,
00224 I.testFunctionProperty(),
00225 nu,
00226 I.number()));
00227 break;
00228 }
00229 case VariationalBilinearOperatorExpression::alphaUV: {
00230 VariationalAlphaUVExpression& I
00231 = dynamic_cast<VariationalAlphaUVExpression&>(*(*i));
00232
00233 ConstReferenceCounting<ScalarFunctionBase> alpha
00234 = AlgebraicOperator::convert(I.alpha());
00235
00236 const size_t& unknownNumber = __unknownList->number(I.unknownName());
00237 const size_t& testNumber = __testFunctionList->number(I.testFunctionName());
00238
00239 __variationalProblem->add(new VariationalAlphaUVOperator(unknownNumber,
00240 I.unknownProperty(),
00241 testNumber,
00242 I.testFunctionProperty(),
00243 alpha));
00244 break;
00245 }
00246 default: {
00247 throw ErrorHandler(__FILE__,__LINE__,
00248 "unexpected operator type",
00249 ErrorHandler::unexpected);
00250 }
00251 }
00252 }
00253 }
00254
00255
00256 template <typename AlgebraicOperator>
00257 void VariationalProblemExpression::
00258 __internalSetLinearBC(VariationalFormulaExpression::LinearOperatorList& linearList)
00259 {
00260 for (VariationalFormulaExpression::LinearOperatorList::iterator
00261 i = linearList.begin(); i != linearList.end(); ++i) {
00262 switch ((*i)->operatorType()) {
00263 case VariationalLinearOperatorExpression::FV: {
00264 VariationalFVExpression& I
00265 = dynamic_cast<VariationalFVExpression&>(**i);
00266
00267 const size_t testNumber = __testFunctionList->number(I.testFunctionName());
00268 ConstReferenceCounting<ScalarFunctionBase> f = AlgebraicOperator::convert(I.f());
00269
00270 ReferenceCounting<BoundaryExpression> boundary = I.border();
00271 ASSERT(boundary != 0);
00272
00273 if (boundary->boundary()->type() == Boundary::list) {
00274 this->__splitLinearBoundaryList(testNumber, f, boundary->boundary());
00275 } else {
00276 __variationalProblem->add(new VariationalBorderOperatorFV(testNumber,
00277 f,
00278 boundary->boundary()));
00279 }
00280 break;
00281 }
00282 default: {
00283 throw ErrorHandler(__FILE__,__LINE__,
00284 "unexpected operator type",
00285 ErrorHandler::unexpected);
00286 }
00287 }
00288 }
00289 }
00290
00291
00292 template <typename AlgebraicOperator>
00293 void VariationalProblemExpression::
00294 __internalSetLinear(VariationalFormulaExpression::LinearOperatorList& linearList)
00295 {
00296 for (VariationalFormulaExpression::LinearOperatorList::iterator
00297 i = linearList.begin(); i != linearList.end(); ++i) {
00298
00299 VariationalOperator::Property testFunctionProperty = VariationalOperator::normal;
00300
00301 switch ((*i)->operatorType()) {
00302 case VariationalLinearOperatorExpression::FV: {
00303 VariationalFVExpression& I
00304 = dynamic_cast<VariationalFVExpression&>(**i);
00305 I.execute();
00306
00307 const size_t testFunctionNumber = __testFunctionList->number(I.testFunctionName());
00308 ConstReferenceCounting<ScalarFunctionBase> f = AlgebraicOperator::convert(I.f());
00309
00310 __variationalProblem->add(new VariationalOperatorFV(testFunctionNumber,
00311 testFunctionProperty,
00312 f));
00313 break;
00314 }
00315 case VariationalLinearOperatorExpression::FdxGV: {
00316 VariationalFdxGVExpression& I
00317 = dynamic_cast<VariationalFdxGVExpression&>(**i);
00318
00319 I.execute();
00320
00321 const size_t testFunctionNumber = __testFunctionList->number(I.testFunctionName());
00322 ConstReferenceCounting<ScalarFunctionBase> f = AlgebraicOperator::convert(I.f());
00323 ConstReferenceCounting<ScalarFunctionBase> g = I.g()->function();
00324
00325 __variationalProblem->add(new VariationalOperatorFdxGV(testFunctionNumber,
00326 testFunctionProperty,
00327 f,g,
00328 I.number()));
00329
00330 break;
00331 }
00332 case VariationalLinearOperatorExpression::FdxV: {
00333 VariationalFdxVExpression& I
00334 = dynamic_cast<VariationalFdxVExpression&>(**i);
00335
00336 I.execute();
00337
00338 const size_t testFunctionNumber = __testFunctionList->number(I.testFunctionName());
00339 ConstReferenceCounting<ScalarFunctionBase> f = AlgebraicOperator::convert(I.f());
00340
00341 __variationalProblem->add(new VariationalOperatorFdxV(testFunctionNumber,
00342 testFunctionProperty,
00343 f,I.number()));
00344 break;
00345 }
00346 case VariationalLinearOperatorExpression::FgradGgradV: {
00347 VariationalFgradGgradVExpression& I
00348 = dynamic_cast<VariationalFgradGgradVExpression&>(*(*i));
00349
00350 I.execute();
00351
00352 const size_t testFunctionNumber = __testFunctionList->number(I.testFunctionName());
00353 ConstReferenceCounting<ScalarFunctionBase> f = AlgebraicOperator::convert(I.f());
00354 ConstReferenceCounting<ScalarFunctionBase> g = I.g()->function();
00355
00356 __variationalProblem->add(new VariationalOperatorFgradGgradV(testFunctionNumber,
00357 testFunctionProperty,
00358 f,g));
00359
00360 break;
00361 }
00362 default: {
00363 throw ErrorHandler(__FILE__,__LINE__,
00364 "unexpected operator type",
00365 ErrorHandler::unexpected);
00366 }
00367 }
00368 }
00369 }
00370
00371 void
00372 VariationalProblemExpression::
00373 __splitBoundaryList(BoundaryConditionSet& bcSet, const PDECondition* pde, const Boundary* b)
00374 {
00375 const BoundaryList& boundaryList = dynamic_cast<const BoundaryList&>(*b);
00376
00377 for (BoundaryList::List::const_iterator i = boundaryList.list().begin();
00378 i != boundaryList.list().end(); ++i) {
00379 if ((*i)->type() == Boundary::list) {
00380 this->__splitBoundaryList(bcSet, pde, *i);
00381 } else {
00382 bcSet.addBoundaryCondition(new BoundaryCondition(pde, *i));
00383 }
00384 }
00385 }
00386
00387 bool VariationalProblemExpression::
00388 hasPOVBoundary() const
00389 {
00390 if (__dirichletList->hasPOVBoundary()) return true;
00391 if (__variationalFormula->hasPOVBoundary()) return true;
00392 return false;
00393 }
00394
00395 bool VariationalProblemExpression::
00396 hasPredefinedBoundary() const
00397 {
00398 if (__dirichletList->hasPredefinedBoundary()) return true;
00399 if (__variationalFormula->hasPredefinedBoundary()) return true;
00400 return false;
00401 }
00402
00403 void VariationalProblemExpression::
00404 execute()
00405 {
00406 __variationalFormula->execute();
00407 __dirichletList->execute();
00408 __testFunctionList->execute();
00409
00410 __unknownList = Information::instance().getUnknownList();
00411
00412 std::vector<ReferenceCounting<BoundaryConditionSet> > listOfBCSet;
00413 listOfBCSet.resize(__testFunctionList->size());
00414
00415 for (size_t i=0; i<listOfBCSet.size(); ++i) {
00416 listOfBCSet[i] = new BoundaryConditionSet();
00417 }
00418
00419 for (VariationalDirichletListExpression::iterator
00420 i = __dirichletList->begin();
00421 i != __dirichletList->end(); ++i) {
00422 size_t number = __unknownList->number((*i)->unknownName());
00423 BoundaryConditionSet& bcSet = (*listOfBCSet[number]);
00424 const BoundaryCondition& b = * (*i)->boundaryCondition();
00425 if (b.boundary()->type() == Boundary::list) {
00426 const Boundary* bc = b.boundary();
00427 const PDECondition* pde = b.condition();
00428
00429 this->__splitBoundaryList(bcSet, pde, bc);
00430 } else {
00431 bcSet.addBoundaryCondition((*i)->boundaryCondition());
00432 }
00433 }
00434
00435
00436 std::vector<ConstReferenceCounting<BoundaryConditionSet> > listOfConstBCSet;
00437 listOfConstBCSet.resize(listOfBCSet.size());
00438 for (size_t i=0; i<listOfBCSet.size(); ++i) {
00439 listOfConstBCSet[i] = listOfBCSet[i];
00440 }
00441
00442 __variationalProblem = new VariationalProblem(listOfConstBCSet);
00443
00444 __internalSetBilinear<AlgebraicPlus>(__variationalFormula->__bilinearPlus);
00445 __internalSetBilinear<AlgebraicMinus>(__variationalFormula->__bilinearMinus);
00446
00447 __internalSetLinear<AlgebraicPlus>(__variationalFormula->__linearPlus);
00448 __internalSetLinear<AlgebraicMinus>(__variationalFormula->__linearMinus);
00449
00450 __internalSetBilinearBC<AlgebraicPlus>(__variationalFormula->__bilinearBorderPlus);
00451 __internalSetBilinearBC<AlgebraicMinus>(__variationalFormula->__bilinearBorderMinus);
00452
00453 __internalSetLinearBC<AlgebraicPlus>(__variationalFormula->__linearBorderPlus);
00454 __internalSetLinearBC<AlgebraicMinus>(__variationalFormula->__linearBorderMinus);
00455 }
00456
00457
00458 VariationalProblemExpression::
00459 VariationalProblemExpression(ReferenceCounting<VariationalFormulaExpression> v,
00460 ReferenceCounting<VariationalDirichletListExpression> d,
00461 ReferenceCounting<TestFunctionExpressionList> t)
00462 : ProblemExpression(ProblemExpression::variationalProblem),
00463 __variationalFormula(v),
00464 __dirichletList(d),
00465 __testFunctionList(t)
00466 {
00467 ;
00468 }
00469
00470
00471 VariationalProblemExpression::
00472 VariationalProblemExpression(const VariationalProblemExpression& vp)
00473 : ProblemExpression(vp),
00474 __variationalFormula(vp.__variationalFormula),
00475 __dirichletList(vp.__dirichletList),
00476 __unknownList(vp.__unknownList),
00477 __testFunctionList(vp.__testFunctionList),
00478 __variationalProblem(vp.__variationalProblem)
00479 {
00480 ;
00481 }
00482
00483
00484 VariationalProblemExpression::
00485 ~VariationalProblemExpression()
00486 {
00487 ;
00488 }
00489
00490
00491 ReferenceCounting<VariationalProblem>
00492 VariationalProblemExpression::variationalProblem()
00493 {
00494 return __variationalProblem;
00495 }