libMesh
Loading...
Searching...
No Matches
mesh_function.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20// Local Includes
21#include "libmesh/mesh_function.h"
22#include "libmesh/dense_vector.h"
23#include "libmesh/equation_systems.h"
24#include "libmesh/numeric_vector.h"
25#include "libmesh/dof_map.h"
26#include "libmesh/point_locator_tree.h"
27#include "libmesh/fe_base.h"
28#include "libmesh/fe_interface.h"
29#include "libmesh/fe_compute_data.h"
30#include "libmesh/mesh_base.h"
31#include "libmesh/point.h"
32#include "libmesh/elem.h"
33#include "libmesh/int_range.h"
34#include "libmesh/fe_map.h"
35
36namespace libMesh
37{
38
39
40//------------------------------------------------------------------
41// MeshFunction methods
43 const NumericVector<Number> & vec,
44 const DofMap & dof_map,
45 std::vector<unsigned int> vars,
46 const FunctionBase<Number> * master) :
47 FunctionBase<Number> (master),
48 ParallelObject (eqn_systems),
49 _eqn_systems (eqn_systems),
50 _vector (vec),
51 _dof_map (dof_map),
52 _system_vars (std::move(vars)),
53 _out_of_mesh_mode (false)
54{
55}
56
57
58
60 const NumericVector<Number> & vec,
61 const DofMap & dof_map,
62 const unsigned int var,
63 const FunctionBase<Number> * master) :
64 FunctionBase<Number> (master),
65 ParallelObject (eqn_systems),
66 _eqn_systems (eqn_systems),
67 _vector (vec),
68 _dof_map (dof_map),
69 _system_vars (1,var),
70 _out_of_mesh_mode (false)
71{
72}
73
75 FunctionBase<Number> (mf._master),
76 ParallelObject (mf._eqn_systems),
77 _eqn_systems (mf._eqn_systems),
78 _vector (mf._vector),
79 _dof_map (mf._dof_map),
80 _system_vars (mf._system_vars),
81 _out_of_mesh_mode (mf._out_of_mesh_mode)
82{
83 // Initialize the mf and set the point locator if the
84 // input mf had done so.
85 if(mf.initialized())
86 {
87 this->MeshFunction::init();
88
91
92 }
93
94 if (mf._subdomain_ids)
96 std::make_unique<std::set<subdomain_id_type>>
97 (*mf._subdomain_ids);
98}
99
100MeshFunction::~MeshFunction () = default;
101
102
103
105{
106 // are indices of the desired variable(s) provided?
107 libmesh_assert_greater (this->_system_vars.size(), 0);
108
109 // Don't do twice...
110 if (this->_initialized)
111 {
113 return;
114 }
115
116 // The Mesh owns the "master" PointLocator, while handing us a
117 // PointLocator "proxy" that forwards all requests to the master.
118 const MeshBase & mesh = this->_eqn_systems.get_mesh();
120
121 // ready for use
122 this->_initialized = true;
123}
124
125
126
127void
129{
130 // only delete the point locator when we are the master
131 if (_point_locator && !_master)
132 _point_locator.reset();
133
134 this->_initialized = false;
135}
136
137
138
139std::unique_ptr<FunctionBase<Number>> MeshFunction::clone () const
140{
141 return std::make_unique<MeshFunction>(*this);
142}
143
144
145
147 const Real time)
148{
149 libmesh_assert (this->initialized());
150
151 DenseVector<Number> buf (1);
152 this->operator() (p, time, buf);
153 return buf(0);
154}
155
156std::map<const Elem *, Number> MeshFunction::discontinuous_value (const Point & p,
157 const Real time)
158{
159 libmesh_assert (this->initialized());
160
161 std::map<const Elem *, DenseVector<Number>> buffer;
162 this->discontinuous_value (p, time, buffer);
163 std::map<const Elem *, Number> return_value;
164 for (const auto & [elem, vec] : buffer)
165 return_value[elem] = vec(0);
166 // NOTE: If no suitable element is found, then the map return_value is empty. This
167 // puts burden on the user of this function but I don't really see a better way.
168 return return_value;
169}
170
172 const Real time)
173{
174 libmesh_assert (this->initialized());
175
176 std::vector<Gradient> buf (1);
177 this->gradient(p, time, buf);
178 return buf[0];
179}
180
181std::map<const Elem *, Gradient> MeshFunction::discontinuous_gradient (const Point & p,
182 const Real time)
183{
184 libmesh_assert (this->initialized());
185
186 std::map<const Elem *, std::vector<Gradient>> buffer;
187 this->discontinuous_gradient (p, time, buffer);
188 std::map<const Elem *, Gradient> return_value;
189 for (const auto & [elem, vec] : buffer)
190 return_value[elem] = vec[0];
191 // NOTE: If no suitable element is found, then the map return_value is empty. This
192 // puts burden on the user of this function but I don't really see a better way.
193 return return_value;
194}
195
196#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
198 const Real time)
199{
200 libmesh_assert (this->initialized());
201
202 std::vector<Tensor> buf (1);
203 this->hessian(p, time, buf);
204 return buf[0];
205}
206#endif
207
209 const Real time,
210 DenseVector<Number> & output)
211{
212 this->operator() (p, time, output, this->_subdomain_ids.get());
213}
214
216 const Real,
217 DenseVector<Number> & output,
218 const std::set<subdomain_id_type> * subdomain_ids)
219{
220 libmesh_assert (this->initialized());
221
222 const Elem * element = this->find_element(p,subdomain_ids);
223
224 if (!element)
225 {
226 // We'd better be in out_of_mesh_mode if we couldn't find an
227 // element in the mesh
229 output = _out_of_mesh_value;
230 }
231 else
232 {
233 {
234 const unsigned int dim = element->dim();
235
236
237 // Get local coordinates to feed these into compute_data().
238 // Note that the fe_type can safely be used from the 0-variable,
239 // since the inverse mapping is the same for all FEFamilies
240 const Point mapped_point (FEMap::inverse_map (dim, element,
241 p));
242
243 // resize the output vector to the number of output values
244 // that the user told us, this include multiple entries for
245 // the spatial components of vector variable
246 unsigned int output_size = 0;
247 for (auto index : index_range(this->_system_vars))
248 {
249 const unsigned int var = _system_vars[index];
250
251 if (var == libMesh::invalid_uint)
252 {
254 index < _out_of_mesh_value.size());
255 output(index) = _out_of_mesh_value(index);
256 continue;
257 }
258
259 const FEType & fe_type = this->_dof_map.variable_type(var);
260
261 // Adding entries for each scalar variable and spatial components of
262 // vector variables
263 switch (fe_type.family)
264 {
265 case HIERARCHIC_VEC:
267 case LAGRANGE_VEC:
268 case L2_LAGRANGE_VEC:
269 case MONOMIAL_VEC:
270 case NEDELEC_ONE:
271 case RAVIART_THOMAS:
273 {
274 output_size = output_size + dim;
275 break;
276 }
277 default:
278 {
279 output_size++;
280 break;
281 }
282 }
283
284 }
285 output.resize(output_size);
286
287 // Adding a counter to keep the output indexing correct for mix scalar-vector output sets
288 unsigned int vec_count = 0;
289
290 // loop over all vars
291 for (auto index : index_range(this->_system_vars))
292 {
293 // the data for this variable
294 const unsigned int var = _system_vars[index];
295
296 if (var == libMesh::invalid_uint)
297 {
299 index < _out_of_mesh_value.size());
300 output(index) = _out_of_mesh_value(index);
301 continue;
302 }
303
304 const FEType & fe_type = this->_dof_map.variable_type(var);
305
306 // The method between vector and scalar variable are different:
307 // For scalar variables, we use the previous established method of using FEInterface::compute_data
308 // For vector variables, we call the phi() data directly to build the variable solution
309 switch (fe_type.family)
310 {
311 case HIERARCHIC_VEC:
313 case LAGRANGE_VEC:
314 case L2_LAGRANGE_VEC:
315 case MONOMIAL_VEC:
316 case NEDELEC_ONE:
317 case RAVIART_THOMAS:
319 {
320 // Calling the physical mesh point needed for the shape function
321 FEComputeData data (this->_eqn_systems, mapped_point);
322 const Point & pt = data.p;
323
324 // where the solution values for the var-th variable are stored
325 std::vector<dof_id_type> dof_indices;
326 this->_dof_map.dof_indices (element, dof_indices, var);
327
328 // Calling the properly-transformed shape function using get_phi()
329 std::unique_ptr<FEVectorBase> vec_fe = FEVectorBase::build(dim, fe_type);
330 std::vector<Point> vec_pt = {pt};
331 const std::vector<std::vector<RealGradient>> & vec_phi = vec_fe->get_phi();
332 vec_fe->reinit(element, &vec_pt);
333
334 // interpolate the solution
335 {
336 for (unsigned int d = 0; d < dim; d++)
337 {
338 Number value = 0.;
339
340 for (auto i : index_range(dof_indices))
341 value += this->_vector(dof_indices[i]) * (vec_phi[i][0](d));
342
343 output(index+vec_count*(dim-1)+d) = value;
344 }
345 }
346
347 vec_count++;
348 break;
349 }
350 default:
351 {
352 // Build an FEComputeData that contains both input and output data
353 // for the specific compute_data method.
354
355 FEComputeData data (this->_eqn_systems, mapped_point);
356
357 FEInterface::compute_data (dim, fe_type, element, data);
358
359 // where the solution values for the var-th variable are stored
360 std::vector<dof_id_type> dof_indices;
361 this->_dof_map.dof_indices (element, dof_indices, var);
362
363 // interpolate the solution
364 {
365 Number value = 0.;
366
367 for (auto i : index_range(dof_indices))
368 value += this->_vector(dof_indices[i]) * data.shape[i];
369
370 output(index+vec_count*(dim-1)) = value;
371 }
372 break;
373 }
374 }
375
376 // next variable
377 }
378 }
379 }
380}
381
383 const Real time,
384 std::map<const Elem *, DenseVector<Number>> & output)
385{
386 this->discontinuous_value (p, time, output, this->_subdomain_ids.get());
387}
388
389
390
392 const Real,
393 std::map<const Elem *, DenseVector<Number>> & output,
394 const std::set<subdomain_id_type> * subdomain_ids)
395{
396 libmesh_assert (this->initialized());
397
398 // clear the output map
399 output.clear();
400
401 // get the candidate elements
402 std::set<const Elem *> candidate_element = this->find_elements(p,subdomain_ids);
403
404 // loop through all candidates, if the set is empty this function will return an
405 // empty map
406 for (const auto & element : candidate_element)
407 {
408 if (!element)
409 {
410 // We'd better be in out_of_mesh_mode if we couldn't find an
411 // element in the mesh
413 output[element] = _out_of_mesh_value;
414 continue;
415 }
416
417 const unsigned int dim = element->dim();
418
419 // define a temporary vector to store all values
420 DenseVector<Number> temp_output (cast_int<unsigned int>(this->_system_vars.size()));
421
422 // Get local coordinates to feed these into compute_data().
423 // Note that the fe_type can safely be used from the 0-variable,
424 // since the inverse mapping is the same for all FEFamilies
425 const Point mapped_point (FEMap::inverse_map (dim, element, p));
426
427 // loop over all vars
428 for (auto index : index_range(this->_system_vars))
429 {
430 // the data for this variable
431 const unsigned int var = _system_vars[index];
432
433 if (var == libMesh::invalid_uint)
434 {
436 index < _out_of_mesh_value.size());
437 temp_output(index) = _out_of_mesh_value(index);
438 continue;
439 }
440
441 const FEType & fe_type = this->_dof_map.variable_type(var);
442
443 // Build an FEComputeData that contains both input and output data
444 // for the specific compute_data method.
445 {
446 FEComputeData data (this->_eqn_systems, mapped_point);
447
448 FEInterface::compute_data (dim, fe_type, element, data);
449
450 // where the solution values for the var-th variable are stored
451 std::vector<dof_id_type> dof_indices;
452 this->_dof_map.dof_indices (element, dof_indices, var);
453
454 // interpolate the solution
455 {
456 Number value = 0.;
457
458 for (auto i : index_range(dof_indices))
459 value += this->_vector(dof_indices[i]) * data.shape[i];
460
461 temp_output(index) = value;
462 }
463
464 }
465
466 // next variable
467 }
468
469 // Insert temp_output into output
470 output[element] = temp_output;
471 }
472}
473
474
475
477 const Real time,
478 std::vector<Gradient> & output)
479{
480 this->gradient(p, time, output, this->_subdomain_ids.get());
481}
482
483
484
486 const Real,
487 std::vector<Gradient> & output,
488 const std::set<subdomain_id_type> * subdomain_ids)
489{
490 libmesh_assert (this->initialized());
491
492 const Elem * element = this->find_element(p,subdomain_ids);
493
494 this->_gradient_on_elem(p, element, output);
495}
496
497
499 const Real time,
500 std::map<const Elem *, std::vector<Gradient>> & output)
501{
502 this->discontinuous_gradient (p, time, output, this->_subdomain_ids.get());
503}
504
505
506
508 const Real,
509 std::map<const Elem *, std::vector<Gradient>> & output,
510 const std::set<subdomain_id_type> * subdomain_ids)
511{
512 libmesh_assert (this->initialized());
513
514 // clear the output map
515 output.clear();
516
517 // get the candidate elements
518 std::set<const Elem *> candidate_element = this->find_elements(p,subdomain_ids);
519
520 // loop through all candidates, if the set is empty this function will return an
521 // empty map
522 for (const auto & element : candidate_element)
523 {
524 // define a temporary vector to store all values
525 std::vector<Gradient> temp_output (cast_int<unsigned int>(this->_system_vars.size()));
526
527 this->_gradient_on_elem(p, element, temp_output);
528
529 // Insert temp_output into output
530 output.emplace(element, std::move(temp_output));
531 }
532}
533
534
535
537 const Elem * element,
538 std::vector<Gradient> & output)
539{
540 // resize the output vector to the number of output values
541 // that the user told us
542 output.resize (this->_system_vars.size());
543
544 if (!element)
545 {
546 libmesh_error_msg_if(!_out_of_mesh_mode,
547 "MeshFunction couldn't find element at p=" <<
548 p << ", but is not in out-of-mesh mode");
549 libmesh_assert_equal_to (_out_of_mesh_value.size(),
550 this->_system_vars.size());
551 for (auto i : index_range(this->_system_vars))
552 output[i] = Gradient(_out_of_mesh_value[i]);
553 return;
554 }
555
556 const unsigned int dim = element->dim();
557
558 // Get local coordinates to feed these into compute_data().
559 // Note that the fe_type can safely be used from the 0-variable,
560 // since the inverse mapping is the same for all FEFamilies
561 const Point mapped_point (FEMap::inverse_map (dim, element,
562 p));
563
564 std::vector<Point> point_list (1, mapped_point);
565
566 // loop over all vars
567 for (auto index : index_range(this->_system_vars))
568 {
569 // the data for this variable
570 const unsigned int var = _system_vars[index];
571
572 if (var == libMesh::invalid_uint)
573 {
575 index < _out_of_mesh_value.size());
576 output[index] = Gradient(_out_of_mesh_value(index));
577 continue;
578 }
579
580 const FEType & fe_type = this->_dof_map.variable_type(var);
581
582 // where the solution values for the var-th variable are stored
583 std::vector<dof_id_type> dof_indices;
584 this->_dof_map.dof_indices (element, dof_indices, var);
585
586 // interpolate the solution
587 Gradient grad(0.);
588
589 // for performance-reasons, we use different algorithms now.
590 // TODO: Check that both give the same result for finite elements.
591 // Otherwive it is wrong...
592 if (!element->infinite())
593 {
594 std::unique_ptr<FEBase> point_fe (FEBase::build(dim, fe_type));
595 const std::vector<std::vector<RealGradient>> & dphi = point_fe->get_dphi();
596 point_fe->reinit(element, &point_list);
597
598 for (auto i : index_range(dof_indices))
599 grad.add_scaled(dphi[i][0], this->_vector(dof_indices[i]));
600
601 }
602#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
603 else
604 {
605 // Build an FEComputeData that contains both input and output data
606 // for the specific compute_data method.
607 //
608 // TODO: enable this for a vector of points as well...
609 FEComputeData data (this->_eqn_systems, mapped_point);
610 data.enable_derivative();
611 FEInterface::compute_data (dim, fe_type, element, data);
612
613 // grad [x] = data.dshape[i](v) * dv/dx * dof_index [i]
614 // sum over all indices
615 for (auto i : index_range(dof_indices))
616 {
617 // local coordinates
618 for (std::size_t v=0; v<dim; v++)
619 for (std::size_t xyz=0; xyz<LIBMESH_DIM; xyz++)
620 {
621 // FIXME: this needs better syntax: It is matrix-vector multiplication.
622 grad(xyz) += data.local_transform[v][xyz]
623 * data.dshape[i](v)
624 * this->_vector(dof_indices[i]);
625 }
626 }
627 }
628#endif
629 output[index] = grad;
630 }
631}
632
633
634#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
636 const Real time,
637 std::vector<Tensor> & output)
638{
639 this->hessian(p, time, output, this->_subdomain_ids.get());
640}
641
642
643
645 const Real,
646 std::vector<Tensor> & output,
647 const std::set<subdomain_id_type> * subdomain_ids)
648{
649 libmesh_assert (this->initialized());
650
651 // resize the output vector to the number of output values
652 // that the user told us
653 output.resize (this->_system_vars.size());
654
655 const Elem * element = this->find_element(p,subdomain_ids);
656
657 if (!element)
658 {
659 libmesh_error_msg_if(!_out_of_mesh_mode,
660 "MeshFunction couldn't find element at p=" <<
661 p << ", but is not in out-of-mesh mode");
662 libmesh_assert_equal_to (_out_of_mesh_value.size(),
663 this->_system_vars.size());
664 for (auto i : index_range(this->_system_vars))
665 output[i] = Tensor(_out_of_mesh_value[i]);
666 return;
667 }
668 else
669 {
670 if(element->infinite())
671 libmesh_warning("Warning: Requested the Hessian of an Infinite element."
672 << "Second derivatives for Infinite elements"
673 << " are not yet implemented!"
674 << std::endl);
675
676 {
677 const unsigned int dim = element->dim();
678
679
680 // Get local coordinates to feed these into compute_data().
681 // Note that the fe_type can safely be used from the 0-variable,
682 // since the inverse mapping is the same for all FEFamilies
683 const Point mapped_point (FEMap::inverse_map (dim, element,
684 p));
685
686 std::vector<Point> point_list (1, mapped_point);
687
688 // loop over all vars
689 for (auto index : index_range(this->_system_vars))
690 {
691 // the data for this variable
692 const unsigned int var = _system_vars[index];
693
694 if (var == libMesh::invalid_uint)
695 {
697 index < _out_of_mesh_value.size());
698 output[index] = Tensor(_out_of_mesh_value(index));
699 continue;
700 }
701 const FEType & fe_type = this->_dof_map.variable_type(var);
702
703 std::unique_ptr<FEBase> point_fe (FEBase::build(dim, fe_type));
704 const std::vector<std::vector<RealTensor>> & d2phi =
705 point_fe->get_d2phi();
706 point_fe->reinit(element, &point_list);
707
708 // where the solution values for the var-th variable are stored
709 std::vector<dof_id_type> dof_indices;
710 this->_dof_map.dof_indices (element, dof_indices, var);
711
712 // interpolate the solution
713 Tensor hess;
714
715 for (auto i : index_range(dof_indices))
716 hess.add_scaled(d2phi[i][0], this->_vector(dof_indices[i]));
717
718 output[index] = hess;
719 }
720 }
721 }
722}
723#endif
724
726 const std::set<subdomain_id_type> * subdomain_ids) const
727{
728 // Ensure that in the case of a master mesh function, the
729 // out-of-mesh mode is enabled either for both or for none. This is
730 // important because the out-of-mesh mode is also communicated to
731 // the point locator. Since this is time consuming, enable it only
732 // in debug mode.
733#ifdef DEBUG
734 if (this->_master != nullptr)
735 {
736 const MeshFunction * master =
737 cast_ptr<const MeshFunction *>(this->_master);
738 libmesh_error_msg_if(_out_of_mesh_mode!=master->_out_of_mesh_mode,
739 "ERROR: If you use out-of-mesh-mode in connection with master mesh "
740 "functions, you must enable out-of-mesh mode for both the master and the slave mesh function.");
741 }
742#endif
743
744 // locate the point in the other mesh
745 const Elem * element = (*_point_locator)(p, subdomain_ids);
746
747 // Make sure that the element found is evaluable
748 return this->check_found_elem(element, p);
749}
750
751std::set<const Elem *> MeshFunction::find_elements(const Point & p,
752 const std::set<subdomain_id_type> * subdomain_ids) const
753{
754 // Ensure that in the case of a master mesh function, the
755 // out-of-mesh mode is enabled either for both or for none. This is
756 // important because the out-of-mesh mode is also communicated to
757 // the point locator. Since this is time consuming, enable it only
758 // in debug mode.
759#ifdef DEBUG
760 if (this->_master != nullptr)
761 {
762 const MeshFunction * master =
763 cast_ptr<const MeshFunction *>(this->_master);
764 libmesh_error_msg_if(_out_of_mesh_mode!=master->_out_of_mesh_mode,
765 "ERROR: If you use out-of-mesh-mode in connection with master mesh "
766 "functions, you must enable out-of-mesh mode for both the master and the slave mesh function.");
767 }
768#endif
769
770 // locate the point in the other mesh
771 std::set<const Elem *> candidate_elements;
772 std::set<const Elem *> final_candidate_elements;
773 (*_point_locator)(p, candidate_elements, subdomain_ids);
774
775 // For each candidate Elem, if it is evaluable, add it to the set of
776 // final candidate Elems.
777 for (const auto & element : candidate_elements)
778 final_candidate_elements.insert(this->check_found_elem(element, p));
779
780 return final_candidate_elements;
781}
782
783const Elem *
784MeshFunction::check_found_elem(const Elem * element, const Point & p) const
785{
786 // If the PointLocator did not find an Element containing Point p,
787 // OR if the PointLocator found a local element containting Point p,
788 // we can simply return it.
789 if (!element || (element->processor_id() == this->processor_id()))
790 return element;
791
792 // Otherwise, the PointLocator returned a valid but non-local
793 // element. Therefore, we have to do some further checks:
794 //
795 // 1.) If we have a SERIAL _vector, then we can just return the
796 // non-local element, because all the DOFs are available.
797 if (_vector.type() == SERIAL)
798 return element;
799
800 // 2.) If we have a GHOSTED _vector, then we can return a non-local
801 // Element provided that all of its DOFs are ghosted on this
802 // processor. That should be faster than the other option, which
803 // is to search through all the Elem's point_neighbors() for a
804 // suitable local Elem.
805 if (_vector.type() == GHOSTED && _dof_map.is_evaluable(*element))
806 return element;
807
808 // 3.) If we have a PARALLEL vector, then we search the non-local
809 // Elem's point neighbors for a local one to return instead. If
810 // we don't eventually find one, we just return nullptr.
811 std::set<const Elem *> point_neighbors;
812 element->find_point_neighbors(p, point_neighbors);
813 element = nullptr;
814 for (const auto & elem : point_neighbors)
815 if (elem->processor_id() == this->processor_id())
816 {
817 element = elem;
818 break;
819 }
820
821 return element;
822}
823
825{
826 libmesh_assert (this->initialized());
827 return *_point_locator;
828}
829
835
837{
838 libmesh_assert (this->initialized());
839 _point_locator->enable_out_of_mesh_mode();
840 _out_of_mesh_mode = true;
842}
843
845{
847 v(0) = value;
849}
850
852{
853 libmesh_assert (this->initialized());
854 _point_locator->disable_out_of_mesh_mode();
855 _out_of_mesh_mode = false;
856}
857
859{
860 _point_locator->set_close_to_point_tol(tol);
861 _point_locator->set_contains_point_tol(tol);
862}
863
865{
866 _point_locator->unset_close_to_point_tol();
867}
868
869void MeshFunction::set_subdomain_ids(const std::set<subdomain_id_type> * subdomain_ids)
870{
871 if (subdomain_ids)
872 _subdomain_ids = std::make_unique<std::set<subdomain_id_type>>(*subdomain_ids);
873 else
874 _subdomain_ids.reset();
875}
876
877} // namespace libMesh
unsigned int dim
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
virtual unsigned int size() const override final
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition dof_map.C:2201
const FEType & variable_type(const unsigned int i) const
Definition dof_map.h:2388
bool is_evaluable(const DofObjectSubclass &obj, unsigned int var_num=libMesh::invalid_uint) const
Definition dof_map.C:2673
processor_id_type processor_id() const
Definition dof_object.h:881
This is the base class from which all geometric element types are derived.
Definition elem.h:96
void find_point_neighbors(const Point &p, std::set< const Elem * > &neighbor_set) const
This function finds all active elements (including this one) which are in the same manifold as this e...
Definition elem.C:967
virtual unsigned short dim() const =0
virtual bool infinite() const =0
This is the EquationSystems class.
const MeshBase & get_mesh() const
class FEComputeData hides arbitrary data to be passed to and from children of FEBase through the FEIn...
const Point & p
Holds the point where the data are to be computed.
std::vector< Gradient > dshape
Storage for the computed shape derivative values.
std::vector< std::vector< Real > > local_transform
Storage for local to global mapping at p.
void enable_derivative()
Enable the computation of shape gradients (dshape).
std::vector< Number > shape
Storage for the computed shape function values.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
static void compute_data(const unsigned int dim, const FEType &fe_t, const Elem *elem, FEComputeData &data)
Lets the appropriate child of FEBase compute the requested data for the input specified in data,...
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
Definition fe_map.C:1512
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
FEFamily family
The type of finite element.
Definition fe_type.h:228
Base class for functors that can be evaluated at a point and (optionally) time.
const FunctionBase * _master
Const pointer to our master, initialized to nullptr.
bool _initialized
When init() was called so that everything is ready for calls to operator() (...), then this bool is t...
This is the MeshBase class.
Definition mesh_base.h:81
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition mesh_base.C:1833
This class provides function-like objects for data distributed over a mesh.
Tensor hessian(const Point &p, const Real time=0.)
MeshFunction(const EquationSystems &eqn_systems, const NumericVector< Number > &vec, const DofMap &dof_map, std::vector< unsigned int > vars, const FunctionBase< Number > *master=nullptr)
Constructor for mesh based functions with vectors as return value.
const EquationSystems & _eqn_systems
The equation systems handler, from which the data are gathered.
std::map< const Elem *, Number > discontinuous_value(const Point &p, const Real time=0.)
std::unique_ptr< PointLocatorBase > _point_locator
A point locator is needed to locate the points in the mesh.
const std::vector< unsigned int > _system_vars
The indices of the variables within the other system for which data are to be gathered.
void set_subdomain_ids(const std::set< subdomain_id_type > *subdomain_ids)
Choose a default list of subdomain ids to be searched for points.
std::set< const Elem * > find_elements(const Point &p, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
virtual void init() override
Override the FunctionBase::init() member function.
std::unique_ptr< std::set< subdomain_id_type > > _subdomain_ids
A default set of subdomain ids in which to search for points.
~MeshFunction()
Destructor.
void set_point_locator_tolerance(Real tol)
We may want to specify a tolerance for the PointLocator to use, since in some cases the point we want...
void _gradient_on_elem(const Point &p, const Elem *element, std::vector< Gradient > &output)
Helper function for finding a gradient as evaluated from a specific element.
bool _out_of_mesh_mode
true if out-of-mesh mode is enabled.
void disable_out_of_mesh_mode()
Disables out-of-mesh mode.
virtual void clear() override
Clears the function.
DenseVector< Number > _out_of_mesh_value
Value to return outside the mesh if out-of-mesh mode is enabled.
Gradient gradient(const Point &p, const Real time=0.)
const NumericVector< Number > & _vector
A reference to the vector that holds the data that is to be interpolated.
const PointLocatorBase & get_point_locator() const
virtual std::unique_ptr< FunctionBase< Number > > clone() const override
const Elem * find_element(const Point &p, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Helper function to reduce code duplication.
void enable_out_of_mesh_mode(const DenseVector< Number > &value)
Enables out-of-mesh mode.
void unset_point_locator_tolerance()
Turn off the user-specified PointLocator tolerance.
const DofMap & _dof_map
Need access to the DofMap of the other system.
std::map< const Elem *, Gradient > discontinuous_gradient(const Point &p, const Real time=0.)
virtual Number operator()(const Point &p, const Real time=0.) override
const Elem * check_found_elem(const Elem *element, const Point &p) const
Helper function that is called by MeshFunction::find_element() and MeshFunction::find_elements() to e...
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
ParallelType type() const
An object whose state is distributed along a set of processors.
processor_id_type processor_id() const
This is the base class for point locators.
Real get_close_to_point_tol() const
Get the close-to-point tolerance.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
void add_scaled(const TypeTensor< T2 > &, const T &)
Add a scaled tensor to this tensor without creating a temporary.
void add_scaled(const TypeVector< T2 > &, const T &)
Add a scaled value to this vector without creating a temporary.
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
MeshBase & mesh
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
NumberVectorValue Gradient
libmesh_assert(ctx)
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition libmesh.h:303
NumberTensorValue Tensor
@ L2_RAVIART_THOMAS
@ L2_HIERARCHIC_VEC
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const bool value
Definition xdr_io.C:55