/* return the index the next receive */ void CommunicatorT::WaitReceive(const ArrayT<MPI_Request>& requests, int& index, int& source) const { const char caller[] = "CommunicatorT::WaitReceive"; Log(kModerate, caller, "waiting for 1 of %d", requests.Length()); index = source = -1; #ifdef __TAHOE_MPI__ /* grab completed receive */ MPI_Status status; int ret = MPI_Waitany(requests.Length(), (MPI_Request*) requests.Pointer(), &index, &status); #ifdef CHECK_MPI_RETURN if (ret != MPI_SUCCESS) Log(kFail, caller, "MPI_Waitany failed"); #endif #ifdef CHECK_MPI_STATUS if (status.MPI_ERROR != MPI_SUCCESS) Log(kFail, caller, "bad status: %d", status.MPI_ERROR); #endif source = status.MPI_SOURCE; #endif Log(kModerate, caller, "received request at index %d from %d", index, source); }
/* free any uncompleted requests */ void CommunicatorT::FreeRequests(ArrayT<MPI_Request>& requests) const { #ifdef __TAHOE_MPI__ const char caller[] = "CommunicatorT::FreeRequests"; /* free any uncompleted receive requests */ for (int i = 0; i < requests.Length(); i++) if (requests[i] != MPI_REQUEST_NULL) { Log(kLow, "caller", "cancelling request %d/%d", i+1, requests.Length()); /* cancel request */ MPI_Cancel(&requests[i]); MPI_Status status; MPI_Wait(&requests[i], &status); int flag; MPI_Test_cancelled(&status, &flag); if (flag ) Log(kLow, "caller", "cancelling request %d/%d: DONE", i+1, requests.Length()); else Log(kLow, "caller", "cancelling request %d/%d: FAIL", i+1, requests.Length()); } #else #pragma unused(requests) #endif }
/* block until all sends posted with CommunicatorT::PostSend have completed */ void CommunicatorT::WaitSends(const ArrayT<MPI_Request>& requests) { const char caller[] = "CommunicatorT::WaitSends"; Log(kModerate, caller, "waiting for 1 of %d", requests.Length()); /* complete all sends */ for (int i = 0; i < requests.Length(); i++) { int index = -1; #ifdef __TAHOE_MPI__ /* grab completed receive */ MPI_Status status; int ret = MPI_Waitany(requests.Length(), (MPI_Request*) requests.Pointer(), &index, &status); #ifdef CHECK_MPI_RETURN if (ret != MPI_SUCCESS) Log(kFail, caller, "MPI_Waitany failed"); #endif #ifdef CHECK_MPI_STATUS if (status.MPI_ERROR != MPI_SUCCESS) { WriteStatus(Log(), caller, status); Log(kFail, caller, "bad status: %d", status.MPI_ERROR); } #endif #endif Log(kLow, caller, "completing send at index %d", index); } }
/* change the number of active element groups */ void ElementListT::SetActiveElementGroupMask(const ArrayT<bool>& mask) { /* first time */ if (fAllElementGroups.Length() == 0) { /* cache all pointers */ fAllElementGroups.Dimension(Length()); for (int i = 0; i < fAllElementGroups.Length(); i++) { ElementBaseT* element = (*this)[i]; fAllElementGroups[i] = element; } } /* check */ if (mask.Length() != fAllElementGroups.Length()) ExceptionT::SizeMismatch("ElementListT::SetActiveElementGroupMask", "expecting mask length %d not %d", fAllElementGroups.Length(), mask.Length()); /* reset active element groups */ int num_active = 0; for (int i = 0; i < mask.Length(); i++) if (mask[i]) num_active++; /* cast this to an ArrayT */ ArrayT<ElementBaseT*>& element_list = *this; element_list.Dimension(num_active); num_active = 0; for (int i = 0; i < mask.Length(); i++) if (mask[i]) element_list[num_active++] = fAllElementGroups[i]; }
void Quad2Tri::BackSlashSideSets (ArrayT<iArray2DT>& sidesets) { fSideSetData.Allocate (sidesets.Length()); for (int s=0; s < sidesets.Length(); s++) { fSideSetData[s].Allocate (sidesets[s].MajorDim(), 2); fSideSetData[s] = 0; int *e = sidesets[s].Pointer(); int *f = sidesets[s].Pointer(1); int *enew = fSideSetData[s].Pointer(); int *fnew = fSideSetData[s].Pointer(1); for (int i=0; i < sidesets[s].MajorDim(); i++) { *enew = *e * 2; if (*f == 1 || *f == 2) { *enew += 1; *fnew = *f - 1; } else if (*f == 0) *fnew = 1; else *fnew = 0; e += 2; f += 2; enew += 2; fnew += 2; } } }
/* initialize the state variable array */ void MR_RP2DT::InitStateVariables(ArrayT<double>& state) { int num_state = NumStateVariables(); if (state.Length() != num_state) { #ifndef _SIERRA_TEST_ cout << "\n SurfacePotentialT::InitStateVariables: expecting state variable array\n" << " length " << num_state << ", found length " << state.Length() << endl; #endif throw ExceptionT::kSizeMismatch; } /* clear */ if (num_state > 0) state = 0.0; /* Initializing internal state variables */ double enp = state[14]; double esp = state[15]; double fchi = fchi_r + (fchi_p - fchi_r)*exp(-falpha_chi*enp); double fc = fc_r + (fc_p - fc_r)*exp(-falpha_c*esp); double ftan_phi = tan(fphi_r) + (tan(fphi_p) - tan(fphi_r))*exp(-falpha_phi*esp); double ftan_psi = (tan(fpsi_p))*exp(-falpha_psi*esp); state[6] = fchi; state[7] = fc ; state[8] = ftan_phi; state[9] = ftan_psi; state[13] = 0.; state[nTiedFlag] = kTiedNode; }
/* echo element connectivity data */ void SCNIMFT::DefineElements(const ArrayT<StringT>& block_ID, const ArrayT<int>& mat_index) { const char caller[] = "SCNIMFT::DefineElements"; //TEMP if (block_ID.Length() > 1) ExceptionT::GeneralFail(caller, "mutliple block ID's not supported %d", block_ID.Length()); /* access to the model database */ ModelManagerT& model = ElementSupport().ModelManager(); fElementConnectivities.Dimension(1); // NB THIS IS SPECIALIZED TO ONLY ONE ELEMENT BLOCK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! model.ReadConnectivity(block_ID[0]); /* set pointer to connectivity list */ fElementConnectivities[0] = model.ElementGroupPointer(block_ID[0]); // Get nodal coordinates int nsd = NumSD(); fNodalCoordinates.Dimension(fNodes.Length(), nsd); fNodalCoordinates.RowCollect(fNodes, model.Coordinates()); /* set up element cards for state variable storage */ fElementCards.Dimension(fNodes.Length()); /* one card per node */ for (int i = 0; i < fElementCards.Length(); i++) fElementCards[i].SetMaterialNumber(mat_index[0]); fCellGeometry->DefineElements(block_ID, mat_index); }
void NodeManagerPrimitive::AddNodeSet (const StringT& setID, const ArrayT<int>& nodes, CSEConstants::NodeMapMethodT transfermethod) { int dex; fNodeSetID.HasValue (setID, dex); if (dex > -1) { int num = nodes.Length(); int length = fNodeSetData[dex].Length(); fNodeSetData[dex].Resize (length + num, CSEConstants::kNotSet); fNodeSetData[dex].CopyPart (length, nodes, 0, num); RemoveRepeats (fNodeSetData[dex]); out << " Added to Node Set. . . . . . . . . . = " << setID << '\n' << endl; } else { int length = fNodeSetID.Length(); fNodeSetData.Resize (length + 1); fNodeSetID.Resize (length + 1, ""); fNodeSetData[length].Allocate (nodes.Length()); fNodeSetData[length].CopyPart (0, nodes, 0, nodes.Length()); fNodeSetID[length] = setID; int ml = fTransMethods.Length(); fTransMethods.Resize (ml + 1, transfermethod); out << " Added Node Set . . . . . . . . . . . = " << setID << '\n' << endl; } }
void MFPenaltyContact2DT::ComputeStrikerCoordinates(const ArrayT<int>& strikers) { /* dimension */ fStrikerCoords_man.SetMajorDimension(strikers.Length(), false); /* current striker coords */ if (strikers.Length() > 0) { /* reconstruct displacement field */ if (fSCNI) { fSCNI_tmp = strikers; if (!fSCNI->GlobalToLocalNumbering(fSCNI_tmp)) ExceptionT::GeneralFail("MFPenaltyContact2DT::ComputeStrikerCoordinates", "SCNI global->local failed"); fSCNI->InterpolatedFieldAtNodes(fSCNI_tmp, fStrikerCoords); } else { iArrayT tmp; tmp.Alias(strikers); fElementGroup->NodalDOFs(tmp, fStrikerCoords); } /* compute current coordinates */ const dArray2DT& init_coords = ElementSupport().InitialCoordinates(); for (int i = 0; i < strikers.Length(); i++) fStrikerCoords.AddToRowScaled(i, 1.0, init_coords(strikers[i])); } }
void TextInputT::ElementGroupNames (ArrayT<StringT>& groupnames) const { if (groupnames.Length() != fBlockID.Length()) throw ExceptionT::kSizeMismatch; for (int i=0; i < groupnames.Length(); i++) { groupnames[i] = fBlockID[i]; } }
/* assemble the element contribution */ void PSPASESMatrixT::Assemble(const ElementMatrixT& elMat, const ArrayT<int>& eqnos) { const char caller[] = "PSPASESMatrixT::Assemble"; /* element matrix format */ ElementMatrixT::FormatT format = elMat.Format(); /* two cases: element matrix is diagonal, or it's not. */ int end_update = fStartEQ + fLocNumEQ - 1; if (format == ElementMatrixT::kDiagonal) { /* diagonal entries only */ const double *pelMat = elMat.Pointer(); int inc = elMat.Rows() + 1; /* offset between diag entries are */ int nee = eqnos.Length(); for (int i = 0; i < nee; ++i) { int eq = eqnos[i]; if (eq >= fStartEQ && eq <= end_update) /* active eqn */ { eq--; double* a = (*this)(eq,eq); if (a) *a += *pelMat; else ExceptionT::OutOfRange(caller); } pelMat += inc; } } else if (format == ElementMatrixT::kNonSymmetric || format == ElementMatrixT::kSymmetric || format == ElementMatrixT::kSymmetricUpper ) { /* fill matrix */ if (format != ElementMatrixT::kNonSymmetric) elMat.CopySymmetric(); int nee = eqnos.Length(); // number of equations for element for (int col = 0; col < nee; ++col) { int ceqno = eqnos[col] - 1; if (ceqno > -1) /* active eqn */ { for (int row = 0; row < nee; ++row) { int reqno = eqnos[row]; if (reqno >= fStartEQ && reqno <= end_update) /* active eqn */ { reqno--; double* a = (*this)(reqno,ceqno); if (a) *a += 0.5*(elMat(row,col) + elMat(col,row)); else ExceptionT::OutOfRange(caller); } } } } } else ExceptionT::GeneralFail(caller, "unsupported element matrix format %d", format); }
/* collect subset */ void LocalArrayT::Collect(const ArrayT<int>& nodes, const LocalArrayT& source) { #if __option(extended_errorcheck) if (nodes.Length() != fNumNodes || source.fMinorDim != fMinorDim) ExceptionT::SizeMismatch("LocalArrayT::Collect"); #endif for (int j = 0; j < fMinorDim; j++) for (int i = 0; i < nodes.Length(); i++) (*this)(i,j) = source(nodes[i],j); }
/* return true if all values are the same */ bool MessageT::Same(const ArrayT<int>& a) const { if (a.Length() == 0) return true; else { int i = a[0]; for (int j = 1; j < a.Length(); j++) if (a[j] != i) return false; return true; } }
void DiagonalMatrixT::Assemble(const ElementMatrixT& elMat, const ArrayT<int>& row_eqnos, const ArrayT<int>& col_eqnos) { /* pick out diagonal values */ for (int row = 0; row < row_eqnos.Length(); row++) for (int col = 0; col < col_eqnos.Length(); col++) if (row_eqnos[row] == col_eqnos[col]) { int eqno = row_eqnos[row] - 1; if (eqno > -1) fMatrix[eqno] += elMat(row, col); } }
int ElementSupportT::RegisterOutput(ArrayT<StringT>& n_labels, ArrayT<StringT>& e_labels) { /* copy labels */ fNodeOutputLabels.Dimension(n_labels.Length()); for (int i = 0; i < fNodeOutputLabels.Length(); i++) fNodeOutputLabels[i] = n_labels[i]; fElemOutputLabels.Dimension(e_labels.Length()); for (int i = 0; i < fElemOutputLabels.Length(); i++) fElemOutputLabels[i] = e_labels[i]; return 0; }
/* renumber the positive values in oldsequences - returns the number * of re-sequenced labels. labels are assumed to increase contiguously * through the rows of the oldsequences */ int CMReLabellerT::Renumber(ArrayT<iArray2DT*>& oldsequences) { /* first row handled by each sequence */ iArrayT maxrow(oldsequences.Length()); for (int k = 0; k < oldsequences.Length(); k++) { maxrow[k] = oldsequences[k]->MajorDim(); /* offset from previous sequence */ if (k > 0) maxrow[k] += maxrow[k-1]; } /* make graph */ fGraph.MakeGraph(); /* initialize */ Initialize(); /* pick start and end nodes */ SelectNodes(); /* relabel */ CMSequence(); ReverseSequence(); /* re-sequence positive values */ int label = 0; for (int i = 0; i < fGraph.NumNodes(); i++) { /* next node in line for new labels */ int next = fSequence[i]; /* get pointer to the correct sequence */ int seqnum = 0; while (next >= maxrow[seqnum]) seqnum++; if (seqnum > 0) next -= maxrow[seqnum - 1]; iArray2DT& currsequence = *oldsequences[seqnum]; int* pseq = currsequence(next); int subdim = currsequence.MinorDim(); for (int j = 0; j < subdim; j++) { int& oldlabel = *pseq++; if (oldlabel > 0) oldlabel = ++label; } } return label; }
void DiagonalMatrixT::Assemble(const nArrayT<double>& diagonal_elMat, const ArrayT<int>& eqnos) { #if __option(extended_errorcheck) /* dimension check */ if (diagonal_elMat.Length() != eqnos.Length()) throw ExceptionT::kSizeMismatch; #endif for (int i = 0; i < eqnos.Length(); i++) { int eqno = eqnos[i] - 1; if (eqno > -1) fMatrix[eqno] += diagonal_elMat[i]; } }
static void TraceArray(JSTracer* trc, void* data) { ArrayT* array = static_cast<ArrayT *>(data); for (unsigned i = 0; i < array->Length(); ++i) JS_CallHeapObjectTracer(trc, &array->ElementAt(i), "array-element"); }
void MeshFreeSurfaceShapeT::NeighborCounts(ArrayT<int>& counts) const { const ArrayT<int>& counts_1 = fMFSurfaceSupport->NeighborCounts(0); const ArrayT<int>& counts_2 = fMFSurfaceSupport->NeighborCounts(1); counts.Dimension(counts_1.Length()); for (int i = 0; i < counts.Length(); i++) counts[i] = counts_1[i] + counts_2[i]; }
void TextInputT::ReadNodeLabels (ArrayT<StringT>& nlabels) const { /* allocate */ nlabels.Dimension(NumNodeVariables()); /* copy */ for (int i=0; i < nlabels.Length(); i++) nlabels[i] = fNodeVariable[i]; }
void TextInputT::ReadElementLabels (ArrayT<StringT>& elabels) const { /* allocate */ elabels.Dimension(NumElementVariables()); /* copy */ for (int i=0; i < elabels.Length(); i++) elabels[i] = fElementVariable[i]; }
void LocalArrayT::SetLocal(const ArrayT<int>& keys) { #if __option (extended_errorcheck) const char caller[] = "LocalArrayT::SetLocal"; if (!fGlobal) ExceptionT::GeneralFail(caller); if (keys.Length() != fNumNodes) ExceptionT::SizeMismatch(caller); #endif fGlobal->SetLocal(keys,*this); }
// with this method original quad facets are always a triangle 0 facet void Quad2Tri::XMethodSideSets (ArrayT<iArray2DT>& sidesets) { fSideSetData.Allocate (sidesets.Length()); for (int s=0; s < sidesets.Length(); s++) { fSideSetData[s].Allocate (sidesets[s].MajorDim(), 2); fSideSetData[s] = 0; int *e = sidesets[s].Pointer(); int *f = sidesets[s].Pointer(1); int *en = fSideSetData[s].Pointer(); for (int i=0; i < sidesets[s].MajorDim(); i++) { *en = *e *4 + *f; e += 2; f += 2; en += 2; } } }
void PartitionT::Set(int num_parts, int id, const ArrayT<int>& part_map, const ArrayT<int>& node_map, const ArrayT<const iArray2DT*>& connects_1, const ArrayT<const RaggedArray2DT<int>*>& connects_2) { const char caller[] = "PartitionT::Set"; /* check */ if (part_map.Length() != node_map.Length()) ExceptionT::SizeMismatch(caller, "part map length %d must equal node map length %d", part_map.Length(), node_map.Length()); /* total number of partitions */ fNumPartitions = num_parts; if (fNumPartitions < 1) ExceptionT::GeneralFail(caller, "bad size %d", fNumPartitions); /* set ID */ fID = id; if (fID < 0 || fID >= fNumPartitions) ExceptionT::OutOfRange(caller, "bad id %d", fID); /* numbering is global */ fScope = kLocal; /* resolve internal/boundary nodes */ ClassifyNodes(part_map, connects_1, connects_2); /* set node map */ fNodeMap_man.SetLength(node_map.Length(), false); int nnd = fNodes_i.Length() + fNodes_b.Length() + fNodes_e.Length(); if (fNodeMap.Length() != nnd) ExceptionT::GeneralFail(caller, "expecting %d entries in node map %d", nnd, fNodeMap.Length()); fNodeMap.Copy(node_map.Pointer()); /* set send information */ SetReceive(part_map); /* clear inverse maps */ fInvNodeMap.Free(); for (int i = 0; i < fInvElementMap.Length(); i++) fInvElementMap.Free(); }
// with this method original quad facets are always a triangle 0 facet void Quad2Tri::StarSideSets (ArrayT<iArray2DT>& sidesets) { fSideSetData.Allocate (sidesets.Length()); for (int s=0; s < sidesets.Length(); s++) { fSideSetData[s].Allocate (2*sidesets[s].MajorDim(), 2); fSideSetData[s] = 0; int *e = sidesets[s].Pointer(); int *f = sidesets[s].Pointer(1); int *enew = fSideSetData[s].Pointer(); for (int i=0; i < sidesets[s].MajorDim(); i++) { *enew = *e *8 + *f *2; enew += 2; *enew = *e *8 + *f *2 + 1; enew += 2; e += 2; f += 2; } } }
void Quad2Tri::SlashSideSets (ArrayT<iArray2DT>& sidesets) { fSideSetData.Allocate (sidesets.Length()); for (int s=0; s < sidesets.Length(); s++) { fSideSetData[s].Allocate (sidesets[s].MajorDim(), 2); fSideSetData[s] = 0; int *e = sidesets[s].Pointer(); int *f = sidesets[s].Pointer(1); int *enew = fSideSetData[s].Pointer(); int *fnew = fSideSetData[s].Pointer(1); for (int i=0; i < sidesets[s].MajorDim(); i++) { *enew = *e * 2 + ((*f < 2) ? 0 : 1); *fnew = *f - ((*f < 2) ? 0 : 2); e += 2; f += 2; enew += 2; fnew += 2; } } }
/* broadcast character array */ void CommunicatorT::Broadcast(int source, ArrayT<char>& data) { if (source == Rank()) { Log(kModerate, "Broadcast", "sending %d", data.Length()); if (LogLevel() == kLow) Log() << setw(10) << "data: " << data.Pointer() << '\n'; } #ifdef __TAHOE_MPI__ int ret = MPI_Bcast(data.Pointer(), data.Length(), MPI_CHAR, source, fComm); #ifdef CHECK_MPI_RETURN if (ret != MPI_SUCCESS) Log(kFail, "CommunicatorT::Broadcast", "MPI_Bcast failed"); #endif #endif if (source != Rank()) { Log(kModerate, "Broadcast", "received %d", data.Length()); if (LogLevel() == kLow) Log() << setw(10) << "data: " << data.Pointer() << '\n'; } }
/* sort edges by minimum degree */ void CMReLabellerT::SortByMinDegree(ArrayT<int>& edges) { int numedges = edges.Length(); // array with degrees of edges iArrayT edgedegrees(numedges); for( int i = 0; i < numedges; i++) { edgedegrees[i] = fGraph.Degree(edges[i]); } // sort edges by degree in ascending order AZ_sort(edgedegrees.Pointer(), numedges, edges.Pointer(), NULL); }
/* store outgoing data (count maps onto fCommID) */ void PartitionT::SetOutgoing(const ArrayT<iArrayT>& nodes_out) { /* checks */ if (nodes_out.Length() != fCommID.Length()) { cout << "\n PartitionT::SetIncoming: expecting dimension of outgoing ID's (" << nodes_out.Length() << ")\n"; cout << " to be the same as the Comm ID list (" << fCommID.Length() << ")" << endl; throw ExceptionT::kSizeMismatch; } /* only at global scope for now */ if (fScope != kGlobal) { cout << "\n PartitionT::SetOutgoing: number scope must be global" << endl; throw ExceptionT::kGeneralFail; } /* store */ fNodes_out.Dimension(nodes_out.Length()); for (int i = 0; i < fNodes_out.Length(); i++) fNodes_out[i] = nodes_out[i]; }
void MR_RP2DT::ComputeOutput(const dArrayT& jump_u, const ArrayT<double>& state, dArrayT& output) { #pragma unused(jump_u) #if __option(extended_errorcheck) if (state.Length() != NumStateVariables()) throw ExceptionT::kGeneralFail; #endif output[0] = state[4]; output[1] = state[5];; output[2] = state[6]; output[3] = state[7]; output[4] = state[8]; output[5] = state[10]; output[6] = state[13]; output[7] = state[16]; }