The following example examines the von Mises stress in each element during a particular frame of field output. If the stress is greater than a certain maximum value, the program prints the strain components for the element.
odb_FieldOutputRepository& fieldRep = frame1.fieldOutputs();
odb_FieldOutput& stressField = fieldRep.get("S");
odb_FieldOutput& strainField = fieldRep.get("LE");
const odb_SequenceFieldValue& seqStressVal =
stressField.values();
int numFV = seqStressVal.size();
int strainComp = 0;
for (int loc=0; loc < numFV; loc++) {
const odb_FieldValue stressVal = seqStressVal[loc];
if (stressVal.mises() > stressCap) {
cout << "Element label = " << stressVal.elementLabel()
<< endl;
cout << "Integration Point = "
<< stressVal.integrationPoint() << endl;
const odb_SequenceFieldValue& seqStrainVal =
strainField.values();
const odb_FieldValue strainVal = seqStrainVal[loc];
const float* const data = strainVal.data(strainComp);
cout << " LE : ";
for (int comp=0; comp < strainComp; comp++)
cout << data[comp];
cout << endl;
}
}
In this example every time the script calls the strainField.values method, Abaqus must reconstruct the sequence of FieldValue objects. This reconstruction could result in a significant performance degradation, particularly for a large model. A slight change in the program greatly improves its performance, as shown in the following example:
odb_FieldOutputRepository& fieldRep =
frame1.fieldOutputs();
odb_FieldOutput& stressField = fieldRep.get("S");
odb_FieldOutput& strainField = fieldRep.get("LE");
const odb_SequenceFieldValue& seqStressVal =
stressField.values();
const odb_SequenceFieldValue& seqStrainVal =
strainField.values();
int numFV = seqStressVal.size();
int strainComp = 0;
for (int loc=0; loc < numFV; loc++) {
const odb_FieldValue stressVal = seqStressVal[loc];
if (stressVal.mises() > stressCap) {
cout << "Element label = " << stressVal.elementLabel()
<< endl;
cout << "Integration Point = "
<< stressVal.integrationPoint() << endl;
const odb_FieldValue strainVal = seqStrainVal[loc];
const float* data = strainVal.data(strainComp);
cout << " LE : ";
for (int comp = 0; comp < strainComp; comp++)
cout << data[comp];
cout << endl;
}
}
}
Similarly, if you expect to retrieve more than one frame from an output database, you should create a temporary variable that holds the entire frame repository. You can then provide the logic to retrieve the desired frames from the repository and avoid recreating the repository each time. For example, executing the following statements could be very slow:
int numFrames = step1.frames().size();
for (int n=0; n < numFrames; n++)
odb_Frame& frame = step1.frames()[n];
Creating a temporary variable to hold the frame repository provides the same functionality and speeds up the process: odb_SequenceFrame& frameRepository = step1.frames();
int numFrames = frameRepository.size();
for (int n=0; n < numFrames; n++)
odb_Frame& frame = frameRepository[n];
Such a potential loss of performance will not be a problem when accessing a load case frame. Accessing a load case frame does not result in the creation of a frame repository and, thus, does not suffer from a corresponding loss of performance. |