Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "MeshCut2DNucleationBase.h" 11 : #include "XFEMAppTypes.h" 12 : #include "XFEM.h" 13 : 14 : #include "MooseMesh.h" 15 : 16 : #include "libmesh/parallel_algebra.h" 17 : #include "libmesh/parallel.h" 18 : 19 : InputParameters 20 34 : MeshCut2DNucleationBase::validParams() 21 : { 22 34 : InputParameters params = ElementUserObject::validParams(); 23 68 : params.addParam<std::vector<BoundaryName>>( 24 : "initiate_on_boundary", 25 : "Cracks can only initiate on elements adjacent to specified boundaries."); 26 68 : params.addParam<Real>("nucleation_radius", 27 68 : 0, 28 : "Cracks will only nucleate if they are outside the nucleation_radius of an " 29 : "existing crack."); 30 : // Make this userobject execute before every other standard UO including meshCutterUO 31 68 : params.setDocString( 32 : "execution_order_group", 33 : "Nucleation UO needs to be completely executed before GeometricCutUserObject."); 34 34 : params.set<int>("execution_order_group") = -1; 35 : 36 34 : ExecFlagEnum & exec = params.set<ExecFlagEnum>("execute_on"); 37 34 : exec.addAvailableFlags(EXEC_XFEM_MARK); 38 68 : params.setDocString("execute_on", exec.getDocString()); 39 34 : params.set<ExecFlagEnum>("execute_on") = EXEC_XFEM_MARK; 40 34 : return params; 41 0 : } 42 : 43 17 : MeshCut2DNucleationBase::MeshCut2DNucleationBase(const InputParameters & parameters) 44 : : ElementUserObject(parameters), 45 34 : _mesh(_subproblem.mesh()), 46 34 : _nucleation_radius(getParam<Real>("nucleation_radius")) 47 : { 48 17 : FEProblemBase * fe_problem = dynamic_cast<FEProblemBase *>(&_subproblem); 49 17 : if (fe_problem == NULL) 50 0 : paramError("Problem casting _subproblem to FEProblemBase in MeshCut2DNucleationBase"); 51 34 : _xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(fe_problem->getXFEM()); 52 17 : if (_xfem == nullptr) 53 0 : paramError("Problem casting to XFEM in MeshCut2DNucleationBase"); 54 : 55 34 : if (isParamValid("initiate_on_boundary")) 56 : { 57 : std::vector<BoundaryName> initiation_boundary_names = 58 8 : getParam<std::vector<BoundaryName>>("initiate_on_boundary"); 59 4 : _initiation_boundary_ids = _mesh.getBoundaryIDs(initiation_boundary_names); 60 4 : } 61 17 : } 62 : 63 : void 64 181 : MeshCut2DNucleationBase::initialize() 65 : { 66 : _nucleated_elems.clear(); 67 181 : } 68 : 69 : void 70 56652 : MeshCut2DNucleationBase::execute() 71 : { 72 : std::pair<RealVectorValue, RealVectorValue> cutterElemNodes; 73 56652 : bool is_cut = _xfem->isElemCut(_current_elem); 74 56652 : if (_current_elem->processor_id() != processor_id()) 75 0 : return; 76 : 77 56652 : unsigned int current_eid = _current_elem->id(); 78 : std::map<unsigned int, std::pair<RealVectorValue, RealVectorValue>>::iterator mit; 79 : mit = _nucleated_elems.find(current_eid); 80 : 81 : bool cut_element = false; 82 56652 : if (_initiation_boundary_ids.empty()) 83 : { 84 : // nucleating crack in bulk 85 : // This does not currently allow for nucleation in an element that is already cut 86 51198 : cut_element = (!is_cut && doesElementCrack(cutterElemNodes)); 87 : } 88 : else 89 : { 90 : // nucleating crack on specified boundary 91 : bool isOnBoundary = false; 92 10314 : for (unsigned int i = 0; i < _initiation_boundary_ids.size(); ++i) 93 5454 : if (_mesh.isBoundaryElem(current_eid, _initiation_boundary_ids[i])) 94 : { 95 : isOnBoundary = true; 96 : break; 97 : } 98 : // This does not currently allow for nucleation in an element that is already cut 99 5454 : cut_element = (!is_cut && isOnBoundary && doesElementCrack(cutterElemNodes)); 100 : } 101 : 102 : if (cut_element) 103 : { 104 748 : if (mit != _nucleated_elems.end()) 105 0 : mooseError("ERROR: element ", current_eid, " already marked for crack nucleation."); 106 : 107 748 : _nucleated_elems[current_eid] = cutterElemNodes; 108 : } 109 : } 110 : 111 : void 112 0 : MeshCut2DNucleationBase::threadJoin(const UserObject & y) 113 : { 114 : const auto & xmuo = static_cast<const MeshCut2DNucleationBase &>(y); 115 0 : for (std::map<unsigned int, std::pair<RealVectorValue, RealVectorValue>>::const_iterator mit = 116 : xmuo._nucleated_elems.begin(); 117 0 : mit != xmuo._nucleated_elems.end(); 118 : ++mit) 119 : { 120 0 : _nucleated_elems[mit->first] = mit->second; // TODO do error checking for duplicates here too 121 : } 122 0 : } 123 : 124 : void 125 180 : MeshCut2DNucleationBase::finalize() 126 : { 127 180 : _communicator.set_union(_nucleated_elems); 128 : // _nucleated_elems is not cleared here because it needs to be available to the mesh cutter 129 180 : }