Skip to content

Commit 2cda5ec

Browse files
committed
generalize body force for FEA solver and add centrifugal loads
1 parent 2fb25a5 commit 2cda5ec

File tree

13 files changed

+73
-61
lines changed

13 files changed

+73
-61
lines changed

Common/include/CConfig.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ class CConfig {
10041004
bool ExtraOutput; /*!< \brief Check if extra output need. */
10051005
bool Wall_Functions; /*!< \brief Use wall functions with the turbulence model */
10061006
long ExtraHeatOutputZone; /*!< \brief Heat solver zone with extra screen output */
1007-
bool DeadLoad; /*!< \brief Application of dead loads to the FE analysis */
1007+
bool CentrifugalForce; /*!< \brief Application of centrifugal forces to the FE analysis */
10081008
bool PseudoStatic; /*!< \brief Application of dead loads to the FE analysis */
10091009
bool SteadyRestart; /*!< \brief Restart from a steady state for FSI problems. */
10101010
su2double Newmark_beta, /*!< \brief Parameter alpha for Newmark method. */
@@ -8942,10 +8942,9 @@ class CConfig {
89428942
su2double GetAitkenDynMinInit(void) const { return AitkenDynMinInit; }
89438943

89448944
/*!
8945-
* \brief Decide whether to apply dead loads to the model.
8946-
* \return <code>TRUE</code> if the dead loads are to be applied, <code>FALSE</code> otherwise.
8945+
* \brief Decide whether to apply centrifugal forces to the model.
89478946
*/
8948-
bool GetDeadLoad(void) const { return DeadLoad; }
8947+
bool GetCentrifugalForce(void) const { return CentrifugalForce; }
89498948

89508949
/*!
89518950
* \brief Identifies if the mesh is matching or not (temporary, while implementing interpolation procedures).

Common/src/CConfig.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,11 +2507,11 @@ void CConfig::SetConfig_Options() {
25072507
addEnumOption("NONLINEAR_FEM_SOLUTION_METHOD", Kind_SpaceIteScheme_FEA, Space_Ite_Map_FEA, STRUCT_SPACE_ITE::NEWTON);
25082508
/* DESCRIPTION: Formulation for bidimensional elasticity solver */
25092509
addEnumOption("FORMULATION_ELASTICITY_2D", Kind_2DElasForm, ElasForm_2D, STRUCT_2DFORM::PLANE_STRAIN);
2510-
/* DESCRIPTION: Apply dead loads
2511-
* Options: NO, YES \ingroup Config */
2512-
addBoolOption("DEAD_LOAD", DeadLoad, false);
2510+
/* DESCRIPTION: Apply centrifugal forces
2511+
* Options: NO, YES \ingroup Config */
2512+
addBoolOption("CENTRIFUGAL_FORCE", CentrifugalForce, false);
25132513
/* DESCRIPTION: Temporary: pseudo static analysis (no density in dynamic analysis)
2514-
* Options: NO, YES \ingroup Config */
2514+
* Options: NO, YES \ingroup Config */
25152515
addBoolOption("PSEUDO_STATIC", PseudoStatic, false);
25162516
/* DESCRIPTION: Parameter alpha for Newmark scheme (s) */
25172517
addDoubleOption("NEWMARK_BETA", Newmark_beta, 0.25);
@@ -3070,6 +3070,8 @@ void CConfig::SetConfig_Parsing(istream& config_buffer){
30703070
newString.append("DYNAMIC_ANALYSIS is deprecated. Use TIME_DOMAIN instead.\n\n");
30713071
else if (!option_name.compare("SPECIES_USE_STRONG_BC"))
30723072
newString.append("SPECIES_USE_STRONG_BC is deprecated. Use MARKER_SPECIES_STRONG_BC= (marker1, ...) instead.\n\n");
3073+
else if (!option_name.compare("DEAD_LOAD"))
3074+
newString.append("DEAD_LOAD is deprecated. Use GRAVITY_FORCE or BODY_FORCE instead.\n\n");
30733075
else {
30743076
/*--- Find the most likely candidate for the unrecognized option, based on the length
30753077
of start and end character sequences shared by candidates and the option. ---*/

SU2_CFD/include/numerics/CNumerics.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,10 +1483,10 @@ class CNumerics {
14831483
inline virtual void Compute_Mass_Matrix(CElement *element_container, const CConfig* config) { }
14841484

14851485
/*!
1486-
* \brief A virtual member to compute the residual component due to dead loads
1486+
* \brief A virtual member to compute the residual component due to body forces.
14871487
* \param[in] element_container - Element structure for the particular element integrated.
14881488
*/
1489-
inline virtual void Compute_Dead_Load(CElement *element_container, const CConfig* config) { }
1489+
inline virtual void Compute_Body_Forces(CElement *element_container, const CConfig* config) { }
14901490

14911491
/*!
14921492
* \brief A virtual member to compute the averaged nodal stresses

SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,11 @@ class CFEAElasticity : public CNumerics {
159159
void Compute_Mass_Matrix(CElement *element_container, const CConfig *config) final;
160160

161161
/*!
162-
* \brief Compute the nodal gravity loads for an element.
163-
* \param[in,out] element_container - The element for which the dead loads are computed.
162+
* \brief Compute the nodal inertial loads for an element.
163+
* \param[in,out] element_container - The element for which the inertial loads are computed.
164164
* \param[in] config - Definition of the problem.
165165
*/
166-
void Compute_Dead_Load(CElement *element_container, const CConfig *config) final;
166+
void Compute_Body_Forces(CElement *element_container, const CConfig *config) final;
167167

168168
/*!
169169
* \brief Build the tangent stiffness matrix of an element.

SU2_CFD/include/solvers/CFEASolver.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class CFEASolver : public CFEASolverBase {
9898
bool element_based; /*!< \brief Bool to determine if an element-based file is used. */
9999
bool topol_filter_applied; /*!< \brief True if density filtering has been performed. */
100100
bool initial_calc = true; /*!< \brief Becomes false after first call to Preprocessing. */
101+
bool body_forces = false; /*!< \brief Whether any body force is active. */
101102

102103
/*!
103104
* \brief The highest level in the variable hierarchy this solver can safely use,
@@ -335,14 +336,14 @@ class CFEASolver : public CFEASolverBase {
335336
const CConfig *config);
336337

337338
/*!
338-
* \brief Compute the dead loads.
339+
* \brief Compute the inertial loads.
339340
* \param[in] geometry - Geometrical definition of the problem.
340341
* \param[in] numerics - Description of the numerical method.
341342
* \param[in] config - Definition of the particular problem.
342343
*/
343-
void Compute_DeadLoad(CGeometry *geometry,
344-
CNumerics **numerics,
345-
const CConfig *config) final;
344+
void Compute_BodyForces(CGeometry *geometry,
345+
CNumerics **numerics,
346+
const CConfig *config) final;
346347

347348
/*!
348349
* \brief Clamped boundary conditions.

SU2_CFD/include/solvers/CSolver.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3645,9 +3645,9 @@ class CSolver {
36453645
* \param[in] numerics - Description of the numerical method.
36463646
* \param[in] config - Definition of the particular problem.
36473647
*/
3648-
inline virtual void Compute_DeadLoad(CGeometry *geometry,
3649-
CNumerics **numerics,
3650-
const CConfig *config) { }
3648+
inline virtual void Compute_BodyForces(CGeometry *geometry,
3649+
CNumerics **numerics,
3650+
const CConfig *config) { }
36513651

36523652
/*!
36533653
* \brief A virtual member. Set the volumetric heat source

SU2_CFD/src/numerics/elasticity/CFEAElasticity.cpp

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "../../../include/numerics/elasticity/CFEAElasticity.hpp"
2929
#include "../../../../Common/include/parallelization/omp_structure.hpp"
30+
#include "../../../../Common/include/toolboxes/geometry_toolbox.hpp"
3031

3132

3233
CFEAElasticity::CFEAElasticity(unsigned short val_nDim, unsigned short val_nVar,
@@ -226,7 +227,11 @@ void CFEAElasticity::Compute_Mass_Matrix(CElement *element, const CConfig *confi
226227
}
227228

228229

229-
void CFEAElasticity::Compute_Dead_Load(CElement *element, const CConfig *config) {
230+
void CFEAElasticity::Compute_Body_Forces(CElement *element, const CConfig *config) {
231+
232+
const bool gravity = config->GetGravityForce();
233+
const bool body_force = config->GetBody_Force();
234+
const bool centrifugal = config->GetCentrifugalForce();
230235

231236
/*--- Initialize values for the material model considered ---*/
232237
SetElement_Properties(element, config);
@@ -237,13 +242,24 @@ void CFEAElasticity::Compute_Dead_Load(CElement *element, const CConfig *config)
237242
AD::SetPreaccIn(Rho_s_DL);
238243
element->SetPreaccIn_Coords(false);
239244

240-
/* -- Gravity directionality:
241-
* -- For 2D problems, we assume the direction for gravity is -y
242-
* -- For 3D problems, we assume the direction for gravity is -z
243-
*/
244-
su2double g_force[3] = {0.0,0.0,0.0};
245-
g_force[nDim - 1] = -STANDARD_GRAVITY;
245+
std::array<su2double, 3> acceleration{};
246+
if (gravity) {
247+
/*--- For 2D problems, we assume gravity is in the -y direction,
248+
* and for 3D problems in the -z direction. ---*/
249+
acceleration[nDim - 1] = -STANDARD_GRAVITY;
250+
} else if (body_force) {
251+
for (auto iDim = 0u; iDim < nDim; iDim++) {
252+
acceleration[iDim] = config->GetBody_Force_Vector()[iDim];
253+
}
254+
}
246255

256+
std::array<su2double, 3> center{}, omega{};
257+
if (centrifugal) {
258+
for (auto iDim = 0u; iDim < nDim; iDim++) {
259+
center[iDim] = config->GetMotion_Origin(iDim);
260+
omega[iDim] = config->GetRotation_Rate(iDim);
261+
}
262+
}
247263
element->ClearElement(); /*--- Restart the element to avoid adding over previous results. --*/
248264
element->ComputeGrad_Linear(); /*--- Need to compute the gradients to obtain the Jacobian. ---*/
249265

@@ -256,15 +272,26 @@ void CFEAElasticity::Compute_Dead_Load(CElement *element, const CConfig *config)
256272
/*--- The dead load is computed in the reference configuration ---*/
257273
const auto Jac_X = element->GetJ_X(iGauss);
258274

259-
for (auto iNode = 0; iNode < nNode; iNode++) {
275+
for (auto iNode = 0u; iNode < nNode; iNode++) {
260276
const auto Ni = element->GetNi(iNode,iGauss);
261277

262-
su2double FAux_Dead_Load[3] = {0.0,0.0,0.0};
278+
auto total_accel = acceleration;
279+
if (centrifugal) {
280+
/*--- For nonlinear this should probably use the current (deformed)
281+
* coordinates, but it should not make a big difference. ---*/
282+
std::array<su2double, 3> r{}, wr{}, w2r{};
283+
for (auto iDim = 0u; iDim < nDim; iDim++) {
284+
r[iDim] = element->GetRef_Coord(iNode, iDim) - center[iDim];
285+
}
286+
GeometryToolbox::CrossProduct(omega.data(), r.data(), wr.data());
287+
GeometryToolbox::CrossProduct(omega.data(), wr.data(), w2r.data());
288+
for (auto iDim = 0; iDim < 3; ++iDim) total_accel[iDim] += w2r[iDim];
289+
}
290+
std::array<su2double, 3> force{};
263291
for (auto iDim = 0u; iDim < nDim; iDim++) {
264-
FAux_Dead_Load[iDim] = Weight * Ni * Jac_X * Rho_s_DL * g_force[iDim];
292+
force[iDim] = Weight * Ni * Jac_X * Rho_s_DL * total_accel[iDim];
265293
}
266-
element->Add_FDL_a(iNode, FAux_Dead_Load);
267-
294+
element->Add_FDL_a(iNode, force.data());
268295
}
269296

270297
}

SU2_CFD/src/output/CAdjElasticityOutput.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void CAdjElasticityOutput::SetHistoryOutputFields(CConfig *config){
113113
if (config->GetTime_Domain() && !config->GetPseudoStatic()) {
114114
AddHistoryOutput("SENS_RHO_" + iVarS, "Sens[Rho" + iVarS + ']', ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", "d Objective / d Material density");
115115
}
116-
if (config->GetDeadLoad()) {
116+
if (config->GetGravityForce() || config->GetBody_Force() || config->GetCentrifugalForce()) {
117117
AddHistoryOutput("SENS_RHO_DL_" + iVarS, "Sens[RhoDL" + iVarS + ']', ScreenOutputFormat::SCIENTIFIC, "SENSITIVITY", "d Objective / d Dead load density");
118118
}
119119
}
@@ -151,7 +151,7 @@ inline void CAdjElasticityOutput::LoadHistoryData(CConfig *config, CGeometry *ge
151151
if (config->GetTime_Domain() && !config->GetPseudoStatic()) {
152152
SetHistoryOutputValue("SENS_RHO_" + iVarS, solver[ADJFEA_SOL]->GetTotal_Sens_Rho(iVar));
153153
}
154-
if (config->GetDeadLoad()) {
154+
if (config->GetGravityForce() || config->GetBody_Force() || config->GetCentrifugalForce()) {
155155
SetHistoryOutputValue("SENS_RHO_DL_" + iVarS, solver[ADJFEA_SOL]->GetTotal_Sens_Rho_DL(iVar));
156156
}
157157
}

SU2_CFD/src/solvers/CFEASolver.cpp

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ CFEASolver::CFEASolver(LINEAR_SOLVER_MODE mesh_deform_mode) : CFEASolverBase(mes
4949

5050
CFEASolver::CFEASolver(CGeometry *geometry, CConfig *config) : CFEASolverBase(geometry, config) {
5151

52-
bool dynamic = (config->GetTime_Domain());
52+
bool dynamic = config->GetTime_Domain();
5353
config->SetDelta_UnstTimeND(config->GetDelta_UnstTime());
5454

5555
/*--- Test whether we consider dielectric elastomers ---*/
@@ -59,6 +59,7 @@ CFEASolver::CFEASolver(CGeometry *geometry, CConfig *config) : CFEASolverBase(ge
5959
element_based = false;
6060
topol_filter_applied = false;
6161
initial_calc = true;
62+
body_forces = config->GetGravityForce() || config->GetBody_Force() || config->GetCentrifugalForce();
6263

6364
/*--- Here is where we assign the kind of each element ---*/
6465

@@ -121,22 +122,15 @@ CFEASolver::CFEASolver(CGeometry *geometry, CConfig *config) : CFEASolverBase(ge
121122

122123
/*--- The length of the solution vector depends on whether the problem is static or dynamic ---*/
123124

124-
unsigned short nSolVar;
125125
string text_line, filename;
126126
ifstream restart_file;
127127

128-
if (dynamic) nSolVar = 3 * nVar;
129-
else nSolVar = nVar;
130-
131-
auto* SolInit = new su2double[nSolVar]();
132-
133128
/*--- Initialize from zero everywhere ---*/
134129

135-
nodes = new CFEABoundVariable(SolInit, nPoint, nDim, nVar, config);
130+
std::array<su2double, 3 * MAXNVAR> zeros{};
131+
nodes = new CFEABoundVariable(zeros.data(), nPoint, nDim, nVar, config);
136132
SetBaseClassPointerToNodes();
137133

138-
delete [] SolInit;
139-
140134
/*--- Set which points are vertices and allocate boundary data. ---*/
141135

142136
for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++)
@@ -567,7 +561,6 @@ void CFEASolver::Preprocessing(CGeometry *geometry, CSolver **solver_container,
567561

568562
const bool dynamic = config->GetTime_Domain();
569563
const bool disc_adj_fem = (config->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_FEM);
570-
const bool body_forces = config->GetDeadLoad();
571564
const bool topology_mode = config->GetTopology_Optimization();
572565

573566
/*
@@ -602,7 +595,7 @@ void CFEASolver::Preprocessing(CGeometry *geometry, CSolver **solver_container,
602595
* Only initialized once, at the first iteration of the first time step.
603596
*/
604597
if (body_forces && (initial_calc || disc_adj_fem))
605-
Compute_DeadLoad(geometry, numerics, config);
598+
Compute_BodyForces(geometry, numerics, config);
606599

607600
/*--- Clear the linear system solution. ---*/
608601
SU2_OMP_PARALLEL
@@ -1415,7 +1408,7 @@ void CFEASolver::Compute_NodalStress(CGeometry *geometry, CNumerics **numerics,
14151408

14161409
}
14171410

1418-
void CFEASolver::Compute_DeadLoad(CGeometry *geometry, CNumerics **numerics, const CConfig *config) {
1411+
void CFEASolver::Compute_BodyForces(CGeometry *geometry, CNumerics **numerics, const CConfig *config) {
14191412

14201413
/*--- Start OpenMP parallel region. ---*/
14211414

@@ -1465,7 +1458,7 @@ void CFEASolver::Compute_DeadLoad(CGeometry *geometry, CNumerics **numerics, con
14651458
/*--- Set the properties of the element and compute its mass matrix. ---*/
14661459
element->Set_ElProperties(element_properties[iElem]);
14671460

1468-
numerics[FEA_TERM + thread*MAX_TERMS]->Compute_Dead_Load(element, config);
1461+
numerics[FEA_TERM + thread*MAX_TERMS]->Compute_Body_Forces(element, config);
14691462

14701463
/*--- Add contributions of this element to the mass matrix. ---*/
14711464
for (iNode = 0; iNode < nNodes; iNode++) {
@@ -2113,7 +2106,6 @@ void CFEASolver::ImplicitNewmark_Iteration(const CGeometry *geometry, CNumerics
21132106
const bool linear_analysis = (config->GetGeometricConditions() == STRUCT_DEFORMATION::SMALL);
21142107
const bool nonlinear_analysis = (config->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE);
21152108
const bool newton_raphson = (config->GetKind_SpaceIteScheme_FEA() == STRUCT_SPACE_ITE::NEWTON);
2116-
const bool body_forces = config->GetDeadLoad();
21172109

21182110
/*--- For simplicity, no incremental loading is handled with increment of 1. ---*/
21192111
const su2double loadIncr = config->GetIncrementalLoad()? loadIncrement : su2double(1.0);
@@ -2301,7 +2293,6 @@ void CFEASolver::GeneralizedAlpha_Iteration(const CGeometry *geometry, CNumerics
23012293
const bool linear_analysis = (config->GetGeometricConditions() == STRUCT_DEFORMATION::SMALL);
23022294
const bool nonlinear_analysis = (config->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE);
23032295
const bool newton_raphson = (config->GetKind_SpaceIteScheme_FEA() == STRUCT_SPACE_ITE::NEWTON);
2304-
const bool body_forces = config->GetDeadLoad();
23052296

23062297
/*--- Blend between previous and current timestep. ---*/
23072298
const su2double alpha_f = config->Get_Int_Coeffs(2);
@@ -2925,9 +2916,6 @@ void CFEASolver::Compute_OFVolFrac(CGeometry *geometry, const CConfig *config)
29252916

29262917
void CFEASolver::Compute_OFCompliance(CGeometry *geometry, const CConfig *config)
29272918
{
2928-
/*--- Types of loads to consider ---*/
2929-
const bool body_forces = config->GetDeadLoad();
2930-
29312919
/*--- If the loads are being applied incrementaly ---*/
29322920
const bool incremental_load = config->GetIncrementalLoad();
29332921

SU2_CFD/src/variables/CFEAVariable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ CFEAVariable::CFEAVariable(const su2double *val_fea, unsigned long npoint, unsig
4646
* still work as expected for the primal solver). ---*/
4747

4848
const bool dynamic_analysis = config->GetTime_Domain();
49-
const bool body_forces = config->GetDeadLoad();
49+
const bool body_forces = config->GetGravityForce() || config->GetBody_Force() || config->GetCentrifugalForce();
5050
const bool prestretch_fem = config->GetPrestretch(); // Structure is prestretched
5151
const bool discrete_adjoint = config->GetDiscrete_Adjoint();
5252
const bool refgeom = config->GetRefGeom(); // Reference geometry needs to be stored

0 commit comments

Comments
 (0)