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 59 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().

60 {
61 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
62  const MeshBase& mesh = es.get_mesh();
63  const unsigned int dim = mesh.mesh_dimension();
64  LinearImplicitSystem & f_system = es.get_system<LinearImplicitSystem> (system_name);
65  const DofMap& dof_map = f_system.get_dof_map();
66  const FEType fe_type = dof_map.variable_type(0);
67  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
68  std::unique_ptr<FEBase> inf_fe (FEBase::build_InfFE(dim, fe_type));
69 
70  const std::set<dof_id_type > charged_objects = es.parameters.get<std::set<dof_id_type> >("charged_elem_id");
71  const auto qrule=fe_type.default_quadrature_rule(/*dim = */ 3, /*extra order = */ 3);
72 
73  fe->attach_quadrature_rule (&*qrule);
74  inf_fe->attach_quadrature_rule (&*qrule);
75 
78 
79  // This vector will hold the degree of freedom indices for
80  // the element. These define where in the global system
81  // the element degrees of freedom get mapped.
82  std::vector<dof_id_type> dof_indices;
83 
84  // Now we will loop over all the elements in the mesh that
85  // live on the local processor.
86  for (const auto & elem : mesh.active_local_element_ptr_range())
87  {
88  // Get the degree of freedom indices for the
89  // current element. These define where in the global
90  // matrix and right-hand-side this element will
91  // contribute to.
92  dof_map.dof_indices (elem, dof_indices);
93 
94  // unifyging finite and infinite elements
95  FEBase * cfe = libmesh_nullptr;
96 
97  if (elem->infinite())
98  cfe = inf_fe.get();
99  else
100  cfe = fe.get();
101 
102  // The element Jacobian * quadrature weight at each integration point.
103  const std::vector<Real>& JxW = cfe->get_JxWxdecay_sq();
104  // The element shape functions evaluated at the quadrature points.
105  const std::vector<std::vector<Real> >& phi = cfe->get_phi_over_decayxR();
106  const std::vector<std::vector<RealGradient> >& dphi = cfe->get_dphi_over_decayxR();
107  const std::vector<Real>& sob_w = cfe->get_Sobolev_weightxR_sq();
108  const std::vector<RealGradient>& dsob_w = cfe->get_Sobolev_dweightxR_sq();
109 
110  // Compute the element-specific data for the current
111  // element. This involves computing the location of the
112  // quadrature points (q_point) and the shape functions
113  // (phi, dphi) for the current element.
114  cfe->reinit (elem);
115  M.resize (dof_indices.size(), dof_indices.size());
116  f.resize (dof_indices.size());
117 
118  Real rho;
119  // check if charged_objects contains elem->id(), we add the corresponding charge to the rhs vector
120  if (charged_objects.count(elem->id()))
121  rho=1./elem->volume();
122  else
123  rho = 0;
124 
125  const unsigned int max_qp = cfe->n_quadrature_points();
126  for (unsigned int qp=0; qp<max_qp; ++qp)
127  {
128  const unsigned int n_sf =
129  FEInterface::n_dofs(cfe->get_fe_type(), elem);
130  for (unsigned int i=0; i<n_sf; ++i)
131  {
132  if (rho > 0)
133  f(i) -=4*pi*JxW[qp]*rho*phi[i][qp];
134 
135  // store the test functions derivative (which contains the extra sobolev weight)
136  // separately; so we don't need to recompute it for each j.
137  const RealGradient dphi_i=dphi[i][qp]*sob_w[qp]+phi[i][qp]*dsob_w[qp];
138  for (unsigned int j=0; j<n_sf; ++j)
139  {
140  M(i,j) += JxW[qp]*dphi_i*dphi[j][qp];
141  }
142  }
143  }
144  dof_map.constrain_element_matrix_and_vector(M, f, dof_indices);
145  f_system.matrix->add_matrix(M, dof_indices);
146  f_system.rhs->add_vector(f, dof_indices);
147  }
148  f_system.rhs->close();
149  f_system.matrix->close();
153 #else //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
154  // Avoid compiler warnings
155  libmesh_ignore(es, system_name);
156 #endif
157  return;
158 }
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:85
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:451
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:422
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:2417
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:292

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 160 of file miscellaneous_ex15.C.

References libMesh::EquationSystems::add_system(), libMesh::System::add_variable(), libMesh::MeshBase::allow_renumbering(), assemble_func(), libMesh::System::attach_assemble_function(), libMesh::MeshTools::Generation::build_cube(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::CARTESIAN, libMesh::Elem::child_ref_range(), libMesh::ParallelObject::comm(), dim, 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::MeshBase::is_serial(), libMesh::JACOBI_20_00, libMesh::LAGRANGE, libMesh::libmesh_assert(), mesh, libMesh::EquationSystems::parameters, libMesh::MeshBase::print_info(), libMesh::PRISM18, libMesh::MeshBase::query_elem_ptr(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::MeshRefinement::refine_fraction(), libMesh::EquationSystems::reinit(), libMesh::SECOND, libMesh::Parameters::set(), TIMPI::Communicator::set_union(), libMesh::LinearImplicitSystem::solve(), libMesh::MeshBase::sub_point_locator(), and libMesh::Parallel::sync_dofobject_data_by_id().

161 {
162  // Initialize libMesh and the dependent libraries.
163  LibMeshInit init (argc, argv);
164 
165  // Tell the user what we are doing.
166  std::cout << "Running " << argv[0];
167  for (int i=1; i<argc; i++)
168  std::cout << " " << argv[i];
169  std::cout << std::endl << std::endl;
170 
171 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
172  libmesh_example_requires(false, "--enable-ifem");
173 #else
174 
175  // Skip this example if libMesh was compiled with <3 dimensions.
176  // INFINITE ELEMENTS ARE IMPLEMENTED ONLY FOR 3 DIMENSIONS AT THE MOMENT.
177  libmesh_example_requires(3 <= LIBMESH_DIM, "3D support");
178 
179  int dim = 3;
180  // creation of an empty mesh-object
181  Mesh mesh(init.comm(), dim);
182 
183  // We're going to keep track of elements by id, so we don't want
184  // even a DistributedMesh to renumber them.
185  mesh.allow_renumbering(false);
186 
187  // fill the meshes with a spherical grid of type HEX27 with radius r
188  MeshTools::Generation::build_cube (mesh, /*nx= */5, /*ny=*/5, /*nz=*/3,
189  /*xmin=*/ -5.2, /*xmax=*/5.2,
190  /*ymin=*/ -5.2, /*ymax=*/5.2,
191  /*zmin=*/ -3.2, /*zmax=*/3.2,
192  PRISM18 /* Currently, these elements cannot be viewed by paraview.*/
193  );
194 
195  mesh.print_info();
196 
197  // The infinite elements are attached to all elements that build the outer surface of the FEM-region.
198  InfElemBuilder builder(mesh);
199  builder.build_inf_elem(true);
200  // find the neighbours; for correct linking the two areas
202 
203  // Reassign subdomain_id() of all infinite elements.
204  // and their neighbours. This makes finding the surface
205  // between these elemests much easier.
206  for (auto & elem : mesh.element_ptr_range())
207  if (elem->infinite())
208  {
209  elem->subdomain_id() = 1;
210  // the base elements are always the 0-th neighbor.
211  elem->neighbor_ptr(0)->subdomain_id()=2;
212  }
213 
214  // If we're on a distributed mesh then we might have missed some
215  // ghosted base elements with remote infinite elements.
216  if (!mesh.is_serial())
217  {
218  SyncSubdomainIds sync_obj(mesh);
220  (mesh.comm(), mesh.elements_begin(), mesh.elements_end(),
221  sync_obj);
222  }
223 
224  // Now we set the sources of the field: prism-shaped objects that are
225  // determined here by containing certain points:
226  auto p_pt_lctr = mesh.sub_point_locator();
227  auto & pt_lctr = *p_pt_lctr;
228  pt_lctr.enable_out_of_mesh_mode();
229 
230  std::set<dof_id_type> charged_elem_ids;
231  {
232  Point pt_0(-3.,-3.0,-1.5);
233  Point pt_1(2.,-2.6,-1.5);
234  Point pt_2(2., 3.1, 1.7);
235  const Elem * elem_0=pt_lctr(pt_0);
236  if (elem_0)
237  charged_elem_ids.insert(elem_0->id());
238  const Elem * elem_1=pt_lctr(pt_1);
239  if (elem_1)
240  charged_elem_ids.insert(elem_1->id());
241  const Elem * elem_2=pt_lctr(pt_2);
242  if (elem_2)
243  charged_elem_ids.insert(elem_2->id());
244 
245  // On a distributed mesh we might not have every point in a
246  // semilocal element on every processor
247  if (!mesh.is_serial())
248  mesh.comm().set_union(charged_elem_ids);
249 
250  // But we should have every point on *some* processor
251  libmesh_assert_equal_to(charged_elem_ids.size(), 3);
252  }
253 
254  // Create an equation systems object
255  EquationSystems eq_sys (mesh);
256 
257  // This is the only system added here.
258  LinearImplicitSystem & eig_sys = eq_sys.add_system<LinearImplicitSystem> ("Poisson");
259 
260  eq_sys.parameters.set<std::set<dof_id_type> >("charged_elem_id")=charged_elem_ids;
261 
262  //set the complete type of the variable
264 
265  // Name the variable of interest 'phi' and approximate it as \p fe_type.
266  eig_sys.add_variable("phi", fe_type);
267 
268  // attach the name of the function that assembles the matrix equation:
270 
271  // Initialize the data structures for the equation system.
272  eq_sys.init();
273 
274  // Solve system. This function calls the assemble-functions.
275  eig_sys.solve();
276 
277 #ifdef LIBMESH_ENABLE_AMR
278  for (unsigned int i=0; i< 2; ++i)
279  {
280  ErrorVector error;
281  MeshRefinement mesh_refinement(mesh);
282  KellyErrorEstimator error_estimator;
283 
284  error_estimator.estimate_error(eig_sys, error);
285  mesh_refinement.refine_fraction()=0.3;
286  mesh_refinement.flag_elements_by_error_fraction(error);
287  error_estimator.estimate_error(eig_sys, error);
288  mesh_refinement.refine_and_coarsen_elements();
289  eq_sys.reinit();
290 
291  // in the refined mesh, find the elements that describe the
292  // sources of gravitational field: Due to refinement, there are
293  // successively more elements to account for the same object.
294  std::set<dof_id_type> charged_elem_children;
295  for(auto id : charged_elem_ids)
296  {
297  Elem * charged_elem = mesh.query_elem_ptr(id);
298  if (!charged_elem)
299  {
301  continue;
302  }
303 
304  if (charged_elem->has_children())
305  {
306  for(auto & child : charged_elem->child_ref_range())
307  if (!child.is_remote())
308  charged_elem_children.insert(child.id());
309  }
310  else
311  charged_elem_children.insert(charged_elem->id());
312  }
313 
314  charged_elem_ids=charged_elem_children;
315  if (!mesh.is_serial())
316  mesh.comm().set_union(charged_elem_ids);
317 
318  eq_sys.parameters.set<std::set<dof_id_type> >("charged_elem_id")=charged_elem_ids;
319 
320  // re-assemble and than solve again.
321  eig_sys.solve();
322  }
323 #endif // LIBMESH_ENABLE_AMR
324 
325  // All done.
326 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
327  return 0;
328 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
This is the EquationSystems class.
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1776
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use...
Definition: mesh_base.h:1350
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 ...
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true)=0
Locate element face (edge in 2D) neighbors.
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
const Parallel::Communicator & comm() const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:91
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:1588
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2352
virtual bool is_serial() const
Definition: mesh_base.h:353
Implements (adaptive) mesh refinement algorithms for a MeshBase.
dof_id_type id() const
Definition: dof_object.h:819
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:1698
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libmesh_assert(ctx)
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:1344
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:1954
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
This class is used to build infinite elements on top of an existing mesh.
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...
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
T & set(const std::string &)
Definition: parameters.h:494
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:2993
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.
void set_union(T &data, const unsigned int root_id) const