1 #ifndef DUNE_PDELAB_GRIDOPERATOR_ONESTEP_ENGINEBASE_HH 2 #define DUNE_PDELAB_GRIDOPERATOR_ONESTEP_ENGINEBASE_HH 3 4 namespace Dune{ 5 namespace PDELab{ 6 7 /** 8 \brief The local assembler engine for UDG sub triangulations which 9 assembles the residual vector 10 11 \tparam LA The local udg assembler 12 13 */ 14 template<typename OSLA, typename LAE0, typename LAE1> 15 class OneStepLocalAssemblerEngineBase 16 { 17 public: 18 //! The type of the wrapping local assembler 19 typedef OSLA OneStepLocalAssembler; 20 21 typedef typename LAE0::Traits Traits; 22 23 template<typename TrialConstraintsContainer, typename TestConstraintsContainer> needsConstraintsCaching(const TrialConstraintsContainer & cu,const TestConstraintsContainer & cv) const24 bool needsConstraintsCaching(const TrialConstraintsContainer& cu, const TestConstraintsContainer& cv) const 25 { 26 return (lae0->needsConstraintsCaching(cu,cv) or lae1->needsConstraintsCaching(cu,cv)); 27 } 28 29 30 //! Types of the subordinate assemblers and engines 31 //! @{ 32 typedef typename OSLA::LocalAssemblerDT0 LocalAssemblerDT0; 33 typedef typename OSLA::LocalAssemblerDT1 LocalAssemblerDT1; 34 35 typedef LAE0 LocalAssemblerEngineDT0; 36 typedef LAE1 LocalAssemblerEngineDT1; 37 //! @} 38 39 //! The type for real numbers 40 typedef typename OSLA::Real Real; 41 42 typedef OSLA LocalAssembler; 43 44 /** 45 \brief Constructor 46 47 \param [in] local_assembler_ The local assembler object which 48 creates this engine 49 */ OneStepLocalAssemblerEngineBase(const LocalAssembler & local_assembler_)50 OneStepLocalAssemblerEngineBase(const LocalAssembler & local_assembler_) 51 : invalid_lae0(nullptr), 52 invalid_lae1(nullptr), 53 la(local_assembler_), 54 lae0(invalid_lae0), lae1(invalid_lae1), 55 implicit(true) 56 {} 57 58 //! Query methods for the global grid assembler 59 //! @{ requireSkeleton() const60 bool requireSkeleton() const 61 { return implicit && (lae0->requireSkeleton() || lae1->requireSkeleton()); } requireSkeletonTwoSided() const62 bool requireSkeletonTwoSided() const 63 { return lae0->requireSkeletonTwoSided() || lae1->requireSkeletonTwoSided(); } requireUVVolume() const64 bool requireUVVolume() const 65 { return lae0->requireUVVolume() || lae1->requireUVVolume(); } requireVVolume() const66 bool requireVVolume() const 67 { return lae0->requireVVolume() || lae1->requireVVolume(); } requireUVSkeleton() const68 bool requireUVSkeleton() const 69 { return lae0->requireUVSkeleton() || lae1->requireUVSkeleton(); } requireVSkeleton() const70 bool requireVSkeleton() const 71 { return lae0->requireVSkeleton() || lae1->requireVSkeleton(); } requireUVBoundary() const72 bool requireUVBoundary() const 73 { return lae0->requireUVBoundary() || lae1->requireUVBoundary(); } requireVBoundary() const74 bool requireVBoundary() const 75 { return lae0->requireVBoundary() || lae1->requireVBoundary(); } requireUVProcessor() const76 bool requireUVProcessor() const 77 { return lae0->requireUVProcessor() || lae1->requireUVProcessor(); } requireVProcessor() const78 bool requireVProcessor() const 79 { return lae0->requireVProcessor() || lae1->requireVProcessor(); } requireUVEnrichedCoupling() const80 bool requireUVEnrichedCoupling() const 81 { return lae0->requireUVEnrichedCoupling() || lae1->requireUVEnrichedCoupling(); } requireVEnrichedCoupling() const82 bool requireVEnrichedCoupling() const 83 { return lae0->requireVEnrichedCoupling() || lae1->requireVEnrichedCoupling(); } requireUVVolumePostSkeleton() const84 bool requireUVVolumePostSkeleton() const 85 { return lae0->requireUVVolumePostSkeleton() || lae1->requireUVVolumePostSkeleton();} requireVVolumePostSkeleton() const86 bool requireVVolumePostSkeleton() const 87 { return lae0->requireVVolumePostSkeleton() || lae1->requireVVolumePostSkeleton(); } 88 //! @} 89 90 91 //! Public access to the wrapping local assembler localAssembler()92 const LocalAssembler & localAssembler(){ return la; } 93 localAssemblerEngineDT0()94 LocalAssemblerEngineDT0& localAssemblerEngineDT0() 95 { 96 return *lae0; 97 } 98 localAssemblerEngineDT0() const99 const LocalAssemblerEngineDT0& localAssemblerEngineDT0() const 100 { 101 return *lae0; 102 } 103 localAssemblerEngineDT1()104 LocalAssemblerEngineDT1& localAssemblerEngineDT1() 105 { 106 return *lae1; 107 } 108 localAssemblerEngineDT1() const109 const LocalAssemblerEngineDT1& localAssemblerEngineDT1() const 110 { 111 return *lae1; 112 } 113 partition() const114 auto partition() const 115 { 116 return localAssemblerEngineDT0().partition(); 117 } 118 setLocalAssemblerEngineDT0(LocalAssemblerEngineDT0 & lae0_)119 void setLocalAssemblerEngineDT0(LocalAssemblerEngineDT0& lae0_) 120 { 121 lae0 = &lae0_; 122 } 123 setLocalAssemblerEngineDT1(LocalAssemblerEngineDT1 & lae1_)124 void setLocalAssemblerEngineDT1(LocalAssemblerEngineDT1& lae1_) 125 { 126 lae1 = &lae1_; 127 } 128 trialConstraints() const129 const typename OneStepLocalAssembler::Traits::TrialGridFunctionSpaceConstraints& trialConstraints() const 130 { 131 return localAssemblerEngineDT0().trialConstraints(); 132 } 133 testConstraints() const134 const typename OneStepLocalAssembler::Traits::TestGridFunctionSpaceConstraints& testConstraints() const 135 { 136 return localAssemblerEngineDT0().testConstraints(); 137 } 138 139 //! Called immediately after binding of local function space in 140 //! global assembler. 141 //! @{ 142 template<typename EG, typename LFSU, typename LFSV> onBindLFSUV(const EG & eg,const LFSU & lfsu,const LFSV & lfsv)143 void onBindLFSUV(const EG & eg, const LFSU & lfsu, const LFSV & lfsv) 144 { 145 lae0->onBindLFSUV(eg,lfsu,lfsv); 146 lae1->onBindLFSUV(eg,lfsu,lfsv); 147 } 148 149 template<typename EG, typename LFSV> onBindLFSV(const EG & eg,const LFSV & lfsv)150 void onBindLFSV(const EG & eg, const LFSV & lfsv) 151 { 152 lae0->onBindLFSV(eg,lfsv); 153 lae1->onBindLFSV(eg,lfsv); 154 } 155 156 template<typename IG, typename LFSU, typename LFSV> onBindLFSUVInside(const IG & ig,const LFSU & lfsu,const LFSV & lfsv)157 void onBindLFSUVInside(const IG & ig, const LFSU & lfsu, const LFSV & lfsv) 158 { 159 lae0->onBindLFSUVInside(ig,lfsu,lfsv); 160 lae1->onBindLFSUVInside(ig,lfsu,lfsv); 161 } 162 163 template<typename IG, 164 typename LFSU_S, typename LFSV_S, 165 typename LFSU_N, typename LFSV_N> onBindLFSUVOutside(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s,const LFSU_N & lfsu_n,const LFSV_N & lfsv_n)166 void onBindLFSUVOutside(const IG & ig, 167 const LFSU_S & lfsu_s, const LFSV_S & lfsv_s, 168 const LFSU_N & lfsu_n, const LFSV_N & lfsv_n) 169 { 170 lae0->onBindLFSUVOutside(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n); 171 lae1->onBindLFSUVOutside(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n); 172 } 173 174 template<typename IG, typename LFSV> onBindLFSVInside(const IG & ig,const LFSV & lfsv)175 void onBindLFSVInside(const IG & ig, const LFSV & lfsv) 176 { 177 lae0->onBindLFSVInside(ig,lfsv); 178 lae1->onBindLFSVInside(ig,lfsv); 179 } 180 181 template<typename IG, 182 typename LFSV_S, 183 typename LFSV_N> onBindLFSVOutside(const IG & ig,const LFSV_S & lfsv_s,const LFSV_N & lfsv_n)184 void onBindLFSVOutside(const IG & ig, 185 const LFSV_S & lfsv_s, 186 const LFSV_N & lfsv_n) 187 { 188 lae0->onBindLFSVOutside(ig,lfsv_s,lfsv_n); 189 lae1->onBindLFSVOutside(ig,lfsv_s,lfsv_n); 190 } 191 192 template<typename IG, 193 typename LFSU_S, typename LFSV_S, 194 typename LFSU_N, typename LFSV_N, 195 typename LFSU_C, typename LFSV_C> onBindLFSUVCoupling(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s,const LFSU_N & lfsu_n,const LFSV_N & lfsv_n,const LFSU_C & lfsu_c,const LFSV_C & lfsv_c)196 void onBindLFSUVCoupling(const IG & ig, 197 const LFSU_S & lfsu_s, const LFSV_S & lfsv_s, 198 const LFSU_N & lfsu_n, const LFSV_N & lfsv_n, 199 const LFSU_C & lfsu_c, const LFSV_C & lfsv_c) 200 { 201 lae0->onBindLFSUVCoupling(ig, 202 lfsu_s,lfsv_s, 203 lfsu_n,lfsv_n, 204 lfsu_c,lfsv_c); 205 lae1->onBindLFSUVCoupling(ig, 206 lfsu_s,lfsv_s, 207 lfsu_n,lfsv_n, 208 lfsu_c,lfsv_c); 209 } 210 211 template<typename IG, 212 typename LFSV_S, 213 typename LFSV_N, 214 typename LFSV_C> onBindLFSVCoupling(const IG & ig,const LFSV_S & lfsv_s,const LFSV_N & lfsv_n,const LFSV_C & lfsv_c)215 void onBindLFSVCoupling(const IG & ig, 216 const LFSV_S & lfsv_s, 217 const LFSV_N & lfsv_n, 218 const LFSV_C & lfsv_c) 219 { 220 lae0->onBindLFSVCoupling(ig,lfsv_s,lfsv_n,lfsv_c); 221 lae1->onBindLFSVCoupling(ig,lfsv_s,lfsv_n,lfsv_c); 222 } 223 224 //! @} 225 226 //! Called when the local function space is about to be rebound or 227 //! discarded 228 //! @{ 229 template<typename EG, typename LFSU, typename LFSV> onUnbindLFSUV(const EG & eg,const LFSU & lfsu,const LFSV & lfsv)230 void onUnbindLFSUV(const EG & eg, const LFSU & lfsu, const LFSV & lfsv) 231 { 232 lae0->onUnbindLFSUV(eg,lfsu, lfsv); 233 lae1->onUnbindLFSUV(eg,lfsu, lfsv); 234 } 235 236 template<typename EG, typename LFSV> onUnbindLFSV(const EG & eg,const LFSV & lfsv)237 void onUnbindLFSV(const EG & eg, const LFSV & lfsv) 238 { 239 lae0->onUnbindLFSV(eg,lfsv); 240 lae1->onUnbindLFSV(eg,lfsv); 241 } 242 243 template<typename IG, typename LFSU, typename LFSV> onUnbindLFSUVInside(const IG & ig,const LFSU & lfsu,const LFSV & lfsv)244 void onUnbindLFSUVInside(const IG & ig, const LFSU & lfsu, const LFSV & lfsv) 245 { 246 lae0->onUnbindLFSUVInside(ig,lfsu, lfsv); 247 lae1->onUnbindLFSUVInside(ig,lfsu, lfsv); 248 } 249 250 template<typename IG, 251 typename LFSU_S, typename LFSV_S, 252 typename LFSU_N, typename LFSV_N> onUnbindLFSUVOutside(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s,const LFSU_N & lfsu_n,const LFSV_N & lfsv_n)253 void onUnbindLFSUVOutside(const IG & ig, 254 const LFSU_S & lfsu_s, const LFSV_S & lfsv_s, 255 const LFSU_N & lfsu_n, const LFSV_N & lfsv_n) 256 { 257 lae0->onUnbindLFSUVOutside(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n); 258 lae1->onUnbindLFSUVOutside(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n); 259 } 260 261 template<typename IG, typename LFSV> onUnbindLFSVInside(const IG & ig,const LFSV & lfsv)262 void onUnbindLFSVInside(const IG & ig, const LFSV & lfsv) 263 { 264 lae0->onUnbindLFSVInside(ig,lfsv); 265 lae1->onUnbindLFSVInside(ig,lfsv); 266 } 267 268 template<typename IG, 269 typename LFSV_S, 270 typename LFSV_N> onUnbindLFSVOutside(const IG & ig,const LFSV_S & lfsv_s,const LFSV_N & lfsv_n)271 void onUnbindLFSVOutside(const IG & ig, 272 const LFSV_S & lfsv_s, 273 const LFSV_N & lfsv_n) 274 { 275 lae0->onUnbindLFSVOutside(ig,lfsv_s,lfsv_n); 276 lae1->onUnbindLFSVOutside(ig,lfsv_s,lfsv_n); 277 } 278 279 template<typename IG, 280 typename LFSU_S, typename LFSV_S, 281 typename LFSU_N, typename LFSV_N, 282 typename LFSU_C, typename LFSV_C> onUnbindLFSUVCoupling(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s,const LFSU_N & lfsu_n,const LFSV_N & lfsv_n,const LFSU_C & lfsu_c,const LFSV_C & lfsv_c)283 void onUnbindLFSUVCoupling(const IG & ig, 284 const LFSU_S & lfsu_s, const LFSV_S & lfsv_s, 285 const LFSU_N & lfsu_n, const LFSV_N & lfsv_n, 286 const LFSU_C & lfsu_c, const LFSV_C & lfsv_c) 287 { 288 lae0->onUnbindLFSUVCoupling(ig, 289 lfsu_s,lfsv_s, 290 lfsu_n,lfsv_n, 291 lfsu_c,lfsv_c); 292 lae1->onUnbindLFSUVCoupling(ig, 293 lfsu_s,lfsv_s, 294 lfsu_n,lfsv_n, 295 lfsu_c,lfsv_c); 296 } 297 298 template<typename IG, 299 typename LFSV_S, 300 typename LFSV_N, 301 typename LFSV_C> onUnbindLFSVCoupling(const IG & ig,const LFSV_S & lfsv_s,const LFSV_N & lfsv_n,const LFSV_C & lfsv_c)302 void onUnbindLFSVCoupling(const IG & ig, 303 const LFSV_S & lfsv_s, 304 const LFSV_N & lfsv_n, 305 const LFSV_C & lfsv_c) 306 { 307 lae0->onUnbindLFSVCoupling(ig,lfsv_s,lfsv_n,lfsv_c); 308 lae1->onUnbindLFSVCoupling(ig,lfsv_s,lfsv_n,lfsv_c); 309 } 310 311 //! @} 312 313 //! Methods for loading of the local function's 314 //! coefficients. 315 //!@{ 316 template<typename LFSU> loadCoefficientsLFSUInside(const LFSU & lfsu_s)317 void loadCoefficientsLFSUInside(const LFSU & lfsu_s) 318 { 319 lae0->loadCoefficientsLFSUInside(lfsu_s); 320 lae1->loadCoefficientsLFSUInside(lfsu_s); 321 } 322 template<typename LFSU> loadCoefficientsLFSUOutside(const LFSU & lfsu_n)323 void loadCoefficientsLFSUOutside(const LFSU & lfsu_n) 324 { 325 lae0->loadCoefficientsLFSUOutside(lfsu_n); 326 lae1->loadCoefficientsLFSUOutside(lfsu_n); 327 } 328 template<typename LFSU> loadCoefficientsLFSUCoupling(const LFSU & lfsu_c)329 void loadCoefficientsLFSUCoupling(const LFSU & lfsu_c) 330 { 331 lae0->loadCoefficientsLFSUCoupling(lfsu_c); 332 lae1->loadCoefficientsLFSUCoupling(lfsu_c); 333 } 334 //! @} 335 336 //! @name Assembling methods 337 //! @{ 338 339 template<typename EG> skipEntity(const EG & eg)340 bool skipEntity(const EG & eg) 341 { 342 bool rv = lae0->skipEntity(eg); 343 if (rv != lae1->skipEntity(eg)) 344 DUNE_THROW(NotImplemented, 345 "Spatial and temporal local operators are not allowed " 346 "to have different custom cell assembly rules"); 347 return rv; 348 } 349 350 template<typename IG> skipIntersection(const IG & ig)351 bool skipIntersection(const IG & ig) 352 { 353 bool rv = lae0->skipIntersection(ig); 354 if (rv != lae1->skipIntersection(ig)) 355 DUNE_THROW(NotImplemented, 356 "Spatial and temporal local operators are not allowed " 357 "to have different custom intersection assembly rules"); 358 return rv; 359 } 360 361 template<typename EG, typename LFSU, typename LFSV> assembleUVVolume(const EG & eg,const LFSU & lfsu,const LFSV & lfsv)362 void assembleUVVolume(const EG & eg, const LFSU & lfsu, const LFSV & lfsv) 363 { 364 if(implicit) 365 lae0->assembleUVVolume(eg,lfsu,lfsv); 366 lae1->assembleUVVolume(eg,lfsu,lfsv); 367 } 368 369 template<typename EG, typename LFSV> assembleVVolume(const EG & eg,const LFSV & lfsv)370 void assembleVVolume(const EG & eg, const LFSV & lfsv) 371 { 372 if(implicit) 373 lae0->assembleVVolume(eg,lfsv); 374 lae1->assembleVVolume(eg,lfsv); 375 } 376 377 template<typename IG, typename LFSU_S, typename LFSV_S, typename LFSU_N, typename LFSV_N> assembleUVSkeleton(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s,const LFSU_N & lfsu_n,const LFSV_N & lfsv_n)378 void assembleUVSkeleton(const IG & ig, const LFSU_S & lfsu_s, const LFSV_S & lfsv_s, 379 const LFSU_N & lfsu_n, const LFSV_N & lfsv_n) 380 { 381 if(implicit) 382 lae0->assembleUVSkeleton(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n); 383 lae1->assembleUVSkeleton(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n); 384 } 385 386 template<typename IG, typename LFSV_S, typename LFSV_N> assembleVSkeleton(const IG & ig,const LFSV_S & lfsv_s,const LFSV_N & lfsv_n)387 void assembleVSkeleton(const IG & ig, const LFSV_S & lfsv_s, const LFSV_N & lfsv_n) 388 { 389 if(implicit) 390 lae0->assembleVSkeleton(ig,lfsv_s,lfsv_n); 391 lae1->assembleVSkeleton(ig,lfsv_s,lfsv_n); 392 } 393 394 template<typename IG, typename LFSU_S, typename LFSV_S> assembleUVBoundary(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s)395 void assembleUVBoundary(const IG & ig, const LFSU_S & lfsu_s, const LFSV_S & lfsv_s) 396 { 397 if(implicit) 398 lae0->assembleUVBoundary(ig,lfsu_s,lfsv_s); 399 lae1->assembleUVBoundary(ig,lfsu_s,lfsv_s); 400 } 401 402 template<typename IG, typename LFSV_S> assembleVBoundary(const IG & ig,const LFSV_S & lfsv_s)403 void assembleVBoundary(const IG & ig, const LFSV_S & lfsv_s) 404 { 405 if(implicit) 406 lae0->assembleVBoundary(ig,lfsv_s); 407 lae1->assembleVBoundary(ig,lfsv_s); 408 } 409 410 template<typename IG, typename LFSU_S, typename LFSV_S> assembleUVProcessor(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s)411 void assembleUVProcessor(const IG & ig, const LFSU_S & lfsu_s, const LFSV_S & lfsv_s) 412 { 413 if(implicit) 414 lae0->assembleUVProcessor(ig,lfsu_s,lfsv_s); 415 lae1->assembleUVProcessor(ig,lfsu_s,lfsv_s); 416 } 417 418 template<typename IG, typename LFSV_S> assembleVProcessor(const IG & ig,const LFSV_S & lfsv_s)419 void assembleVProcessor(const IG & ig, const LFSV_S & lfsv_s) 420 { 421 if(implicit) 422 lae0->assembleVProcessor(ig,lfsv_s); 423 lae1->assembleVProcessor(ig,lfsv_s); 424 } 425 426 template<typename IG, typename LFSU_S, typename LFSV_S, typename LFSU_N, typename LFSV_N, 427 typename LFSU_C, typename LFSV_C> assembleUVEnrichedCoupling(const IG & ig,const LFSU_S & lfsu_s,const LFSV_S & lfsv_s,const LFSU_N & lfsu_n,const LFSV_N & lfsv_n,const LFSU_C & lfsu_c,const LFSV_C & lfsv_c)428 void assembleUVEnrichedCoupling(const IG & ig, 429 const LFSU_S & lfsu_s, const LFSV_S & lfsv_s, 430 const LFSU_N & lfsu_n, const LFSV_N & lfsv_n, 431 const LFSU_C & lfsu_c, const LFSV_C & lfsv_c) 432 { 433 if(implicit) 434 lae0->assembleUVEnrichedCoupling(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n,lfsu_c,lfsv_c); 435 lae1->assembleUVEnrichedCoupling(ig,lfsu_s,lfsv_s,lfsu_n,lfsv_n,lfsu_c,lfsv_c); 436 } 437 438 template<typename IG, typename LFSV_S, typename LFSV_N, typename LFSV_C> assembleVEnrichedCoupling(const IG & ig,const LFSV_S & lfsv_s,const LFSV_N & lfsv_n,const LFSV_C & lfsv_c)439 void assembleVEnrichedCoupling(const IG & ig, 440 const LFSV_S & lfsv_s, 441 const LFSV_N & lfsv_n, 442 const LFSV_C & lfsv_c) 443 { 444 if(implicit) 445 lae0->assembleVEnrichedCoupling(ig,lfsv_s,lfsv_n,lfsv_c); 446 } 447 448 template<typename EG, typename LFSU, typename LFSV> assembleUVVolumePostSkeleton(const EG & eg,const LFSU & lfsu,const LFSV & lfsv)449 void assembleUVVolumePostSkeleton(const EG & eg, const LFSU & lfsu, const LFSV & lfsv) 450 { 451 if(implicit) 452 lae0->assembleUVVolumePostSkeleton(eg,lfsu,lfsv); 453 } 454 455 template<typename EG, typename LFSV> assembleVVolumePostSkeleton(const EG & eg,const LFSV & lfsv)456 void assembleVVolumePostSkeleton(const EG & eg, const LFSV & lfsv) 457 { 458 if(implicit) 459 lae0->assembleVVolumePostSkeleton(eg,lfsv); 460 } 461 //! @} 462 463 private: 464 465 LocalAssemblerEngineDT0 * const invalid_lae0; 466 LocalAssemblerEngineDT1 * const invalid_lae1; 467 468 protected: 469 470 //! Reference to the wrapping local assembler object which 471 //! constructed this engine 472 const LocalAssembler & la; 473 474 LocalAssemblerEngineDT0 * lae0; 475 LocalAssemblerEngineDT1 * lae1; 476 477 bool implicit; 478 479 }; // End of class OneStepLocalAssemblerEngineBase 480 481 } 482 } 483 484 #endif // DUNE_PDELAB_GRIDOPERATOR_ONESTEP_ENGINEBASE_HH 485