@@ -1395,6 +1395,7 @@ ex_value(number vValue[],
13951395// number of shape functions
13961396 static const size_t numSH = ref_elem_type::numCorners;
13971397
1398+
13981399// FV1 SCVF ip
13991400 if (vLocIP == geo.scvf_local_ips ())
14001401 {
@@ -1411,22 +1412,41 @@ ex_value(number vValue[],
14111412
14121413 // compute derivative w.r.t. to unknowns iff needed
14131414 if (bDeriv)
1415+ {
14141416 for (size_t sh = 0 ; sh < scvf.num_sh (); ++sh)
14151417 vvvDeriv[ip][_C_][sh] = scvf.shape (sh);
1418+
1419+ // do not forget that number of DoFs (== vvvDeriv[ip][_C_])
1420+ // might be > scvf.num_sh() in case of hanging nodes!
1421+ size_t ndof = vvvDeriv[ip][_C_].size ();
1422+ for (size_t sh = scvf.num_sh (); sh < ndof; ++sh)
1423+ vvvDeriv[ip][_C_][sh] = 0.0 ;
1424+ }
14161425 }
14171426 }
14181427// FV1 SCV ip
14191428 else if (vLocIP == geo.scv_local_ips ())
14201429 {
1421- // solution at ip
1422- for (size_t sh = 0 ; sh < numSH; ++sh)
1423- vValue[sh] = u (_C_, sh);
1430+ // Loop Sub Control Volumes (SCV)
1431+ for (size_t ip = 0 ; ip < geo.num_scv (); ++ip)
1432+ {
1433+ // Get current SCV
1434+ const typename TFVGeom::SCV& scv = geo.scv (ip);
14241435
1425- // set derivatives if needed
1426- if (bDeriv)
1427- for (size_t sh = 0 ; sh < numSH; ++sh)
1428- for (size_t sh2 = 0 ; sh2 < numSH; ++sh2)
1429- vvvDeriv[sh][_C_][sh2] = (sh==sh2) ? 1.0 : 0.0 ;
1436+ // get corner of SCV
1437+ const size_t co = scv.node_id ();
1438+
1439+ // solution at ip
1440+ vValue[ip] = u (_C_, co);
1441+
1442+ // set derivatives if needed
1443+ if (bDeriv)
1444+ {
1445+ size_t ndof = vvvDeriv[ip][_C_].size ();
1446+ for (size_t sh = 0 ; sh < ndof; ++sh)
1447+ vvvDeriv[ip][_C_][sh] = (sh==co) ? 1.0 : 0.0 ;
1448+ }
1449+ }
14301450 }
14311451// general case
14321452 else
@@ -1451,8 +1471,15 @@ ex_value(number vValue[],
14511471 // compute derivative w.r.t. to unknowns iff needed
14521472 // \todo: maybe store shapes directly in vvvDeriv
14531473 if (bDeriv)
1474+ {
14541475 for (size_t sh = 0 ; sh < numSH; ++sh)
14551476 vvvDeriv[ip][_C_][sh] = vShape[sh];
1477+
1478+ // beware of hanging nodes!
1479+ size_t ndof = vvvDeriv[ip][_C_].size ();
1480+ for (size_t sh = numSH; sh < ndof; ++sh)
1481+ vvvDeriv[ip][_C_][sh] = 0.0 ;
1482+ }
14561483 }
14571484 }
14581485}
@@ -1485,16 +1512,6 @@ ex_grad(MathVector<dim> vValue[],
14851512// number of shape functions
14861513 static const size_t numSH = ref_elem_type::numCorners;
14871514
1488- // reset the values for the derivatives
1489- // this is necessary as vvvDeriv comes uninitialized
1490- // and in the case of hanging nodes, vvvDeriv[ip][c].size() may be
1491- // larger than geo.scvf(ip).num_sh(), thus some uninit'ed values
1492- // are never changed (resulting in solver breakdowns, NaNs etc.)
1493- if (bDeriv)
1494- for (size_t ip = 0 ; ip < nip; ++ip)
1495- for (size_t c = 0 ; c < vvvDeriv[ip].size (); ++c)
1496- for (size_t sh = 0 ; sh < vvvDeriv[ip][c].size (); ++sh)
1497- vvvDeriv[ip][c][sh] = 0.0 ;
14981515
14991516// FV1 SCVF ip
15001517 if (vLocIP == geo.scvf_local_ips ())
@@ -1514,6 +1531,11 @@ ex_grad(MathVector<dim> vValue[],
15141531 {
15151532 for (size_t sh = 0 ; sh < scvf.num_sh (); ++sh)
15161533 vvvDeriv[ip][_C_][sh] = scvf.global_grad (sh);
1534+
1535+ // beware of hanging nodes!
1536+ size_t ndof = vvvDeriv[ip][_C_].size ();
1537+ for (size_t sh = scvf.num_sh (); sh < ndof; ++sh)
1538+ vvvDeriv[ip][_C_][sh] = 0.0 ;
15171539 }
15181540 }
15191541 }
@@ -1548,8 +1570,15 @@ ex_grad(MathVector<dim> vValue[],
15481570
15491571 // compute derivative w.r.t. to unknowns iff needed
15501572 if (bDeriv)
1573+ {
15511574 for (size_t sh = 0 ; sh < numSH; ++sh)
15521575 MatVecMult (vvvDeriv[ip][_C_][sh], JTInv, vLocGrad[sh]);
1576+
1577+ // beware of hanging nodes!
1578+ size_t ndof = vvvDeriv[ip][_C_].size ();
1579+ for (size_t sh = numSH; sh < ndof; ++sh)
1580+ vvvDeriv[ip][_C_][sh] = 0.0 ;
1581+ }
15531582 }
15541583 }
15551584};
0 commit comments