- The root
assembly
-
An output database contains only one root assembly. You access the root
assembly through the OdbAssembly object.
odb_Assembly& rootAssy = odb.rootAssembly();
- Part
instances
-
Part instances are stored in the instance repository under
the OdbAssembly object. The following statements display
the repository keys of the part instances in the tutorial output database:
odb_InstanceRepositoryIT instIter(rootAssy.instances());
for (instIter.first(); !instIter.isDone(); instIter.next())
cout << instIter.currentKey().CStr() << endl;
The output database contains only one part instance, and the resulting
output is
PART-1-1
From a part instance or part you can retrieve the node and
element information as follows:
{
odb_Instance& instance1 =
rootAssy.instances()["PART-1-1"];
odb_Enum::odb_DimensionEnum instanceType =
instance1.embeddedSpace();
const odb_SequenceNode& nodeList = instance1.nodes();
int nodeListSize = nodeList.size();
if (instanceType == odb_Enum::THREE_D) {
for (int n=0; n<nodeListSize; n++) {
const odb_Node node = nodeList[n];
int nodeLabel = node.label();
const float* const coord = node.coordinates();
cout << "Xcoord: " << coord[0] << " , Ycoord: "
<< coord[1] << " , Zcoord: " << coord[2] << endl;
}
}
else if((instanceType == odb_Enum::TWO_D_PLANAR) ||
(instanceType == odb_Enum::AXISYMMETRIC)) {
for (int n=0; n<nodeListSize; n++) {
const odb_Node node = nodeList[n];
int nodeLabel = node.label();
const float* const coord = node.coordinates();
cout << "Xcoord: " << coord[0] << " , Ycoord: "
<< coord[1] << endl;
}
}
const odb_SequenceElement& elementList =
instance1.elements();
int elementListSize = elementList.size();
cout << "Element Connectivity Data" << endl;
cout << "Element Label : constituent node labels ..."
<< endl;
int numNodes = 0;
for (int e=0; e<elementListSize; e++) {
const odb_Element element = elementList[e];
int elementLabel = element.label();
cout << elementLabel <<" : ";
odb_String elementType = element.type();
const int* const conn =
element.connectivity(numNodes);
for (int j=0; j<numNodes; j++)
cout << " " << conn[j];
cout << endl;
}
}
- Regions
-
Regions in the output database are OdbSet objects.
Regions refer to the part and assembly sets stored in the output database. A
part set refers to elements or nodes in an individual part and appears in each
instance of the part in the assembly. An assembly set refers to the elements or
nodes in part instances in the assembly. A region can be one of the following:
-
A node set
-
An element set
-
A surface
For example, the following statement displays the node sets in the
OdbAssembly object:
cout << "Node set keys:" << endl;
odb_SetRepositoryIT setIter( rootAssy.nodeSets() );
for (setIter.first(); !setIter.isDone(); setIter.next())
cout << setIter.currentKey().CStr() << endl;
The resulting output is
Node set keys:
ALL NODES
The following statements display the node sets and the element sets in the
PART-1-1 part instance:
{
odb_InstanceRepository& iCon =
odb.rootAssembly().instances();
odb_Instance& instance = iCon["PART-1-1"];
cout << "Node set keys:" << endl;
odb_SetRepositoryIT setItN( instance.nodeSets() );
for (setItN.first(); !setItN.isDone(); setItN.next())
cout << setItN.currentKey().CStr() << endl;
cout << "Element set keys:" << endl;
odb_SetRepositoryIT setItE( instance.elementSets() );
for (setItE.first(); !setItE.isDone(); setItE.next())
cout << setItE.currentKey().CStr() << endl;
}
The resulting output is
Node set keys:
BOT
N481
TOP
N1
...
Element set keys:
CENT
FOAM
...
The following statement assigns a variable
(topNodeSet) to the
'TOP' node set in the
PART-1-1 part instance:
odb_InstanceRepository& iCon =
odb.rootAssembly().instances();
odb_Instance& instance = iCon["PART-1-1"];
odb_Set& topNodeSet = instance.nodeSets()["TOP"];
The type of the object to which topNodeSet
refers is OdbSet. After you create a variable
that refers to a region, you can use the variable to refer to a subset of field
output data, as described in
Using regions to read a subset of field output data.
To access the set information on a part instance:
// node set information
odb_Set& nodeSet = instance.nodeSets()["CENTER"];
const odb_SequenceNode& nodeList = nodeSet.nodes();
// surface information
odb_Set& surface = instance.surfaces()["IMPACTOR"];
const odb_SequenceElement& elementList =
surface.elements();
const odb_SequenceElementFace& faces =
surface.faces();
// iterators are used to get all sets
odb_SetRepository& elementSetRepository =
instance.elementSets();
odb_SetRepositoryIT elSetRepIter(elementSetRepository);
for (elSetRepIter.first(); !elSetRepIter.isDone();
elSetRepIter.next()) {
odb_Set& set =
elementSetRepository[elSetRepIter.currentKey()];
cout << "element set " << elSetRepIter.currentKey().CStr()
<< endl;
cout << " number of elements : ";
cout << set.size() << endl;
}
The set information in an assembly set is keyed by instance
name and can be accessed using the following:
// assembly surface information
odb_Set& aSurface = rootAssy.surfaces()["TARGET"];
odb_SequenceString instanceNames =
aSurface.instanceNames();
int totalNames = instanceNames.size();
for (int name=0; name<totalNames; name++) {
const odb_String& iName = instanceNames[name];
const odb_SequenceElement& els =
aSurface.elements(iName);
const odb_SequenceElementFace& face =
aSurface.faces(iName);
}
- Materials
-
You can read material data from an output database.
Materials are stored in the materials repository under the
Odb object.
Extend the Material commands available
to the Odb object using the following statement:
odb_MaterialApi materialApi;
odb.extendApi(odb_Enum::odb_MATERIAL,materialApi);
Access the materials repository using the command:
odb_MaterialContainer& materialContainer = materialApi.materials();
odb_MaterialContainerIT matIT(materialContainer);
for (matIT.first(); !matIT.isDone(); matIT.next()) {
cout << "Material Name : " << matIT.currentKey().CStr() << endl;
const odb_Material& myMaterial = matIT.currentValue();
To print isotropic elastic material properties in a material object:
odb_Elastic elastic = myMaterial.elastic();
if (elastic.hasValue()) {
if (elastic.type() == "ISOTROPIC") {
cout << "isotropic elastic behavior, type = "
<< elastic.moduli().CStr() << endl;
odb_String tableHeader("Youngs modulus Poisson's ratio ");
if (elastic.temperatureDependency())
tableHeader.append("Temperature ");
for (int i = 0, max = elastic.dependencies(); i < max; ++i)
tableHeader.append(" field # ").append(i);
cout << tableHeader.CStr() << endl;
odb_SequenceSequenceFloat table = elastic.table();
for (int r = 0, rows = table.size(); r <rows; ++r) {
const odb_SequenceFloat& data = table[r];
for (int c = 0, cols = data.size(); c < cols; ++c) {
cout << data[c] << " ";
}
cout << endl;
}
}
}
Some Material definitions have suboptions. For example, to access the
smoothing type used for biaxial test data specified for a hyperelastic
material:
odb_Hyperelastic hyperelastic = myMaterial.hyperelastic();
if (hyperelastic.hasValue()) {
bool testData = hyperelastic.testData();
odb_BiaxialTestData biaxialTestData =
hyperelastic.biaxialTestData();
odb_String smoothingType("smoothing type: ");
if (biaxialTestData.hasValue()) {
odb_Union smoothing = biaxialTestData.smoothing();
switch(smoothing.type()) {
case (odb_UNION_STRING):
smoothingType.append(smoothing.getString());
break;
case (odb_UNION_INT):
smoothingType.append(smoothing.getInt());
break;
case (odb_UNION_FLOAT):
smoothingType.append(smoothing.getFloat());
break;
case (odb_UNION_DOUBLE):
smoothingType.append(smoothing.getDouble());
break;
case (odb_UNION_BOOL):
smoothingType.append(smoothing.getBool());
break;
}
cout << smoothingType.CStr() << endl;
}
}
Material commands
describes the Material object commands in more detail; the
odb_Union object is defined in
Union object.
- Sections
-
You can read section data from an output database.
Sections are stored in the sections repository under the
Odb object.
Extend the Section commands available
to the Odb object using the following statement:
odb_SectionApi sectionApi;
odb.extendApi(odb_Enum::odb_SECTION,sectionApi);
The following statements display the repository keys of the sections in an
output database:
odb_SectionContainer& sectionContainer =
sectionApi.sections();
odb_SectionContainerIT scIT(sectionContainer);
for (scIT.first(); !scIT.isDone(); scIT.next()) {
cout << "Section Name : " << scIT.currentKey().CStr() << endl;
}
The Section object can be one of the various section
types. The odb_isA method
can be used to determine the section type. For example, to determine
whether a section is of type homogeneous solid section and to
print it's thickness and associated material name:
for (scIT.first(); !scIT.isDone(); scIT.next()) {
const odb_Section& mySection = scIT.currentValue();
if (odb_isA(odb_HomogeneousSolidSection,mySection)) {
odb_HomogeneousSolidSection homogeneousSolidSection =
odb_dynamicCast(
odb_HomogeneousSolidSection, mySection);
odb_String material =
homogeneousSolidSection.material();
cout << "material name = " << material.CStr() << endl;
float thickness = homogeneousSolidSection.thickness();
cout << "thickness = " << thickness << endl;
}
}
Similarily, to access the beam profile repository:
odb_ProfileContainer profileContainer =
sectionApi.profiles();
int numProfiles = sectionApi.numProfiles();
cout << "Total Number of profiles in the ODB: "
<< numProfiles << endl;
The Profile object can be one of the various profile
types. The odb_isA method
can be used to determine the profile type. For example, to output the
radius of all circular profiles in the odb:
odb_ProfileContainerIT pcIT(profileContainer);
for (pcIT.first(); !pcIT.isDone(); pcIT.next()) {
const odb_Profile& myProfile = pcIT.currentValue();
if (odb_isA(odb_CircularProfile,myProfile)) {
odb_CircularProfile circularProfile =
odb_dynamicCast( odb_CircularProfile, myProfile );
cout << "profile name = " << myProfile.name().CStr()
<< " radius = " << circularProfile.r();
}
}
- Section
assignments
-
Section assignments are stored in the sectionAssignments
repository under the OdbAssembly object.
All elements in an
Abaqus
analysis need to be associated with section and material properties. Section
assignments provide the relationship between elements in a part instance and
their section properties. The section properties include the associated
material name. To access the sectionAssignments repository from
the PartInstance object:
odb_InstanceRepository& instanceRepository =
odb.rootAssembly().instances();
odb_InstanceRepositoryIT instIT(instanceRepository);
for (instIT.first(); !instIT.isDone(); instIT.next()) {
const odb_Instance& instance = instIT.currentValue();
odb_SequenceSectionAssignment sectionAssignmentSeq =
instance.sectionAssignments();
int sects = sectionAssignmentSeq.size();
cout << "Instance : " << instance.name().CStr() << endl;
for (int s = 0; s < sects; ++s) {
odb_SectionAssignment sa = sectionAssignmentSeq[s];
odb_String sectionName = sa.sectionName();
cout << " Section : " << sectionName.CStr() << endl;
odb_Set set = sa.region();
const odb_SequenceElement& elements = set.elements();
int size = elements.size();
cout << " Elements associated with this section : "
<< endl;
for (int e = 0; e< size; ++e)
cout << elements[e].label() << endl;
}
}