84 for (
int k=0; k<max_its; k++)
87 const real_t f = int_sigmoid_psi.
Sum() - target_volume;
90 const real_t df = int_der_sigmoid_psi.
Sum();
94 if (abs(dc) < tol) { done =
true;
break; }
98 mfem_warning(
"Projection reached maximum iteration without converging. "
99 "Result may not be accurate.");
102 return int_sigmoid_psi.
Sum();
177int main(
int argc,
char *argv[])
184 real_t vol_fraction = 0.5;
191 bool glvis_visualization =
true;
192 bool paraview_output =
false;
195 args.
AddOption(&ref_levels,
"-r",
"--refine",
196 "Number of times to refine the mesh uniformly.");
198 "Order (degree) of the finite elements.");
200 "Step length for gradient descent.");
202 "Length scale for ρ.");
203 args.
AddOption(&max_it,
"-mi",
"--max-it",
204 "Maximum number of gradient descent iterations.");
205 args.
AddOption(&ntol,
"-ntol",
"--rel-tol",
206 "Normalized exit tolerance.");
207 args.
AddOption(&itol,
"-itol",
"--abs-tol",
208 "Increment exit tolerance.");
209 args.
AddOption(&vol_fraction,
"-vf",
"--volume-fraction",
210 "Volume fraction for the material density.");
211 args.
AddOption(&lambda,
"-lambda",
"--lambda",
215 args.
AddOption(&rho_min,
"-rmin",
"--psi-min",
216 "Minimum of density coefficient.");
217 args.
AddOption(&glvis_visualization,
"-vis",
"--visualization",
"-no-vis",
218 "--no-visualization",
219 "Enable or disable GLVis visualization.");
220 args.
AddOption(¶view_output,
"-pv",
"--paraview",
"-no-pv",
222 "Enable or disable ParaView output.");
236 for (
int i = 0; i<mesh.
GetNBE(); i++)
246 center(0) = 0.5*(coords1[0] + coords2[0]);
247 center(1) = 0.5*(coords1[1] + coords2[1]);
249 if (abs(center(0) - 0.0) < 1e-10)
263 for (
int lev = 0; lev < ref_levels; lev++)
280 mfem::out <<
"Number of state unknowns: " << state_size << std::endl;
281 mfem::out <<
"Number of filter unknowns: " << filter_size << std::endl;
282 mfem::out <<
"Number of control unknowns: " << control_size << std::endl;
290 rho_filter = vol_fraction;
310 ElasticitySolver->
SetMesh(&mesh);
313 Vector center(2); center(0) = 2.9; center(1) = 0.5;
314 Vector force(2); force(0) = 0.0; force(1) = -1.0;
356 real_t domain_volume = vol_form(onegf);
357 const real_t target_volume = domain_volume * vol_fraction;
363 if (glvis_visualization)
386 for (
int k = 1; k <= max_it; k++)
390 mfem::out <<
"\nStep = " << k << std::endl;
395 FilterSolver->
Solve();
404 ElasticitySolver->
Solve();
412 FilterSolver->
Solve();
425 const real_t material_volume =
proj(psi, target_volume);
429 real_t norm_reduced_gradient = norm_increment/
alpha;
433 mfem::out <<
"norm of the reduced gradient = " << norm_reduced_gradient <<
435 mfem::out <<
"norm of the increment = " << norm_increment << endl;
436 mfem::out <<
"compliance = " << compliance << std::endl;
437 mfem::out <<
"volume fraction = " << material_volume / domain_volume <<
440 if (glvis_visualization)
444 sout_r <<
"solution\n" << mesh << r_gf
445 <<
"window_title 'Design density r(ρ̃)'" << flush;
456 if (norm_reduced_gradient < ntol && norm_increment < itol)
462 delete ElasticitySolver;
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
@ GaussLobatto
Closed type.
A coefficient that is constant across space and time.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
Returns f(u(x)) - f(v(x)) where u, v are scalar GridFunctions and f:R → R.
Class for solving Poisson's equation:
void SetDiffusionCoefficient(Coefficient *diffcf_)
void SetRHSCoefficient(Coefficient *rhscf_)
void SetOrder(int order_)
void SetMesh(Mesh *mesh_)
void SetMassCoefficient(Coefficient *masscf_)
GridFunction * GetFEMSolution()
void SetEssentialBoundary(const Array< int > &ess_bdr_)
Class for domain integration .
Abstract data type element.
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
void SetAttribute(const int attr)
Set element's attribute.
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
Class for grid function - Vector with associated FE space.
virtual real_t ComputeL1Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
FiniteElementSpace * FESpace()
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Arbitrary order H1-conforming (continuous) finite elements.
Integrator that inverts the matrix assembled by another integrator.
Arbitrary order "L2-conforming" discontinuous finite elements.
Class for solving linear elasticity:
GridFunction * GetFEMSolution()
void SetEssentialBoundary(const Array< int > &ess_bdr_)
void SetRHSCoefficient(VectorCoefficient *rhs_cf_)
void SetMesh(Mesh *mesh_)
LinearForm * GetLinearForm()
void SetOrder(int order_)
void SetLameCoefficients(Coefficient *lambda_cf_, Coefficient *mu_cf_)
Returns f(u(x)) where u is a scalar GridFunction and f:R → R.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
int GetNBE() const
Returns number of boundary elements.
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, real_t sx=1.0, real_t sy=1.0, bool sfc_ordering=true)
Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny quadrilaterals if type = QUADRILATER...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
Helper class for ParaView visualization data.
void SetHighOrderOutput(bool high_order_output_)
void SetLevelsOfDetail(int levels_of_detail_)
virtual void Save() override
void SetDataFormat(VTKFormat fmt)
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Solid isotropic material penalization (SIMP) coefficient.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Strain energy density coefficient.
real_t Sum() const
Return the sum of the vector entries.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Volumetric force for linear elasticity.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
real_t proj(GridFunction &psi, real_t target_volume, real_t tol=1e-12, int max_its=10)
Bregman projection of ρ = sigmoid(ψ) onto the subspace ∫_Ω ρ dx = θ vol(Ω) as follows:
real_t sigmoid(real_t x)
Sigmoid function.
real_t u(const Vector &xvec)
void mfem_warning(const char *msg)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
real_t inv_sigmoid(real_t x)
Inverse sigmoid function.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
real_t der_sigmoid(real_t x)
Derivative of sigmoid function.