-
Notifications
You must be signed in to change notification settings - Fork 6
/
Functions.cpp
150 lines (136 loc) · 5.33 KB
/
Functions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "Functions.h"
#include "TopOpt.h"
using namespace std;
const char *Function_Base::name[] = {"Compliance", "Volume", "Stability", "Frequency"};
/********************************************************************
* Constructor for base optimization/compliance function
*
* @param values: Objective weights or constraint values
* @param min_val: Minimum value for function (used in function normalization)
* @param max_val: Maximum value for function (used in function normalization)
* @param objective: True if function is an objective, False if it is a constraint
* @param calc_gradient: Indicate if we need the function gradient as well
*
* @return void
*******************************************************************/
Function_Base::Function_Base(std::vector<PetscScalar> &values, PetscScalar min_val,
PetscScalar max_val, PetscBool objective, PetscBool calc_gradient)
{
nvals = values.size();
this->values = VectorXPS::Zero(nvals);
weights = VectorXPS::Zero(nvals);
copy(values.begin(), values.end(), weights.data());
this->min_val = min_val;
this->max_val = max_val;
this->objective = objective;
this->calc_gradient = calc_gradient;
}
/********************************************************************
* Compute the value and sensitivities of the function
*
* @param topOpt: The topology optimization object
*
* @return ierr: PetscErrorCode
*
*******************************************************************/
PetscErrorCode Function_Base::Compute(TopOpt *topOpt)
{
PetscErrorCode ierr = 0;
if (topOpt->verbose >= 2) {
ierr = PetscFPrintf(topOpt->comm, topOpt->output, "Calling %s function\n",
name[this->func_type]); CHKERRQ(ierr);
}
ierr = Function(topOpt); CHKERRQ(ierr);
// Calculate combined function value and gradient
if (topOpt->verbose >= 3) {
ierr = PetscFPrintf(topOpt->comm, topOpt->output,
"Tabulating results of %s function\n",
name[this->func_type]); CHKERRQ(ierr);
}
PetscInt i = 0;
value = (objective==PETSC_TRUE?weights(i):1)*(values(i)-min_val);
value -= (objective==PETSC_TRUE?0:weights(i));
gradient = (objective==PETSC_TRUE?weights(i):1)*gradients.col(i);
value /= max_val-min_val;
gradient /= max_val-min_val;
return ierr;
}
/********************************************************************
* Call all the functions to get a total objective and all constraints
*
* @param topOpt: The topology optimization object
* @param f: Objective value
* @param dfdx: Objective sensitivities
* @param g: Constraint values
* @param dgdx: Constraint sensitivities
*
* @return ierr: PetscErrorCode
*
*******************************************************************/
PetscErrorCode Function_Base::Function_Call(TopOpt *topOpt, double &f,
Eigen::VectorXd &dfdx, Eigen::VectorXd &g, Eigen::MatrixXd &dgdx)
{
PetscErrorCode ierr = 0;
int constraint = 0;
f = 0; dfdx.setZero(topOpt->nLocElem); dgdx.setZero(topOpt->nLocElem, dgdx.cols());
for (unsigned int ii = 0; ii < topOpt->function_list.size(); ii++) {
ierr = topOpt->function_list[ii]->Compute(topOpt); CHKERRQ(ierr);
if (topOpt->function_list[ii]->objective == PETSC_TRUE) {
f += topOpt->function_list[ii]->value;
dfdx += topOpt->function_list[ii]->gradient;
}
else {
g(constraint) = topOpt->function_list[ii]->value;
dgdx.col(constraint) = topOpt->function_list[ii]->gradient;
constraint++;
}
}
int ind = 0;
for (int ii = 0; ii < topOpt->nLocElem; ii++) {
if (topOpt->active(ii)) {
dfdx(ind) = dfdx(ii);
dgdx.row(ind) = dgdx.row(ii);
ind++;
}
}
dfdx.conservativeResize(ind);
dgdx.conservativeResize(ind, dgdx.cols());
return ierr;
}
/********************************************************************
* Call all possible functions and print their values
*
* @param topOpt: The topology optimization object
*
* @return ierr: PetscErrorCode
*
*******************************************************************/
PetscErrorCode Function_Base::Normalization(TopOpt *topOpt)
{
PetscErrorCode ierr = 0;
std::vector<PetscScalar> values; values.push_back(1);
PetscScalar min = 0, max = 1;
PetscBool objective = PETSC_TRUE, gradient = PETSC_FALSE;
Function_Base *function;
function = new Compliance(values, min, max, objective, gradient);
ierr = function->Function(topOpt); CHKERRQ(ierr);
ierr = PetscFPrintf(topOpt->comm, topOpt->output, "\tCompliance:\t%1.16g\n",
function->values(0)); CHKERRQ(ierr);
delete function;
function = new Volume(values, min, max, objective, gradient);
ierr = function->Function(topOpt); CHKERRQ(ierr);
ierr = PetscFPrintf(topOpt->comm, topOpt->output, "\tVolume:\t%1.16g\n",
function->values(0)); CHKERRQ(ierr);
delete function;
function = new Stability(values, min, max, objective, gradient);
ierr = function->Function(topOpt); CHKERRQ(ierr);
ierr = PetscFPrintf(topOpt->comm, topOpt->output, "\tStability:\t%1.16g\n",
function->values(0)); CHKERRQ(ierr);
delete function;
function = new Frequency(values, min, max, objective, gradient);
ierr = function->Function(topOpt); CHKERRQ(ierr);
ierr = PetscFPrintf(topOpt->comm, topOpt->output, "\tFrequency:\t%1.16g\n",
function->values(0)); CHKERRQ(ierr);
delete function;
return ierr;
}