void MaterialPropertyStorage::initProps(MaterialData & material_data, const Elem & elem, unsigned int side, unsigned int n_qpoints) { material_data.resize(n_qpoints); auto n = _stateful_prop_id_to_prop_id.size(); if (props(&elem, side).size() < n) props(&elem, side).resize(n, nullptr); if (propsOld(&elem, side).size() < n) propsOld(&elem, side).resize(n, nullptr); if (propsOlder(&elem, side).size() < n) propsOlder(&elem, side).resize(n, nullptr); // init properties (allocate memory. etc) for (unsigned int i = 0; i < n; i++) { auto prop_id = _stateful_prop_id_to_prop_id[i]; // duplicate the stateful property in property storage (all three states - we will reuse the // allocated memory there) // also allocating the right amount of memory, so we do not have to resize, etc. if (props(&elem, side)[i] == nullptr) props(&elem, side)[i] = material_data.props()[prop_id]->init(n_qpoints); if (propsOld(&elem, side)[i] == nullptr) propsOld(&elem, side)[i] = material_data.propsOld()[prop_id]->init(n_qpoints); if (hasOlderProperties() && propsOlder(&elem, side)[i] == nullptr) propsOlder(&elem, side)[i] = material_data.propsOlder()[prop_id]->init(n_qpoints); } }
void MaterialPropertyStorage::restrictStatefulProps( const std::vector<std::pair<unsigned int, QpMap>> & coarsening_map, const std::vector<const Elem *> & coarsened_element_children, QBase & qrule, QBase & qrule_face, MaterialData & material_data, const Elem & elem, int input_side) { unsigned int side; bool doing_a_side = input_side != -1; unsigned int n_qpoints = 0; if (!doing_a_side) { side = 0; // Use 0 for the elem n_qpoints = qrule.n_points(); } else { side = input_side; n_qpoints = qrule_face.n_points(); } initProps(material_data, elem, side, n_qpoints); // Copy from the child stateful properties for (unsigned int qp = 0; qp < coarsening_map.size(); qp++) { const std::pair<unsigned int, QpMap> & qp_pair = coarsening_map[qp]; unsigned int child = qp_pair.first; mooseAssert(child < coarsened_element_children.size(), "Coarsened element children vector not initialized"); const Elem * child_elem = coarsened_element_children[child]; const QpMap & qp_map = qp_pair.second; for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i) { mooseAssert(props().contains(child_elem), "Child element pointer is not in the MaterialProps data structure"); PropertyValue * child_property = props(child_elem, side)[i]; PropertyValue * parent_property = props(&elem, side)[i]; parent_property->qpCopy(qp, child_property, qp_map._to); propsOld(&elem, side)[i]->qpCopy(qp, propsOld(child_elem, side)[i], qp_map._to); if (hasOlderProperties()) propsOlder(&elem, side)[i]->qpCopy(qp, propsOlder(child_elem, side)[i], qp_map._to); } } }
void MaterialPropertyStorage::swapBack(MaterialData & material_data, const Elem & elem, unsigned int side) { Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); shallowCopyDataBack(_stateful_prop_id_to_prop_id, props()[&elem][side], material_data.props()); shallowCopyDataBack(_stateful_prop_id_to_prop_id, propsOld()[&elem][side], material_data.propsOld()); if (hasOlderProperties()) shallowCopyDataBack(_stateful_prop_id_to_prop_id, propsOlder()[&elem][side], material_data.propsOlder()); }
void MaterialPropertyStorage::copy(MaterialData & material_data, const Elem & elem_to, const Elem & elem_from, unsigned int side, unsigned int n_qpoints) { initProps(material_data, elem_to, side, n_qpoints); for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i) { for (unsigned int qp = 0; qp < n_qpoints; ++qp) { props(&elem_to, side)[i]->qpCopy(qp, props(&elem_from, side)[i], qp); propsOld(&elem_to, side)[i]->qpCopy(qp, propsOld(&elem_from, side)[i], qp); if (hasOlderProperties()) propsOlder(&elem_to, side)[i]->qpCopy(qp, propsOlder(&elem_from, side)[i], qp); } } }
void MaterialPropertyStorage::copy(MaterialData & material_data, const Elem & elem_to, const Elem & elem_from, unsigned int side, unsigned int n_qpoints) { // WARNING: This is not capable of copying material data to/from elements on other processors. // It only works if both elem_to and elem_from are both on the local processor. // We can't currently check to ensure that they're on processor here because this isn't a ParallelObject. if (props()[&elem_to][side].size() == 0) props()[&elem_to][side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOld()[&elem_to][side].size() == 0) propsOld()[&elem_to][side].resize(_stateful_prop_id_to_prop_id.size()); if (hasOlderProperties()) if (propsOlder()[&elem_to][side].size() == 0) propsOlder()[&elem_to][side].resize(_stateful_prop_id_to_prop_id.size()); // init properties (allocate memory. etc) for (unsigned int i=0; i < _stateful_prop_id_to_prop_id.size(); ++i) { // duplicate the stateful property in property storage (all three states - we will reuse the allocated memory there) // also allocating the right amount of memory, so we do not have to resize, etc. if (props()[&elem_to][side][i] == NULL) props()[&elem_to][side][i] = material_data.props()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (propsOld()[&elem_to][side][i] == NULL) propsOld()[&elem_to][side][i] = material_data.propsOld()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (hasOlderProperties()) if (propsOlder()[&elem_to][side][i] == NULL) propsOlder()[&elem_to][side][i] = material_data.propsOlder()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); for (unsigned int qp=0; qp<n_qpoints; ++qp) { props()[&elem_to][side][i]->qpCopy(qp, props()[&elem_from][side][i], qp); propsOld()[&elem_to][side][i]->qpCopy(qp, propsOld()[&elem_from][side][i], qp); if (hasOlderProperties()) propsOlder()[&elem_to][side][i]->qpCopy(qp, propsOlder()[&elem_from][side][i], qp); } } }
void MaterialPropertyStorage::initStatefulProps(MaterialData & material_data, const std::vector<MooseSharedPointer<Material> > & mats, unsigned int n_qpoints, const Elem & elem, unsigned int side/* = 0*/) { // NOTE: since materials are storing their computed properties in MaterialData class, we need to // juggle the memory between MaterialData and MaterialProperyStorage classes material_data.size(n_qpoints); if (props()[&elem][side].size() == 0) props()[&elem][side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOld()[&elem][side].size() == 0) propsOld()[&elem][side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOlder()[&elem][side].size() == 0) propsOlder()[&elem][side].resize(_stateful_prop_id_to_prop_id.size()); // init properties (allocate memory. etc) for (unsigned int i=0; i < _stateful_prop_id_to_prop_id.size(); ++i) { // duplicate the stateful property in property storage (all three states - we will reuse the allocated memory there) // also allocating the right amount of memory, so we do not have to resize, etc. if (props()[&elem][side][i] == NULL) props()[&elem][side][i] = material_data.props()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (propsOld()[&elem][side][i] == NULL) propsOld()[&elem][side][i] = material_data.propsOld()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (hasOlderProperties()) if (propsOlder()[&elem][side][i] == NULL) propsOlder()[&elem][side][i] = material_data.propsOlder()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); } // copy from storage to material data swap(material_data, elem, side); // run custom init on properties for (const auto & mat : mats) mat->initStatefulProperties(n_qpoints); swapBack(material_data, elem, side); // Copy the properties to Old and Older as needed if (hasStatefulProperties()) for (unsigned int i=0; i < _stateful_prop_id_to_prop_id.size(); ++i) for (unsigned int qp=0; qp < n_qpoints; ++qp) { propsOld()[&elem][side][i]->qpCopy(qp, props()[&elem][side][i], qp); if (hasOlderProperties()) propsOlder()[&elem][side][i]->qpCopy(qp, props()[&elem][side][i], qp); } }
void MaterialPropertyStorage::initStatefulProps(MaterialData & material_data, const std::vector<std::shared_ptr<Material>> & mats, unsigned int n_qpoints, const Elem & elem, unsigned int side /* = 0*/) { // NOTE: since materials are storing their computed properties in MaterialData class, we need to // juggle the memory between MaterialData and MaterialProperyStorage classes initProps(material_data, elem, side, n_qpoints); // copy from storage to material data swap(material_data, elem, side); // run custom init on properties for (const auto & mat : mats) mat->initStatefulProperties(n_qpoints); swapBack(material_data, elem, side); if (!hasStatefulProperties()) return; // This second call to initProps covers cases where code in // "init[Qp]StatefulProperties" may have called a get/declare for a stateful // property affecting the _stateful_prop_id_to_prop_id vector among other // things. This is necessary because a call to // getMaterialProperty[Old/Older] can potentially trigger a material to // become stateful that previously wasn't. This needs to go after the // swapBack. initProps(material_data, elem, side, n_qpoints); // Copy the properties to Old and Older as needed for (unsigned int i = 0; i < _stateful_prop_id_to_prop_id.size(); ++i) { auto curr = props(&elem, side)[i]; auto old = propsOld(&elem, side)[i]; auto older = propsOlder(&elem, side)[i]; for (unsigned int qp = 0; qp < n_qpoints; ++qp) { old->qpCopy(qp, curr, qp); if (hasOlderProperties()) older->qpCopy(qp, curr, qp); } } }
void MaterialPropertyStorage::prolongStatefulProps(const std::vector<std::vector<QpMap> > & refinement_map, QBase & qrule, QBase & qrule_face, MaterialPropertyStorage & parent_material_props, MaterialData & child_material_data, const Elem & elem, const int input_parent_side, const int input_child, const int input_child_side) { mooseAssert(input_child != -1 || input_parent_side == input_child_side, "Invalid inputs!"); unsigned int n_qpoints = 0; // If we passed in -1 for these then we really need to store properties at 0 unsigned int parent_side = input_parent_side == -1 ? 0 : input_parent_side; unsigned int child_side = input_child_side == -1 ? 0 : input_child_side; if (input_child_side == -1) // Not doing side projection (ie, doing volume projection) n_qpoints = qrule.n_points(); else n_qpoints = qrule_face.n_points(); child_material_data.size(n_qpoints); unsigned int n_children = elem.n_children(); std::vector<unsigned int> children; if (input_child != -1) // Passed in a child explicitly children.push_back(input_child); else { children.resize(n_children); for (unsigned int child=0; child < n_children; child++) children[child] = child; } for (const auto & child : children) { // If we're not projecting an internal child side, but we are projecting sides, see if this child is on that side if (input_child == -1 && input_child_side != -1 && !elem.is_child_on_side(child, parent_side)) continue; const Elem * child_elem = elem.child(child); mooseAssert(child < refinement_map.size(), "Refinement_map vector not initialized"); const std::vector<QpMap> & child_map = refinement_map[child]; if (props()[child_elem][child_side].size() == 0) props()[child_elem][child_side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOld()[child_elem][child_side].size() == 0) propsOld()[child_elem][child_side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOlder()[child_elem][child_side].size() == 0) propsOlder()[child_elem][child_side].resize(_stateful_prop_id_to_prop_id.size()); // init properties (allocate memory. etc) for (unsigned int i=0; i < _stateful_prop_id_to_prop_id.size(); ++i) { // duplicate the stateful property in property storage (all three states - we will reuse the allocated memory there) // also allocating the right amount of memory, so we do not have to resize, etc. if (props()[child_elem][child_side][i] == NULL) props()[child_elem][child_side][i] = child_material_data.props()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (propsOld()[child_elem][child_side][i] == NULL) propsOld()[child_elem][child_side][i] = child_material_data.propsOld()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (hasOlderProperties()) if (propsOlder()[child_elem][child_side][i] == NULL) propsOlder()[child_elem][child_side][i] = child_material_data.propsOlder()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); // Copy from the parent stateful properties for (unsigned int qp=0; qp<refinement_map[child].size(); qp++) { PropertyValue * child_property = props()[child_elem][child_side][i]; mooseAssert(props().contains(&elem), "Parent pointer is not in the MaterialProps data structure"); PropertyValue * parent_property = parent_material_props.props()[&elem][parent_side][i]; child_property->qpCopy(qp, parent_property, child_map[qp]._to); propsOld()[child_elem][child_side][i]->qpCopy(qp, parent_material_props.propsOld()[&elem][parent_side][i], child_map[qp]._to); if (hasOlderProperties()) propsOlder()[child_elem][child_side][i]->qpCopy(qp, parent_material_props.propsOlder()[&elem][parent_side][i], child_map[qp]._to); } } } }
void MaterialPropertyStorage::restrictStatefulProps(const std::vector<std::pair<unsigned int, QpMap> > & coarsening_map, std::vector<const Elem *> & coarsened_element_children, QBase & qrule, QBase & qrule_face, MaterialData & material_data, const Elem & elem, int input_side) { unsigned int side; bool doing_a_side = input_side != -1; unsigned int n_qpoints = 0; if (!doing_a_side) { side = 0; // Use 0 for the elem n_qpoints = qrule.n_points(); } else { side = input_side; n_qpoints = qrule_face.n_points(); } material_data.size(n_qpoints); // First, make sure that storage has been set aside for this element. //initStatefulProps(material_data, mats, n_qpoints, elem, side); if (props()[&elem][side].size() == 0) props()[&elem][side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOld()[&elem][side].size() == 0) propsOld()[&elem][side].resize(_stateful_prop_id_to_prop_id.size()); if (propsOlder()[&elem][side].size() == 0) propsOlder()[&elem][side].resize(_stateful_prop_id_to_prop_id.size()); // init properties (allocate memory. etc) for (unsigned int i=0; i < _stateful_prop_id_to_prop_id.size(); ++i) { // duplicate the stateful property in property storage (all three states - we will reuse the allocated memory there) // also allocating the right amount of memory, so we do not have to resize, etc. if (props()[&elem][side][i] == NULL) props()[&elem][side][i] = material_data.props()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (propsOld()[&elem][side][i] == NULL) propsOld()[&elem][side][i] = material_data.propsOld()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); if (hasOlderProperties()) if (propsOlder()[&elem][side][i] == NULL) propsOlder()[&elem][side][i] = material_data.propsOlder()[ _stateful_prop_id_to_prop_id[i] ]->init(n_qpoints); } // Copy from the child stateful properties for (unsigned int qp=0; qp<coarsening_map.size(); qp++) { const std::pair<unsigned int, QpMap> & qp_pair = coarsening_map[qp]; unsigned int child = qp_pair.first; mooseAssert(child < coarsened_element_children.size(), "Coarsened element children vector not initialized"); const Elem * child_elem = coarsened_element_children[child]; const QpMap & qp_map = qp_pair.second; for (unsigned int i=0; i < _stateful_prop_id_to_prop_id.size(); ++i) { mooseAssert(props().contains(child_elem), "Child element pointer is not in the MaterialProps data structure"); PropertyValue * child_property = props()[child_elem][side][i]; PropertyValue * parent_property = props()[&elem][side][i]; parent_property->qpCopy(qp, child_property, qp_map._to); propsOld()[&elem][side][i]->qpCopy(qp, propsOld()[child_elem][side][i], qp_map._to); if (hasOlderProperties()) propsOlder()[&elem][side][i]->qpCopy(qp, propsOlder()[child_elem][side][i], qp_map._to); } } }