21 "Compute updated densities based on sensitivities using an optimality criteria method to " 22 "keep the volume and cost constraints satisified.");
26 "Relative tolerance on both compliance and cost to end the bisection method.");
29 "Name of the density_sensitivity variable.");
31 "Name of the cost density sensitivity variable.");
32 params.
addParam<VariableName>(
"thermal_sensitivity",
33 "Name of the thermal density sensitivity variable.");
36 params.
addParam<
Real>(
"bisection_move", 0.01,
"Bisection move for the updated solution.");
37 params.
addParam<
bool>(
"adaptive_move",
39 "Whether incremental moves in the bisection algorithm will be reduced as " 40 "the number of iterations increases. Note that the time must correspond to " 41 "iteration number for better results.");
44 params.
addParam<
Real>(
"bisection_lower_bound", 0,
"Lower bound for the bisection algorithm.");
45 params.
addParam<
Real>(
"bisection_upper_bound", 1e16,
"Upper bound for the bisection algorithm.");
48 "weight_mechanical_thermal",
49 "List of values between 0 and 1 to weight the stiffness and thermal sensitivities");
51 params.
addParam<
bool>(
"use_thermal_compliance",
53 "Whether to include the thermal compliance in the sensitivities to " 54 "minimize in conjunction with stiffness compliance.");
61 _mesh(_subproblem.
mesh()),
62 _density_sensitivity_name(getParam<VariableName>(
"density_sensitivity")),
63 _cost_density_sensitivity_name(getParam<VariableName>(
"cost_density_sensitivity")),
64 _cost_name(getParam<VariableName>(
"cost")),
65 _design_density(&writableVariable(
"design_density")),
66 _density_sensitivity(&_subproblem.getStandardVariable(_tid, _density_sensitivity_name)),
67 _cost_density_sensitivity(
68 &_subproblem.getStandardVariable(_tid, _cost_density_sensitivity_name)),
69 _cost(_subproblem.getStandardVariable(_tid, _cost_name)),
70 _volume_fraction(getParam<
Real>(
"volume_fraction")),
71 _cost_fraction(getParam<
Real>(
"cost_fraction")),
72 _relative_tolerance(getParam<
Real>(
"relative_tolerance")),
73 _lower_bound(getParam<
Real>(
"bisection_lower_bound")),
74 _upper_bound(getParam<
Real>(
"bisection_upper_bound")),
75 _bisection_move(getParam<
Real>(
"bisection_move")),
76 _adaptive_move(getParam<bool>(
"adaptive_move")),
77 _thermal_sensitivity_name(
78 isParamValid(
"thermal_sensitivity") ? getParam<VariableName>(
"thermal_sensitivity") :
""),
79 _thermal_sensitivity(isParamValid(
"thermal_sensitivity")
80 ? &_subproblem.getStandardVariable(_tid, _thermal_sensitivity_name)
87 "The thermal_sensitivity variable name must be provided by the user if " 88 "include_thermal_compliance is chosen to be true.");
92 _weight_values = getParam<std::vector<Real>>(
"weight_mechanical_thermal");
95 "Weighing of sensitivities is only available for the mechanical compliance and " 96 "the thermal compliances problems, respectively.");
100 "This parameter needs to be provided when including thermal sensitivity.");
106 paramError(
"adaptive_move",
"Cannot find a transient executioner for adaptive bisection move.");
109 paramError(
"design_density",
"Design density must be a finite element variable");
112 paramError(
"density_sensitivity",
"Design sensitivity must be a finite element variable");
116 "Cost density sensitivity must be a finite element variable");
140 mooseError(
"Element data not found for the current element id.");
152 for (
const auto & sub_id :
blockIDs())
153 for (
const auto & elem :
_mesh.
getMesh().active_local_subdomain_elements_ptr_range(sub_id))
159 ->getElementalValue(elem),
161 ->getElementalValue(elem),
188 bool perform_loop =
true;
194 Real lmid = 0.5 * (l2 + l1);
197 Real cmid = 0.5 * (c2 + c1);
200 Real curr_total_volume = 0;
203 Real curr_total_cost = 0;
210 elem_data.old_density,
212 elem_data.cost_sensitivity,
213 elem_data.thermal_sensitivity *
220 elem_data.new_density = new_density;
222 curr_total_volume += new_density * elem_data.volume;
224 curr_total_cost += new_density * elem_data.volume * elem_data.cost;
253 Real cost_sensitivity,
254 Real temp_sensitivity,
262 const Real move_min = 1.0e-3;
270 Real denominator = lmid + cmid * cost + cmid * current_density * cost_sensitivity;
273 const Real damping = 1.0;
275 Real updated_density = std::max(
278 current_density - move,
280 std::min(current_density + move,
282 MathUtils::pow(std::sqrt((-(dc + temp_sensitivity) / denominator)),
286 return updated_density;
Real computeUpdatedDensity(Real current_density, Real dc, Real cost_sensitivity, Real thermal_sensitivity, Real cost, Real lmid, Real cmid)
std::map< dof_id_type, ElementData > _elem_data_map
Data structure to hold old density, sensitivity, volume, current density.
const MooseWritableVariable * _cost_density_sensitivity
The filtered density sensitivity variable (cost)
std::vector< Real > _weight_values
Element user object that performs SIMP optimization using a bisection algorithm applying a volume con...
const MooseWritableVariable * _density_sensitivity
The filtered density sensitivity variable (elasticity)
const Real _cost_fraction
The cost fraction to be enforced.
const Real _relative_tolerance
static InputParameters validParams()
virtual void setNodalValue(const Real &value, unsigned int idx=0)=0
Real _total_allowable_volume
Total volume allowed for volume contraint.
static InputParameters validParams()
const Parallel::Communicator & _communicator
virtual const std::set< SubdomainID > & blockIDs() const
OutputData getElementalValue(const Elem *elem, unsigned int idx=0) const
const Real _bisection_move
Bisection algorithm move.
virtual void execute() override
bool isParamValid(const std::string &name) const
void performOptimCritLoop()
Performs the optimality criterion loop (bisection)
const Real _upper_bound
Upper bound for bisection algorithm.
const Real _lower_bound
Lower bound for bisection algorithm.
Real _total_allowable_cost
Total volume allowed for cost contraint.
MooseVariable * _thermal_sensitivity
Thermal compliance variable.
void paramError(const std::string ¶m, Args... args) const
Executioner * getExecutioner() const
const MooseVariable & _cost
The cost variable.
MooseWritableVariable * _design_density
The pseudo-density variable.
const MooseMesh & _mesh
The system mesh.
DensityUpdateTwoConstraints(const InputParameters ¶meters)
virtual void timestepSetup() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Elem *const & _current_elem
static const std::string alpha
const bool _adaptive_move
Whether bisection moves are adaptive.
void mooseError(Args &&... args) const
const Real _volume_fraction
The volume fraction to be enforced.
registerMooseObject("OptimizationApp", DensityUpdateTwoConstraints)
void gatherElementData()
Gathers element date necessary to perform the bisection algorithm for optimization.