inline SweptElementData::VertexDataRef::VertexDataRef(const HomCoord &this_min, const HomCoord &this_max, const HomXform &tmp_xform, SweptVertexData *this_seq) : xform(tmp_xform), invXform(tmp_xform.inverse()), srcSeq(this_seq) { minmax[0] = HomCoord(this_min); minmax[1] = HomCoord(this_max); }
ScdElementData::ScdElementData( EntityHandle shandle, const int imin, const int jmin, const int kmin, const int imax, const int jmax, const int kmax, int *is_p) : SequenceData(0, shandle, shandle + calc_num_entities( shandle, imax-imin, jmax-jmin, kmax-kmin, is_p) - 1) { // need to have meaningful parameters assert(imax >= imin && jmax >= jmin && kmax >= kmin); isPeriodic[0] = (is_p ? is_p[0] : 0); isPeriodic[1] = (is_p ? is_p[1] : 0); boxParams[0] = HomCoord(imin, jmin, kmin); boxParams[1] = HomCoord(imax, jmax, kmax); boxParams[2] = HomCoord(1, 1, 1); // assign and compute parameter stuff dIJK[0] = boxParams[1][0] - boxParams[0][0] + 1; dIJK[1] = boxParams[1][1] - boxParams[0][1] + 1; dIJK[2] = boxParams[1][2] - boxParams[0][2] + 1; dIJKm1[0] = dIJK[0] - (isPeriodic[0] ? 0 : 1); dIJKm1[1] = dIJK[1] - (isPeriodic[1] ? 0 : 1); dIJKm1[2] = dIJK[2] - 1; }
SweptElementData::SweptElementData( EntityHandle shandle, const int imin, const int jmin, const int kmin, const int imax, const int jmax, const int kmax, const int* /*Cq*/ ) : SequenceData(0, shandle, shandle + calc_num_entities( shandle, imax-imin, jmax-jmin, kmax-kmin ) - 1) { // need to have meaningful parameters assert(imax >= imin && jmax >= jmin && kmax >= kmin); elementParams[0] = HomCoord(imin, jmin, kmin); elementParams[1] = HomCoord(imax, jmax, kmax); elementParams[2] = HomCoord(1, 1, 1); // assign and compute parameter stuff dIJK[0] = elementParams[1][0] - elementParams[0][0] + 1; dIJK[1] = elementParams[1][1] - elementParams[0][1] + 1; dIJK[2] = elementParams[1][2] - elementParams[0][2] + 1; dIJKm1[0] = dIJK[0] - 1; dIJKm1[1] = dIJK[1] - 1; dIJKm1[2] = dIJK[2] - 1; }
ErrorCode ScdInterface::create_scd_sequence(const HomCoord &low, const HomCoord &high, EntityType tp, int starting_id, ScdBox *&new_box, int *is_periodic) { HomCoord tmp_size = high - low + HomCoord(1, 1, 1, 0); if ((tp == MBHEX && 1 >= tmp_size[2]) || (tp == MBQUAD && 1 >= tmp_size[1]) || (tp == MBEDGE && 1 >= tmp_size[0])) return MB_TYPE_OUT_OF_RANGE; Core *mbcore = dynamic_cast<Core*>(mbImpl); SequenceManager *seq_mgr = mbcore->sequence_manager(); EntitySequence *tmp_seq; EntityHandle start_ent, scd_set; // construct the sequence ErrorCode rval = seq_mgr->create_scd_sequence(low, high, tp, starting_id, start_ent, tmp_seq, is_periodic); if (MB_SUCCESS != rval) return rval; // create the set for this rectangle rval = create_box_set(low, high, scd_set); if (MB_SUCCESS != rval) return rval; // make the ScdBox new_box = new ScdBox(this, scd_set, tmp_seq); if (!new_box) return MB_FAILURE; // set the start vertex/element Range new_range; if (MBVERTEX == tp) { new_range.insert(start_ent, start_ent+new_box->num_vertices()-1); } else { new_range.insert(start_ent, start_ent+new_box->num_elements()-1); } // put the entities in the box set rval = mbImpl->add_entities(scd_set, new_range); if (MB_SUCCESS != rval) return rval; // tag the set with the box rval = mbImpl->tag_set_data(box_set_tag(), &scd_set, 1, &new_box); if (MB_SUCCESS != rval) return rval; return MB_SUCCESS; }
inline ErrorCode SweptElementData::get_params_connectivity(const int i, const int j, const int k, std::vector<EntityHandle>& connectivity) const { if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; connectivity.push_back(get_vertex(i, j, k)); connectivity.push_back(get_vertex(i+1, j, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; connectivity.push_back(get_vertex(i+1, j+1, k)); connectivity.push_back(get_vertex(i, j+1, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; connectivity.push_back(get_vertex(i, j, k+1)); connectivity.push_back(get_vertex(i+1, j, k+1)); connectivity.push_back(get_vertex(i+1, j+1, k+1)); connectivity.push_back(get_vertex(i, j+1, k+1)); return MB_SUCCESS; }
inline ErrorCode ScdElementData::get_params_connectivity(const int i, const int j, const int k, std::vector<EntityHandle>& connectivity) const { if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE; int ip1 = (isPeriodic[0] ? (i+1)%dIJKm1[0] : i+1), jp1 = (isPeriodic[1] ? (j+1)%dIJKm1[1] : j+1); connectivity.push_back(get_vertex(i, j, k)); connectivity.push_back(get_vertex(ip1, j, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS; connectivity.push_back(get_vertex(ip1, jp1, k)); connectivity.push_back(get_vertex(i, jp1, k)); if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS; connectivity.push_back(get_vertex(i, j, k+1)); connectivity.push_back(get_vertex(ip1, j, k+1)); connectivity.push_back(get_vertex(ip1, jp1, k+1)); connectivity.push_back(get_vertex(i, jp1, k+1)); return MB_SUCCESS; }
inline EntityHandle get_vertex(int i, int j, int k) const { return get_vertex(HomCoord(i,j,k)); }
ScdBox::ScdBox(ScdInterface *impl, EntityHandle bset, EntitySequence *seq1, EntitySequence *seq2) : scImpl(impl), boxSet(bset), vertDat(NULL), elemSeq(NULL), startVertex(0), startElem(0) { for (int i = 0; i < 6; i++) boxDims[i] = 0; for (int i = 0; i < 3; i++) locallyPeriodic[i] = false; VertexSequence *vseq = dynamic_cast<VertexSequence *>(seq1); if (vseq) vertDat = dynamic_cast<ScdVertexData*>(vseq->data()); if (vertDat) { // retrieve the parametric space for (int i = 0; i < 3; i++) { boxDims[i] = vertDat->min_params()[i]; boxDims[3+i] = vertDat->max_params()[i]; } startVertex = vertDat->start_handle(); } else if (impl->boxDimsTag) { // look for parametric space info on set ErrorCode rval = impl->mbImpl->tag_get_data(impl->boxDimsTag, &bset, 1, boxDims); if (MB_SUCCESS == rval) { Range verts; impl->mbImpl->get_entities_by_dimension(bset, 0, verts); if (!verts.empty()) startVertex = *verts.begin(); } } elemSeq = dynamic_cast<StructuredElementSeq *>(seq2); if (!elemSeq) elemSeq = dynamic_cast<StructuredElementSeq *>(seq1); if (elemSeq) { if (vertDat) { // check the parametric space to make sure it's consistent assert(elemSeq->sdata()->min_params() == HomCoord(boxDims, 3) && (elemSeq->sdata()->max_params() + HomCoord(1, 1, 1)) == HomCoord(boxDims, 3)); } else { // get the parametric space from the element sequence for (int i = 0; i < 3; i++) { boxDims[i] = elemSeq->sdata()->min_params()[i]; boxDims[3+i] = elemSeq->sdata()->max_params()[i]; } } startElem = elemSeq->start_handle(); } else { Range elems; impl->mbImpl->get_entities_by_dimension(bset, (boxDims[2] == boxDims[5] ? (boxDims[1] == boxDims[4] ? 1 : 2) : 3), elems); if (!elems.empty()) startElem = *elems.begin(); // call the following w/o looking at return value, since it doesn't really need to be there if (impl->boxPeriodicTag) impl->mbImpl->tag_get_data(impl->boxPeriodicTag, &bset, 1, locallyPeriodic); } assert(vertDat || elemSeq || boxDims[0] != boxDims[3]|| boxDims[1] != boxDims[4]|| boxDims[2] != boxDims[5]); boxSize = HomCoord(boxDims+3, 3) - HomCoord(boxDims, 3) + HomCoord(1, 1, 1); boxSizeIJ = (boxSize[1] ? boxSize[1] : 1) * boxSize[0]; boxSizeIM1 = boxSize[0]-(locallyPeriodic[0] ? 0 : 1); boxSizeIJM1 = (boxSize[1] ? (boxSize[1]-(locallyPeriodic[1] ? 0 : 1)) : 1) * boxSizeIM1; scImpl->add_box(this); }
ErrorCode ScdInterface::construct_box(HomCoord low, HomCoord high, const double * const coords, unsigned int num_coords, ScdBox *& new_box, int * const lperiodic, ScdParData *par_data, bool assign_gids, int tag_shared_ents) { // create a rectangular structured mesh block ErrorCode rval; int tmp_lper[3] = {0, 0, 0}; if (lperiodic) std::copy(lperiodic, lperiodic+3, tmp_lper); #ifndef MOAB_HAVE_MPI if (-1 != tag_shared_ents) ERRORR(MB_FAILURE, "Parallel capability requested but MOAB not compiled parallel."); if (-1 == tag_shared_ents && !assign_gids) assign_gids = true; // need to assign gids in order to tag shared verts #else if (par_data && low == high && ScdParData::NOPART != par_data->partMethod) { // requesting creation of parallel mesh, so need to compute partition if (!par_data->pComm) { // this is a really boneheaded way to have to create a PC par_data->pComm = ParallelComm::get_pcomm(mbImpl, 0); if (NULL == par_data->pComm) par_data->pComm = new ParallelComm(mbImpl, MPI_COMM_WORLD); } int ldims[6]; rval = compute_partition(par_data->pComm->size(), par_data->pComm->rank(), *par_data, ldims, tmp_lper, par_data->pDims); ERRORR(rval, "Error returned from compute_partition."); low.set(ldims[0],ldims[1],ldims[2]); high.set(ldims[3],ldims[4],ldims[5]); if (par_data->pComm->get_debug_verbosity() > 0) { std::cout << "Proc " << par_data->pComm->rank() << ": " << *par_data; std::cout << "Proc " << par_data->pComm->rank() << " local dims: " << low << "-" << high << std::endl; } } #endif HomCoord tmp_size = high - low + HomCoord(1, 1, 1, 0); if ((tmp_size[1] && num_coords && (int)num_coords < tmp_size[0]) || (tmp_size[2] && num_coords && (int)num_coords < tmp_size[0]*tmp_size[1])) return MB_FAILURE; rval = create_scd_sequence(low, high, MBVERTEX, 0, new_box); ERRORR(rval, "Trouble creating scd vertex sequence."); // set the vertex coordinates double *xc, *yc, *zc; rval = new_box->get_coordinate_arrays(xc, yc, zc); ERRORR(rval, "Couldn't get vertex coordinate arrays."); if (coords && num_coords) { unsigned int i = 0; for (int kl = low[2]; kl <= high[2]; kl++) { for (int jl = low[1]; jl <= high[1]; jl++) { for (int il = low[0]; il <= high[0]; il++) { xc[i] = coords[3*i]; if (new_box->box_size()[1]) yc[i] = coords[3*i+1]; if (new_box->box_size()[2]) zc[i] = coords[3*i+2]; i++; } } } } else { unsigned int i = 0; for (int kl = low[2]; kl <= high[2]; kl++) { for (int jl = low[1]; jl <= high[1]; jl++) { for (int il = low[0]; il <= high[0]; il++) { xc[i] = (double) il; if (new_box->box_size()[1]) yc[i] = (double) jl; else yc[i] = 0.0; if (new_box->box_size()[2]) zc[i] = (double) kl; else zc[i] = 0.0; i++; } } } } // create element sequence Core *mbcore = dynamic_cast<Core*>(mbImpl); SequenceManager *seq_mgr = mbcore->sequence_manager(); EntitySequence *tmp_seq; EntityHandle start_ent; // construct the sequence EntityType this_tp = MBHEX; if (1 >= tmp_size[2]) this_tp = MBQUAD; if (1 >= tmp_size[2] && 1 >= tmp_size[1]) this_tp = MBEDGE; rval = seq_mgr->create_scd_sequence(low, high, this_tp, 0, start_ent, tmp_seq, tmp_lper); ERRORR(rval, "Trouble creating scd element sequence."); new_box->elem_seq(tmp_seq); new_box->start_element(start_ent); // add vertex seq to element seq, forward orientation, unity transform rval = new_box->add_vbox(new_box, // p1: imin,jmin low, low, // p2: imax,jmin low + HomCoord(1, 0, 0), low + HomCoord(1, 0, 0), // p3: imin,jmax low + HomCoord(0, 1, 0), low + HomCoord(0, 1, 0)); ERRORR(rval, "Error constructing structured element sequence."); // add the new hexes to the scd box set; vertices were added in call to create_scd_sequence Range tmp_range(new_box->start_element(), new_box->start_element() + new_box->num_elements() - 1); rval = mbImpl->add_entities(new_box->box_set(), tmp_range); ERRORR(rval, "Couldn't add new hexes to box set."); if (par_data) new_box->par_data(*par_data); if (assign_gids) { rval = assign_global_ids(new_box); ERRORR(rval, "Trouble assigning global ids"); } #ifdef MOAB_HAVE_MPI if (par_data && -1 != tag_shared_ents) { rval = tag_shared_vertices(par_data->pComm, new_box); } #endif return MB_SUCCESS; }
inline bool SweptVertexData::contains(const int i, const int j, const int k) const { return contains(HomCoord(i, j, k)); }