00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <VariationalFormulaExpression.hpp>
00021
00022 #include <FunctionExpressionConstant.hpp>
00023
00024 #include <PDESystem.hpp>
00025
00026 bool VariationalFormulaExpression::
00027 hasPOVBoundary() const
00028 {
00029 return __givenMultiLinearExpression->hasPOVBoundary();
00030 }
00031
00032 bool VariationalFormulaExpression::
00033 hasPredefinedBoundary() const
00034 {
00035 return __givenMultiLinearExpression->hasPOVBoundary();
00036 }
00037
00038 void VariationalFormulaExpression::
00039 __getBandLForms2D(MultiLinearExpressionSum::iterator begin,
00040 MultiLinearExpressionSum::iterator end,
00041 BilinearOperatorList& bilinearPlus,
00042 BilinearOperatorList& bilinearMinus,
00043 LinearOperatorList& linearPlus,
00044 LinearOperatorList& linearMinus,
00045 ReferenceCounting<BoundaryExpression> borderExpression)
00046 {
00047 for (MultiLinearExpressionSum::iterator j = begin;
00048 j != end; ++j) {
00049 ReferenceCounting<FunctionExpression> f
00050 = (*j)->getFunction();
00051
00052 switch ((*j)->operatorType()) {
00053 case MultiLinearExpression::UV: {
00054 const std::string& unknownName = (*j)->getUnknownName();
00055 const std::string& testFunctionName = (*j)->getTestFunctionName();
00056
00057 const VariationalOperator::Property unknownProperty = (*j)->getUnknownProperty();
00058 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00059
00060 bilinearPlus.push_back(new VariationalAlphaUVExpression(f,
00061 unknownName,
00062 unknownProperty,
00063 testFunctionName,
00064 testFunctionProperty,
00065 borderExpression));
00066 break;
00067 }
00068 case MultiLinearExpression::V: {
00069 const std::string& testFunctionName = (*j)->getTestFunctionName();
00070 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00071
00072 linearMinus.push_back(new VariationalFVExpression(f,
00073 testFunctionName,
00074 testFunctionProperty,
00075 borderExpression));
00076 break;
00077 }
00078 default: {
00079 throw ErrorHandler(__FILE__,__LINE__,
00080 "unexpected operator type",
00081 ErrorHandler::unexpected);
00082 }
00083 }
00084 }
00085 }
00086
00087
00088 template <typename ListType>
00089 std::ostream&
00090 VariationalFormulaExpression::__putList(const ListType& listType,
00091 char delimiter,
00092 bool& first,
00093 std::ostream& os) const
00094 {
00095 for (typename ListType::const_iterator i = listType.begin();
00096 i != listType.end(); ++i) {
00097 os << "\t ";
00098 if (not(first) or (delimiter != '+')) {
00099 os << delimiter;
00100 } else {
00101 os << ' ';
00102 }
00103 first = false;
00104 os << "int";
00105 if ((*i)->border() != 0) {
00106 os << '[' << *(*i)->border() << ']';
00107 }
00108 os << '(' << **i << ")\n";
00109 }
00110 return os;
00111 }
00112
00113
00114 std::ostream& VariationalFormulaExpression::
00115 put(std::ostream& os) const
00116 {
00117 bool first = true;
00118 os << '\n';
00119 __putList(__bilinearPlus, '+' , first, os);
00120 __putList(__bilinearMinus, '-', first , os);
00121
00122 __putList(__bilinearBorderPlus, '+', first , os);
00123 __putList(__bilinearBorderMinus, '-', first , os);
00124
00125 os << "\t =";
00126
00127 if ( __linearPlus.size()
00128 +__linearMinus.size()
00129 +__linearBorderPlus.size()
00130 +__linearBorderMinus.size()==0) {
00131 os << " 0";
00132 } else {
00133 os << '\n';
00134 first = true;
00135
00136 __putList(__linearPlus, '+', first , os);
00137 __putList(__linearMinus, '-', first , os);
00138
00139 __putList(__linearBorderPlus, '+', first , os);
00140 __putList(__linearBorderMinus, '-', first , os);
00141
00142 os << ";\n";
00143 }
00144 return os;
00145 }
00146
00147
00148 void VariationalFormulaExpression::
00149 __getBandLForms3D(MultiLinearExpressionSum::iterator begin,
00150 MultiLinearExpressionSum::iterator end,
00151 BilinearOperatorList& bilinearPlus,
00152 BilinearOperatorList& bilinearMinus,
00153 LinearOperatorList& linearPlus,
00154 LinearOperatorList& linearMinus)
00155 {
00156 for (MultiLinearExpressionSum::iterator j = begin;
00157 j != end; ++j) {
00158
00159 ReferenceCounting<FunctionExpression> f
00160 = (*j)->getFunction();
00161
00162 switch ((*j)->operatorType()) {
00163 case MultiLinearExpression::gradUgradV: {
00164 const std::string& unknownName = (*j)->getUnknownName();
00165 const std::string& testFunctionName = (*j)->getTestFunctionName();
00166
00167 const VariationalOperator::Property unknownProperty = (*j)->getUnknownProperty();
00168 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00169
00170 bilinearPlus.push_back(new VariationalMuGradUGradVExpression(f,
00171 unknownName,
00172 unknownProperty,
00173 testFunctionName,
00174 testFunctionProperty));
00175 break;
00176 }
00177 case MultiLinearExpression::dxUdxV: {
00178 const std::string& unknownName = (*j)->getUnknownName();
00179 const std::string& testFunctionName = (*j)->getTestFunctionName();
00180
00181 IntegratedOperatorExpression::OperatorType t
00182 = (*j)->getTestFunctionOperator();
00183
00184 size_t m = 0;
00185 switch (t) {
00186 case (IntegratedOperatorExpression::dx): {
00187 m=0;
00188 break;
00189 }
00190 case (IntegratedOperatorExpression::dy): {
00191 m=1;
00192 break;
00193 }
00194 case (IntegratedOperatorExpression::dz): {
00195 m=2;
00196 break;
00197 }
00198 default: {
00199 throw ErrorHandler(__FILE__,__LINE__,
00200 "unexpected derivative number",
00201 ErrorHandler::unexpected);
00202 }
00203 }
00204
00205 t = (*j)->getUnknownOperator();
00206
00207 size_t n = 0;
00208 switch (t) {
00209 case (IntegratedOperatorExpression::dx): {
00210 n=0;
00211 break;
00212 }
00213 case (IntegratedOperatorExpression::dy): {
00214 n=1;
00215 break;
00216 }
00217 case (IntegratedOperatorExpression::dz): {
00218 n=2;
00219 break;
00220 }
00221 default: {
00222 throw ErrorHandler(__FILE__,__LINE__,
00223 "unexpected derivative number",
00224 ErrorHandler::unexpected);
00225 }
00226 }
00227
00228 const VariationalOperator::Property unknownProperty = (*j)->getUnknownProperty();
00229 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00230
00231 bilinearPlus.push_back(new VariationalAlphaDxUDxVExpression(f,m,n,
00232 unknownName,
00233 unknownProperty,
00234 testFunctionName,
00235 testFunctionProperty));
00236 break;
00237 }
00238 case MultiLinearExpression::UdxV: {
00239 const std::string& unknownName = (*j)->getUnknownName();
00240 const std::string& testFunctionName = (*j)->getTestFunctionName();
00241
00242 IntegratedOperatorExpression::OperatorType t
00243 = (*j)->getTestFunctionOperator();
00244
00245 size_t n = 0;
00246 switch (t) {
00247 case (IntegratedOperatorExpression::dx): {
00248 n=0;
00249 break;
00250 }
00251 case (IntegratedOperatorExpression::dy): {
00252 n=1;
00253 break;
00254 }
00255 case (IntegratedOperatorExpression::dz): {
00256 n=2;
00257 break;
00258 }
00259 case (IntegratedOperatorExpression::gradient): {
00260 throw ErrorHandler(__FILE__,__LINE__,
00261 "\""+stringify(**j)+"\" is not an allowed construction",
00262 ErrorHandler::normal);
00263 break;
00264 }
00265 default: {
00266 throw ErrorHandler(__FILE__,__LINE__,
00267 "unexpected derivative number",
00268 ErrorHandler::unexpected);
00269 }
00270 }
00271
00272 const VariationalOperator::Property unknownProperty = (*j)->getUnknownProperty();
00273 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00274
00275 bilinearPlus.push_back(new VariationalNuUdxVExpression(f,n,
00276 unknownName,
00277 unknownProperty,
00278 testFunctionName,
00279 testFunctionProperty));
00280 break;
00281 }
00282 case MultiLinearExpression::dxUV: {
00283 const std::string& unknownName = (*j)->getUnknownName();
00284 const std::string& testFunctionName = (*j)->getTestFunctionName();
00285
00286 IntegratedOperatorExpression::OperatorType t
00287 = (*j)->getUnknownOperator();
00288
00289 size_t n = 0;
00290 switch (t) {
00291 case (IntegratedOperatorExpression::dx): {
00292 n=0;
00293 break;
00294 }
00295 case (IntegratedOperatorExpression::dy): {
00296 n=1;
00297 break;
00298 }
00299 case (IntegratedOperatorExpression::dz): {
00300 n=2;
00301 break;
00302 }
00303 case (IntegratedOperatorExpression::gradient): {
00304 throw ErrorHandler(__FILE__,__LINE__,
00305 "\""+stringify(**j)+"\" is not an allowed construction",
00306 ErrorHandler::normal);
00307 break;
00308 }
00309 default: {
00310 throw ErrorHandler(__FILE__,__LINE__,
00311 "unexpected derivative number",
00312 ErrorHandler::unexpected);
00313 }
00314 }
00315 const VariationalOperator::Property unknownProperty = (*j)->getUnknownProperty();
00316 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00317
00318 bilinearPlus.push_back(new VariationalNuDxUVExpression(f,n,
00319 unknownName,
00320 unknownProperty,
00321 testFunctionName,
00322 testFunctionProperty));
00323 break;
00324 }
00325 case MultiLinearExpression::UV: {
00326 const std::string& unknownName = (*j)->getUnknownName();
00327 const std::string& testFunctionName = (*j)->getTestFunctionName();
00328
00329 const VariationalOperator::Property unknownProperty = (*j)->getUnknownProperty();
00330 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00331
00332 bilinearPlus.push_back(new VariationalAlphaUVExpression(f,
00333 unknownName,
00334 unknownProperty,
00335 testFunctionName,
00336 testFunctionProperty));
00337 break;
00338 }
00339 case MultiLinearExpression::gradV: {
00340 const std::string& testFunctionName = (*j)->getTestFunctionName();
00341 throw ErrorHandler(__FILE__,__LINE__,
00342 "cannot discretize 'int("+stringify(*f)+"*grad("+testFunctionName+"))'",
00343 ErrorHandler::normal);
00344 break;
00345 }
00346 case MultiLinearExpression::dxV: {
00347 const std::string& testFunctionName = (*j)->getTestFunctionName();
00348
00349 IntegratedOperatorExpression::OperatorType t
00350 = (*j)->getTestFunctionOperator();
00351
00352 size_t n = 0;
00353 switch (t) {
00354 case (IntegratedOperatorExpression::dx): {
00355 n=0;
00356 break;
00357 }
00358 case (IntegratedOperatorExpression::dy): {
00359 n=1;
00360 break;
00361 }
00362 case (IntegratedOperatorExpression::dz): {
00363 n=2;
00364 break;
00365 }
00366 default: {
00367 throw ErrorHandler(__FILE__,__LINE__,
00368 "unexpected derivative number",
00369 ErrorHandler::unexpected);
00370 }
00371 }
00372
00373 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00374
00375 linearMinus.push_back(new VariationalFdxVExpression(f,
00376 testFunctionName,
00377 testFunctionProperty,
00378 n));
00379 break;
00380 }
00381 case MultiLinearExpression::V: {
00382 const std::string& testFunctionName = (*j)->getTestFunctionName();
00383
00384 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00385
00386 linearMinus.push_back(new VariationalFVExpression(f,
00387 testFunctionName,
00388 testFunctionProperty));
00389 break;
00390 }
00391 case MultiLinearExpression::dxFV: {
00392 ReferenceCounting<FunctionExpression> g
00393 = (*j)->getFunctionExpression();
00394
00395 const std::string& testFunctionName = (*j)->getTestFunctionName();
00396
00397 IntegratedOperatorExpression::OperatorType t
00398 = (*j)->getFunctionOperator();
00399
00400 size_t n = 0;
00401 switch (t) {
00402 case (IntegratedOperatorExpression::dx): {
00403 n=0;
00404 break;
00405 }
00406 case (IntegratedOperatorExpression::dy): {
00407 n=1;
00408 break;
00409 }
00410 case (IntegratedOperatorExpression::dz): {
00411 n=2;
00412 break;
00413 }
00414 default: {
00415 throw ErrorHandler(__FILE__,__LINE__,
00416 "unexpected derivative number",
00417 ErrorHandler::unexpected);
00418 }
00419 }
00420
00421 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00422
00423 linearMinus.push_back(new VariationalFdxGVExpression(f,g,
00424 testFunctionName,
00425 testFunctionProperty,
00426 n));
00427 break;
00428 }
00429 case MultiLinearExpression::gradFgradV: {
00430 ReferenceCounting<FunctionExpression> g
00431 = (*j)->getFunctionExpression();
00432 const std::string& testFunctionName = (*j)->getTestFunctionName();
00433
00434 const VariationalOperator::Property testFunctionProperty = (*j)->getTestFunctionProperty();
00435
00436 linearMinus.push_back(new VariationalFgradGgradVExpression(f,g,
00437 testFunctionName,
00438 testFunctionProperty));
00439 break;
00440 }
00441 default: {
00442 throw ErrorHandler(__FILE__,__LINE__,
00443 "unexpected operator type",
00444 ErrorHandler::unexpected);
00445 }
00446 }
00447 }
00448 }
00449
00450 void VariationalFormulaExpression::
00451 __getBilinearAndLinearForms(MultiLinearFormSumExpression::iterator begin,
00452 MultiLinearFormSumExpression::iterator end,
00453 BilinearOperatorList& bilinearPlus,
00454 BilinearOperatorList& bilinearMinus,
00455 BilinearOperatorList& bilinearBorderPlus,
00456 BilinearOperatorList& bilinearBorderMinus,
00457 LinearOperatorList& linearPlus,
00458 LinearOperatorList& linearMinus,
00459 LinearOperatorList& linearBorderPlus,
00460 LinearOperatorList& linearBorderMinus)
00461 {
00462 ReferenceCounting<RealExpression> r
00463 = new RealExpressionValue(1);
00464
00465 ReferenceCounting<FunctionExpression> one
00466 = new FunctionExpressionConstant(r);
00467
00468 for(MultiLinearFormSumExpression::iterator i = begin;
00469 i != end; ++i) {
00470
00471 MultiLinearExpressionSum& m = *(*i)->multiLinearExpression();
00472
00473 if ((*i)->formType() == MultiLinearFormExpression::threeD) {
00474 __getBandLForms3D(m.beginPlus(), m.endPlus(),
00475 bilinearPlus, bilinearMinus,
00476 linearPlus, linearMinus);
00477
00478 __getBandLForms3D(m.beginMinus(), m.endMinus(),
00479 bilinearMinus, bilinearPlus,
00480 linearMinus, linearPlus);
00481 } else {
00482 __getBandLForms2D(m.beginPlus(), m.endPlus(),
00483 bilinearBorderPlus, bilinearBorderMinus,
00484 linearBorderPlus, linearBorderMinus,
00485 (*i)->boundaryExpression());
00486
00487 __getBandLForms2D(m.beginMinus(), m.endMinus(),
00488 bilinearBorderMinus, bilinearBorderPlus,
00489 linearBorderMinus, linearBorderPlus,
00490 (*i)->boundaryExpression());
00491 }
00492 }
00493 }
00494
00495
00496 void VariationalFormulaExpression::
00497 execute()
00498 {
00499 for (BilinearOperatorList::iterator i = __bilinearPlus.begin();
00500 i != __bilinearPlus.end(); ++i) {
00501 (*i)->execute();
00502 }
00503
00504 for (BilinearOperatorList::iterator i = __bilinearMinus.begin();
00505 i != __bilinearMinus.end(); ++i) {
00506 (*i)->execute();
00507 }
00508
00509 for (LinearOperatorList::iterator i = __linearPlus.begin();
00510 i != __linearPlus.end(); ++i) {
00511 (*i)->execute();
00512 }
00513
00514 for (LinearOperatorList::iterator i = __linearMinus.begin();
00515 i != __linearMinus.end(); ++i) {
00516 (*i)->execute();
00517 }
00518
00519 for (BilinearOperatorList::iterator i = __bilinearBorderPlus.begin();
00520 i != __bilinearBorderPlus.end(); ++i) {
00521 (*i)->execute();
00522 }
00523
00524 for (BilinearOperatorList::iterator i = __bilinearBorderMinus.begin();
00525 i != __bilinearBorderMinus.end(); ++i) {
00526 (*i)->execute();
00527 }
00528
00529 for (LinearOperatorList::iterator i = __linearBorderPlus.begin();
00530 i != __linearBorderPlus.end(); ++i) {
00531 (*i)->execute();
00532 }
00533
00534 for (LinearOperatorList::iterator i = __linearBorderMinus.begin();
00535 i != __linearBorderMinus.end(); ++i) {
00536 (*i)->execute();
00537 }
00538 }
00539
00540 VariationalFormulaExpression::
00541 VariationalFormulaExpression(ReferenceCounting<MultiLinearFormSumExpression> m)
00542 : Expression(Expression::variationalFormula),
00543 __givenMultiLinearExpression(m)
00544 {
00545 this->__getBilinearAndLinearForms(__givenMultiLinearExpression->plusBegin(),
00546 __givenMultiLinearExpression->plusEnd(),
00547 __bilinearPlus,
00548 __bilinearMinus,
00549 __bilinearBorderPlus,
00550 __bilinearBorderMinus,
00551 __linearPlus,
00552 __linearMinus,
00553 __linearBorderPlus,
00554 __linearBorderMinus);
00555
00556 this->__getBilinearAndLinearForms(__givenMultiLinearExpression->minusBegin(),
00557 __givenMultiLinearExpression->minusEnd(),
00558 __bilinearMinus,
00559 __bilinearPlus,
00560 __bilinearBorderMinus,
00561 __bilinearBorderPlus,
00562 __linearMinus,
00563 __linearPlus,
00564 __linearBorderMinus,
00565 __linearBorderPlus);
00566 }
00567
00568 VariationalFormulaExpression::
00569 VariationalFormulaExpression(const VariationalFormulaExpression& v)
00570 : Expression(v),
00571 __givenMultiLinearExpression(v.__givenMultiLinearExpression),
00572 __bilinearPlus(v.__bilinearPlus),
00573 __bilinearMinus(v.__bilinearMinus),
00574 __linearPlus(v.__linearPlus),
00575 __linearMinus(v.__linearMinus)
00576 {
00577 ;
00578 }
00579
00580 VariationalFormulaExpression::
00581 ~VariationalFormulaExpression()
00582 {
00583 ;
00584 }