libMesh
Functions
miscellaneous_ex15.C File Reference

Go to the source code of this file.

Functions

void assemble_func (EquationSystems &es, const std::string &system_name)
 
int main (int argc, char **argv)
 

Function Documentation

◆ assemble_func()

void assemble_func ( EquationSystems es,
const std::string &  system_name 
)

All done!

Definition at line 57 of file miscellaneous_ex15.C.

References libMesh::SparseMatrix< T >::add_matrix(), libMesh::NumericVector< T >::add_vector(), libMesh::FEGenericBase< OutputType >::build(), libMesh::FEGenericBase< OutputType >::build_InfFE(), libMesh::NumericVector< T >::close(), libMesh::SparseMatrix< T >::close(), libMesh::FEType::default_quadrature_rule(), dim, libMesh::Parameters::get(), libMesh::System::get_dof_map(), libMesh::FEGenericBase< OutputType >::get_dphi_over_decayxR(), libMesh::FEAbstract::get_fe_type(), libMesh::FEAbstract::get_JxWxdecay_sq(), libMesh::EquationSystems::get_mesh(), libMesh::FEGenericBase< OutputType >::get_phi_over_decayxR(), libMesh::FEGenericBase< OutputType >::get_Sobolev_dweightxR_sq(), libMesh::FEGenericBase< OutputType >::get_Sobolev_weightxR_sq(), libMesh::EquationSystems::get_system(), libMesh::libmesh_ignore(), libMesh::ImplicitSystem::matrix, mesh, libMesh::MeshBase::mesh_dimension(), libMesh::FEInterface::n_dofs(), libMesh::FEAbstract::n_quadrature_points(), libMesh::EquationSystems::parameters, libMesh::pi, libMesh::Real, libMesh::FEAbstract::reinit(), libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), and libMesh::ExplicitSystem::rhs.

Referenced by main().

58 {
59 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
60  const MeshBase& mesh = es.get_mesh();
61  const unsigned int dim = mesh.mesh_dimension();
62  LinearImplicitSystem & f_system = es.get_system<LinearImplicitSystem> (system_name);
63  const DofMap& dof_map = f_system.get_dof_map();
64  const FEType fe_type = dof_map.variable_type(0);
65  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
66  std::unique_ptr<FEBase> inf_fe (FEBase::build_InfFE(dim, fe_type));
67 
68  const std::vector<dof_id_type > charged_objects = es.parameters.get<std::vector<dof_id_type> >("charged_elem_id");
69  const auto qrule=fe_type.default_quadrature_rule(/*dim = */ 3, /*extra order = */ 3);
70 
71  fe->attach_quadrature_rule (&*qrule);
72  inf_fe->attach_quadrature_rule (&*qrule);
73 
76 
77  // This vector will hold the degree of freedom indices for
78  // the element. These define where in the global system
79  // the element degrees of freedom get mapped.
80  std::vector<dof_id_type> dof_indices;
81 
82  // Now we will loop over all the elements in the mesh that
83  // live on the local processor.
84  for (const auto & elem : mesh.active_local_element_ptr_range())
85  {
86  // Get the degree of freedom indices for the
87  // current element. These define where in the global
88  // matrix and right-hand-side this element will
89  // contribute to.
90  dof_map.dof_indices (elem, dof_indices);
91 
92  // unifyging finite and infinite elements
93  FEBase * cfe = libmesh_nullptr;
94 
95  if (elem->infinite())
96  cfe = inf_fe.get();
97  else
98  cfe = fe.get();
99 
100  // The element Jacobian * quadrature weight at each integration point.
101  const std::vector<Real>& JxW = cfe->get_JxWxdecay_sq();
102  // The element shape functions evaluated at the quadrature points.
103  const std::vector<std::vector<Real> >& phi = cfe->get_phi_over_decayxR();
104  const std::vector<std::vector<RealGradient> >& dphi = cfe->get_dphi_over_decayxR();
105  const std::vector<Real>& sob_w = cfe->get_Sobolev_weightxR_sq();
106  const std::vector<RealGradient>& dsob_w = cfe->get_Sobolev_dweightxR_sq();
107 
108  // Compute the element-specific data for the current
109  // element. This involves computing the location of the
110  // quadrature points (q_point) and the shape functions
111  // (phi, dphi) for the current element.
112  cfe->reinit (elem);
113  M.resize (dof_indices.size(), dof_indices.size());
114  f.resize (dof_indices.size());
115 
116  Real rho;
117  // check if charged_objects contains elem->id(), we add the corresponding charge to the rhs vector
118  if (std::find(charged_objects.begin(), charged_objects.end(), elem->id()) != charged_objects.end())
119  rho=1./elem->volume();
120  else
121  rho = 0;
122 
123  const unsigned int max_qp = cfe->n_quadrature_points();
124  for (unsigned int qp=0; qp<max_qp; ++qp)
125  {
126  const unsigned int n_sf =
127  FEInterface::n_dofs(cfe->get_fe_type(), elem);
128  for (unsigned int i=0; i<n_sf; ++i)
129  {
130  if (rho > 0)
131  f(i) -=4*pi*JxW[qp]*rho*phi[i][qp];
132 
133  // store the test functions derivative (which contains the extra sobolev weight)
134  // separately; so we don't need to recompute it for each j.
135  const RealGradient dphi_i=dphi[i][qp]*sob_w[qp]+phi[i][qp]*dsob_w[qp];
136  for (unsigned int j=0; j<n_sf; ++j)
137  {
138  M(i,j) += JxW[qp]*dphi_i*dphi[j][qp];
139  }
140  }
141  }
142  dof_map.constrain_element_matrix_and_vector(M, f, dof_indices);
143  f_system.matrix->add_matrix(M, dof_indices);
144  f_system.rhs->add_vector(f, dof_indices);
145  }
146  f_system.rhs->close();
147  f_system.matrix->close();
151 #else //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
152  // Avoid compiler warnings
153  libmesh_ignore(es, system_name);
154 #endif
155  return;
156 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
virtual const std::vector< Real > & get_Sobolev_weightxR_sq() const
Definition: fe_base.h:470
unsigned int dim
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:396
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i]...
MeshBase & mesh
NumericVector< Number > * rhs
The system matrix.
const T_sys & get_system(std::string_view name) const
This is the MeshBase class.
Definition: mesh_base.h:75
FEType get_fe_type() const
Definition: fe_abstract.h:520
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:34
void libmesh_ignore(const Args &...)
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
const T & get(std::string_view) const
Definition: parameters.h:426
virtual const std::vector< Real > & get_JxWxdecay_sq() const
This function is the variant of get_JxW() for InfFE.
Definition: fe_abstract.h:292
virtual unsigned int n_quadrature_points() const
Definition: fe_abstract.C:1279
virtual const std::vector< std::vector< OutputShape > > & get_phi_over_decayxR() const
Definition: fe_base.h:493
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)=0
This is at the core of this class.
virtual void close()=0
Calls the NumericVector&#39;s internal assembly routines, ensuring that the values are consistent across ...
virtual void close()=0
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
SparseMatrix< Number > * matrix
The system matrix.
const MeshBase & get_mesh() const
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Definition: dense_matrix.h:895
unsigned int mesh_dimension() const
Definition: mesh_base.C:372
Parameters parameters
Data structure holding arbitrary parameters.
virtual const std::vector< RealGradient > & get_Sobolev_dweightxR_sq() const
Definition: fe_base.h:480
const DofMap & get_dof_map() const
Definition: system.h:2374
This class forms the foundation from which generic finite elements may be derived.
virtual const std::vector< std::vector< OutputGradient > > & get_dphi_over_decayxR() const
Definition: fe_base.h:501
const Real pi
.
Definition: libmesh.h:299

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 158 of file miscellaneous_ex15.C.

References libMesh::EquationSystems::add_system(), libMesh::System::add_variable(), assemble_func(), libMesh::System::attach_assemble_function(), libMesh::MeshTools::Generation::build_cube(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::CARTESIAN, libMesh::Elem::child_ref_range(), dim, libMesh::MeshBase::elem_ptr(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::MeshBase::find_neighbors(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::FOURTH, libMesh::Elem::has_children(), libMesh::DofObject::id(), libMesh::TriangleWrapper::init(), libMesh::EquationSystems::init(), libMesh::JACOBI_20_00, libMesh::LAGRANGE, mesh, libMesh::EquationSystems::parameters, libMesh::MeshBase::print_info(), libMesh::PRISM18, libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::MeshRefinement::refine_fraction(), libMesh::EquationSystems::reinit(), libMesh::SECOND, libMesh::Parameters::set(), and libMesh::LinearImplicitSystem::solve().

159 {
160  // Initialize libMesh and the dependent libraries.
161  LibMeshInit init (argc, argv);
162 
163  // Tell the user what we are doing.
164  std::cout << "Running " << argv[0];
165  for (int i=1; i<argc; i++)
166  std::cout << " " << argv[i];
167  std::cout << std::endl << std::endl;
168 
169 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
170  libmesh_example_requires(false, "--enable-ifem");
171 #else
172 
173  // Skip this example if libMesh was compiled with <3 dimensions.
174  // INFINITE ELEMENTS ARE IMPLEMENTED ONLY FOR 3 DIMENSIONS AT THE MOMENT.
175  libmesh_example_requires(3 <= LIBMESH_DIM, "3D support");
176 
177  int dim = 3;
178  // creation of an empty mesh-object
179  Mesh mesh(init.comm(), dim);
180 
181  // fill the meshes with a spherical grid of type HEX27 with radius r
182  MeshTools::Generation::build_cube (mesh, /*nx= */5, /*ny=*/5, /*nz=*/3,
183  /*xmin=*/ -5.2, /*xmax=*/5.2,
184  /*ymin=*/ -5.2, /*ymax=*/5.2,
185  /*zmin=*/ -3.2, /*zmax=*/3.2,
186  PRISM18 /* Currently, these elements cannot be viewed by paraview.*/
187  );
188 
189  mesh.print_info();
190 
191  // The infinite elements are attached to all elements that build the outer surface of the FEM-region.
192  InfElemBuilder builder(mesh);
193  builder.build_inf_elem(true);
194  // find the neighbours; for correct linking the two areas
196 
197  // Reassign subdomain_id() of all infinite elements.
198  // and their neighbours. This makes finding the surface
199  // between these elemests much easier.
200  for (auto & elem : mesh.element_ptr_range())
201  if (elem->infinite())
202  {
203  elem->subdomain_id() = 1;
204  // the base elements are always the 0-th neighbor.
205  elem->neighbor_ptr(0)->subdomain_id()=2;
206  }
207 
208 
209  // Now we set the sources of the field: prism-shaped objects that are
210  // determined here by containing certain points:
211  PointLocatorTree pt_lctr(mesh);
212  std::vector<dof_id_type> charged_elem_ids(3);
213  {
214  Point pt_0(-3.,-3.0,-1.5);
215  Point pt_1(2.,-2.6,-1.5);
216  Point pt_2(2., 3.1, 1.7);
217  const Elem * elem_0=pt_lctr(pt_0);
218  if (elem_0)
219  charged_elem_ids[0]=elem_0->id();
220  else
221  // this indicates some error which I don't know how to handle.
222  libmesh_not_implemented();
223  const Elem * elem_1=pt_lctr(pt_1);
224  if (elem_1)
225  charged_elem_ids[1]=elem_1->id();
226  else
227  libmesh_not_implemented();
228  const Elem * elem_2=pt_lctr(pt_2);
229  if (elem_2)
230  charged_elem_ids[2]=elem_2->id();
231  else
232  libmesh_not_implemented();
233  }
234 
235  // Create an equation systems object
236  EquationSystems eq_sys (mesh);
237 
238  // This is the only system added here.
239  LinearImplicitSystem & eig_sys = eq_sys.add_system<LinearImplicitSystem> ("Poisson");
240 
241  eq_sys.parameters.set<std::vector<dof_id_type> >("charged_elem_id")=charged_elem_ids;
242 
243  //set the complete type of the variable
245 
246  // Name the variable of interest 'phi' and approximate it as \p fe_type.
247  eig_sys.add_variable("phi", fe_type);
248 
249  // attach the name of the function that assembles the matrix equation:
251 
252  // Initialize the data structures for the equation system.
253  eq_sys.init();
254 
255  // Solve system. This function calls the assemble-functions.
256  eig_sys.solve();
257 
258 #ifdef LIBMESH_ENABLE_AMR
259  for (unsigned int i=0; i< 2; ++i)
260  {
261  ErrorVector error;
262  MeshRefinement mesh_refinement(mesh);
263  KellyErrorEstimator error_estimator;
264 
265  error_estimator.estimate_error(eig_sys, error);
266  mesh_refinement.refine_fraction()=0.3;
267  mesh_refinement.flag_elements_by_error_fraction(error);
268  error_estimator.estimate_error(eig_sys, error);
269  mesh_refinement.refine_and_coarsen_elements();
270  eq_sys.reinit();
271 
272  // in the refined mesh, find the elements that describe the
273  // sources of gravitational field: Due to refinement, there are
274  // successively more elements to account for the same object.
275  std::vector<dof_id_type> charged_elem_child(0);
276  for(unsigned int j=0; j< charged_elem_ids.size(); ++j)
277  {
278  Elem * charged_elem = mesh.elem_ptr(charged_elem_ids[j]);
279  if (charged_elem->has_children())
280  {
281  for(auto & child : charged_elem->child_ref_range())
282  charged_elem_child.push_back(child.id());
283  }
284  else
285  charged_elem_child.push_back(charged_elem->id());
286  }
287 
288  charged_elem_ids=charged_elem_child;
289  eq_sys.parameters.set<std::vector<dof_id_type> >("charged_elem_id")=charged_elem_ids;
290 
291  // re-assemble and than solve again.
292  eig_sys.solve();
293  }
294 #endif // LIBMESH_ENABLE_AMR
295 
296  // All done.
297 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
298  return 0;
299 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
This is the EquationSystems class.
This is a point locator.
unsigned int dim
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:90
virtual void solve() override
Assembles & solves the linear system A*x=b.
Parameters parameters
Parameters for the system. If a parameter is not provided, it should be retrieved from the EquationSy...
Definition: system.h:1526
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2346
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
Locate element face (edge in 2D) neighbors.
Implements (adaptive) mesh refinement algorithms for a MeshBase.
dof_id_type id() const
Definition: dof_object.h:828
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition: mesh_base.C:1562
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
Definition: system.C:1357
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
Register a user function to use in assembling the system matrix and RHS.
Definition: system.C:2161
This class is used to build infinite elements on top of an existing mesh.
virtual const Elem * elem_ptr(const dof_id_type i) const =0
void assemble_func(EquationSystems &es, const std::string &system_name)
This class implements the Kelly error indicator which is based on the flux jumps between elements...
T & set(const std::string &)
Definition: parameters.h:469
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the derived class&#39;s jump error estimate formula to estimate the error on each cell...
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
bool has_children() const
Definition: elem.h:2979
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.