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 "DomainUserObject.h" 11 : #include "MooseVariableFE.h" 12 : #include "SubProblem.h" 13 : #include "Assembly.h" 14 : 15 : InputParameters 16 43433 : DomainUserObject::validParams() 17 : { 18 43433 : InputParameters params = UserObject::validParams(); 19 43433 : params += BlockRestrictable::validParams(); 20 43433 : params += ThreeMaterialPropertyInterface::validParams(); 21 43433 : params += TransientInterface::validParams(); 22 43433 : params += RandomInterface::validParams(); 23 43433 : params.addParam<std::vector<BoundaryName>>( 24 : "interface_boundaries", "The interface boundaries on which this object will execute"); 25 : // Need one layer of ghosting 26 43433 : params.addRelationshipManager("ElementSideNeighborLayers", 27 : Moose::RelationshipManagerType::GEOMETRIC | 28 : Moose::RelationshipManagerType::ALGEBRAIC); 29 43433 : return params; 30 0 : } 31 : 32 334 : DomainUserObject::DomainUserObject(const InputParameters & parameters) 33 : : UserObject(parameters), 34 : BlockRestrictable(this), 35 : ThreeMaterialPropertyInterface(this, blockIDs(), Moose::EMPTY_BOUNDARY_IDS), 36 : NeighborCoupleableMooseVariableDependencyIntermediateInterface(this, false, false), 37 : TransientInterface(this), 38 334 : RandomInterface(parameters, _fe_problem, _tid, false), 39 : ElementIDInterface(this), 40 668 : _mesh(_subproblem.mesh()), 41 334 : _current_elem(_assembly.elem()), 42 334 : _current_elem_volume(_assembly.elemVolume()), 43 334 : _current_side(_assembly.side()), 44 334 : _current_side_elem(_assembly.sideElem()), 45 334 : _current_side_volume(_assembly.sideElemVolume()), 46 334 : _neighbor_elem(_assembly.neighbor()), 47 334 : _current_neighbor_volume(_assembly.neighborVolume()), 48 334 : _current_boundary_id(_assembly.currentBoundaryID()), 49 334 : _normals(_assembly.normals()), 50 334 : _q_point(_assembly.qPoints()), 51 334 : _qrule(_assembly.qRule()), 52 334 : _JxW(_assembly.JxW()), 53 334 : _q_point_face(_assembly.qPointsFace()), 54 334 : _qrule_face(_assembly.qRuleFace()), 55 334 : _JxW_face(_assembly.JxWFace()), 56 1002 : _coord(_assembly.coordTransformation()) 57 : { 58 334 : if (isParamValid("interface_boundaries")) 59 : { 60 187 : const auto & interface_boundaries = getParam<std::vector<BoundaryName>>("interface_boundaries"); 61 187 : _interface_bnd_ids = MooseMeshUtils::getBoundaryIDSet(_mesh, interface_boundaries, false); 62 : 63 374 : for (const auto interface_bnd_id : _interface_bnd_ids) 64 : { 65 : // check on which side the interface is connected with the subdomain of this domain user 66 : // object 67 187 : const auto & primary_connected_blocks = _mesh.getBoundaryConnectedBlocks(interface_bnd_id); 68 187 : bool has_full_primary_connection = true; 69 374 : for (const auto interface_connected_block : primary_connected_blocks) 70 187 : if (!hasBlocks(interface_connected_block)) 71 0 : has_full_primary_connection = false; 72 : 73 : const auto & secondary_connected_blocks = 74 187 : _mesh.getBoundaryConnectedSecondaryBlocks(interface_bnd_id); 75 187 : bool has_full_secondary_connection = true; 76 374 : for (const auto interface_connected_block : secondary_connected_blocks) 77 187 : if (!hasBlocks(interface_connected_block)) 78 100 : has_full_secondary_connection = false; 79 : 80 : // we push the subdomains on the other side for the interface 81 187 : if (has_full_primary_connection) 82 187 : _interface_connected_blocks[interface_bnd_id] = secondary_connected_blocks; 83 0 : else if (has_full_secondary_connection) 84 0 : _interface_connected_blocks[interface_bnd_id] = primary_connected_blocks; 85 : else 86 0 : paramError("interface_boundaries", 87 : "Not all sides in the interface with ID ", 88 : interface_bnd_id, 89 : " is connected with the domain of the domain user object ", 90 0 : name()); 91 187 : } 92 : } 93 334 : } 94 : 95 : const MooseVariableFieldBase * 96 187 : DomainUserObject::getInterfaceFieldVar(const std::string & var_name, 97 : const unsigned int comp, 98 : const std::set<BoundaryID> * interfaces) 99 : { 100 187 : const auto * const field_var = getFieldVar(var_name, comp); 101 : mooseAssert(field_var, "We should not be able to return a null variable"); 102 187 : if (interfaces) 103 0 : _var_interfaces[field_var->name()] = *interfaces; 104 : else 105 187 : _var_interfaces[field_var->name()] = _interface_bnd_ids; 106 187 : return field_var; 107 : } 108 : 109 : void 110 1161 : DomainUserObject::checkVariable(const MooseVariableFieldBase & variable) const 111 : { 112 1161 : auto it = _var_interfaces.find(variable.name()); 113 1161 : if (it != _var_interfaces.end()) 114 : { 115 : // we could have done this check in the constructor but to be consistent with other block 116 : // restrictable checks, we'll do it here 117 561 : auto & bnd_ids = it->second; 118 1122 : for (const auto bnd_id : bnd_ids) 119 : { 120 561 : const auto & connected_blocks = libmesh_map_find(_interface_connected_blocks, bnd_id); 121 1122 : for (const auto & bid : connected_blocks) 122 561 : if (!variable.hasBlocks(bid)) 123 0 : mooseError("Variable '", 124 0 : variable.name(), 125 : "' is not defined on the interface connected block '", 126 0 : _mesh.getSubdomainName(bid), 127 : "'"); 128 : } 129 : } 130 : else 131 600 : BlockRestrictable::checkVariable(variable); 132 1161 : }