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 "XFEMMaterialStateMarkerBase.h" 11 : 12 : #include "XFEM.h" 13 : #include "MooseMesh.h" 14 : 15 : #include "libmesh/parallel_algebra.h" 16 : #include "libmesh/parallel.h" 17 : 18 : InputParameters 19 18 : XFEMMaterialStateMarkerBase::validParams() 20 : { 21 18 : InputParameters params = ElementUserObject::validParams(); 22 36 : params.addParam<std::vector<BoundaryName>>( 23 : "initiate_on_boundary", 24 : "Permit cracks to initiate in elements adjacent to specified boundaries"); 25 36 : params.addParam<bool>("secondary_cracks", false, "should secondary cracks be allowed"); 26 18 : return params; 27 0 : } 28 : 29 9 : XFEMMaterialStateMarkerBase::XFEMMaterialStateMarkerBase(const InputParameters & parameters) 30 : : ElementUserObject(parameters), 31 9 : _mesh(_subproblem.mesh()), 32 18 : _secondary_cracks(getParam<bool>("secondary_cracks")) 33 : { 34 9 : FEProblemBase * fe_problem = dynamic_cast<FEProblemBase *>(&_subproblem); 35 9 : if (fe_problem == nullptr) 36 0 : mooseError("Problem casting _subproblem to FEProblemBase in XFEMMaterialStateMarkerBase"); 37 18 : _xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(fe_problem->getXFEM()); 38 9 : if (_xfem == nullptr) 39 0 : mooseError("Problem casting to XFEM in XFEMMaterialStateMarkerBase"); 40 9 : if (isNodal()) 41 0 : mooseError("XFEMMaterialStateMarkerBase can only be run on an element variable"); 42 : 43 18 : if (isParamValid("initiate_on_boundary")) 44 : { 45 : std::vector<BoundaryName> initiation_boundary_names = 46 0 : getParam<std::vector<BoundaryName>>("initiate_on_boundary"); 47 0 : _initiation_boundary_ids = _mesh.getBoundaryIDs(initiation_boundary_names, true); 48 0 : } 49 9 : } 50 : 51 : void 52 18 : XFEMMaterialStateMarkerBase::initialize() 53 : { 54 : _marked_elems.clear(); 55 : _marked_frags 56 : .clear(); // mark the fragment which has secondary crack growing from the primary crack 57 : _marked_elem_sides.clear(); 58 18 : } 59 : 60 : void 61 1500 : XFEMMaterialStateMarkerBase::execute() 62 : { 63 : RealVectorValue direction; 64 1500 : bool isCut = _xfem->isElemCut(_current_elem); 65 1500 : bool isCTE = _xfem->isElemAtCrackTip(_current_elem); 66 : bool isOnBoundary = false; 67 : unsigned int boundarySide = 99999; 68 1500 : unsigned int _current_eid = _current_elem->id(); 69 : std::map<unsigned int, RealVectorValue>::iterator mit; 70 : mit = _marked_elems.find(_current_eid); 71 : 72 1500 : for (unsigned int i = 0; i < _initiation_boundary_ids.size(); ++i) 73 : { 74 0 : if (_mesh.isBoundaryElem(_current_eid, _initiation_boundary_ids[i])) 75 : { 76 : isOnBoundary = true; 77 0 : boundarySide = _mesh.sideWithBoundaryID(_current_elem, _initiation_boundary_ids[i]); 78 : } 79 : } 80 : 81 1500 : if (isCTE && doesElementCrack(direction)) 82 : { 83 12 : if (mit != _marked_elems.end()) 84 : { 85 0 : mooseError("ERROR: element ", _current_eid, " already marked for crack growth."); 86 : } 87 12 : _marked_elems[_current_eid] = direction; 88 : } 89 1488 : else if (isOnBoundary && doesElementCrack(direction)) 90 : { 91 0 : if (mit != _marked_elems.end()) 92 : { 93 0 : mooseError("ERROR: element ", _current_eid, " already marked for crack growth."); 94 : } 95 0 : _marked_elems[_current_eid] = direction; 96 0 : _marked_elem_sides[_current_eid] = boundarySide; 97 : } 98 1488 : else if (isCut && _secondary_cracks && doesElementCrack(direction)) 99 : { 100 0 : if (mit != _marked_elems.end()) 101 : { 102 0 : mooseError("ERROR: element ", _current_eid, " already marked for crack growth."); 103 : } 104 0 : _marked_elems[_current_eid] = direction; 105 0 : _marked_frags.insert(_current_eid); 106 : } 107 1500 : } 108 : 109 : void 110 0 : XFEMMaterialStateMarkerBase::threadJoin(const UserObject & y) 111 : { 112 0 : const auto & xmuo = dynamic_cast<const XFEMMaterialStateMarkerBase &>(y); 113 : 114 0 : for (std::map<unsigned int, RealVectorValue>::const_iterator mit = xmuo._marked_elems.begin(); 115 0 : mit != xmuo._marked_elems.end(); 116 : ++mit) 117 : { 118 0 : _marked_elems[mit->first] = mit->second; // TODO do error checking for duplicates here too 119 : } 120 : 121 0 : for (std::set<unsigned int>::const_iterator mit = xmuo._marked_frags.begin(); 122 0 : mit != xmuo._marked_frags.end(); 123 : ++mit) 124 : { 125 0 : _marked_frags.insert(*mit); // TODO do error checking for duplicates here too 126 : } 127 : 128 0 : for (std::map<unsigned int, unsigned int>::const_iterator mit = xmuo._marked_elem_sides.begin(); 129 0 : mit != xmuo._marked_elem_sides.end(); 130 : ++mit) 131 : { 132 0 : _marked_elem_sides[mit->first] = mit->second; // TODO do error checking for duplicates here too 133 : } 134 0 : } 135 : 136 : void 137 18 : XFEMMaterialStateMarkerBase::finalize() 138 : { 139 18 : _communicator.set_union(_marked_elems); 140 18 : _communicator.set_union(_marked_frags); 141 18 : _communicator.set_union(_marked_elem_sides); 142 : 143 18 : _xfem->clearStateMarkedElems(); 144 : std::map<unsigned int, RealVectorValue>::iterator mit; 145 36 : for (mit = _marked_elems.begin(); mit != _marked_elems.end(); ++mit) 146 : { 147 18 : if (_marked_elem_sides.find(mit->first) != _marked_elem_sides.end()) 148 : { 149 0 : _xfem->addStateMarkedElem(mit->first, mit->second, _marked_elem_sides[mit->first]); 150 : } 151 18 : else if (_marked_frags.find(mit->first) != _marked_frags.end()) 152 : { 153 0 : _xfem->addStateMarkedFrag(mit->first, mit->second); 154 : } 155 : else 156 : { 157 18 : _xfem->addStateMarkedElem(mit->first, mit->second); 158 : } 159 : } 160 : _marked_elems.clear(); 161 : _marked_frags.clear(); 162 : _marked_elem_sides.clear(); 163 18 : } 164 : 165 : bool 166 0 : XFEMMaterialStateMarkerBase::doesElementCrack(RealVectorValue & direction) 167 : { 168 0 : direction(1) = 1.0; 169 0 : return true; 170 : }