Commit c4782571 authored by Andreas Wagner's avatar Andreas Wagner
Browse files

adds bilinear-form for a penalty term with arguments L2 projected on the constants

parent 5bfaa2db
Pipeline #25688 failed with stages
in 2 seconds
...@@ -259,51 +259,105 @@ inline void jump( const std::array< Point3D, 6 >& points, ...@@ -259,51 +259,105 @@ inline void jump( const std::array< Point3D, 6 >& points,
const uint_t difference = ( levelUp > levelDown ) ? ( levelUp - levelDown ) : ( levelDown - levelUp ); const uint_t difference = ( levelUp > levelDown ) ? ( levelUp - levelDown ) : ( levelDown - levelUp );
const auto numSubEdges = real_t( 1u << difference ); const auto numSubEdges = real_t( 1u << difference );
real_t leftPtUp, rightPtUp, leftPtDown, rightPtDown, edgeLength; real_t leftPtUp, rightPtUp, leftPtDown, rightPtDown, alphaTimesEdgeLength;
if ( levelUp > levelDown ) if ( levelUp > levelDown )
{ {
leftPtUp = 0.; // Situation:
rightPtUp = 1.; // Up-triangle
leftPtDown = real_t( offset ) / numSubEdges; // 0 1
rightPtDown = real_t( offset + 1 ) / numSubEdges; // +---+
edgeLength = alpha * ( points[0] - points[1] ).norm(); // +---o---o---o---+
// 0 1/4 2/4 3/4 1
// Down-triangle
leftPtUp = 0.;
rightPtUp = 1.;
leftPtDown = real_t( offset ) / numSubEdges;
rightPtDown = real_t( offset + 1 ) / numSubEdges;
alphaTimesEdgeLength = alpha * ( points[0] - points[1] ).norm();
} }
else else
{ {
leftPtUp = real_t( offset ) / numSubEdges; // Reverse situation:
rightPtUp = real_t( offset + 1 ) / numSubEdges; // Up-triangle
leftPtDown = 0.; // 0 1/4 2/4 3/4 1
rightPtDown = 1.; // +---o---o---o---+
edgeLength = alpha * ( points[3] - points[4] ).norm(); // +---+
// 0 1
// Down-triangle
leftPtUp = real_t( offset ) / numSubEdges;
rightPtUp = real_t( offset + 1 ) / numSubEdges;
leftPtDown = 0.;
rightPtDown = 1.;
alphaTimesEdgeLength = alpha * ( points[3] - points[4] ).norm();
} }
const real_t middlePtUp = 0.5 * ( leftPtUp + rightPtUp ); const real_t middlePtUp = 0.5 * ( leftPtUp + rightPtUp );
const real_t middlePtDown = 0.5 * ( leftPtDown + rightPtDown ); const real_t middlePtDown = 0.5 * ( leftPtDown + rightPtDown );
// Simpson's rule // Applying Simpson's rule to integrate the hat functions:
tensor[index2x4( 0, 0 )] += +edgeLength / 6 * // (the comments below are just here to retain useful formatting.
( ( 1 - leftPtUp ) * ( 1 - leftPtUp ) + 4. * ( 1 - middlePtUp ) * ( 1 - middlePtUp ) + tensor[index2x4( 0, 0 )] += +alphaTimesEdgeLength / 6 *
( 1 - rightPtUp ) * ( 1 - rightPtUp ) ); ( +( 1 - leftPtUp ) * ( 1 - leftPtUp ) //
tensor[index2x4( 0, 1 )] += + 4. * ( 1 - middlePtUp ) * ( 1 - middlePtUp ) //
+edgeLength / 6 * + ( 1 - rightPtUp ) * ( 1 - rightPtUp ) );
( ( 1 - leftPtUp ) * ( leftPtUp ) + 4. * ( 1 - middlePtUp ) * ( middlePtUp ) + ( 1 - rightPtUp ) * ( rightPtUp ) ); tensor[index2x4( 0, 1 )] += +alphaTimesEdgeLength / 6 *
tensor[index2x4( 0, 2 )] += -edgeLength / 6 * ( +( 1 - leftPtUp ) * ( leftPtUp ) //
( ( 1 - leftPtUp ) * ( 1 - leftPtDown ) + 4. * ( 1 - middlePtUp ) * ( 1 - middlePtDown ) + + 4. * ( 1 - middlePtUp ) * ( middlePtUp ) //
( 1 - rightPtUp ) * ( 1 - rightPtDown ) ); + ( 1 - rightPtUp ) * ( rightPtUp ) );
tensor[index2x4( 0, 3 )] += tensor[index2x4( 0, 2 )] += -alphaTimesEdgeLength / 6 *
-edgeLength / 6 * ( +( 1 - leftPtUp ) * ( 1 - leftPtDown ) //
( ( 1 - leftPtUp ) * ( leftPtDown ) + 4. * ( 1 - middlePtUp ) * ( middlePtDown ) + ( 1 - rightPtUp ) * ( rightPtDown ) ); + 4. * ( 1 - middlePtUp ) * ( 1 - middlePtDown ) //
tensor[index2x4( 1, 0 )] += + ( 1 - rightPtUp ) * ( 1 - rightPtDown ) );
+edgeLength / 6 * tensor[index2x4( 0, 3 )] += -alphaTimesEdgeLength / 6 *
( ( leftPtUp ) * ( 1 - leftPtUp ) + 4. * ( middlePtUp ) * ( 1 - middlePtUp ) + ( rightPtUp ) * ( 1 - rightPtUp ) ); ( +( 1 - leftPtUp ) * ( leftPtDown ) //
tensor[index2x4( 1, 1 )] += + 4. * ( 1 - middlePtUp ) * ( middlePtDown ) //
+edgeLength / 6 * ( ( leftPtUp ) * ( leftPtUp ) + 4. * ( middlePtUp ) * ( middlePtUp ) + ( rightPtUp ) * ( rightPtUp ) ); + ( 1 - rightPtUp ) * ( rightPtDown ) );
tensor[index2x4( 1, 2 )] += tensor[index2x4( 1, 0 )] += +alphaTimesEdgeLength / 6 *
-edgeLength / 6 * ( +( leftPtUp ) * ( 1 - leftPtUp ) //
( ( leftPtUp ) * ( 1 - leftPtDown ) + 4. * ( middlePtUp ) * ( 1 - middlePtDown ) + ( rightPtUp ) * ( 1 - rightPtDown ) ); + 4. * ( middlePtUp ) * ( 1 - middlePtUp ) //
tensor[index2x4( 1, 3 )] += + ( rightPtUp ) * ( 1 - rightPtUp ) );
-edgeLength / 6 * tensor[index2x4( 1, 1 )] += +alphaTimesEdgeLength / 6 *
( ( leftPtUp ) * ( leftPtDown ) + 4. * ( middlePtUp ) * ( middlePtDown ) + ( rightPtUp ) * ( rightPtDown ) ); ( ( leftPtUp ) * ( leftPtUp ) //
+ 4. * ( middlePtUp ) * ( middlePtUp ) //
+ ( rightPtUp ) * ( rightPtUp ) );
tensor[index2x4( 1, 2 )] += -alphaTimesEdgeLength / 6 *
( +( leftPtUp ) * ( 1 - leftPtDown ) //
+ 4. * ( middlePtUp ) * ( 1 - middlePtDown ) //
+ ( rightPtUp ) * ( 1 - rightPtDown ) );
tensor[index2x4( 1, 3 )] += -alphaTimesEdgeLength / 6 *
( +( leftPtUp ) * ( leftPtDown ) //
+ 4. * ( middlePtUp ) * ( middlePtDown ) //
+ ( rightPtUp ) * ( rightPtDown ) );
}
/// This function assembles the terms
/// alpha * inner(jump(P(u)), jump(P(v)))*dS
/// over the interior boundary, were alpha is some coefficient and
/// P the L2-projection on the space of constant functions on the edges.
/// It assumes a vertex ordering of the form
/// 0 1
/// +-------------+
/// 3 4
/// where the indices above (0 and 1) are the local indices of the upper cell,
/// and the indices below (3 and 4) are the local indices of the lower cell.
inline void jumpProjected( const std::array< Point3D, 6 >& points,
const uint_t& levelUp,
const uint_t& levelDown,
const uint_t,
const real_t& alpha,
EdgeTensor& tensor )
{
// we integrate over the smaller edge which belongs to a face with a higher refinement level.
auto const edgeLength = levelUp > levelDown ? ( points[0] - points[1] ).norm() : ( points[3] - points[4] ).norm();
auto const alphaTimesEdgeLength = alpha * edgeLength;
tensor[index2x4( 0, 0 )] += +alphaTimesEdgeLength / 4 * ( +1 );
tensor[index2x4( 0, 1 )] += +alphaTimesEdgeLength / 4 * ( +1 );
tensor[index2x4( 0, 2 )] += +alphaTimesEdgeLength / 4 * ( -1 );
tensor[index2x4( 0, 3 )] += +alphaTimesEdgeLength / 4 * ( -1 );
tensor[index2x4( 1, 0 )] += +alphaTimesEdgeLength / 4 * ( +1 );
tensor[index2x4( 1, 1 )] += +alphaTimesEdgeLength / 4 * ( +1 );
tensor[index2x4( 1, 2 )] += +alphaTimesEdgeLength / 4 * ( -1 );
tensor[index2x4( 1, 3 )] += +alphaTimesEdgeLength / 4 * ( -1 );
} }
/// Creates the matrix for the affine transformation to our counter-clockwise reference triangle. /// Creates the matrix for the affine transformation to our counter-clockwise reference triangle.
...@@ -735,6 +789,7 @@ class VariableMacroEdgeForm ...@@ -735,6 +789,7 @@ class VariableMacroEdgeForm
const real_t delta = Transpose ? eps_ : delta_; const real_t delta = Transpose ? eps_ : delta_;
const real_t eps = Transpose ? delta_ : eps_; const real_t eps = Transpose ? delta_ : eps_;
jump( points, levelUp, levelDown, offset, sigma_ * hInv, tensor ); jump( points, levelUp, levelDown, offset, sigma_ * hInv, tensor );
// jumpProjected( points, levelUp, levelDown, offset, sigma_ * hInv, tensor );
jumpAvg< UpperFaceOrientatedCW >( points, levelUp, levelDown, offset, eps, delta, kappa_, tensor ); jumpAvg< UpperFaceOrientatedCW >( points, levelUp, levelDown, offset, eps, delta, kappa_, tensor );
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment