@@ -1588,6 +1588,20 @@ void CFEASolver::BC_Clamped_Post(CGeometry *geometry, const CConfig *config, uns
15881588
15891589}
15901590
1591+ namespace {
1592+ /* --- Helper for BC_Sym_Plane ---*/
1593+ template <typename Read, typename Write>
1594+ void SubtractProjection (unsigned short nDim, const su2double* n, const Read& read, const Write& write) {
1595+ su2double tmp[3 ] = {};
1596+ for (auto iDim = 0u ; iDim < nDim; ++iDim) tmp[iDim] = read (iDim);
1597+ const su2double proj = DotProduct (nDim, tmp, n);
1598+ for (auto iDim = 0u ; iDim < nDim; ++iDim) {
1599+ tmp[iDim] -= proj * n[iDim];
1600+ write (iDim, tmp[iDim]);
1601+ }
1602+ }
1603+ }
1604+
15911605void CFEASolver::BC_Sym_Plane (CGeometry *geometry, const CConfig *config, unsigned short val_marker) {
15921606
15931607 if (geometry->GetnElem_Bound (val_marker) == 0 ) return ;
@@ -1610,14 +1624,8 @@ void CFEASolver::BC_Sym_Plane(CGeometry *geometry, const CConfig *config, unsign
16101624 case 3 : TriangleNormal (nodeCoord, normal); break ;
16111625 case 4 : QuadrilateralNormal (nodeCoord, normal); break ;
16121626 }
1613-
1614- auto axis = 0u ;
1615- for (auto iDim = 1u ; iDim < MAXNDIM; ++iDim)
1616- axis = (fabs (normal[iDim]) > fabs (normal[axis]))? iDim : axis;
1617-
1618- if (fabs (normal[axis]) < 0.99 *Norm (int (MAXNDIM),normal)) {
1619- SU2_MPI::Error (" The structural solver only supports axis-aligned symmetry planes." ,CURRENT_FUNCTION);
1620- }
1627+ const su2double area = Norm (int (MAXNDIM), normal);
1628+ for (auto iDim = 0u ; iDim < MAXNDIM; ++iDim) normal[iDim] /= area;
16211629
16221630 /* --- Impose zero displacement perpendicular to the symmetry plane. ---*/
16231631
@@ -1627,20 +1635,29 @@ void CFEASolver::BC_Sym_Plane(CGeometry *geometry, const CConfig *config, unsign
16271635 const auto iPoint = geometry->vertex [val_marker][iVertex]->GetNode ();
16281636
16291637 /* --- Set and enforce solution at current and previous time-step ---*/
1630- nodes->SetSolution (iPoint, axis, 0.0 );
1638+ #define SUBTRACT_PROJECTION (READ, WRITE ) \
1639+ SubtractProjection (nDim, normal, [&](unsigned short iDim) { return nodes->READ (iPoint, iDim); }, \
1640+ [&](unsigned short iDim, const su2double& x) { nodes->WRITE (iPoint, iDim, x); });
1641+ SUBTRACT_PROJECTION (GetSolution, SetSolution)
16311642 if (dynamic) {
1632- nodes-> SetSolution_Vel (iPoint, axis, 0.0 );
1633- nodes-> SetSolution_Accel (iPoint, axis, 0.0 );
1634- nodes-> Set_Solution_time_n (iPoint, axis, 0.0 );
1635- nodes-> SetSolution_Vel_time_n (iPoint, axis, 0.0 );
1636- nodes-> SetSolution_Accel_time_n (iPoint, axis, 0.0 );
1643+ SUBTRACT_PROJECTION (GetSolution_Vel, SetSolution_Vel)
1644+ SUBTRACT_PROJECTION (GetSolution_Accel, SetSolution_Accel)
1645+ SUBTRACT_PROJECTION (GetSolution_time_n, Set_Solution_time_n)
1646+ SUBTRACT_PROJECTION (GetSolution_Vel_time_n, SetSolution_Vel_time_n)
1647+ SUBTRACT_PROJECTION (GetSolution_Accel_time_n, SetSolution_Accel_time_n)
16371648 }
16381649
16391650 /* --- Set and enforce 0 solution for mesh deformation ---*/
1640- nodes->SetBound_Disp (iPoint, axis, 0.0 );
1641- LinSysSol (iPoint, axis) = 0.0 ;
1642- if (LinSysReact.GetLocSize () > 0 ) LinSysReact (iPoint, axis) = 0.0 ;
1643- Jacobian.EnforceSolutionAtDOF (iPoint, axis, su2double (0.0 ), LinSysRes);
1651+ SUBTRACT_PROJECTION (GetBound_Disp, SetBound_Disp)
1652+ #undef SUBTRACT_PROJECTION
1653+
1654+ SubtractProjection (nDim, normal, [&](unsigned short iDim) { return LinSysSol (iPoint, iDim); },
1655+ [&](unsigned short iDim, const su2double& x) { LinSysSol (iPoint, iDim) = x; });
1656+ if (LinSysReact.GetLocSize () > 0 ) {
1657+ SubtractProjection (nDim, normal, [&](unsigned short iDim) { return LinSysReact (iPoint, iDim); },
1658+ [&](unsigned short iDim, const su2double& x) { LinSysReact (iPoint, iDim) = x; });
1659+ }
1660+ Jacobian.EnforceZeroProjection (iPoint, normal, LinSysRes);
16441661
16451662 }
16461663
0 commit comments