84 for (
int k=0; k<max_its; k++)
86 int_sigmoid_psi.Assemble();
87 const double f = int_sigmoid_psi.Sum() - target_volume;
89 int_der_sigmoid_psi.Assemble();
90 const double df = int_der_sigmoid_psi.Sum();
92 const double dc = -
f/df;
94 if (abs(dc) < tol) { done =
true;
break; }
98 mfem_warning(
"Projection reached maximum iteration without converging. " 99 "Result may not be accurate.");
101 int_sigmoid_psi.Assemble();
102 return int_sigmoid_psi.Sum();
177 int main(
int argc,
char *argv[])
184 double vol_fraction = 0.5;
188 double rho_min = 1e-6;
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.");
231 Mesh mesh = Mesh::MakeCartesian2D(3, 1, mfem::Element::Type::QUADRILATERAL,
236 for (
int i = 0; i<mesh.
GetNBE(); i++)
242 double * coords1 = mesh.
GetVertex(vertices[0]);
243 double * coords2 = mesh.
GetVertex(vertices[1]);
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++)
272 BasisType::GaussLobatto);
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 double domain_volume = vol_form(onegf);
357 const double target_volume = domain_volume * vol_fraction;
363 if (glvis_visualization)
386 for (
int k = 1; k <= max_it; k++)
388 if (k > 1) {
alpha *= ((double) k) / ((double) k-1); }
390 mfem::out <<
"\nStep = " << k << std::endl;
395 FilterSolver->
Solve();
404 ElasticitySolver->
Solve();
412 FilterSolver->
Solve();
425 const double material_volume =
proj(psi, target_volume);
429 double 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;
452 paraview_dc.
SetTime((
double)k);
456 if (norm_reduced_gradient < ntol && norm_increment < itol)
462 delete ElasticitySolver;
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Class for domain integration L(v) := (f, v)
Class for grid function - Vector with associated FE space.
GridFunction * GetFEMSolution()
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetDataFormat(VTKFormat fmt)
A coefficient that is constant across space and time.
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
void PrintOptions(std::ostream &out) const
Print the options.
LinearForm * GetLinearForm()
int Dimension() const
Dimension of the reference space used within the elements.
Helper class for ParaView visualization data.
void PrintUsage(std::ostream &out) const
Print the usage message.
void SetEssentialBoundary(const Array< int > &ess_bdr_)
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
bool Good() const
Return true if the command line options were parsed successfully.
int GetNBE() const
Returns number of boundary elements.
double inv_sigmoid(double x)
Inverse sigmoid function.
double der_sigmoid(double x)
Derivative of sigmoid function.
Integrator that inverts the matrix assembled by another integrator.
void SetEssentialBoundary(const Array< int > &ess_bdr_)
Returns f(u(x)) where u is a scalar GridFunction and f:R → R.
Returns f(u(x)) - f(v(x)) where u, v are scalar GridFunctions and f:R → R.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
Class for solving linear elasticity:
Strain energy density coefficient.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SetRHSCoefficient(Coefficient *rhscf_)
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
double sigmoid(double x)
Sigmoid function.
int main(int argc, char *argv[])
void SetHighOrderOutput(bool high_order_output_)
FiniteElementSpace * FESpace()
void SetTime(double t)
Set physical time (for time-dependent simulations)
virtual double ComputeL1Error(Coefficient &exsol, const IntegrationRule *irs[]=NULL) const
GridFunction * GetFEMSolution()
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
double proj(GridFunction &psi, double target_volume, double tol=1e-12, int max_its=10)
Bregman projection of ρ = sigmoid(ψ) onto the subspace ∫_Ω ρ dx = θ vol(Ω) as follows: ...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void SetMesh(Mesh *mesh_)
void SetDiffusionCoefficient(Coefficient *diffcf_)
Solid isotropic material penalization (SIMP) coefficient.
void SetOrder(int order_)
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void mfem_warning(const char *msg)
Function called by the macro MFEM_WARNING.
void SetMassCoefficient(Coefficient *masscf_)
void SetOrder(int order_)
Class for solving Poisson's equation:
void SetAttribute(const int attr)
Set element's attribute.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
int Size() const
Return the logical size of the array.
void SetLevelsOfDetail(int levels_of_detail_)
void SetLameCoefficients(Coefficient *lambda_cf_, Coefficient *mu_cf_)
Arbitrary order H1-conforming (continuous) finite elements.
virtual void Save() override
double u(const Vector &xvec)
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
void SetMesh(Mesh *mesh_)
Abstract data type element.
Volumetric force for linear elasticity.
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
void SetRHSCoefficient(VectorCoefficient *rhs_cf_)
Arbitrary order "L2-conforming" discontinuous finite elements.
double f(const Vector &p)